Aleksander Morgado: > On 16/04/12 18:00, Alexander Orlov wrote: > > When I send an USSD query, it should be encoded to proper charset (UCS2 > > in my case). But it is not. Because of this USSD queries do not work at > > all on my ZTE MF192 modem: > > > > (ttyACM0): --> 'AT+CUSD=1,"*100#",15<CR>' > > (ttyACM0):<-- '<CR><LF>ERROR<CR><LF>' > > > > In git logs I have found this commit: > > http://cgit.freedesktop.org/ModemManager/ModemManager/commit/plugins/mm-modem-zte.c?id=a57618b091faec24d22bfce5f384248c52cd2511 > > > > It disables hex encoding for USSD requests for all ZTE modems. > > > > With that patch reversed, USSD works fine for me: > > > > (ttyACM0): --> 'AT+CUSD=1,"002A0031003000300023",15<CR>' > > (ttyACM0):<-- '<CR><LF>+CUSD: > > 0,"04110430043B0430043D0441003A003600390037002C0039003604400020041E043F043B0430044204300020043A043004400442043E04390020043F043E00200431002F043F002004420435043B04350444043E043D04430020002B00370034003900350037003600360030003100360036",72<CR><LF><CR><LF>OK<CR><LF>' > > decode_ussd_response(): USSD data coding scheme 72 > > > > So, I think, ModemManager should match modem model and decide, if it > > needs hex encodings. What do you think about this? > > If the case is that some models don't allow UCS2-hex encoded strings > even if UCS2 is the desired charset; then I would default to trying to > use the specified charset and if it fails, then try with the fallback > MM_MODEM_GSM_USSD_SCHEME_7BIT as in that patch. It would just need one > failure to really decide which logic to use. Otherwise we'll end up > needing to maintain some table of devices showing that behaviour, which > is possibly not a good thing to do.
Aleksander, thank you for reply! I have done the patch witch uses this idea. It should work for all modems, but probably needs testing with models that don't understand hex-encodings. -- Alexander Orlov
--- a/src/mm-generic-gsm.c 2012-03-13 23:06:12.000000000 +0400 +++ b/src/mm-generic-gsm.c 2012-04-21 23:00:28.524568172 +0400 @@ -125,6 +125,7 @@ gboolean ussd_enabled; MMCallbackInfo *pending_ussd_info; MMModemGsmUssdState ussd_state; + gboolean ussd_text_mode; char *ussd_network_request; char *ussd_network_notification; @@ -1682,6 +1683,7 @@ } MM_GENERIC_GSM_GET_PRIVATE (user_data)->ussd_enabled = TRUE; + MM_GENERIC_GSM_GET_PRIVATE (user_data)->ussd_text_mode = FALSE; } static void @@ -5498,6 +5500,12 @@ ussd_update_state (self, ussd_state); if (priv->pending_ussd_info) { + /* If command is cleared, hex mode fails; remember this state */ + if (mm_callback_info_get_data (priv->pending_ussd_info, "command") == NULL) { + priv->ussd_text_mode = TRUE; + mm_warn ("Failed to use hex mode for USSD, assuming text mode"); + } + if (error) priv->pending_ussd_info->error = g_error_copy (error); mm_callback_info_schedule (priv->pending_ussd_info); @@ -5514,6 +5522,10 @@ GError *error, gpointer user_data) { + char *command; + char *atc_command; + guint scheme = 0; + MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMGenericGsmPrivate *priv; @@ -5526,6 +5538,21 @@ if (error) { /* Some immediate error happened when sending the USSD request */ + command = mm_callback_info_get_data (info, "command"); + if (priv->ussd_text_mode == FALSE && command) { + /* Try to send request in plain text format */ + scheme = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "scheme")); + g_assert (scheme); + atc_command = g_strdup_printf ("+CUSD=1,\"%s\",%d", command, scheme); + mm_at_serial_port_queue_command (port, atc_command, 10, ussd_send_done, info); + g_free (atc_command); + + /* Clear the command, so we don't keep getting here */ + mm_callback_info_set_data (info, "command", NULL, NULL); + return; + } + + /* Looks like it's hard error */ info->error = g_error_copy (error); priv->pending_ussd_info = NULL; mm_callback_info_schedule (info); @@ -5573,7 +5600,15 @@ mm_callback_info_schedule (info); return; } - atc_command = g_strdup_printf ("+CUSD=1,\"%s\",%d", hex, scheme); + + /* Cache the command and scheme since we might use them later */ + mm_callback_info_set_data (info, "command", g_strdup (command), g_free); + mm_callback_info_set_data (info, "scheme", GUINT_TO_POINTER (scheme), NULL); + + if (priv->ussd_text_mode) + atc_command = g_strdup_printf ("+CUSD=1,\"%s\",%d", command, scheme); + else + atc_command = g_strdup_printf ("+CUSD=1,\"%s\",%d", hex, scheme); g_free (hex); mm_at_serial_port_queue_command (port, atc_command, 10, ussd_send_done, info);
--- a/plugins/mm-modem-zte.c 2012-03-13 23:06:11.000000000 +0400 +++ b/plugins/mm-modem-zte.c 2012-04-23 23:26:54.233481197 +0400 @@ -26,18 +26,15 @@ #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_GSM_USSD, modem_gsm_ussd_init) ) #define MM_MODEM_ZTE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_ZTE, MMModemZtePrivate)) @@ -687,19 +684,6 @@ /*****************************************************************************/ -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) { @@ -727,12 +711,6 @@ } 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);
_______________________________________________ networkmanager-list mailing list networkmanager-list@gnome.org http://mail.gnome.org/mailman/listinfo/networkmanager-list