diff options
author | Dan Williams <dcbw@redhat.com> | 2011-04-18 22:48:05 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2011-04-18 22:48:05 -0500 |
commit | 76bdc658d31c8c64dd74a120ec68d8126dd273cf (patch) | |
tree | 285db946c21f859ebb40f592909d65fd8dab5f28 | |
parent | 8333fb657ab6e30e51aec8f4449dc4c505fea6f4 (diff) |
samsung: use common Icera code
Port the differences over to the common Icera code (there were only
two) and remove the duplicate code from the Samsung plugin. The
Icera NWSTATE regex had to be adjusted to capture "-1" in the first
element which wasn't handled before but which I've seen on the
Samsung Y3300 before the card has registered.
-rw-r--r-- | plugins/mm-modem-icera.c | 8 | ||||
-rwxr-xr-x | plugins/mm-modem-samsung-gsm.c | 633 |
2 files changed, 67 insertions, 574 deletions
diff --git a/plugins/mm-modem-icera.c b/plugins/mm-modem-icera.c index 11f95b54..d34e71ee 100644 --- a/plugins/mm-modem-icera.c +++ b/plugins/mm-modem-icera.c @@ -172,12 +172,16 @@ static MMModemGsmAccessTech nwstate_to_act (const char *str) { /* small 'g' means CS, big 'G' means PS */ - if (!strcmp (str, "2G-GPRS")) + if (!strcmp (str, "2g")) + return MM_MODEM_GSM_ACCESS_TECH_GSM; + else if (!strcmp (str, "2G-GPRS")) return MM_MODEM_GSM_ACCESS_TECH_GPRS; else if (!strcmp (str, "2G-EDGE")) return MM_MODEM_GSM_ACCESS_TECH_EDGE; else if (!strcmp (str, "3G")) return MM_MODEM_GSM_ACCESS_TECH_UMTS; + else if (!strcmp (str, "3g")) + return MM_MODEM_GSM_ACCESS_TECH_UMTS; else if (!strcmp (str, "3G-HSDPA")) return MM_MODEM_GSM_ACCESS_TECH_HSDPA; else if (!strcmp (str, "3G-HSUPA")) @@ -671,7 +675,7 @@ mm_modem_icera_register_unsolicted_handlers (MMModemIcera *self, GRegex *regex; /* %NWSTATE: <rssi>,<mccmnc>,<tech>,<connected>,<regulation> */ - regex = g_regex_new ("\\r\\n%NWSTATE:\\s*(\\d+),(\\d+),([^,]*),([^,]*),(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + regex = g_regex_new ("\\r\\n%NWSTATE:\\s*(-?\\d+),(\\d+),([^,]*),([^,]*),(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); mm_at_serial_port_add_unsolicited_msg_handler (port, regex, nwstate_changed, self, NULL); g_regex_unref (regex); diff --git a/plugins/mm-modem-samsung-gsm.c b/plugins/mm-modem-samsung-gsm.c index 2f28c054..ca4dceaf 100755 --- a/plugins/mm-modem-samsung-gsm.c +++ b/plugins/mm-modem-samsung-gsm.c @@ -30,34 +30,28 @@ #include "mm-callback-info.h" #include "mm-modem-gsm-card.h" #include "mm-log.h" +#include "mm-modem-icera.h" static void modem_init (MMModem *modem_class); static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class); static void modem_simple_init (MMModemSimple *class); static void modem_gsm_card_init (MMModemGsmCard *class); - +static void modem_icera_init (MMModemIcera *icera_class); G_DEFINE_TYPE_EXTENDED (MMModemSamsungGsm, mm_modem_samsung_gsm, MM_TYPE_GENERIC_GSM, 0, G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init) G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init) + G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_ICERA, modem_icera_init) G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init) G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_CARD, modem_gsm_card_init)) #define MM_MODEM_SAMSUNG_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_SAMSUNG_GSM, MMModemSamsungGsmPrivate)) -#define SAMSUNG_IPDPACT_DISCONNECTED 0 -#define SAMSUNG_IPDPACT_CONNECTED 1 -#define SAMSUNG_IPDPACT_CONNECTING 2 -#define SAMSUNG_IPDPACT_CONNECTED_FAILED 3 - typedef struct { - char * band; - MMCallbackInfo *connect_pending_data; - - char *username; - char *password; + gboolean disposed; - MMModemGsmAccessTech last_act; + MMModemIceraPrivate *icera; + char *band; } MMModemSamsungGsmPrivate; #define IPDPADDR_TAG "%IPDPADDR: " @@ -68,34 +62,22 @@ mm_modem_samsung_gsm_new (const char *device, const char *driver, const char *plugin) { + MMModem *modem; + g_return_val_if_fail (device != NULL, NULL); g_return_val_if_fail (driver != NULL, NULL); g_return_val_if_fail (plugin != NULL, NULL); - return MM_MODEM (g_object_new (MM_TYPE_MODEM_SAMSUNG_GSM, - MM_MODEM_MASTER_DEVICE, device, - MM_MODEM_DRIVER, driver, - MM_MODEM_PLUGIN, plugin, - MM_MODEM_IP_METHOD, MM_MODEM_IP_METHOD_DHCP, - NULL)); -} - -static void -connect_pending_done (MMModemSamsungGsm *self) -{ - MMModemSamsungGsmPrivate *priv = MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (self); - GError *error = NULL; - - if (priv->connect_pending_data) { - if (priv->connect_pending_data->error) { - error = priv->connect_pending_data->error; - priv->connect_pending_data->error = NULL; - } + modem = MM_MODEM (g_object_new (MM_TYPE_MODEM_SAMSUNG_GSM, + MM_MODEM_MASTER_DEVICE, device, + MM_MODEM_DRIVER, driver, + MM_MODEM_PLUGIN, plugin, + MM_MODEM_IP_METHOD, MM_MODEM_IP_METHOD_DHCP, + NULL)); + if (modem) + MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (modem)->icera = mm_modem_icera_init_private (); - /* Complete the connect */ - mm_generic_gsm_connect_complete (MM_GENERIC_GSM (self), error, priv->connect_pending_data); - priv->connect_pending_data = NULL; - } + return modem; } typedef struct { @@ -136,147 +118,21 @@ band_mm_to_samsung (MMModemGsmBand band, MMModemGsmNetwork *modem) return FALSE; } -static gint samsung_get_cid (MMModemSamsungGsm *self) -{ - gint cid; - - cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (self)); - if (cid < 0) { - g_warn_if_fail (cid >= 0); - cid = 0; - } - - return cid; -} - -static gboolean -parse_ipsys (MMModemSamsungGsm *self, - const char *reply, - MMModemGsmAllowedMode *out_mode) -{ - int mode, domain; - - if (reply == NULL || !g_str_has_prefix (reply, "%IPSYS:")) - return FALSE; - - if (sscanf (reply + 7, "%d,%d", &mode, &domain) == 2) { - MMModemGsmAllowedMode new_mode = MM_MODEM_GSM_ALLOWED_MODE_ANY; - - /* Network mode */ - if (mode == 2) - new_mode = MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED; - else if (mode == 3) - new_mode = MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED; - else if (mode == 0) - new_mode = MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY; - else if (mode == 1) - new_mode = MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY; - - if (out_mode) - *out_mode = new_mode; - - return TRUE; - } - - return FALSE; -} - - -static void -get_allowed_mode_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (info->modem); - MMModemGsmAllowedMode allowed = MM_MODEM_GSM_ALLOWED_MODE_ANY; - - if (error) - info->error = g_error_copy (error); - else if (parse_ipsys (self, response->str, &allowed)) - mm_callback_info_set_result (info, GUINT_TO_POINTER (allowed), NULL); - - mm_callback_info_schedule (info); -} - - static void get_allowed_mode (MMGenericGsm *gsm, MMModemUIntFn callback, gpointer user_data) { - MMCallbackInfo *info; - MMAtSerialPort *port; - - info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data); - - port = mm_generic_gsm_get_best_at_port (gsm, &info->error); - if (!port) { - mm_callback_info_schedule (info); - return; - } - - mm_at_serial_port_queue_command (port, "AT%IPSYS?", 3, get_allowed_mode_done, info); -} - -static void -set_allowed_mode_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - - if (error) - info->error = g_error_copy (error); - - mm_callback_info_schedule (info); + mm_modem_icera_get_allowed_mode (MM_MODEM_ICERA (gsm), callback, user_data); } - static void set_allowed_mode (MMGenericGsm *gsm, MMModemGsmAllowedMode mode, MMModemFn callback, gpointer user_data) { - MMCallbackInfo *info; - MMAtSerialPort *port; - int i; - char *command; - - info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); - - port = mm_generic_gsm_get_best_at_port (gsm, &info->error); - if (!port) { - mm_callback_info_schedule (info); - return; - } - - switch (mode) { - case MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY: - i = 0; - break; - case MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY: - i = 1; - break; - case MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED: - i = 2; - break; - case MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED: - i = 3; - break; - case MM_MODEM_GSM_ALLOWED_MODE_ANY: - default: - i = 5; - break; - } - - command = g_strdup_printf ("AT%%IPSYS=%d,3",i); - - mm_at_serial_port_queue_command (port, command, 3, set_allowed_mode_done, info); - g_free (command); + mm_modem_icera_set_allowed_mode (MM_MODEM_ICERA (gsm), mode, callback, user_data); } static void @@ -543,69 +399,11 @@ get_unlock_retries (MMModemGsmCard *modem, } static void -get_nwstate_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = user_data; - - info->error = mm_modem_check_removed (info->modem, error); - if (!info->error) { - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (info->modem); - MMModemSamsungGsmPrivate *priv = MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (self); - - /* The unsolicited message handler will already have run and - * removed the NWSTATE response, so we have to work around that. - */ - mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->last_act), NULL); - priv->last_act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; - } - - mm_callback_info_schedule (info); -} - -static void get_access_technology (MMGenericGsm *gsm, MMModemUIntFn callback, gpointer user_data) { - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (gsm); - MMAtSerialPort *port; - MMCallbackInfo *info; - - info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data); - - port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (self), &info->error); - if (!port) { - mm_callback_info_schedule (info); - return; - } - - mm_at_serial_port_queue_command (port, "%NWSTATE=1", 3, get_nwstate_done, info); -} - -static void -_samsung_cleanup (MMModemSamsungGsm *self) -{ - MMModemSamsungGsmPrivate *priv = MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (self); - - /* Clear the pending connection if necessary */ - connect_pending_done (self); - g_free (priv->username); - g_free (priv->password); - memset (priv, 0, sizeof (MMModemSamsungGsmPrivate)); -} - -static void -_samsung_change_unsolicited_messages (MMModemSamsungGsm *self, gboolean enabled) -{ - MMAtSerialPort *primary; - - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); - g_assert (primary); - - mm_at_serial_port_queue_command (primary, enabled ? "%NWSTATE=1" : "%NWSTATE=0", 3, NULL, NULL); + mm_modem_icera_get_access_technology (MM_MODEM_ICERA (gsm), callback, user_data); } typedef struct { @@ -637,6 +435,9 @@ disable (MMModem *modem, MMAtSerialPort *primary; DisableInfo *info; + mm_modem_icera_cleanup (MM_MODEM_ICERA (modem)); + mm_modem_icera_change_unsolicited_messages (MM_MODEM_ICERA (modem), FALSE); + info = g_malloc0 (sizeof (DisableInfo)); info->callback = callback; info->user_data = user_data; @@ -645,10 +446,6 @@ disable (MMModem *modem, primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); g_assert (primary); - /* Turn off unsolicited responses */ - _samsung_cleanup (MM_MODEM_SAMSUNG_GSM (modem)); - _samsung_change_unsolicited_messages (MM_MODEM_SAMSUNG_GSM (modem), FALSE); - /* Random command to ensure unsolicited message disable completes */ mm_at_serial_port_queue_command (primary, "AT+CFUN=0", 5, disable_unsolicited_done, info); } @@ -663,7 +460,7 @@ init_all_done (MMAtSerialPort *port, MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (info->modem); if (!error) - _samsung_change_unsolicited_messages (self, TRUE); + mm_modem_icera_change_unsolicited_messages (MM_MODEM_ICERA (self), TRUE); mm_generic_gsm_enable_complete (MM_GENERIC_GSM (self), error, info); } @@ -717,113 +514,12 @@ do_enable (MMGenericGsm *modem, MMModemFn callback, gpointer user_data) } static void -samsung_call_control (MMModemSamsungGsm *self, - gboolean activate, - MMAtSerialResponseFn callback, - gpointer user_data) -{ - char *command; - MMAtSerialPort *primary; - - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); - g_assert (primary); - - command = g_strdup_printf ("%%IPDPACT=%d,%d", samsung_get_cid(self), activate ? 1 : 0); - mm_at_serial_port_queue_command (primary, command, 3, callback, user_data); - g_free (command); -} - -static void -Samsung_enabled (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - - if (error) { - mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), error, info); - } else { - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (info->modem); - MMModemSamsungGsmPrivate *priv = MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (self); - - priv->connect_pending_data = info; - } -} - -static void -auth_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - - if (error) - mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), error, info); - else { - /* Activate the PDP context and start the data session */ - samsung_call_control (MM_MODEM_SAMSUNG_GSM (info->modem), TRUE, Samsung_enabled, info); - } -} - -static void -old_context_clear_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - gint cid; - char *command; - MMAtSerialPort *primary; - - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (info->modem); - MMModemSamsungGsmPrivate *priv = MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (self); - - cid = samsung_get_cid (self); - - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); - g_assert (primary); - - /* Both user and password are required; otherwise firmware returns an error */ - if (!priv->username || !priv->password) - command = g_strdup_printf ("%%IPDPCFG=%d,0,0,\"\",\"\"", cid); - else { - command = g_strdup_printf ("%%IPDPCFG=%d,0,1,\"%s\",\"%s\"", - cid, - priv->password ? priv->password : "", - priv->username ? priv->username : ""); - - } - - mm_at_serial_port_queue_command (primary, command, 3, auth_done, info); - g_free (command); -} - -static void do_connect (MMModem *modem, const char *number, MMModemFn callback, gpointer user_data) { - MMCallbackInfo *info; - - mm_modem_set_state (modem, MM_MODEM_STATE_CONNECTING, MM_MODEM_STATE_REASON_NONE); - - info = mm_callback_info_new (modem, callback, user_data); - - /* Ensure the PDP context is deactivated */ - samsung_call_control (MM_MODEM_SAMSUNG_GSM (info->modem), FALSE, old_context_clear_done, info); -} - -static void -disconnect_ipdpact_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - mm_callback_info_schedule ((MMCallbackInfo *) user_data); + mm_modem_icera_do_connect (MM_MODEM_ICERA (modem), number, callback, user_data); } static void @@ -832,238 +528,15 @@ do_disconnect (MMGenericGsm *gsm, MMModemFn callback, gpointer user_data) { - MMCallbackInfo *info; - MMAtSerialPort *primary; - char *command; - - info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); - - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); - g_assert (primary); - - command = g_strdup_printf ("AT%%IPDPACT=%d,0", cid); - mm_at_serial_port_queue_command (primary, command, 3, disconnect_ipdpact_done, info); - g_free (command); -} - -static void -Samsung_disconnect_done (MMModem *modem, - GError *error, - gpointer user_data) -{ - g_message ("Modem signaled disconnection from the network"); -} - -static void -connection_enabled (MMAtSerialPort *port, - GMatchInfo *match_info, - gpointer user_data) -{ - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (user_data); - MMModemSamsungGsmPrivate *priv = MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (self); - MMCallbackInfo *info = priv->connect_pending_data; - char *str; - int status, cid, tmp; - - cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (self)); - if (cid < 0) - return; - - str = g_match_info_fetch (match_info, 1); - g_return_if_fail (str != NULL); - tmp = atoi (str); - g_free (str); - - /* Make sure the unsolicited message's CID matches the current CID */ - if (tmp != cid) - return; - - str = g_match_info_fetch (match_info, 2); - g_return_if_fail (str != NULL); - status = atoi (str); - g_free (str); - - switch (status) { - case 0: - /* Disconnected */ - if (mm_modem_get_state (MM_MODEM (self)) >= MM_MODEM_STATE_CONNECTED) - mm_modem_disconnect (MM_MODEM (self), Samsung_disconnect_done, NULL); - break; - case 1: - /* Connected */ - connect_pending_done (self); - break; - case 2: - /* Connecting */ - break; - case 3: - /* Call setup failure? */ - if (info) { - info->error = g_error_new_literal (MM_MODEM_ERROR, - MM_MODEM_ERROR_GENERAL, - "Call setup failed"); - } - connect_pending_done (self); - break; - default: - g_warning ("Unknown Samsung connect status %d", status); - break; - } -} - -static void -handle_mode_change (MMAtSerialPort *port, - GMatchInfo *match_info, - gpointer user_data) -{ - MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (user_data); - MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; - char *str; - int rssi = -1; - - str = g_match_info_fetch (match_info, 1); - if (str) { - rssi = atoi (str); - rssi = CLAMP (rssi, -1, 5); - g_free (str); - } - - str = g_match_info_fetch (match_info, 3); - - /* Better technologies are listed first since modems sometimes say - * stuff like "GPRS/EDGE" and that should be handled as EDGE. - */ - if (strcmp (str, "3G-HSDPA-HSUPA")==0) - act = MM_MODEM_GSM_ACCESS_TECH_HSPA; - else if (strcmp (str, "3G-HSUPA")==0) - act = MM_MODEM_GSM_ACCESS_TECH_HSUPA; - else if (strcmp (str, "3G-HSDPA")==0) - act = MM_MODEM_GSM_ACCESS_TECH_HSDPA; - else if (strcmp (str, "3G")==0) - act = MM_MODEM_GSM_ACCESS_TECH_UMTS; - else if (strcmp (str, "3g")==0) - act = MM_MODEM_GSM_ACCESS_TECH_UMTS; - else if (strcmp (str, "2G-EDGE")==0) - act = MM_MODEM_GSM_ACCESS_TECH_EDGE; - else if (strcmp (str, "2G-GPRS")==0) - act = MM_MODEM_GSM_ACCESS_TECH_GPRS; - else if (strcmp (str, "2g")==0) - act = MM_MODEM_GSM_ACCESS_TECH_GSM; - else - act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; - g_free (str); - - MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (self)->last_act = act; - mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (self), act); -} - -static void -free_dns_array (gpointer data) -{ - g_array_free ((GArray *) data, TRUE); + mm_modem_icera_do_disconnect (gsm, cid, callback, user_data); } static void -ip4_config_invoke (MMCallbackInfo *info) -{ - MMModemIp4Fn callback = (MMModemIp4Fn) info->callback; - - callback (info->modem, - GPOINTER_TO_UINT (mm_callback_info_get_data (info, "ip4-address")), - (GArray *) mm_callback_info_get_data (info, "ip4-dns"), - info->error, info->user_data); -} - -static void -get_ip4_config_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - char **items, **iter; - GArray *dns_array; - int i; - guint32 tmp; - gint cid; - - if (error) { - info->error = g_error_copy (error); - goto out; - } else if (!g_str_has_prefix (response->str, IPDPADDR_TAG)) { - info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, - "Retrieving failed: invalid response."); - goto out; - } - - cid = samsung_get_cid (MM_MODEM_SAMSUNG_GSM (info->modem)); - dns_array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 2); - items = g_strsplit (response->str + strlen (IPDPADDR_TAG), ", ", 0); - - /* Appending data from at%IPDPADDR command - * Skipping when i = 2. Gateway address is not what we want - */ - for (iter = items, i = 0; *iter; iter++, i++) { - if (i == 0) { /* CID */ - long int num; - - errno = 0; - num = strtol (*iter, NULL, 10); - if (errno != 0 || num < 0 || (gint) num != cid) { - info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, - "Unknown CID in OWANDATA response (" - "got %d, expected %d)", (guint) num, cid); - break; - } - } else if (i == 1) { /* IP address */ - if (inet_pton (AF_INET, *iter, &tmp) > 0) - mm_callback_info_set_data (info, "ip4-address", GUINT_TO_POINTER (tmp), NULL); - } else if (i == 3) { /* DNS 1 */ - if (inet_pton (AF_INET, *iter, &tmp) > 0) - g_array_append_val (dns_array, tmp); - } else if (i == 4) { /* DNS 2 */ - if (inet_pton (AF_INET, *iter, &tmp) > 0) - g_array_append_val (dns_array, tmp); - } - } - - g_strfreev (items); - mm_callback_info_set_data (info, "ip4-dns", dns_array, free_dns_array); - - out: - mm_callback_info_schedule (info); -} - - -static void get_ip4_config (MMModem *modem, MMModemIp4Fn callback, gpointer user_data) { - MMCallbackInfo *info; - char *command; - MMAtSerialPort *primary; - - info = mm_callback_info_new_full (modem, ip4_config_invoke, G_CALLBACK (callback), user_data); - - command = g_strdup_printf ("AT%%IPDPADDR=%d", samsung_get_cid (MM_MODEM_SAMSUNG_GSM (modem))); - - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); - g_assert (primary); - - mm_at_serial_port_queue_command (primary, command, 3, get_ip4_config_done, info); - g_free (command); -} - -static const char * -get_string_property (GHashTable *properties, const char *name) -{ - GValue *value; - - value = (GValue *) g_hash_table_lookup (properties, name); - if (value && G_VALUE_HOLDS_STRING (value)) - return g_value_get_string (value); - return NULL; + mm_modem_icera_get_ip4_config (MM_MODEM_ICERA (modem), callback, user_data); } static void @@ -1072,18 +545,14 @@ simple_connect (MMModemSimple *simple, MMModemFn callback, gpointer user_data) { - MMModemSamsungGsmPrivate *priv = MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (simple); - MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemSimple *parent_iface; + MMCallbackInfo *info = (MMCallbackInfo *) user_data; - g_free (priv->username); - priv->username = g_strdup (get_string_property (properties, "username")); - g_free (priv->password); - priv->password = g_strdup (get_string_property (properties, "password")); + /* Let icera cache user & password */ + mm_modem_icera_simple_connect (MM_MODEM_ICERA (simple), properties); parent_iface = g_type_interface_peek_parent (MM_MODEM_SIMPLE_GET_INTERFACE (simple)); parent_iface->connect (MM_MODEM_SIMPLE (simple), properties, callback, info); - } static gboolean @@ -1110,27 +579,24 @@ grab_port (MMModem *modem, port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); if (port && MM_IS_AT_SERIAL_PORT (port)) { - GRegex *regex; - g_object_set (port, MM_PORT_CARRIER_DETECT, FALSE, MM_SERIAL_PORT_SEND_DELAY, (guint64) 0, NULL); - /* %NWSTATE: <rssi>,<mccmnc>,<tech>,<connected>,<regulation> */ - regex = g_regex_new ("\\r\\n\\%NWSTATE: (\\d),(\\d+),\\s*([^,\\s]*)\\s*,(.+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_mode_change, modem, NULL); - g_regex_unref (regex); - - /* %IPDPACT: <cid>,<status>,0 */ - regex = g_regex_new ("\\r\\n%IPDPACT:\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, connection_enabled, modem, NULL); - g_regex_unref (regex); + /* Add Icera-specific handlers */ + mm_modem_icera_register_unsolicted_handlers (MM_MODEM_ICERA (gsm), MM_AT_SERIAL_PORT (port)); } return !!port; } +static MMModemIceraPrivate * +get_icera_private (MMModemIcera *icera) +{ + return MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (icera)->icera; +} + static void modem_init (MMModem *modem_class) { @@ -1142,6 +608,12 @@ modem_init (MMModem *modem_class) } static void +modem_icera_init (MMModemIcera *icera) +{ + icera->get_private = get_icera_private; +} + +static void modem_simple_init (MMModemSimple *class) { class->connect = simple_connect; @@ -1166,6 +638,21 @@ mm_modem_samsung_gsm_init (MMModemSamsungGsm *self) } static void +dispose (GObject *object) +{ + MMModemSamsungGsm *self = MM_MODEM_SAMSUNG_GSM (object); + MMModemSamsungGsmPrivate *priv = MM_MODEM_SAMSUNG_GSM_GET_PRIVATE (self); + + if (priv->disposed == FALSE) { + priv->disposed = TRUE; + + mm_modem_icera_dispose_private (MM_MODEM_ICERA (self)); + } + + G_OBJECT_CLASS (mm_modem_samsung_gsm_parent_class)->dispose (object); +} + +static void mm_modem_samsung_gsm_class_init (MMModemSamsungGsmClass *klass) { @@ -1177,6 +664,8 @@ mm_modem_samsung_gsm_class_init (MMModemSamsungGsmClass *klass) g_type_class_add_private (object_class, sizeof (MMModemSamsungGsmPrivate)); + object_class->dispose = dispose; + gsm_class->do_disconnect = do_disconnect; gsm_class->do_enable = do_enable; |