diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/Makefile.am | 3 | ||||
-rw-r--r-- | plugins/Makefile.in | 5 | ||||
-rw-r--r-- | plugins/mm-modem-gobi-gsm.c | 53 | ||||
-rw-r--r-- | plugins/mm-modem-huawei-gsm.c | 51 | ||||
-rw-r--r-- | plugins/mm-modem-icera.c | 75 | ||||
-rw-r--r-- | plugins/mm-modem-mbm.c | 29 | ||||
-rw-r--r-- | plugins/mm-modem-nokia.c | 4 | ||||
-rw-r--r-- | plugins/mm-modem-option-utils.c | 130 | ||||
-rwxr-xr-x | plugins/mm-modem-samsung-gsm.c | 8 | ||||
-rw-r--r-- | plugins/mm-modem-sierra-gsm.c | 2 | ||||
-rw-r--r-- | plugins/mm-modem-zte.c | 25 | ||||
-rw-r--r-- | plugins/mm-plugin-option.c | 9 | ||||
-rwxr-xr-x | plugins/mm-plugin-samsung.c | 2 |
13 files changed, 337 insertions, 59 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 8eaffb4..47fc3b0 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -375,6 +375,9 @@ libmm_plugin_samsung_la_LDFLAGS = \ -module \ -avoid-version +libmm_plugin_samsung_la_LIBADD = \ + $(builddir)/libicera-utils.la + udevrulesdir = $(UDEV_BASE_DIR)/rules.d udevrules_DATA = \ 77-mm-ericsson-mbm.rules \ diff --git a/plugins/Makefile.in b/plugins/Makefile.in index 1c6e440..df6b5e3 100644 --- a/plugins/Makefile.in +++ b/plugins/Makefile.in @@ -194,7 +194,7 @@ libmm_plugin_option_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libmm_plugin_option_la_LDFLAGS) \ $(LDFLAGS) -o $@ -libmm_plugin_samsung_la_LIBADD = +libmm_plugin_samsung_la_DEPENDENCIES = $(builddir)/libicera-utils.la am_libmm_plugin_samsung_la_OBJECTS = \ libmm_plugin_samsung_la-mm-plugin-samsung.lo \ libmm_plugin_samsung_la-mm-modem-samsung-gsm.lo @@ -834,6 +834,9 @@ libmm_plugin_samsung_la_LDFLAGS = \ -module \ -avoid-version +libmm_plugin_samsung_la_LIBADD = \ + $(builddir)/libicera-utils.la + udevrulesdir = $(UDEV_BASE_DIR)/rules.d udevrules_DATA = \ 77-mm-ericsson-mbm.rules \ diff --git a/plugins/mm-modem-gobi-gsm.c b/plugins/mm-modem-gobi-gsm.c index ab19642..eea13ce 100644 --- a/plugins/mm-modem-gobi-gsm.c +++ b/plugins/mm-modem-gobi-gsm.c @@ -24,6 +24,7 @@ #include "mm-callback-info.h" #include "mm-modem-gsm-card.h" #include "mm-at-serial-port.h" +#include "mm-modem-helpers.h" static void modem_init (MMModem *modem_class); static void modem_gsm_card_init (MMModemGsmCard *gsm_card_class); @@ -56,6 +57,55 @@ mm_modem_gobi_gsm_new (const char *device, /*****************************************************************************/ static void +get_act_request_done (MMAtSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + MMCallbackInfo *info = user_data; + MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; + const char *p; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if (error) + info->error = g_error_copy (error); + else { + p = mm_strip_tag (response->str, "*CNTI:"); + p = strchr (p, ','); + if (p) + act = mm_gsm_string_to_access_tech (p + 1); + } + + mm_callback_info_set_result (info, GUINT_TO_POINTER (act), NULL); + mm_callback_info_schedule (info); +} + +static void +get_access_technology (MMGenericGsm *modem, + MMModemUIntFn callback, + gpointer user_data) +{ + MMAtSerialPort *port; + MMCallbackInfo *info; + + info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); + + port = mm_generic_gsm_get_best_at_port (modem, &info->error); + if (!port) { + mm_callback_info_schedule (info); + return; + } + + mm_at_serial_port_queue_command (port, "*CNTI=0", 3, get_act_request_done, info); +} + +/*****************************************************************************/ + +static void get_string_done (MMAtSerialPort *port, GString *response, GError *error, @@ -118,5 +168,8 @@ mm_modem_gobi_gsm_init (MMModemGobiGsm *self) static void mm_modem_gobi_gsm_class_init (MMModemGobiGsmClass *klass) { + MMGenericGsmClass *gsm_class = MM_GENERIC_GSM_CLASS (klass); + + gsm_class->get_access_technology = get_access_technology; } diff --git a/plugins/mm-modem-huawei-gsm.c b/plugins/mm-modem-huawei-gsm.c index e038069..5f4c2fb 100644 --- a/plugins/mm-modem-huawei-gsm.c +++ b/plugins/mm-modem-huawei-gsm.c @@ -25,21 +25,25 @@ #include "mm-modem-huawei-gsm.h" #include "mm-modem-gsm-network.h" #include "mm-modem-gsm-card.h" +#include "mm-modem-gsm-ussd.h" #include "mm-errors.h" #include "mm-callback-info.h" #include "mm-at-serial-port.h" #include "mm-serial-parsers.h" #include "mm-log.h" +#include "mm-utils.h" static void modem_init (MMModem *modem_class); static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class); static void modem_gsm_card_init (MMModemGsmCard *gsm_card_class); +static void modem_gsm_ussd_init (MMModemGsmUssd *ussd_class); G_DEFINE_TYPE_EXTENDED (MMModemHuaweiGsm, mm_modem_huawei_gsm, MM_TYPE_GENERIC_GSM, 0, G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_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)) - + G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_CARD, modem_gsm_card_init) + G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_USSD, modem_gsm_ussd_init) +) #define MM_MODEM_HUAWEI_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_HUAWEI_GSM, MMModemHuaweiGsmPrivate)) @@ -874,6 +878,42 @@ out: return !!port; } +/* Encode to packed GSM - this is what Huawei supports on all known models */ +static char* +ussd_encode (MMModemGsmUssd *self, const char* command, guint *scheme) +{ + char *hex; + guint8 *gsm, *packed; + guint32 len = 0, packed_len = 0; + + *scheme = MM_MODEM_GSM_USSD_SCHEME_7BIT; + gsm = mm_charset_utf8_to_unpacked_gsm (command, &len); + packed = gsm_pack (gsm, len, 0, &packed_len); + hex = utils_bin2hexstr (packed, packed_len); + g_free (packed); + g_free (gsm); + + return hex; +} + +/* Unparse packed gsm to utf8 */ +static char* +ussd_decode (MMModemGsmUssd *self, const char* reply, guint scheme) +{ + char *bin, *utf8; + guint8 *unpacked; + gsize bin_len; + guint32 unpacked_len; + + bin = utils_hexstr2bin (reply, &bin_len); + unpacked = gsm_unpack ((guint8*)bin, bin_len, 0, &unpacked_len); + utf8 = (char*)mm_charset_gsm_unpacked_to_utf8 (unpacked, unpacked_len); + + g_free (bin); + g_free (unpacked); + return utf8; +} + /*****************************************************************************/ static void @@ -902,6 +942,13 @@ mm_modem_huawei_gsm_init (MMModemHuaweiGsm *self) } static void +modem_gsm_ussd_init (MMModemGsmUssd *ussd_class) +{ + ussd_class->encode = ussd_encode; + ussd_class->decode = ussd_decode; +} + +static void mm_modem_huawei_gsm_class_init (MMModemHuaweiGsmClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); diff --git a/plugins/mm-modem-icera.c b/plugins/mm-modem-icera.c index b093b34..8933142 100644 --- a/plugins/mm-modem-icera.c +++ b/plugins/mm-modem-icera.c @@ -192,11 +192,13 @@ nwstate_to_act (const char *str) 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")) + else if (!strcmp (str, "R99")) + return MM_MODEM_GSM_ACCESS_TECH_UMTS; + else if (!strcmp (str, "3G-HSDPA") || !strcmp (str, "HSDPA")) return MM_MODEM_GSM_ACCESS_TECH_HSDPA; - else if (!strcmp (str, "3G-HSUPA")) + else if (!strcmp (str, "3G-HSUPA") || !strcmp (str, "HSUPA")) return MM_MODEM_GSM_ACCESS_TECH_HSUPA; - else if (!strcmp (str, "3G-HSDPA-HSUPA")) + else if (!strcmp (str, "3G-HSDPA-HSUPA") || !strcmp (str, "HSDPA-HSUPA")) return MM_MODEM_GSM_ACCESS_TECH_HSPA; return MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; @@ -219,7 +221,15 @@ nwstate_changed (MMAtSerialPort *port, g_free (str); } - str = g_match_info_fetch (info, 3); + /* Check the <connection state> field first for the connected access + * technology, otherwise if not connected (ie, "-") use the available + * access technology from the <tech> field. + */ + str = g_match_info_fetch (info, 4); + if (!str || (strcmp (str, "-") == 0)) { + g_free (str); + str = g_match_info_fetch (info, 3); + } if (str) { act = nwstate_to_act (str); g_free (str); @@ -357,13 +367,48 @@ icera_disconnect_done (MMModem *modem, } static void +query_network_error_code_done (MMAtSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + MMModemIcera *self = MM_MODEM_ICERA (user_data); + MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self); + MMCallbackInfo *info = priv->connect_pending_data; + int nw_activation_err; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + if ((error == NULL) && g_str_has_prefix (response->str, "%IER: ")) { + if (sscanf (response->str + 6, "%*d,%*d,%d", &nw_activation_err)) { + /* 3GPP TS 24.008 Annex G error codes: + * 27 - Unknown or missing access point name + * 33 - Requested service option not subscribed + */ + if (nw_activation_err == 27 || nw_activation_err == 33) + info->error = mm_mobile_error_for_code (MM_MOBILE_ERROR_GPRS_NOT_SUBSCRIBED); + } + } + + if (info->error == NULL) { + /* Generic error since parsing the specific one didn't work */ + info->error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "Call setup failed"); + } + connect_pending_done (self); +} + +static void connection_enabled (MMAtSerialPort *port, GMatchInfo *match_info, gpointer user_data) { MMModemIcera *self = MM_MODEM_ICERA (user_data); - MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self); - MMCallbackInfo *info = priv->connect_pending_data; + MMAtSerialPort *primary; char *str; int status, cid, tmp; @@ -400,12 +445,11 @@ connection_enabled (MMAtSerialPort *port, 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); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM(self), MM_PORT_TYPE_PRIMARY); + g_assert (primary); + /* Get additional error details */ + mm_at_serial_port_queue_command (primary, "AT%IER?", 3, + query_network_error_code_done, self); break; default: mm_warn ("Unknown Icera connect status %d", status); @@ -717,7 +761,11 @@ mm_modem_icera_register_unsolicted_handlers (MMModemIcera *self, { GRegex *regex; - /* %NWSTATE: <rssi>,<mccmnc>,<tech>,<connected>,<regulation> */ + /* %NWSTATE: <rssi>,<mccmnc>,<tech>,<connection state>,<regulation> + * + * <connection state> shows the actual access technology in-use when a + * PS connection is active. + */ 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); @@ -848,4 +896,3 @@ mm_modem_icera_get_type (void) return icera_type; } - diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c index 70faef4..7aa8a01 100644 --- a/plugins/mm-modem-mbm.c +++ b/plugins/mm-modem-mbm.c @@ -437,18 +437,28 @@ mbm_emrdy_done (MMAtSerialPort *port, gpointer user_data) { MMCallbackInfo *info = user_data; + MMModemMbmPrivate *priv; /* If the modem has already been removed, return without * scheduling callback */ if (mm_callback_info_check_modem_removed (info)) return; - if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) - mm_warn ("timed out waiting for EMRDY response."); - else { - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); - - priv->have_emrdy = TRUE; + /* EMRDY unsolicited response might have happened between the command + * submission and the response. This was seen once: + * + * (ttyACM0): --> 'AT*EMRDY?<CR>' + * (ttyACM0): <-- 'T*EMRD<CR><LF>*EMRDY: 1<CR><LF>Y?' + * + * So suppress the warning if the unsolicited handler handled the response + * before we get here. + */ + priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); + if (!priv->have_emrdy) { + if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) + mm_warn ("timed out waiting for EMRDY response."); + else + priv->have_emrdy = TRUE; } do_init (port, info); @@ -966,6 +976,13 @@ grab_port (MMModem *modem, if (port && MM_IS_AT_SERIAL_PORT (port)) { GRegex *regex; + /* The Ericsson modems always have a free AT command port, so we + * don't need to flash the ports when disconnecting to get back to + * command mode. F5521gw R2A07 resets port properties like echo when + * flashed, leading to confusion. bgo #650740 + */ + g_object_set (G_OBJECT (port), MM_SERIAL_PORT_FLASH_OK, FALSE, NULL); + if (ptype == MM_PORT_TYPE_PRIMARY) { regex = g_regex_new ("\\r\\n\\*E2NAP: (\\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, mbm_e2nap_received, modem, NULL); diff --git a/plugins/mm-modem-nokia.c b/plugins/mm-modem-nokia.c index 56b8c91..56f4c1b 100644 --- a/plugins/mm-modem-nokia.c +++ b/plugins/mm-modem-nokia.c @@ -58,7 +58,6 @@ grab_port (MMModem *modem, MMGenericGsm *gsm = MM_GENERIC_GSM (modem); MMPortType ptype = MM_PORT_TYPE_IGNORED; MMPort *port = NULL; - gulong send_delay = 5000; if (suggested_type == MM_PORT_TYPE_UNKNOWN) { if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) @@ -76,9 +75,6 @@ grab_port (MMModem *modem, mm_serial_parser_v1_e1_destroy); } - /* N900 appears to need longer delay between port bytes */ - g_object_set (G_OBJECT (port), MM_SERIAL_PORT_SEND_DELAY, send_delay, NULL); - return !!port; } diff --git a/plugins/mm-modem-option-utils.c b/plugins/mm-modem-option-utils.c index 61ca5d1..2316ee4 100644 --- a/plugins/mm-modem-option-utils.c +++ b/plugins/mm-modem-option-utils.c @@ -190,6 +190,22 @@ owcti_to_mm (char owcti, MMModemGsmAccessTech *out_act) } static gboolean +ossys_to_mm (char ossys, MMModemGsmAccessTech *out_act) +{ + if (ossys == '0') { + *out_act = MM_MODEM_GSM_ACCESS_TECH_GPRS; + return TRUE; + } else if (ossys == '2') { + *out_act = MM_MODEM_GSM_ACCESS_TECH_UMTS; + return TRUE; + } else if (ossys == '3') { + *out_act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; + return TRUE; + } + return FALSE; +} + +static gboolean parse_octi_response (GString *response, MMModemGsmAccessTech *act) { MMModemGsmAccessTech cur_act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; @@ -222,6 +238,39 @@ parse_octi_response (GString *response, MMModemGsmAccessTech *act) return success; } +static gboolean +parse_ossys_response (GString *response, MMModemGsmAccessTech *act) +{ + MMModemGsmAccessTech cur_act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; + const char *p; + GRegex *r; + GMatchInfo *match_info; + char *str; + gboolean success = FALSE; + + g_return_val_if_fail (act != NULL, FALSE); + g_return_val_if_fail (response != NULL, FALSE); + + p = mm_strip_tag (response->str, "_OSSYS:"); + + r = g_regex_new ("(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL); + g_return_val_if_fail (r != NULL, FALSE); + + g_regex_match (r, p, 0, &match_info); + if (g_match_info_matches (match_info)) { + str = g_match_info_fetch (match_info, 2); + if (str && ossys_to_mm (str[0], &cur_act)) { + *act = cur_act; + success = TRUE; + } + g_free (str); + } + g_match_info_free (match_info); + g_regex_unref (r); + + return success; +} + static void ossys_octi_request_done (MMAtSerialPort *port, GString *response, @@ -261,18 +310,8 @@ option_ossys_tech_changed (MMAtSerialPort *port, char *str; str = g_match_info_fetch (info, 1); - if (str) { - switch (atoi (str)) { - case 0: - act = MM_MODEM_GSM_ACCESS_TECH_GPRS; - break; - case 2: - act = MM_MODEM_GSM_ACCESS_TECH_UMTS; - break; - default: - break; - } - } + if (str) + ossys_to_mm (str[0], &act); g_free (str); mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (user_data), act); @@ -408,7 +447,7 @@ get_act_octi_request_done (MMAtSerialPort *port, { MMCallbackInfo *info = user_data; MMModemGsmAccessTech octi = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; - MMModemGsmAccessTech owcti; + MMModemGsmAccessTech act; /* If the modem has already been removed, return without * scheduling callback */ @@ -417,9 +456,11 @@ get_act_octi_request_done (MMAtSerialPort *port, if (!error) { if (parse_octi_response (response, &octi)) { - /* If no 3G tech yet or current tech isn't 3G, then 2G tech is the best */ - owcti = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "owcti")); - if (octi && !owcti) + /* If current tech is 2G or unknown then use the more specific + * OCTI response. + */ + act = GPOINTER_TO_UINT (mm_callback_info_get_result (info)); + if (act < MM_MODEM_GSM_ACCESS_TECH_UMTS) mm_callback_info_set_result (info, GUINT_TO_POINTER (octi), NULL); } } @@ -444,13 +485,57 @@ get_act_owcti_request_done (MMAtSerialPort *port, if (!error) { p = mm_strip_tag (response->str, "_OWCTI:"); - if (owcti_to_mm (*p, &owcti)) { - /* 3G tech always takes precedence over 2G tech */ - if (owcti) - mm_callback_info_set_result (info, GUINT_TO_POINTER (owcti), NULL); + if (owcti_to_mm (*p, &owcti) && owcti) + mm_callback_info_set_result (info, GUINT_TO_POINTER (owcti), NULL); + } + + mm_callback_info_chain_complete_one (info); +} + +static void +get_act_ossys_request_done (MMAtSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + MMCallbackInfo *info = user_data; + MMModemGsmAccessTech ossys = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; + gboolean check_2g = TRUE, check_3g = TRUE; + + /* If the modem has already been removed, return without + * scheduling callback */ + if (mm_callback_info_check_modem_removed (info)) + return; + + /* If for some reason the OSSYS request failed, still try to check + * explicit 2G/3G mode with OCTI and OWCTI; maybe we'll get something. + */ + + if (!error) { + /* Response is _OSSYS: <n>,<act> so we must skip the <n> */ + if (parse_ossys_response (response, &ossys)) { + mm_callback_info_set_result (info, GUINT_TO_POINTER (ossys), NULL); + + /* If the OSSYS response indicated a generic access tech type + * then only check for more specific access tech of that type. + */ + if (ossys == MM_MODEM_GSM_ACCESS_TECH_GPRS) + check_3g = FALSE; + if (ossys == MM_MODEM_GSM_ACCESS_TECH_UMTS) + check_2g = FALSE; } } + if (check_2g) + mm_at_serial_port_queue_command (port, "_OCTI?", 3, get_act_octi_request_done, info); + else + mm_callback_info_chain_complete_one (info); /* complete it if it wasn't used */ + + if (check_3g) + mm_at_serial_port_queue_command (port, "_OWCTI?", 3, get_act_owcti_request_done, info); + else + mm_callback_info_chain_complete_one (info); /* complete it if it wasn't used */ + mm_callback_info_chain_complete_one (info); } @@ -463,7 +548,7 @@ option_get_access_technology (MMGenericGsm *modem, MMCallbackInfo *info; info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - mm_callback_info_chain_start (info, 2); + mm_callback_info_chain_start (info, 3); port = mm_generic_gsm_get_best_at_port (modem, &info->error); if (!port) { @@ -471,7 +556,6 @@ option_get_access_technology (MMGenericGsm *modem, return; } - mm_at_serial_port_queue_command (port, "_OCTI?", 3, get_act_octi_request_done, info); - mm_at_serial_port_queue_command (port, "_OWCTI?", 3, get_act_owcti_request_done, info); + mm_at_serial_port_queue_command (port, "_OSSYS?", 3, get_act_ossys_request_done, info); } diff --git a/plugins/mm-modem-samsung-gsm.c b/plugins/mm-modem-samsung-gsm.c index d873653..f2d339b 100755 --- a/plugins/mm-modem-samsung-gsm.c +++ b/plugins/mm-modem-samsung-gsm.c @@ -478,8 +478,12 @@ disable (MMModem *modem, primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); g_assert (primary); - /* Random command to ensure unsolicited message disable completes */ - mm_at_serial_port_queue_command (primary, "AT+CFUN=0", 5, disable_unsolicited_done, info); + /* + * Command to ensure unsolicited message disable completes. + * Turns the radios off, which seems like a reasonable + * think to do when disabling. + */ + mm_at_serial_port_queue_command (primary, "AT+CFUN=4", 5, disable_unsolicited_done, info); } static void diff --git a/plugins/mm-modem-sierra-gsm.c b/plugins/mm-modem-sierra-gsm.c index 6d4e4d5..551142e 100644 --- a/plugins/mm-modem-sierra-gsm.c +++ b/plugins/mm-modem-sierra-gsm.c @@ -580,7 +580,7 @@ clear_user_pass (MMModemSierraGsm *self) g_free (priv->username); priv->username = NULL; g_free (priv->password); - priv->username = NULL; + priv->password = NULL; } static void diff --git a/plugins/mm-modem-zte.c b/plugins/mm-modem-zte.c index 0f69328..6c9f395 100644 --- a/plugins/mm-modem-zte.c +++ b/plugins/mm-modem-zte.c @@ -26,15 +26,19 @@ #include "mm-modem-helpers.h" #include "mm-modem-simple.h" #include "mm-modem-icera.h" +#include "mm-modem-gsm-ussd.h" static void modem_init (MMModem *modem_class); static void modem_icera_init (MMModemIcera *icera_class); static void modem_simple_init (MMModemSimple *simple_class); +static void modem_gsm_ussd_init (MMModemGsmUssd *ussd_class); G_DEFINE_TYPE_EXTENDED (MMModemZte, mm_modem_zte, MM_TYPE_GENERIC_GSM, 0, G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init) G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_ICERA, modem_icera_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init)) + G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init) + G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_USSD, modem_gsm_ussd_init) +) #define MM_MODEM_ZTE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_ZTE, MMModemZtePrivate)) @@ -683,6 +687,19 @@ get_icera_private (MMModemIcera *icera) /*****************************************************************************/ +static char* +ussd_encode (MMModemGsmUssd *self, const char* command, guint *scheme) +{ + char *cmd; + + *scheme = MM_MODEM_GSM_USSD_SCHEME_7BIT; + cmd = g_strdup (command); + + return cmd; +} + +/*****************************************************************************/ + static void modem_init (MMModem *modem_class) { @@ -710,6 +727,12 @@ mm_modem_zte_init (MMModemZte *self) } static void +modem_gsm_ussd_init (MMModemGsmUssd *ussd_class) +{ + ussd_class->encode = ussd_encode; +} + +static void dispose (GObject *object) { MMModemZte *self = MM_MODEM_ZTE (object); diff --git a/plugins/mm-plugin-option.c b/plugins/mm-plugin-option.c index a819b4e..de777cc 100644 --- a/plugins/mm-plugin-option.c +++ b/plugins/mm-plugin-option.c @@ -59,7 +59,7 @@ supports_port (MMPluginBase *base, GUdevDevice *port; guint32 cached = 0, level; const char *driver, *subsys, *name; - guint16 vendor = 0; + guint16 vendor = 0, product = 0; /* Can't do anything with non-serial ports */ port = mm_plugin_base_supports_task_get_port (task); @@ -70,13 +70,14 @@ supports_port (MMPluginBase *base, name = g_udev_device_get_name (port); driver = mm_plugin_base_supports_task_get_driver (task); - if (!driver || (strcmp (driver, "option1") && strcmp (driver, "option"))) + if (!driver || (strcmp (driver, "option1") && strcmp (driver, "option") && strcmp (driver, "nozomi"))) return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; - if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, NULL)) + if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; - if (vendor != 0x0af0) + if ( (vendor != 0x0af0) /* Option USB devices */ + && (vendor != 0x1931 || product != 0x000c)) /* Nozomi CardBus devices */ return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; if (mm_plugin_base_get_cached_port_capabilities (base, port, &cached)) { diff --git a/plugins/mm-plugin-samsung.c b/plugins/mm-plugin-samsung.c index 350d4de..9ea2051 100755 --- a/plugins/mm-plugin-samsung.c +++ b/plugins/mm-plugin-samsung.c @@ -84,7 +84,7 @@ supports_port (MMPluginBase *base, return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; /* Product ID check */ - if (product != 0x6872) + if (product != 0x6872 && product != 0x6906) return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; /* The ethernet ports are obviously supported and don't need probing */ |