Re: [MM] [PATCH 3/3] ZTE: improperly USSD-query encoding



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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]