[PATCH 3/5] ussd: Add mm_modem_gsm_ussd_{de,en}code to the MMModemGsmUssd interface



since some some modems need different quirks to encode/decode USSD
messages.
---
 src/mm-generic-gsm.c    |   69 ++++++++++++++++++++++++++++++++++++----------
 src/mm-modem-gsm-ussd.c |   26 +++++++++++++++++
 src/mm-modem-gsm-ussd.h |   16 +++++++++++
 3 files changed, 96 insertions(+), 15 deletions(-)

diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index d814c57..83e7a0b 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -4740,7 +4740,9 @@ mm_generic_gsm_ussd_cleanup (MMGenericGsm *self)
 }
 
 static char *
-decode_ussd_response (const char *reply, MMModemCharset cur_charset)
+decode_ussd_response (MMGenericGsm *self,
+                      const char *reply,
+                      MMModemCharset cur_charset)
 {
     char **items, **iter, *p;
     char *str = NULL;
@@ -4771,8 +4773,42 @@ decode_ussd_response (const char *reply, MMModemCharset cur_charset)
     if (p)
         *p = '\0';
 
-    /* FIXME: actually use the given encoding scheme */
-    return mm_modem_charset_hex_to_utf8 (str, cur_charset);
+    return mm_modem_gsm_ussd_decode (MM_MODEM_GSM_USSD (self), str,
+                                     cur_charset);
+}
+
+static char*
+ussd_encode (MMModemGsmUssd *modem, const char* command, guint *scheme)
+{
+    MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
+    GByteArray *ussd_command = g_byte_array_new();
+    gboolean success;
+    char *hex = NULL;
+
+    /* encode to cur_charset */
+    success = mm_modem_charset_byte_array_append (ussd_command, command, FALSE,
+                                                  priv->cur_charset);
+    g_warn_if_fail (success == TRUE);
+    if (!success)
+        goto out;
+
+    /* convert to hex representation */
+    hex = utils_bin2hexstr (ussd_command->data, ussd_command->len);
+    *scheme = 15;
+
+ out:
+    g_byte_array_free (ussd_command, TRUE);
+    return hex;
+}
+
+static char*
+ussd_decode (MMModemGsmUssd *modem, const char* reply, guint scheme)
+{
+    MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
+    char *converted;
+
+    converted = mm_modem_charset_hex_to_utf8 (reply, priv->cur_charset);
+    return converted;
 }
 
 static void
@@ -4797,7 +4833,7 @@ cusd_received (MMAtSerialPort *port,
     status = g_ascii_digit_value (*reply);
     switch (status) {
     case 0: /* no further action required */
-        converted = decode_ussd_response (reply, priv->cur_charset);
+        converted = decode_ussd_response (self, reply, priv->cur_charset);
         if (priv->pending_ussd_info) {
             /* Response to the user's request */
             mm_callback_info_set_result (priv->pending_ussd_info, converted, g_free);
@@ -4810,7 +4846,7 @@ cusd_received (MMAtSerialPort *port,
         break;
     case 1: /* further action required */
         ussd_state = MM_MODEM_GSM_USSD_STATE_USER_RESPONSE;
-        converted = decode_ussd_response (reply, priv->cur_charset);
+        converted = decode_ussd_response (self, reply, priv->cur_charset);
         if (priv->pending_ussd_info) {
             mm_callback_info_set_result (priv->pending_ussd_info, converted, g_free);
         } else {
@@ -4889,10 +4925,9 @@ ussd_send (MMModemGsmUssd *modem,
     MMCallbackInfo *info;
     char *atc_command;
     char *hex;
-    GByteArray *ussd_command = g_byte_array_new();
+    guint scheme = 0;
     MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
     MMAtSerialPort *port;
-    gboolean success;
 
     g_warn_if_fail (priv->pending_ussd_info == NULL);
 
@@ -4907,14 +4942,16 @@ ussd_send (MMModemGsmUssd *modem,
     /* Cache the callback info since the response is an unsolicited one */
     priv->pending_ussd_info = info;
 
-    /* encode to cur_charset */
-    success = mm_modem_charset_byte_array_append (ussd_command, command, FALSE, priv->cur_charset);
-    g_warn_if_fail (success == TRUE);
-
-    /* convert to hex representation */
-    hex = utils_bin2hexstr (ussd_command->data, ussd_command->len);
-    g_byte_array_free (ussd_command, TRUE);
-    atc_command = g_strdup_printf ("+CUSD=1,\"%s\",15", hex);
+    hex = mm_modem_gsm_ussd_encode (MM_MODEM_GSM_USSD (modem), command, &scheme);
+    if (!hex) {
+        info->error =  g_error_new (MM_MODEM_ERROR,
+                                    MM_MODEM_ERROR_GENERAL,
+                                    "Failed to encode USSD command '%s'",
+                                    command);
+        mm_callback_info_schedule (info);
+        return;
+    }
+    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);
@@ -5661,6 +5698,8 @@ modem_gsm_ussd_init (MMModemGsmUssd *class)
     class->initiate = ussd_initiate;
     class->respond = ussd_respond;
     class->cancel = ussd_cancel;
+    class->encode = ussd_encode;
+    class->decode = ussd_decode;
 }
 
 static void
diff --git a/src/mm-modem-gsm-ussd.c b/src/mm-modem-gsm-ussd.c
index f90a845..614999c 100644
--- a/src/mm-modem-gsm-ussd.c
+++ b/src/mm-modem-gsm-ussd.c
@@ -137,6 +137,32 @@ mm_modem_gsm_ussd_cancel (MMModemGsmUssd *self,
 
 }
 
+char*
+mm_modem_gsm_ussd_encode (MMModemGsmUssd *self,
+                          const char* command,
+                          guint *schema)
+{
+    if (MM_MODEM_GSM_USSD_GET_INTERFACE (self)->encode)
+        return MM_MODEM_GSM_USSD_GET_INTERFACE (self)->encode(self,
+                                                              command,
+                                                              schema);
+    else
+        return NULL;
+}
+
+char*
+mm_modem_gsm_ussd_decode (MMModemGsmUssd *self,
+                          const char* reply,
+                          guint schema)
+{
+    if (MM_MODEM_GSM_USSD_GET_INTERFACE (self)->decode)
+        return MM_MODEM_GSM_USSD_GET_INTERFACE (self)->decode(self,
+                                                              reply,
+                                                              schema);
+    else
+        return NULL;
+}
+
 /*****************************************************************************/
 
 typedef struct {
diff --git a/src/mm-modem-gsm-ussd.h b/src/mm-modem-gsm-ussd.h
index c8f652b..6859d73 100644
--- a/src/mm-modem-gsm-ussd.h
+++ b/src/mm-modem-gsm-ussd.h
@@ -54,6 +54,14 @@ struct _MMModemGsmUssd {
     void (*cancel) (MMModemGsmUssd *modem,
                     MMModemFn callback,
                     gpointer user_data);
+
+    gchar* (*encode) (MMModemGsmUssd *modem,
+                      const char* command,
+                      guint *scheme);
+
+    gchar* (*decode) (MMModemGsmUssd *modem,
+                      const char* command,
+                      guint scheme);
 };
 
 GType mm_modem_gsm_ussd_get_type (void);
@@ -72,4 +80,12 @@ void mm_modem_gsm_ussd_cancel (MMModemGsmUssd *self,
                                MMModemFn callback,
                                gpointer user_data);
 
+char *mm_modem_gsm_ussd_encode (MMModemGsmUssd *self,
+                                const char* command,
+                                guint *scheme);
+
+char *mm_modem_gsm_ussd_decode (MMModemGsmUssd *self,
+                                const char* reply,
+                                guint scheme);
+
 #endif /* MM_MODEM_GSM_USSD_H */
-- 
1.7.5.4


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