huawei,call: handle in-call URCs in the call object itself

Instead of handling the URCs in the modem object and using the
MMIfaceModem as a bridge to report the status read from the URC to a
call obtained from the MMCallList... just handle the URCs in the call
object itself.
This commit is contained in:
Aleksander Morgado
2018-06-15 00:04:15 +02:00
committed by Dan Williams
parent f71e120fb7
commit fc0feee654
8 changed files with 205 additions and 435 deletions

View File

@@ -103,12 +103,6 @@ struct _MMBroadbandModemHuaweiPrivate {
GRegex *dsflowrpt_regex; GRegex *dsflowrpt_regex;
GRegex *ndisstat_regex; GRegex *ndisstat_regex;
/* Regex for voice call related notifications */
GRegex *conf_regex;
GRegex *conn_regex;
GRegex *cend_regex;
GRegex *ddtmf_regex;
/* Regex to ignore */ /* Regex to ignore */
GRegex *boot_regex; GRegex *boot_regex;
GRegex *connect_regex; GRegex *connect_regex;
@@ -151,8 +145,8 @@ struct _MMBroadbandModemHuaweiPrivate {
/*****************************************************************************/ /*****************************************************************************/
static GList * GList *
get_at_port_list (MMBroadbandModemHuawei *self) mm_broadband_modem_huawei_get_at_port_list (MMBroadbandModemHuawei *self)
{ {
GList *out = NULL; GList *out = NULL;
MMPortSerialAt *port; MMPortSerialAt *port;
@@ -1853,7 +1847,7 @@ set_3gpp_unsolicited_events_handlers (MMBroadbandModemHuawei *self,
{ {
GList *ports, *l; GList *ports, *l;
ports = get_at_port_list (self); ports = mm_broadband_modem_huawei_get_at_port_list (self);
/* Enable/disable unsolicited events in given port */ /* Enable/disable unsolicited events in given port */
for (l = ports; l; l = g_list_next (l)) { for (l = ports; l; l = g_list_next (l)) {
@@ -2517,7 +2511,7 @@ set_cdma_unsolicited_events_handlers (MMBroadbandModemHuawei *self,
{ {
GList *ports, *l; GList *ports, *l;
ports = get_at_port_list (self); ports = mm_broadband_modem_huawei_get_at_port_list (self);
/* Enable/disable unsolicited events in given port */ /* Enable/disable unsolicited events in given port */
for (l = ports; l; l = g_list_next (l)) { for (l = ports; l; l = g_list_next (l)) {
@@ -2862,200 +2856,6 @@ get_detailed_registration_state (MMIfaceModemCdma *self,
task); task);
} }
/*****************************************************************************/
/* Setup/Cleanup unsolicited events (Voice interface) */
static void
huawei_voice_ringback_tone (MMPortSerialAt *port,
GMatchInfo *match_info,
MMBroadbandModemHuawei *self)
{
guint call_x = 0;
if (!mm_get_uint_from_match_info (match_info, 1, &call_x))
return;
mm_dbg ("[^CONF] Ringback tone from call id '%u'", call_x);
mm_iface_modem_voice_call_dialing_to_ringing (MM_IFACE_MODEM_VOICE (self));
}
static void
huawei_voice_call_connection (MMPortSerialAt *port,
GMatchInfo *match_info,
MMBroadbandModemHuawei *self)
{
guint call_x = 0;
guint call_type = 0;
if (!mm_get_uint_from_match_info (match_info, 1, &call_x))
return;
if (!mm_get_uint_from_match_info (match_info, 2, &call_type))
return;
mm_dbg ("[^CONN] Call id '%u' of type '%u' connected", call_x, call_type);
mm_iface_modem_voice_call_ringing_to_active (MM_IFACE_MODEM_VOICE (self));
}
static void
huawei_voice_call_end (MMPortSerialAt *port,
GMatchInfo *match_info,
MMBroadbandModemHuawei *self)
{
guint call_x = 0;
guint duration = 0;
guint cc_cause = 0;
guint end_status = 0;
if (!mm_get_uint_from_match_info (match_info, 1, &call_x))
return;
if (!mm_get_uint_from_match_info (match_info, 2, &duration))
return;
if (!mm_get_uint_from_match_info (match_info, 3, &end_status))
return;
//This is optional
mm_get_uint_from_match_info (match_info, 4, &cc_cause);
mm_dbg ("[^CEND] Call '%u' terminated with status '%u' and cause '%u'. Duration of call '%d'", call_x, end_status, cc_cause, duration);
mm_iface_modem_voice_network_hangup (MM_IFACE_MODEM_VOICE (self));
}
static void
huawei_voice_received_dtmf (MMPortSerialAt *port,
GMatchInfo *match_info,
MMBroadbandModemHuawei *self)
{
gchar *key;
key = g_match_info_fetch (match_info, 1);
if (key) {
mm_dbg ("[^DDTMF] Received DTMF '%s'", key);
mm_iface_modem_voice_received_dtmf (MM_IFACE_MODEM_VOICE (self), key);
}
}
static void
set_voice_unsolicited_events_handlers (MMBroadbandModemHuawei *self,
gboolean enable)
{
GList *ports, *l;
ports = get_at_port_list (self);
/* Enable/disable unsolicited events in given port */
for (l = ports; l; l = g_list_next (l)) {
MMPortSerialAt *port = MM_PORT_SERIAL_AT (l->data);
mm_port_serial_at_add_unsolicited_msg_handler (
port,
self->priv->conf_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_ringback_tone : NULL,
enable ? self : NULL,
NULL);
mm_port_serial_at_add_unsolicited_msg_handler (
port,
self->priv->conn_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_call_connection : NULL,
enable ? self : NULL,
NULL);
mm_port_serial_at_add_unsolicited_msg_handler (
port,
self->priv->cend_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_call_end : NULL,
enable ? self : NULL,
NULL);
mm_port_serial_at_add_unsolicited_msg_handler (
port,
self->priv->ddtmf_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_received_dtmf: NULL,
enable ? self : NULL,
NULL);
}
g_list_free_full (ports, g_object_unref);
}
static gboolean
modem_voice_setup_cleanup_unsolicited_events_finish (MMIfaceModemVoice *self,
GAsyncResult *res,
GError **error)
{
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
parent_voice_setup_unsolicited_events_ready (MMIfaceModemVoice *self,
GAsyncResult *res,
GTask *task)
{
GError *error = NULL;
if (!iface_modem_voice_parent->setup_unsolicited_events_finish (self, res, &error))
g_task_return_error (task, error);
else {
/* Our own setup now */
set_voice_unsolicited_events_handlers (MM_BROADBAND_MODEM_HUAWEI (self), TRUE);
g_task_return_boolean (task, TRUE);
}
g_object_unref (task);
}
static void
modem_voice_setup_unsolicited_events (MMIfaceModemVoice *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
task = g_task_new (self, NULL, callback, user_data);
/* Chain up parent's setup */
iface_modem_voice_parent->setup_unsolicited_events (
self,
(GAsyncReadyCallback)parent_voice_setup_unsolicited_events_ready,
task);
}
static void
parent_voice_cleanup_unsolicited_events_ready (MMIfaceModemVoice *self,
GAsyncResult *res,
GTask *task)
{
GError *error = NULL;
if (!iface_modem_voice_parent->cleanup_unsolicited_events_finish (self, res, &error))
g_task_return_error (task, error);
else
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
static void
modem_voice_cleanup_unsolicited_events (MMIfaceModemVoice *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
task = g_task_new (self, NULL, callback, user_data);
/* Our own cleanup first */
set_voice_unsolicited_events_handlers (MM_BROADBAND_MODEM_HUAWEI (self), FALSE);
/* And now chain up parent's cleanup */
iface_modem_voice_parent->cleanup_unsolicited_events (
self,
(GAsyncReadyCallback)parent_voice_cleanup_unsolicited_events_ready,
task);
}
/*****************************************************************************/ /*****************************************************************************/
/* Enabling unsolicited events (Voice interface) */ /* Enabling unsolicited events (Voice interface) */
@@ -3275,7 +3075,7 @@ enable_disable_unsolicited_rfswitch_event_handler (MMBroadbandModemHuawei *self,
{ {
GList *ports, *l; GList *ports, *l;
ports = get_at_port_list (self); ports = mm_broadband_modem_huawei_get_at_port_list (self);
mm_dbg ("%s ^RFSWITCH unsolicited event handler", mm_dbg ("%s ^RFSWITCH unsolicited event handler",
enable ? "Enable" : "Disable"); enable ? "Enable" : "Disable");
@@ -4053,7 +3853,7 @@ set_ignored_unsolicited_events_handlers (MMBroadbandModemHuawei *self)
{ {
GList *ports, *l; GList *ports, *l;
ports = get_at_port_list (self); ports = mm_broadband_modem_huawei_get_at_port_list (self);
/* Enable/disable unsolicited events in given port */ /* Enable/disable unsolicited events in given port */
for (l = ports; l; l = g_list_next (l)) { for (l = ports; l; l = g_list_next (l)) {
@@ -4162,7 +3962,6 @@ setup_ports (MMBroadbandModem *self)
/* Now reset the unsolicited messages we'll handle when enabled */ /* Now reset the unsolicited messages we'll handle when enabled */
set_3gpp_unsolicited_events_handlers (MM_BROADBAND_MODEM_HUAWEI (self), FALSE); set_3gpp_unsolicited_events_handlers (MM_BROADBAND_MODEM_HUAWEI (self), FALSE);
set_cdma_unsolicited_events_handlers (MM_BROADBAND_MODEM_HUAWEI (self), FALSE); set_cdma_unsolicited_events_handlers (MM_BROADBAND_MODEM_HUAWEI (self), FALSE);
set_voice_unsolicited_events_handlers(MM_BROADBAND_MODEM_HUAWEI (self), FALSE);
/* NMEA GPS monitoring */ /* NMEA GPS monitoring */
gps_data_port = mm_base_modem_peek_port_gps (MM_BASE_MODEM (self)); gps_data_port = mm_base_modem_peek_port_gps (MM_BASE_MODEM (self));
@@ -4259,28 +4058,8 @@ mm_broadband_modem_huawei_init (MMBroadbandModemHuawei *self)
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
self->priv->eons_regex = g_regex_new ("\\r\\n\\^EONS:.+\\r\\n", self->priv->eons_regex = g_regex_new ("\\r\\n\\^EONS:.+\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
/* Voice related regex
* <CR><LF>^ORIG: <call_x>,<call_type><CR><LF> (ignored)
* <CR><LF>^CONF: <call_x><CR><LF>
* <CR><LF>^CONN: <call_x>,<call_type><CR><LF>
* <CR><LF>^CEND: <call_x>,<duration>,<end_status>[,<cc_cause>]<CR><LF>
*/
self->priv->orig_regex = g_regex_new ("\\r\\n\\^ORIG:.+\\r\\n", self->priv->orig_regex = g_regex_new ("\\r\\n\\^ORIG:.+\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
self->priv->conf_regex = g_regex_new ("\\r\\n\\^CONF:\\s*(\\d+)\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
self->priv->conn_regex = g_regex_new ("\\r\\n\\^CONN:\\s*(\\d+),(\\d+)\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
self->priv->cend_regex = g_regex_new ("\\r\\n\\^CEND:\\s*(\\d+),\\s*(\\d+),\\s*(\\d+),?\\s*(\\d*)\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
/* Voice: receive DTMF regex
* <CR><LF>^DDTMF: <key><CR><LF>
* Key should be 0-9, A-D, *, #
*/
self->priv->ddtmf_regex = g_regex_new ("\\r\\n\\^DDTMF:\\s*([0-9A-D\\*\\#])\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
self->priv->ndisdup_support = FEATURE_SUPPORT_UNKNOWN; self->priv->ndisdup_support = FEATURE_SUPPORT_UNKNOWN;
self->priv->rfswitch_support = FEATURE_SUPPORT_UNKNOWN; self->priv->rfswitch_support = FEATURE_SUPPORT_UNKNOWN;
@@ -4330,13 +4109,9 @@ finalize (GObject *object)
g_regex_unref (self->priv->posend_regex); g_regex_unref (self->priv->posend_regex);
g_regex_unref (self->priv->ecclist_regex); g_regex_unref (self->priv->ecclist_regex);
g_regex_unref (self->priv->ltersrp_regex); g_regex_unref (self->priv->ltersrp_regex);
g_regex_unref (self->priv->orig_regex);
g_regex_unref (self->priv->conf_regex);
g_regex_unref (self->priv->conn_regex);
g_regex_unref (self->priv->cend_regex);
g_regex_unref (self->priv->ddtmf_regex);
g_regex_unref (self->priv->cschannelinfo_regex); g_regex_unref (self->priv->cschannelinfo_regex);
g_regex_unref (self->priv->eons_regex); g_regex_unref (self->priv->eons_regex);
g_regex_unref (self->priv->orig_regex);
if (self->priv->syscfg_supported_modes) if (self->priv->syscfg_supported_modes)
g_array_unref (self->priv->syscfg_supported_modes); g_array_unref (self->priv->syscfg_supported_modes);
@@ -4451,10 +4226,6 @@ iface_modem_voice_init (MMIfaceModemVoice *iface)
{ {
iface_modem_voice_parent = g_type_interface_peek_parent (iface); iface_modem_voice_parent = g_type_interface_peek_parent (iface);
iface->setup_unsolicited_events = modem_voice_setup_unsolicited_events;
iface->setup_unsolicited_events_finish = modem_voice_setup_cleanup_unsolicited_events_finish;
iface->cleanup_unsolicited_events = modem_voice_cleanup_unsolicited_events;
iface->cleanup_unsolicited_events_finish = modem_voice_setup_cleanup_unsolicited_events_finish;
iface->enable_unsolicited_events = modem_voice_enable_unsolicited_events; iface->enable_unsolicited_events = modem_voice_enable_unsolicited_events;
iface->enable_unsolicited_events_finish = modem_voice_enable_unsolicited_events_finish; iface->enable_unsolicited_events_finish = modem_voice_enable_unsolicited_events_finish;
iface->disable_unsolicited_events = modem_voice_disable_unsolicited_events; iface->disable_unsolicited_events = modem_voice_disable_unsolicited_events;

View File

@@ -50,5 +50,6 @@ MMBroadbandModemHuawei *mm_broadband_modem_huawei_new (const gchar *device,
MMPortSerialAt *mm_broadband_modem_huawei_peek_port_at_for_data (MMBroadbandModemHuawei *self, MMPortSerialAt *mm_broadband_modem_huawei_peek_port_at_for_data (MMBroadbandModemHuawei *self,
MMPort *port); MMPort *port);
GList *mm_broadband_modem_huawei_get_at_port_list (MMBroadbandModemHuawei *self);
#endif /* MM_BROADBAND_MODEM_HUAWEI_H */ #endif /* MM_BROADBAND_MODEM_HUAWEI_H */

View File

@@ -26,10 +26,178 @@
#include "mm-log.h" #include "mm-log.h"
#include "mm-base-modem-at.h" #include "mm-base-modem-at.h"
#include "mm-broadband-modem-huawei.h"
#include "mm-call-huawei.h" #include "mm-call-huawei.h"
G_DEFINE_TYPE (MMCallHuawei, mm_call_huawei, MM_TYPE_BASE_CALL) G_DEFINE_TYPE (MMCallHuawei, mm_call_huawei, MM_TYPE_BASE_CALL)
struct _MMCallHuaweiPrivate {
GRegex *conf_regex;
GRegex *conn_regex;
GRegex *cend_regex;
GRegex *ddtmf_regex;
};
/*****************************************************************************/
/* In-call unsolicited events */
static void
huawei_voice_ringback_tone (MMPortSerialAt *port,
GMatchInfo *match_info,
MMCallHuawei *self)
{
guint call_x = 0;
if (!mm_get_uint_from_match_info (match_info, 1, &call_x))
return;
mm_dbg ("Ringback tone from call id '%u'", call_x);
if (mm_gdbus_call_get_state (MM_GDBUS_CALL (self)) == MM_CALL_STATE_DIALING)
mm_base_call_change_state (MM_BASE_CALL (self), MM_CALL_STATE_RINGING_OUT, MM_CALL_STATE_REASON_OUTGOING_STARTED);
}
static void
huawei_voice_call_connection (MMPortSerialAt *port,
GMatchInfo *match_info,
MMCallHuawei *self)
{
guint call_x = 0;
guint call_type = 0;
if (!mm_get_uint_from_match_info (match_info, 1, &call_x))
return;
if (!mm_get_uint_from_match_info (match_info, 2, &call_type))
return;
mm_dbg ("Call id '%u' of type '%u' connected", call_x, call_type);
if (mm_gdbus_call_get_state (MM_GDBUS_CALL (self)) == MM_CALL_STATE_RINGING_OUT)
mm_base_call_change_state (MM_BASE_CALL (self), MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_ACCEPTED);
}
static void
huawei_voice_call_end (MMPortSerialAt *port,
GMatchInfo *match_info,
MMCallHuawei *self)
{
guint call_x = 0;
guint duration = 0;
guint cc_cause = 0;
guint end_status = 0;
if (!mm_get_uint_from_match_info (match_info, 1, &call_x))
return;
if (!mm_get_uint_from_match_info (match_info, 2, &duration))
return;
if (!mm_get_uint_from_match_info (match_info, 3, &end_status))
return;
/* This is optional */
mm_get_uint_from_match_info (match_info, 4, &cc_cause);
mm_dbg ("Call id '%u' terminated with status '%u' and cause '%u'. Duration of call '%d'",
call_x, end_status, cc_cause, duration);
mm_base_call_change_state (MM_BASE_CALL (self), MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_TERMINATED);
}
static void
huawei_voice_received_dtmf (MMPortSerialAt *port,
GMatchInfo *match_info,
MMCallHuawei *self)
{
gchar *key;
key = g_match_info_fetch (match_info, 1);
if (!key)
return;
mm_dbg ("Received DTMF '%s'", key);
mm_base_call_received_dtmf (MM_BASE_CALL (self), key);
g_free (key);
}
static gboolean
common_setup_cleanup_unsolicited_events (MMCallHuawei *self,
gboolean enable,
GError **error)
{
MMBaseModem *modem = NULL;
GList *ports, *l;
if (G_UNLIKELY (!self->priv->conf_regex))
self->priv->conf_regex = g_regex_new ("\\r\\n\\^CONF:\\s*(\\d+)\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
if (G_UNLIKELY (!self->priv->conn_regex))
self->priv->conn_regex = g_regex_new ("\\r\\n\\^CONN:\\s*(\\d+),(\\d+)\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
if (G_UNLIKELY (!self->priv->cend_regex))
self->priv->cend_regex = g_regex_new ("\\r\\n\\^CEND:\\s*(\\d+),\\s*(\\d+),\\s*(\\d+),?\\s*(\\d*)\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
if (G_UNLIKELY (!self->priv->ddtmf_regex))
self->priv->ddtmf_regex = g_regex_new ("\\r\\n\\^DDTMF:\\s*([0-9A-D\\*\\#])\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
g_object_get (self,
MM_BASE_CALL_MODEM, &modem,
NULL);
ports = mm_broadband_modem_huawei_get_at_port_list (MM_BROADBAND_MODEM_HUAWEI (modem));
for (l = ports; l; l = g_list_next (l)) {
MMPortSerialAt *port;
port = MM_PORT_SERIAL_AT (l->data);
mm_port_serial_at_add_unsolicited_msg_handler (
port,
self->priv->conf_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_ringback_tone : NULL,
enable ? self : NULL,
NULL);
mm_port_serial_at_add_unsolicited_msg_handler (
port,
self->priv->conn_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_call_connection : NULL,
enable ? self : NULL,
NULL);
mm_port_serial_at_add_unsolicited_msg_handler (
port,
self->priv->cend_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_call_end : NULL,
enable ? self : NULL,
NULL);
mm_port_serial_at_add_unsolicited_msg_handler (
port,
self->priv->ddtmf_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_received_dtmf: NULL,
enable ? self : NULL,
NULL);
}
g_list_free_full (ports, g_object_unref);
g_object_unref (modem);
return TRUE;
}
static gboolean
setup_unsolicited_events (MMBaseCall *self,
GError **error)
{
return common_setup_cleanup_unsolicited_events (MM_CALL_HUAWEI (self), TRUE, error);
}
static gboolean
cleanup_unsolicited_events (MMBaseCall *self,
GError **error)
{
return common_setup_cleanup_unsolicited_events (MM_CALL_HUAWEI (self), FALSE, error);
}
/*****************************************************************************/ /*****************************************************************************/
MMBaseCall * MMBaseCall *
@@ -45,13 +213,37 @@ mm_call_huawei_new (MMBaseModem *modem)
static void static void
mm_call_huawei_init (MMCallHuawei *self) mm_call_huawei_init (MMCallHuawei *self)
{ {
/* Initialize private data */
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_CALL_HUAWEI, MMCallHuaweiPrivate);
}
static void
finalize (GObject *object)
{
MMCallHuawei *self = MM_CALL_HUAWEI (object);
if (self->priv->conf_regex)
g_regex_unref (self->priv->conf_regex);
if (self->priv->conn_regex)
g_regex_unref (self->priv->conn_regex);
if (self->priv->cend_regex)
g_regex_unref (self->priv->cend_regex);
if (self->priv->ddtmf_regex)
g_regex_unref (self->priv->ddtmf_regex);
G_OBJECT_CLASS (mm_call_huawei_parent_class)->finalize (object);
} }
static void static void
mm_call_huawei_class_init (MMCallHuaweiClass *klass) mm_call_huawei_class_init (MMCallHuaweiClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass);
MMBaseCallClass *base_call_class = MM_BASE_CALL_CLASS (klass); MMBaseCallClass *base_call_class = MM_BASE_CALL_CLASS (klass);
base_call_class->setup_unsolicited_events = NULL; g_type_class_add_private (object_class, sizeof (MMCallHuaweiPrivate));
base_call_class->cleanup_unsolicited_events = NULL;
object_class->finalize = finalize;
base_call_class->setup_unsolicited_events = setup_unsolicited_events;
base_call_class->cleanup_unsolicited_events = cleanup_unsolicited_events;
} }

View File

@@ -30,9 +30,11 @@
typedef struct _MMCallHuawei MMCallHuawei; typedef struct _MMCallHuawei MMCallHuawei;
typedef struct _MMCallHuaweiClass MMCallHuaweiClass; typedef struct _MMCallHuaweiClass MMCallHuaweiClass;
typedef struct _MMCallHuaweiPrivate MMCallHuaweiPrivate;
struct _MMCallHuawei { struct _MMCallHuawei {
MMBaseCall parent; MMBaseCall parent;
MMCallHuaweiPrivate *priv;
}; };
struct _MMCallHuaweiClass { struct _MMCallHuaweiClass {

View File

@@ -109,99 +109,6 @@ mm_call_list_get_first_ringing_in_call (MMCallList *self)
return NULL; return NULL;
} }
MMBaseCall *
mm_call_list_get_first_ringing_out_call (MMCallList *self)
{
MMBaseCall *call = NULL;
GList *l;
for (l = self->priv->list; l; l = g_list_next (l)) {
MMCallState state;
g_object_get (MM_BASE_CALL (l->data),
"state", &state,
NULL);
if (state == MM_CALL_STATE_RINGING_IN ||
state == MM_CALL_STATE_RINGING_OUT) {
call = MM_BASE_CALL (l->data);
break;
}
}
return call;
}
MMBaseCall *
mm_call_list_get_first_outgoing_dialing_call (MMCallList *self)
{
MMBaseCall *call = NULL;
GList *l;
for (l = self->priv->list; l; l = g_list_next (l)) {
MMCallState state;
MMCallDirection direction;
g_object_get (MM_BASE_CALL (l->data),
"state", &state,
"direction", &direction,
NULL);
if (direction == MM_CALL_DIRECTION_OUTGOING &&
state == MM_CALL_STATE_DIALING) {
call = MM_BASE_CALL (l->data);
break;
}
}
return call;
}
MMBaseCall *
mm_call_list_get_first_non_terminated_call (MMCallList *self)
{
MMBaseCall *call = NULL;
GList *l;
for (l = self->priv->list; l; l = g_list_next (l)) {
MMCallState state;
g_object_get (MM_BASE_CALL (l->data),
"state", &state,
NULL);
if (state != MM_CALL_STATE_TERMINATED) {
call = MM_BASE_CALL (l->data);
break;
}
}
return call;
}
gboolean
mm_call_list_send_dtmf_to_active_calls (MMCallList *self,
const gchar *dtmf)
{
gboolean signaled = FALSE;
GList *l;
for (l = self->priv->list; l; l = g_list_next (l)) {
MMCallState state;
g_object_get (MM_BASE_CALL (l->data),
"state", &state,
NULL);
if (state == MM_CALL_STATE_ACTIVE) {
signaled = TRUE;
mm_base_call_received_dtmf (MM_BASE_CALL (l->data), dtmf);
}
}
return signaled;
}
/*****************************************************************************/ /*****************************************************************************/
static guint static guint

View File

@@ -69,10 +69,5 @@ gboolean mm_call_list_delete_call (MMCallList *self,
GError **error); GError **error);
MMBaseCall *mm_call_list_get_first_ringing_in_call (MMCallList *self); MMBaseCall *mm_call_list_get_first_ringing_in_call (MMCallList *self);
MMBaseCall *mm_call_list_get_first_ringing_out_call (MMCallList *self);
MMBaseCall *mm_call_list_get_first_outgoing_dialing_call (MMCallList *self);
MMBaseCall *mm_call_list_get_first_non_terminated_call (MMCallList *self);
gboolean mm_call_list_send_dtmf_to_active_calls (MMCallList *self,
const gchar *dtmf);
#endif /* MM_CALL_LIST_H */ #endif /* MM_CALL_LIST_H */

View File

@@ -123,99 +123,6 @@ mm_iface_modem_voice_update_incoming_call_number (MMIfaceModemVoice *self,
return updated; return updated;
} }
gboolean
mm_iface_modem_voice_call_dialing_to_ringing (MMIfaceModemVoice *self)
{
gboolean updated = FALSE;
MMBaseCall *call = NULL;
MMCallList *list = NULL;
g_object_get (MM_BASE_MODEM (self),
MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
NULL);
if (list) {
call = mm_call_list_get_first_outgoing_dialing_call (list);
if (call) {
mm_base_call_change_state (call, MM_CALL_STATE_RINGING_OUT, MM_CALL_STATE_REASON_OUTGOING_STARTED);
updated = TRUE;
} else {
mm_dbg ("Outgoing dialing call does not exist");
}
}
return updated;
}
gboolean
mm_iface_modem_voice_call_ringing_to_active (MMIfaceModemVoice *self)
{
gboolean updated = FALSE;
MMBaseCall *call = NULL;
MMCallList *list = NULL;
g_object_get (MM_BASE_MODEM (self),
MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
NULL);
if (list) {
call = mm_call_list_get_first_ringing_out_call (list);
if (call) {
mm_base_call_change_state (call, MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_ACCEPTED);
updated = TRUE;
} else {
mm_dbg ("Ringing call does not exist");
}
}
return updated;
}
gboolean
mm_iface_modem_voice_network_hangup (MMIfaceModemVoice *self)
{
gboolean updated = FALSE;
MMBaseCall *call = NULL;
MMCallList *list = NULL;
g_object_get (MM_BASE_MODEM (self),
MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
NULL);
if (list) {
call = mm_call_list_get_first_non_terminated_call (list);
if (call) {
mm_base_call_change_state (call, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_TERMINATED);
updated = TRUE;
} else {
mm_dbg ("No call to hangup");
}
}
return updated;
}
gboolean
mm_iface_modem_voice_received_dtmf (MMIfaceModemVoice *self,
gchar *dtmf)
{
gboolean updated = FALSE;
MMCallList *list = NULL;
g_object_get (MM_BASE_MODEM (self),
MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
NULL);
if (list) {
updated = mm_call_list_send_dtmf_to_active_calls (list, dtmf);
}
return updated;
}
/*****************************************************************************/ /*****************************************************************************/
typedef struct { typedef struct {

View File

@@ -123,11 +123,6 @@ gboolean mm_iface_modem_voice_update_incoming_call_number (MMIfaceModemVoi
gchar *number, gchar *number,
guint type, guint type,
guint validity); guint validity);
gboolean mm_iface_modem_voice_call_dialing_to_ringing (MMIfaceModemVoice *self);
gboolean mm_iface_modem_voice_call_ringing_to_active (MMIfaceModemVoice *self);
gboolean mm_iface_modem_voice_network_hangup (MMIfaceModemVoice *self);
gboolean mm_iface_modem_voice_received_dtmf (MMIfaceModemVoice *self,
gchar *dtmf);
/* Look for a new valid multipart reference */ /* Look for a new valid multipart reference */
guint8 mm_iface_modem_voice_get_local_multipart_reference (MMIfaceModemVoice *self, guint8 mm_iface_modem_voice_get_local_multipart_reference (MMIfaceModemVoice *self,