aboutsummaryrefslogtreecommitdiff
path: root/src/mm-generic-gsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-generic-gsm.c')
-rw-r--r--src/mm-generic-gsm.c224
1 files changed, 132 insertions, 92 deletions
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index 1e33a99c..1ca4920c 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -4,22 +4,21 @@
#include <stdio.h>
#include <string.h>
#include "mm-generic-gsm.h"
+#include "mm-gsm-modem.h"
#include "mm-modem-error.h"
#include "mm-callback-info.h"
-static void modem_init (MMModem *modem_class);
-
-G_DEFINE_TYPE_EXTENDED (MMGenericGsm, mm_generic_gsm, MM_TYPE_SERIAL,
- 0, G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init))
+static gpointer mm_generic_gsm_parent_class = NULL;
#define MM_GENERIC_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_GENERIC_GSM, MMGenericGsmPrivate))
typedef struct {
char *driver;
+ guint32 cid;
guint32 pending_id;
} MMGenericGsmPrivate;
-static void register_auto (MMModem *modem, MMCallbackInfo *info);
+static void register_auto (MMGsmModem *modem, MMCallbackInfo *info);
MMModem *
mm_generic_gsm_new (const char *serial_device, const char *driver)
@@ -33,6 +32,14 @@ mm_generic_gsm_new (const char *serial_device, const char *driver)
NULL));
}
+guint32
+mm_generic_gsm_get_cid (MMGenericGsm *modem)
+{
+ g_return_val_if_fail (MM_IS_GENERIC_GSM (modem), 0);
+
+ return MM_GENERIC_GSM_GET_PRIVATE (modem)->cid;
+}
+
/*****************************************************************************/
static void
@@ -175,7 +182,7 @@ set_pin_done (MMSerial *serial,
}
static void
-set_pin (MMModem *modem,
+set_pin (MMGsmModem *modem,
const char *pin,
MMModemFn callback,
gpointer user_data)
@@ -185,7 +192,7 @@ set_pin (MMModem *modem,
char *responses[] = { "OK", "ERROR", "ERR", NULL };
guint id = 0;
- info = mm_callback_info_new (modem, callback, user_data);
+ info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
command = g_strdup_printf ("AT+CPIN=\"%s\"", pin);
if (mm_serial_send_command_string (MM_SERIAL (modem), command))
@@ -222,7 +229,7 @@ register_manual_done (MMSerial *serial,
}
static void
-register_manual (MMModem *modem, const char *network_id, MMCallbackInfo *info)
+register_manual (MMGsmModem *modem, const char *network_id, MMCallbackInfo *info)
{
char *command;
char *responses[] = { "OK", "ERROR", "ERR", NULL };
@@ -246,7 +253,7 @@ automatic_registration_again (gpointer data)
{
MMCallbackInfo *info = (MMCallbackInfo *) data;
- register_auto (MM_MODEM (mm_callback_info_get_data (info, "modem")), info);
+ register_auto (MM_GSM_MODEM (mm_callback_info_get_data (info, "modem")), info);
mm_callback_info_set_data (info, "modem", NULL, NULL);
@@ -292,7 +299,7 @@ register_auto_done (MMSerial *serial,
}
static void
-register_auto (MMModem *modem, MMCallbackInfo *info)
+register_auto (MMGsmModem *modem, MMCallbackInfo *info)
{
char *responses[] = { "+CREG: 0,0", "+CREG: 0,1", "+CREG: 0,2", "+CREG: 0,3", "+CREG: 0,5", NULL };
char *terminators[] = { "OK", "ERROR", "ERR", NULL };
@@ -309,14 +316,14 @@ register_auto (MMModem *modem, MMCallbackInfo *info)
}
static void
-do_register (MMModem *modem,
+do_register (MMGsmModem *modem,
const char *network_id,
MMModemFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
- info = mm_callback_info_new (modem, callback, user_data);
+ info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
if (network_id)
register_manual (modem, network_id, info);
@@ -325,9 +332,9 @@ do_register (MMModem *modem,
}
static void
-dial_done (MMSerial *serial,
- int reply_index,
- gpointer user_data)
+connect_done (MMSerial *serial,
+ int reply_index,
+ gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
@@ -355,15 +362,21 @@ dial_done (MMSerial *serial,
mm_callback_info_schedule (info);
}
-
static void
-dial (MMModem *modem, guint cid, const char *number, MMCallbackInfo *info)
+connect (MMModem *modem,
+ const char *number,
+ MMModemFn callback,
+ gpointer user_data)
{
+ MMCallbackInfo *info;
char *command;
char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL };
guint id = 0;
+ guint32 cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (modem));
+
+ info = mm_callback_info_new (modem, callback, user_data);
- if (cid) {
+ if (cid > 0) {
GString *str;
str = g_string_new ("ATD");
@@ -378,7 +391,7 @@ dial (MMModem *modem, guint cid, const char *number, MMCallbackInfo *info)
command = g_strconcat ("ATDT", number, NULL);
if (mm_serial_send_command_string (MM_SERIAL (modem), command))
- id = mm_serial_wait_for_reply (MM_SERIAL (modem), 60, responses, responses, dial_done, info);
+ id = mm_serial_wait_for_reply (MM_SERIAL (modem), 60, responses, responses, connect_done, info);
g_free (command);
@@ -389,65 +402,6 @@ dial (MMModem *modem, guint cid, const char *number, MMCallbackInfo *info)
}
static void
-set_apn_done (MMSerial *serial,
- int reply_index,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- const char *number = (char *) mm_callback_info_get_data (info, "number");
-
- switch (reply_index) {
- case 0:
- dial (MM_MODEM (serial), 1, number, info);
- break;
- default:
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Setting APN failed");
- break;
- }
-
- if (info->error)
- mm_callback_info_schedule (info);
-}
-
-static void
-set_apn (MMModem *modem, const char *apn, MMCallbackInfo *info)
-{
- char *command;
- char *responses[] = { "OK", "ERROR", NULL };
- guint cid = 1;
- guint id = 0;
-
- command = g_strdup_printf ("AT+CGDCONT=%d, \"IP\", \"%s\"", cid, apn);
- if (mm_serial_send_command_string (MM_SERIAL (modem), command))
- id = mm_serial_wait_for_reply (MM_SERIAL (modem), 3, responses, responses, set_apn_done, info);
-
- g_free (command);
-
- if (!id) {
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Setting APN failed.");
- mm_callback_info_schedule (info);
- }
-}
-
-static void
-connect (MMModem *modem,
- const char *number,
- const char *apn,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- if (apn) {
- mm_callback_info_set_data (info, "number", g_strdup (number), g_free);
- set_apn (modem, apn, info);
- } else
- dial (modem, 0, number, info);
-}
-
-static void
disconnect (MMModem *modem,
MMModemFn callback,
gpointer user_data)
@@ -465,15 +419,15 @@ scan_callback_wrapper (MMModem *modem,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMModemScanFn scan_fn;
+ MMGsmModemScanFn scan_fn;
GPtrArray *results;
gpointer data;
- scan_fn = (MMModemScanFn) mm_callback_info_get_data (info, "scan-callback");
+ scan_fn = (MMGsmModemScanFn) mm_callback_info_get_data (info, "scan-callback");
results = (GPtrArray *) mm_callback_info_get_data (info, "scan-results");
data = mm_callback_info_get_data (info, "scan-data");
- scan_fn (modem, results, error, data);
+ scan_fn (MM_GSM_MODEM (modem), results, error, data);
}
static void
@@ -536,15 +490,15 @@ scan_done (MMSerial *serial, const char *reply, gpointer user_data)
}
static void
-scan (MMModem *modem,
- MMModemScanFn callback,
+scan (MMGsmModem *modem,
+ MMGsmModemScanFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
char *terminators = "\r\n";
guint id = 0;
- info = mm_callback_info_new (modem, scan_callback_wrapper, NULL);
+ info = mm_callback_info_new (MM_MODEM (modem), scan_callback_wrapper, NULL);
info->user_data = info;
mm_callback_info_set_data (info, "scan-callback", callback, NULL);
mm_callback_info_set_data (info, "scan-data", user_data, NULL);
@@ -559,6 +513,53 @@ scan (MMModem *modem,
}
static void
+set_apn_done (MMSerial *serial,
+ int reply_index,
+ gpointer user_data)
+{
+ MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+
+ switch (reply_index) {
+ case 0:
+ /* success */
+ MM_GENERIC_GSM_GET_PRIVATE (serial)->cid = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "CID"));
+ break;
+ default:
+ info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Setting APN failed");
+ break;
+ }
+
+ mm_callback_info_schedule (info);
+}
+
+static void
+set_apn (MMGsmModem *modem,
+ const char *apn,
+ MMModemFn callback,
+ gpointer user_data)
+{
+ MMCallbackInfo *info;
+ char *command;
+ char *responses[] = { "OK", "ERROR", NULL };
+ guint cid = 1;
+ guint id = 0;
+
+ info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
+ mm_callback_info_set_data (info, "CID", GUINT_TO_POINTER (cid), NULL);
+
+ command = g_strdup_printf ("AT+CGDCONT=%d, \"IP\", \"%s\"", cid, apn);
+ if (mm_serial_send_command_string (MM_SERIAL (modem), command))
+ id = mm_serial_wait_for_reply (MM_SERIAL (modem), 3, responses, responses, set_apn_done, info);
+
+ g_free (command);
+
+ if (!id) {
+ info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Setting APN failed.");
+ mm_callback_info_schedule (info);
+ }
+}
+
+static void
get_signal_quality_done (MMSerial *serial, const char *reply, gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
@@ -588,7 +589,7 @@ get_signal_quality_done (MMSerial *serial, const char *reply, gpointer user_data
}
static void
-get_signal_quality (MMModem *modem,
+get_signal_quality (MMGsmModem *modem,
MMModemUIntFn callback,
gpointer user_data)
{
@@ -596,7 +597,7 @@ get_signal_quality (MMModem *modem,
char *terminators = "\r\n";
guint id = 0;
- info = mm_callback_info_uint_new (modem, callback, user_data);
+ info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
if (mm_serial_send_command_string (MM_SERIAL (modem), "AT+CSQ"))
id = mm_serial_get_reply (MM_SERIAL (modem), 10, terminators, get_signal_quality_done, info);
@@ -612,14 +613,19 @@ get_signal_quality (MMModem *modem,
static void
modem_init (MMModem *modem_class)
{
- /* interface implementation */
modem_class->enable = enable;
- modem_class->set_pin = set_pin;
- modem_class->do_register = do_register;
modem_class->connect = connect;
modem_class->disconnect = disconnect;
- modem_class->scan = scan;
- modem_class->get_signal_quality = get_signal_quality;
+}
+
+static void
+gsm_modem_init (MMGsmModem *gsm_modem_class)
+{
+ gsm_modem_class->set_pin = set_pin;
+ gsm_modem_class->do_register = do_register;
+ gsm_modem_class->set_apn = set_apn;
+ gsm_modem_class->scan = scan;
+ gsm_modem_class->get_signal_quality = get_signal_quality;
}
static void
@@ -685,6 +691,7 @@ mm_generic_gsm_class_init (MMGenericGsmClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ mm_generic_gsm_parent_class = g_type_class_peek_parent (klass);
g_type_class_add_private (object_class, sizeof (MMGenericGsmPrivate));
/* Virtual methods */
@@ -704,6 +711,39 @@ mm_generic_gsm_class_init (MMGenericGsmClass *klass)
g_object_class_override_property (object_class,
MM_MODEM_PROP_TYPE,
MM_MODEM_TYPE);
+}
+
+GType
+mm_generic_gsm_get_type (void)
+{
+ static GType generic_gsm_type = 0;
+
+ if (G_UNLIKELY (generic_gsm_type == 0)) {
+ static const GTypeInfo generic_gsm_type_info = {
+ sizeof (MMGenericGsmClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mm_generic_gsm_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (MMGenericGsm),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mm_generic_gsm_init,
+ };
+
+ static const GInterfaceInfo modem_iface_info = {
+ (GInterfaceInitFunc) modem_init
+ };
+
+ static const GInterfaceInfo gsm_modem_iface_info = {
+ (GInterfaceInitFunc) gsm_modem_init
+ };
+
+ generic_gsm_type = g_type_register_static (MM_TYPE_SERIAL, "MMGenericGsm", &generic_gsm_type_info, 0);
+
+ g_type_add_interface_static (generic_gsm_type, MM_TYPE_MODEM, &modem_iface_info);
+ g_type_add_interface_static (generic_gsm_type, MM_TYPE_GSM_MODEM, &gsm_modem_iface_info);
+ }
- mm_modem_install_dbus_info (G_TYPE_FROM_CLASS (klass));
+ return generic_gsm_type;
}