broadband-modem: added voice call support

This commit is contained in:
Riccardo Vangelisti
2015-08-02 10:39:12 +02:00
committed by Aleksander Morgado
parent 886e2963df
commit 5c446c3f43
4 changed files with 417 additions and 0 deletions
+370
View File
@@ -13,6 +13,7 @@
* Copyright (C) 2008 - 2009 Novell, Inc.
* Copyright (C) 2009 - 2012 Red Hat, Inc.
* Copyright (C) 2011 - 2012 Google, Inc.
* Copyright (C) 2015 - Marco Bascetta <marco.bascetta@sadel.it>
*/
#include <config.h>
@@ -35,6 +36,7 @@
#include "mm-iface-modem-simple.h"
#include "mm-iface-modem-location.h"
#include "mm-iface-modem-messaging.h"
#include "mm-iface-modem-voice.h"
#include "mm-iface-modem-time.h"
#include "mm-iface-modem-firmware.h"
#include "mm-iface-modem-signal.h"
@@ -43,6 +45,7 @@
#include "mm-bearer-list.h"
#include "mm-sms-list.h"
#include "mm-sms-part-3gpp.h"
#include "mm-call-list.h"
#include "mm-base-sim.h"
#include "mm-log.h"
#include "mm-modem-helpers.h"
@@ -58,6 +61,7 @@ static void iface_modem_cdma_init (MMIfaceModemCdma *iface);
static void iface_modem_simple_init (MMIfaceModemSimple *iface);
static void iface_modem_location_init (MMIfaceModemLocation *iface);
static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
static void iface_modem_voice_init (MMIfaceModemVoice *iface);
static void iface_modem_time_init (MMIfaceModemTime *iface);
static void iface_modem_signal_init (MMIfaceModemSignal *iface);
static void iface_modem_oma_init (MMIfaceModemOma *iface);
@@ -71,6 +75,7 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModem, mm_broadband_modem, MM_TYPE_BASE_MODEM
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_SIMPLE, iface_modem_simple_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_VOICE, iface_modem_voice_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_SIGNAL, iface_modem_signal_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_OMA, iface_modem_oma_init)
@@ -85,6 +90,7 @@ enum {
PROP_MODEM_SIMPLE_DBUS_SKELETON,
PROP_MODEM_LOCATION_DBUS_SKELETON,
PROP_MODEM_MESSAGING_DBUS_SKELETON,
PROP_MODEM_VOICE_DBUS_SKELETON,
PROP_MODEM_TIME_DBUS_SKELETON,
PROP_MODEM_SIGNAL_DBUS_SKELETON,
PROP_MODEM_OMA_DBUS_SKELETON,
@@ -104,6 +110,7 @@ enum {
PROP_MODEM_MESSAGING_SMS_LIST,
PROP_MODEM_MESSAGING_SMS_PDU_MODE,
PROP_MODEM_MESSAGING_SMS_DEFAULT_STORAGE,
PROP_MODEM_VOICE_CALL_LIST,
PROP_MODEM_SIMPLE_STATUS,
PROP_LAST
};
@@ -188,6 +195,10 @@ struct _MMBroadbandModemPrivate {
gboolean mem2_storage_locked;
MMSmsStorage current_sms_mem2_storage;
/*<--- Modem Voice interface --->*/
/* Properties */
GObject *modem_voice_dbus_skeleton;
MMCallList *modem_voice_call_list;
/*<--- Modem Time interface --->*/
/* Properties */
@@ -6200,6 +6211,283 @@ modem_messaging_create_sms (MMIfaceModemMessaging *self)
return mm_base_sms_new (MM_BASE_MODEM (self));
}
/*****************************************************************************/
/* Check if Voice supported (Voice interface) */
static gboolean
modem_voice_check_support_finish (MMIfaceModemVoice *self,
GAsyncResult *res,
GError **error)
{
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}
static void
ath_format_check_ready (MMBroadbandModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (error) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* ATH command is supported; assume we have full voice capabilities */
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
modem_voice_check_support (MMIfaceModemVoice *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_voice_check_support);
/* We assume that all modems has voice capabilities, but ... */
/* Check ATH support */
mm_base_modem_at_command (MM_BASE_MODEM (self),
"H",
3,
TRUE,
(GAsyncReadyCallback)ath_format_check_ready,
result);
}
/*****************************************************************************/
/* Setup/cleanup voice related unsolicited events (Voice interface) */
static gboolean
modem_voice_setup_cleanup_unsolicited_events_finish (MMIfaceModemVoice *self,
GAsyncResult *res,
GError **error)
{
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}
static void
ring_received (MMPortSerialAt *port,
GMatchInfo *info,
MMBroadbandModem *self)
{
//Do not match anything from regex
(void)info;
mm_iface_modem_voice_create_call(MM_IFACE_MODEM_VOICE(self));
}
static void
cring_received (MMPortSerialAt *port,
GMatchInfo *info,
MMBroadbandModem *self)
{
gchar *str;
/* The match info gives us in which storage the index applies */
str = mm_get_string_unquoted_from_match_info (info, 1);
//TODO: In str you could have "VOICE" or "DATA". Now consider only "VOICE"
g_free (str);
mm_iface_modem_voice_create_call(MM_IFACE_MODEM_VOICE(self));
}
static void
dtmf_received (MMPortSerialAt *port,
GMatchInfo *info,
MMBroadbandModem *self)
{
// GError *error = NULL;
// MMCallPart *part;
// guint length;
// gchar *pdu;
//
// mm_dbg ("Got new non-stored message indication");
//
// if (!mm_get_uint_from_match_info (info, 1, &length))
// return;
//
// pdu = g_match_info_fetch (info, 2);
// if (!pdu)
// return;
//
// part = mm_call_part_3gpp_new_from_pdu (CALL_PART_INVALID_INDEX, pdu, &error);
// if (part) {
// mm_dbg ("Correctly parsed non-stored PDU");
// mm_iface_modem_voice_take_part (MM_IFACE_MODEM_VOICE (self),
// part,
// MM_CALL_STATE_RECEIVED,
// MM_CALL_STORAGE_UNKNOWN);
// } else {
// /* Don't treat the error as critical */
// mm_dbg ("Error parsing non-stored PDU: %s", error->message);
// g_error_free (error);
// }
}
static void
set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self,
gboolean enable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
MMPortSerialAt *ports[2];
GRegex *cring_regex;
GRegex *ring_regex;
GRegex *dtmf_regex;
guint i;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
set_voice_unsolicited_events_handlers);
cring_regex = mm_voice_cring_regex_get ();
ring_regex = mm_voice_ring_regex_get ();
dtmf_regex = mm_voice_dtmf_regex_get ();
ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
/* Enable unsolicited events in given port */
for (i = 0; i < 2; i++) {
if (!ports[i])
continue;
/* Set/unset unsolicited CMTI event handler */
mm_dbg ("(%s) %s voice unsolicited events handlers",
mm_port_get_device (MM_PORT (ports[i])),
enable ? "Setting" : "Removing");
mm_port_serial_at_add_unsolicited_msg_handler (
ports[i],
cring_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn) cring_received : NULL,
enable ? self : NULL,
NULL);
mm_port_serial_at_add_unsolicited_msg_handler (
ports[i],
ring_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn) ring_received : NULL,
enable ? self : NULL,
NULL);
mm_port_serial_at_add_unsolicited_msg_handler (
ports[i],
dtmf_regex,
enable ? (MMPortSerialAtUnsolicitedMsgFn) dtmf_received : NULL,
enable ? self : NULL,
NULL);
}
g_regex_unref (cring_regex);
g_regex_unref (ring_regex);
g_regex_unref (dtmf_regex);
g_simple_async_result_set_op_res_gboolean (result, TRUE);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
static void
modem_voice_setup_unsolicited_events (MMIfaceModemVoice *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
set_voice_unsolicited_events_handlers (self, TRUE, callback, user_data);
}
static void
modem_voice_cleanup_unsolicited_events (MMIfaceModemVoice *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
set_voice_unsolicited_events_handlers (self, FALSE, callback, user_data);
}
/*****************************************************************************/
/* Enable unsolicited events (CALL indications) (Voice interface) */
static gboolean
modem_voice_enable_unsolicited_events_finish (MMIfaceModemVoice *self,
GAsyncResult *res,
GError **error)
{
GError *inner_error = NULL;
mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &inner_error);
if (inner_error) {
g_propagate_error (error, inner_error);
return FALSE;
}
return TRUE;
}
static gboolean
ring_response_processor (MMBaseModem *self,
gpointer none,
const gchar *command,
const gchar *response,
gboolean last_command,
const GError *error,
GVariant **result,
GError **result_error)
{
if (error) {
/* If we get a not-supported error and we're not in the last command, we
* won't set 'result_error', so we'll keep on the sequence */
if (!g_error_matches (error, MM_MESSAGE_ERROR, MM_MESSAGE_ERROR_NOT_SUPPORTED) ||
last_command)
*result_error = g_error_copy (error);
return TRUE;
}
*result = NULL;
return FALSE;
}
static const MMBaseModemAtCommand ring_sequence[] = {
/* Show caller number on RING. */
{ "+CLIP=1", 3, FALSE, ring_response_processor },
/* Show difference between data call and voice call */
{ "+CRC=1", 3, FALSE, ring_response_processor },
{ NULL }
};
static void
modem_voice_enable_unsolicited_events (MMIfaceModemVoice *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
mm_base_modem_at_sequence (
MM_BASE_MODEM (self),
ring_sequence,
NULL, /* response_processor_context */
NULL, /* response_processor_context_free */
callback,
user_data);
}
/*****************************************************************************/
/* Create CALL (Voice interface) */
static MMBaseCall *
modem_voice_create_call (MMIfaceModemVoice *self)
{
return mm_base_call_new (MM_BASE_MODEM (self));
}
/*****************************************************************************/
/* ESN loading (CDMA interface) */
@@ -8123,6 +8411,7 @@ typedef enum {
DISABLING_STEP_IFACE_OMA,
DISABLING_STEP_IFACE_TIME,
DISABLING_STEP_IFACE_MESSAGING,
DISABLING_STEP_IFACE_VOICE,
DISABLING_STEP_IFACE_LOCATION,
DISABLING_STEP_IFACE_CONTACTS,
DISABLING_STEP_IFACE_CDMA,
@@ -8231,6 +8520,7 @@ INTERFACE_DISABLE_READY_FN (iface_modem_3gpp_ussd, MM_IFACE_MODEM_3GPP_USSD, TRU
INTERFACE_DISABLE_READY_FN (iface_modem_cdma, MM_IFACE_MODEM_CDMA, TRUE)
INTERFACE_DISABLE_READY_FN (iface_modem_location, MM_IFACE_MODEM_LOCATION, FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_messaging, MM_IFACE_MODEM_MESSAGING, FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_voice, MM_IFACE_MODEM_VOICE, FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_signal, MM_IFACE_MODEM_SIGNAL, FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_time, MM_IFACE_MODEM_TIME, FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_oma, MM_IFACE_MODEM_OMA, FALSE)
@@ -8379,6 +8669,18 @@ disabling_step (DisablingContext *ctx)
/* Fall down to next step */
ctx->step++;
case DISABLING_STEP_IFACE_VOICE:
if (ctx->self->priv->modem_voice_dbus_skeleton) {
mm_dbg ("Modem has voice capabilities, disabling the Voice interface...");
/* Disabling the Modem Voice interface */
mm_iface_modem_voice_disable (MM_IFACE_MODEM_VOICE (ctx->self),
(GAsyncReadyCallback)iface_modem_voice_disable_ready,
ctx);
return;
}
/* Fall down to next step */
ctx->step++;
case DISABLING_STEP_IFACE_LOCATION:
if (ctx->self->priv->modem_location_dbus_skeleton) {
mm_dbg ("Modem has location capabilities, disabling the Location interface...");
@@ -8485,6 +8787,7 @@ typedef enum {
ENABLING_STEP_IFACE_CONTACTS,
ENABLING_STEP_IFACE_LOCATION,
ENABLING_STEP_IFACE_MESSAGING,
ENABLING_STEP_IFACE_VOICE,
ENABLING_STEP_IFACE_TIME,
ENABLING_STEP_IFACE_SIGNAL,
ENABLING_STEP_IFACE_OMA,
@@ -8585,6 +8888,7 @@ INTERFACE_ENABLE_READY_FN (iface_modem_3gpp_ussd, MM_IFACE_MODEM_3GPP_USSD, TRUE
INTERFACE_ENABLE_READY_FN (iface_modem_cdma, MM_IFACE_MODEM_CDMA, TRUE)
INTERFACE_ENABLE_READY_FN (iface_modem_location, MM_IFACE_MODEM_LOCATION, FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_messaging, MM_IFACE_MODEM_MESSAGING, FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_voice, MM_IFACE_MODEM_VOICE, FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_signal, MM_IFACE_MODEM_SIGNAL, FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_time, MM_IFACE_MODEM_TIME, FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_oma, MM_IFACE_MODEM_OMA, FALSE)
@@ -8744,6 +9048,19 @@ enabling_step (EnablingContext *ctx)
/* Fall down to next step */
ctx->step++;
case ENABLING_STEP_IFACE_VOICE:
if (ctx->self->priv->modem_voice_dbus_skeleton) {
mm_dbg ("Modem has voice capabilities, enabling the Voice interface...");
/* Enabling the Modem Voice interface */
mm_iface_modem_voice_enable (MM_IFACE_MODEM_VOICE (ctx->self),
ctx->cancellable,
(GAsyncReadyCallback)iface_modem_voice_enable_ready,
ctx);
return;
}
/* Fall down to next step */
ctx->step++;
case ENABLING_STEP_IFACE_TIME:
if (ctx->self->priv->modem_time_dbus_skeleton) {
mm_dbg ("Modem has time capabilities, enabling the Time interface...");
@@ -8892,6 +9209,7 @@ typedef enum {
INITIALIZE_STEP_IFACE_CONTACTS,
INITIALIZE_STEP_IFACE_LOCATION,
INITIALIZE_STEP_IFACE_MESSAGING,
INITIALIZE_STEP_IFACE_VOICE,
INITIALIZE_STEP_IFACE_TIME,
INITIALIZE_STEP_IFACE_SIGNAL,
INITIALIZE_STEP_IFACE_OMA,
@@ -9089,6 +9407,7 @@ INTERFACE_INIT_READY_FN (iface_modem_3gpp_ussd, MM_IFACE_MODEM_3GPP_USSD, FALSE)
INTERFACE_INIT_READY_FN (iface_modem_cdma, MM_IFACE_MODEM_CDMA, TRUE)
INTERFACE_INIT_READY_FN (iface_modem_location, MM_IFACE_MODEM_LOCATION, FALSE)
INTERFACE_INIT_READY_FN (iface_modem_messaging, MM_IFACE_MODEM_MESSAGING, FALSE)
INTERFACE_INIT_READY_FN (iface_modem_voice, MM_IFACE_MODEM_VOICE, FALSE)
INTERFACE_INIT_READY_FN (iface_modem_time, MM_IFACE_MODEM_TIME, FALSE)
INTERFACE_INIT_READY_FN (iface_modem_signal, MM_IFACE_MODEM_SIGNAL, FALSE)
INTERFACE_INIT_READY_FN (iface_modem_oma, MM_IFACE_MODEM_OMA, FALSE)
@@ -9196,6 +9515,14 @@ initialize_step (InitializeContext *ctx)
ctx);
return;
case INITIALIZE_STEP_IFACE_VOICE:
/* Initialize the Voice interface */
mm_iface_modem_voice_initialize (MM_IFACE_MODEM_VOICE (ctx->self),
ctx->cancellable,
(GAsyncReadyCallback)iface_modem_voice_initialize_ready,
ctx);
return;
case INITIALIZE_STEP_IFACE_TIME:
/* Initialize the Time interface */
mm_iface_modem_time_initialize (MM_IFACE_MODEM_TIME (ctx->self),
@@ -9259,6 +9586,7 @@ initialize_step (InitializeContext *ctx)
mm_iface_modem_cdma_shutdown (MM_IFACE_MODEM_CDMA (ctx->self));
mm_iface_modem_location_shutdown (MM_IFACE_MODEM_LOCATION (ctx->self));
mm_iface_modem_messaging_shutdown (MM_IFACE_MODEM_MESSAGING (ctx->self));
mm_iface_modem_voice_shutdown (MM_IFACE_MODEM_VOICE (ctx->self));
mm_iface_modem_time_shutdown (MM_IFACE_MODEM_TIME (ctx->self));
mm_iface_modem_simple_shutdown (MM_IFACE_MODEM_SIMPLE (ctx->self));
}
@@ -9463,6 +9791,10 @@ set_property (GObject *object,
g_clear_object (&self->priv->modem_messaging_dbus_skeleton);
self->priv->modem_messaging_dbus_skeleton = g_value_dup_object (value);
break;
case PROP_MODEM_VOICE_DBUS_SKELETON:
g_clear_object (&self->priv->modem_voice_dbus_skeleton);
self->priv->modem_voice_dbus_skeleton = g_value_dup_object (value);
break;
case PROP_MODEM_TIME_DBUS_SKELETON:
g_clear_object (&self->priv->modem_time_dbus_skeleton);
self->priv->modem_time_dbus_skeleton = g_value_dup_object (value);
@@ -9521,6 +9853,10 @@ set_property (GObject *object,
g_clear_object (&self->priv->modem_messaging_sms_list);
self->priv->modem_messaging_sms_list = g_value_dup_object (value);
break;
case PROP_MODEM_VOICE_CALL_LIST:
g_clear_object (&self->priv->modem_voice_call_list);
self->priv->modem_voice_call_list = g_value_dup_object (value);
break;
case PROP_MODEM_MESSAGING_SMS_PDU_MODE:
self->priv->modem_messaging_sms_pdu_mode = g_value_get_boolean (value);
break;
@@ -9567,6 +9903,9 @@ get_property (GObject *object,
case PROP_MODEM_MESSAGING_DBUS_SKELETON:
g_value_set_object (value, self->priv->modem_messaging_dbus_skeleton);
break;
case PROP_MODEM_VOICE_DBUS_SKELETON:
g_value_set_object (value, self->priv->modem_voice_dbus_skeleton);
break;
case PROP_MODEM_TIME_DBUS_SKELETON:
g_value_set_object (value, self->priv->modem_time_dbus_skeleton);
break;
@@ -9618,6 +9957,9 @@ get_property (GObject *object,
case PROP_MODEM_MESSAGING_SMS_LIST:
g_value_set_object (value, self->priv->modem_messaging_sms_list);
break;
case PROP_MODEM_VOICE_CALL_LIST:
g_value_set_object (value, self->priv->modem_voice_call_list);
break;
case PROP_MODEM_MESSAGING_SMS_PDU_MODE:
g_value_set_boolean (value, self->priv->modem_messaging_sms_pdu_mode);
break;
@@ -9706,6 +10048,11 @@ dispose (GObject *object)
g_clear_object (&self->priv->modem_messaging_dbus_skeleton);
}
if (self->priv->modem_voice_dbus_skeleton) {
mm_iface_modem_voice_shutdown (MM_IFACE_MODEM_VOICE (object));
g_clear_object (&self->priv->modem_voice_dbus_skeleton);
}
if (self->priv->modem_time_dbus_skeleton) {
mm_iface_modem_time_shutdown (MM_IFACE_MODEM_TIME (object));
g_clear_object (&self->priv->modem_time_dbus_skeleton);
@@ -9719,6 +10066,7 @@ dispose (GObject *object)
g_clear_object (&self->priv->modem_sim);
g_clear_object (&self->priv->modem_bearer_list);
g_clear_object (&self->priv->modem_messaging_sms_list);
g_clear_object (&self->priv->modem_voice_call_list);
g_clear_object (&self->priv->modem_simple_status);
G_OBJECT_CLASS (mm_broadband_modem_parent_class)->dispose (object);
@@ -9911,6 +10259,20 @@ iface_modem_messaging_init (MMIfaceModemMessaging *iface)
iface->create_sms = modem_messaging_create_sms;
}
static void
iface_modem_voice_init (MMIfaceModemVoice *iface)
{
iface->check_support = modem_voice_check_support;
iface->check_support_finish = modem_voice_check_support_finish;
iface->setup_unsolicited_events = modem_voice_setup_unsolicited_events;
iface->setup_unsolicited_events_finish = modem_voice_setup_cleanup_unsolicited_events_finish;
iface->enable_unsolicited_events = modem_voice_enable_unsolicited_events;
iface->enable_unsolicited_events_finish = modem_voice_enable_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->create_call = modem_voice_create_call;
}
static void
iface_modem_time_init (MMIfaceModemTime *iface)
{
@@ -9996,6 +10358,10 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
PROP_MODEM_MESSAGING_DBUS_SKELETON,
MM_IFACE_MODEM_MESSAGING_DBUS_SKELETON);
g_object_class_override_property (object_class,
PROP_MODEM_VOICE_DBUS_SKELETON,
MM_IFACE_MODEM_VOICE_DBUS_SKELETON);
g_object_class_override_property (object_class,
PROP_MODEM_TIME_DBUS_SKELETON,
MM_IFACE_MODEM_TIME_DBUS_SKELETON);
@@ -10064,6 +10430,10 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
PROP_MODEM_MESSAGING_SMS_LIST,
MM_IFACE_MODEM_MESSAGING_SMS_LIST);
g_object_class_override_property (object_class,
PROP_MODEM_VOICE_CALL_LIST,
MM_IFACE_MODEM_VOICE_CALL_LIST);
g_object_class_override_property (object_class,
PROP_MODEM_MESSAGING_SMS_PDU_MODE,
MM_IFACE_MODEM_MESSAGING_SMS_PDU_MODE);
+1
View File
@@ -13,6 +13,7 @@
* Copyright (C) 2008 - 2009 Novell, Inc.
* Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2011 Google, Inc.
* Copyright (C) 2015 - Marco Bascetta <marco.bascetta@sadel.it>
*/
#ifndef MM_BROADBAND_MODEM_H
+39
View File
@@ -323,6 +323,45 @@ mm_filter_supported_capabilities (MMModemCapability all,
/*****************************************************************************/
GRegex *
mm_voice_ring_regex_get (void)
{
/* Example:
* <CR><LF>RING<CR><LF>
*/
return g_regex_new ("\\r\\nRING\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE,
0,
NULL);
}
GRegex *
mm_voice_cring_regex_get (void)
{
/* Example:
* <CR><LF>+CRING: VOICE<CR><LF>
* <CR><LF>+CRING: DATA<CR><LF>
*/
return g_regex_new ("\\r\\n\\+CRING:\\s*(\\S+)\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE,
0,
NULL);
}
GRegex *
mm_voice_dtmf_regex_get (void)
{
/* Example:
* <CR><LF>^DDTMF: 1<CR><LF>
*/
return g_regex_new ("\\r\\n\\^DDTMF:\\s*([0-9A-D\\*\\#])\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE,
0,
NULL);
}
/*************************************************************************/
/* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
#define CREG1 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])"
+7
View File
@@ -82,6 +82,13 @@ GArray *mm_filter_supported_modes (const GArray *all,
GArray *mm_filter_supported_capabilities (MMModemCapability all,
const GArray *supported_combinations);
/*****************************************************************************/
/* VOICE specific helpers and utilities */
/*****************************************************************************/
GRegex *mm_voice_ring_regex_get (void);
GRegex *mm_voice_cring_regex_get (void);
GRegex *mm_voice_dtmf_regex_get (void);
/*****************************************************************************/
/* 3GPP specific helpers and utilities */
/*****************************************************************************/