aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTambet Ingo <tambet@gmail.com>2008-08-22 14:50:02 +0300
committerTambet Ingo <tambet@gmail.com>2008-08-22 14:50:02 +0300
commit36b1ba72d4180e8bf5e2ffef51af23efdc6f8530 (patch)
tree77a5e7b33837d4dad5044908b390942488e8a0b7 /src
parent91ac2260b75236f87f3c4d9b101656acef27c311 (diff)
Grab the registration information right after a successful registration.
The registration information is stored now because in the generic case, it is not possible to issue AT commands when the device is connected.
Diffstat (limited to 'src')
-rw-r--r--src/mm-generic-gsm.c297
-rw-r--r--src/mm-generic-gsm.h8
-rw-r--r--src/mm-gsm-modem.c2
-rw-r--r--src/mm-gsm-modem.h4
4 files changed, 181 insertions, 130 deletions
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index 518b8198..1c089c1e 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -14,6 +14,9 @@ static gpointer mm_generic_gsm_parent_class = NULL;
typedef struct {
char *driver;
+ char *oper_code;
+ char *oper_name;
+ MMGsmModemRegStatus reg_status;
guint32 cid;
guint32 pending_id;
} MMGenericGsmPrivate;
@@ -40,6 +43,33 @@ mm_generic_gsm_get_cid (MMGenericGsm *modem)
return MM_GENERIC_GSM_GET_PRIVATE (modem)->cid;
}
+void
+mm_generic_gsm_set_reg_status (MMGenericGsm *modem,
+ MMGsmModemRegStatus status)
+{
+ g_return_if_fail (MM_IS_GENERIC_GSM (modem));
+
+ MM_GENERIC_GSM_GET_PRIVATE (modem)->reg_status = status;
+}
+
+void
+mm_generic_gsm_set_operator (MMGenericGsm *modem,
+ const char *code,
+ const char *name)
+{
+ MMGenericGsmPrivate *priv;
+
+ g_return_if_fail (MM_IS_GENERIC_GSM (modem));
+
+ priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
+
+ g_free (priv->oper_code);
+ g_free (priv->oper_name);
+
+ priv->oper_code = g_strdup (code);
+ priv->oper_name = g_strdup (name);
+}
+
/*****************************************************************************/
static void
@@ -206,44 +236,85 @@ set_pin (MMGsmModem *modem,
}
}
+static char *
+parse_operator (const char *reply)
+{
+ char *operator = NULL;
+
+ if (reply && !strncmp (reply, "+COPS: ", 7)) {
+ /* Got valid reply */
+ GRegex *r;
+ GMatchInfo *match_info;
+
+ reply += 7;
+ r = g_regex_new ("(\\d),(\\d),\"(.+)\"", G_REGEX_UNGREEDY, 0, NULL);
+ if (!r)
+ return NULL;
+
+ g_regex_match (r, reply, 0, &match_info);
+ if (g_match_info_matches (match_info))
+ operator = g_match_info_fetch (match_info, 3);
+
+ g_match_info_free (match_info);
+ g_regex_unref (r);
+ }
+
+ return operator;
+}
+
static void
-register_manual_done (MMSerial *serial,
- int reply_index,
- gpointer user_data)
+get_reg_name_done (MMSerial *serial, const char *reply, gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+ char *oper;
- switch (reply_index) {
- case 0:
- /* success */
- break;
- case -1:
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Manual registration timed out");
- break;
- default:
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Manual registration failed");
- break;
- }
+ oper = parse_operator (reply);
+ if (!oper)
+ g_warning ("Could not parse operator");
+
+ mm_generic_gsm_set_operator (MM_GENERIC_GSM (serial),
+ (char *) mm_callback_info_get_data (info, "reg-info-oper-code"),
+ oper);
+ g_free (oper);
mm_callback_info_schedule (info);
}
static void
-register_manual (MMGsmModem *modem, const char *network_id, MMCallbackInfo *info)
+get_reg_code_done (MMSerial *serial, const char *reply, gpointer user_data)
{
- char *command;
- char *responses[] = { "OK", "ERROR", "ERR", NULL };
+ MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+ char *oper;
guint id = 0;
- command = g_strdup_printf ("AT+COPS=1,2,\"%s\"", network_id);
- if (mm_serial_send_command_string (MM_SERIAL (modem), command))
- id = mm_serial_wait_for_reply (MM_SERIAL (modem), 30, responses, responses,
- register_manual_done, info);
+ oper = parse_operator (reply);
+ if (oper) {
+ char *terminators = "\r\n";
- g_free (command);
+ mm_callback_info_set_data (info, "reg-info-oper-code", oper, g_free);
+
+ if (mm_serial_send_command_string (serial, "AT+COPS=3,0;+COPS?"))
+ id = mm_serial_get_reply (MM_SERIAL (serial), 5, terminators, get_reg_name_done, info);
+ }
if (!id) {
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Manual registration failed.");
+ g_warning ("Could not read operator");
+ mm_callback_info_schedule (info);
+ }
+}
+
+static void
+read_operator (MMGenericGsm *modem,
+ MMCallbackInfo *info)
+{
+ char *terminators = "\r\n";
+ guint id = 0;
+
+ if (mm_serial_send_command_string (MM_SERIAL (modem), "AT+COPS=3,2;+COPS?"))
+ id = mm_serial_get_reply (MM_SERIAL (modem), 5, terminators, get_reg_code_done, info);
+
+ if (!id) {
+ g_warning ("Reading operator code failed.");
mm_callback_info_schedule (info);
}
}
@@ -272,15 +343,19 @@ get_reg_status_done (MMSerial *serial,
info->uint_result = (guint32) MM_GSM_MODEM_REG_STATUS_ROAMING;
break;
case -1:
+ info->uint_result = (guint32) MM_GSM_MODEM_REG_STATUS_UNKNOWN;
info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s",
"Reading registration status timed out");
break;
default:
+ info->uint_result = (guint32) MM_GSM_MODEM_REG_STATUS_UNKNOWN;
info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s",
"Reading registration status failed");
break;
}
+ mm_generic_gsm_set_reg_status (MM_GENERIC_GSM (serial), info->uint_result);
+
mm_callback_info_schedule (info);
}
@@ -304,6 +379,64 @@ get_registration_status (MMGsmModem *modem, MMModemUIntFn callback, gpointer use
}
}
+static void
+register_manual_get_status_done (MMModem *modem,
+ guint32 result,
+ GError *error,
+ gpointer user_data)
+{
+ MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+
+ if (result == MM_GSM_MODEM_REG_STATUS_HOME || result == MM_GSM_MODEM_REG_STATUS_ROAMING)
+ read_operator (MM_GENERIC_GSM (modem), info);
+ else
+ mm_callback_info_schedule (info);
+}
+
+static void
+register_manual_done (MMSerial *serial,
+ int reply_index,
+ gpointer user_data)
+{
+ MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+
+ switch (reply_index) {
+ case 0:
+ /* success */
+ get_registration_status (MM_GSM_MODEM (serial), register_manual_get_status_done, info);
+ break;
+ case -1:
+ info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Manual registration timed out");
+ break;
+ default:
+ info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Manual registration failed");
+ break;
+ }
+
+ if (info->error)
+ mm_callback_info_schedule (info);
+}
+
+static void
+register_manual (MMGsmModem *modem, const char *network_id, MMCallbackInfo *info)
+{
+ char *command;
+ char *responses[] = { "OK", "ERROR", "ERR", NULL };
+ guint id = 0;
+
+ command = g_strdup_printf ("AT+COPS=1,2,\"%s\"", network_id);
+ if (mm_serial_send_command_string (MM_SERIAL (modem), command))
+ id = mm_serial_wait_for_reply (MM_SERIAL (modem), 30, responses, responses,
+ register_manual_done, info);
+
+ g_free (command);
+
+ if (!id) {
+ info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Manual registration failed.");
+ mm_callback_info_schedule (info);
+ }
+}
+
static gboolean
automatic_registration_again (gpointer data)
{
@@ -355,7 +488,11 @@ register_auto_done (MMModem *modem,
}
out:
- mm_callback_info_schedule (info);
+
+ if (info->error)
+ mm_callback_info_schedule (info);
+ else
+ read_operator (MM_GENERIC_GSM (modem), info);
}
static void
@@ -381,129 +518,35 @@ do_register (MMGsmModem *modem,
}
-static char *
-parse_operator (const char *reply)
-{
- char *operator = NULL;
-
- if (reply && !strncmp (reply, "+COPS: ", 7)) {
- /* Got valid reply */
- GRegex *r;
- GMatchInfo *match_info;
-
- reply += 7;
- r = g_regex_new ("(\\d),(\\d),\"(.+)\"", G_REGEX_UNGREEDY, 0, NULL);
- if (!r)
- return NULL;
-
- g_regex_match (r, reply, 0, &match_info);
- if (g_match_info_matches (match_info))
- operator = g_match_info_fetch (match_info, 3);
-
- g_match_info_free (match_info);
- g_regex_unref (r);
- }
-
- return operator;
-}
-
static void
-reg_info_callback_wrapper (MMModem *modem,
- GError *error,
- gpointer user_data)
+get_registration_info_done (MMModem *modem, GError *error, gpointer user_data)
{
+ MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
MMGsmModemRegInfoFn reg_info_fn;
reg_info_fn = (MMGsmModemRegInfoFn) mm_callback_info_get_data (info, "reg-info-callback");
reg_info_fn (MM_GSM_MODEM (modem),
- GPOINTER_TO_UINT (mm_callback_info_get_data (info, "reg-info-status")),
- (char *) mm_callback_info_get_data (info, "reg-info-oper-code"),
- (char *) mm_callback_info_get_data (info, "reg-info-oper-name"),
- error,
+ priv->reg_status,
+ priv->oper_code,
+ priv->oper_name,
+ NULL,
mm_callback_info_get_data (info, "reg-info-data"));
}
static void
-get_reg_name_done (MMSerial *serial, const char *reply, gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- char *oper;
-
- oper = parse_operator (reply);
- if (oper)
- mm_callback_info_set_data (info, "reg-info-oper-name", oper, g_free);
- else
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Could not parse operator");
-
- mm_callback_info_schedule (info);
-}
-
-static void
-get_reg_code_done (MMSerial *serial, const char *reply, gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- char *oper;
-
- oper = parse_operator (reply);
- if (oper) {
- char *terminators = "\r\n";
- guint id = 0;
-
- mm_callback_info_set_data (info, "reg-info-oper-code", oper, g_free);
-
- if (mm_serial_send_command_string (serial, "AT+COPS=3,0;+COPS?"))
- id = mm_serial_get_reply (MM_SERIAL (serial), 5, terminators, get_reg_name_done, info);
-
- if (!id)
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Reading operator name failed.");
- } else
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Could not parse operator");
-
- if (info->error)
- mm_callback_info_schedule (info);
-}
-
-static void
-get_reg_info_status_done (MMModem *modem,
- guint32 result,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- char *terminators = "\r\n";
- guint id = 0;
-
- if (!error) {
- mm_callback_info_set_data (info, "reg-info-status", GUINT_TO_POINTER (result), NULL);
- if (mm_serial_send_command_string (MM_SERIAL (modem), "AT+COPS=3,2;+COPS?"))
- id = mm_serial_get_reply (MM_SERIAL (modem), 5, terminators, get_reg_code_done, info);
- }
-
- if (!id) {
- if (error)
- info->error = g_error_copy (error);
- else
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s",
- "Reading operator code failed.");
-
- mm_callback_info_schedule (info);
- }
-}
-
-static void
get_registration_info (MMGsmModem *self,
MMGsmModemRegInfoFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
- info = mm_callback_info_new (MM_MODEM (self), reg_info_callback_wrapper, NULL);
+ info = mm_callback_info_new (MM_MODEM (self), get_registration_info_done, NULL);
info->user_data = info;
mm_callback_info_set_data (info, "reg-info-callback", callback, NULL);
mm_callback_info_set_data (info, "reg-info-data", user_data, NULL);
- get_registration_status (self, get_reg_info_status_done, info);
+ mm_callback_info_schedule (info);
}
static void
@@ -858,6 +901,8 @@ finalize (GObject *object)
}
g_free (priv->driver);
+ g_free (priv->oper_code);
+ g_free (priv->oper_name);
G_OBJECT_CLASS (mm_generic_gsm_parent_class)->finalize (object);
}
diff --git a/src/mm-generic-gsm.h b/src/mm-generic-gsm.h
index 24214432..a439bae5 100644
--- a/src/mm-generic-gsm.h
+++ b/src/mm-generic-gsm.h
@@ -3,7 +3,7 @@
#ifndef MM_GENERIC_GSM_H
#define MM_GENERIC_GSM_H
-#include "mm-modem.h"
+#include "mm-gsm-modem.h"
#include "mm-serial.h"
#define MM_TYPE_GENERIC_GSM (mm_generic_gsm_get_type ())
@@ -27,5 +27,11 @@ MMModem *mm_generic_gsm_new (const char *serial_device,
const char *driver);
guint32 mm_generic_gsm_get_cid (MMGenericGsm *modem);
+void mm_generic_gsm_set_reg_status (MMGenericGsm *modem,
+ MMGsmModemRegStatus status);
+
+void mm_generic_gsm_set_operator (MMGenericGsm *modem,
+ const char *code,
+ const char *name);
#endif /* MM_GENERIC_GSM_H */
diff --git a/src/mm-gsm-modem.c b/src/mm-gsm-modem.c
index f175354a..29dc8c21 100644
--- a/src/mm-gsm-modem.c
+++ b/src/mm-gsm-modem.c
@@ -168,7 +168,7 @@ mm_gsm_modem_get_reg_info (MMGsmModem *self,
static void
get_reg_info_done (MMGsmModem *modem,
- NMGsmModemRegStatus status,
+ MMGsmModemRegStatus status,
const char *oper_code,
const char *oper_name,
GError *error,
diff --git a/src/mm-gsm-modem.h b/src/mm-gsm-modem.h
index 1d1ab569..ea51f4fb 100644
--- a/src/mm-gsm-modem.h
+++ b/src/mm-gsm-modem.h
@@ -46,7 +46,7 @@ typedef enum {
MM_GSM_MODEM_REG_STATUS_DENIED = 3,
MM_GSM_MODEM_REG_STATUS_UNKNOWN = 4,
MM_GSM_MODEM_REG_STATUS_ROAMING = 5
-} NMGsmModemRegStatus;
+} MMGsmModemRegStatus;
typedef struct _MMGsmModem MMGsmModem;
@@ -56,7 +56,7 @@ typedef void (*MMGsmModemScanFn) (MMGsmModem *modem,
gpointer user_data);
typedef void (*MMGsmModemRegInfoFn) (MMGsmModem *modem,
- NMGsmModemRegStatus status,
+ MMGsmModemRegStatus status,
const char *oper_code,
const char *oper_name,
GError *error,