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.
This commit is contained in:
Guido Günther
2011-07-21 15:14:23 -05:00
committed by Dan Williams
parent 94e717b854
commit b82cec8c7e
3 changed files with 96 additions and 15 deletions

View File

@@ -4768,7 +4768,9 @@ mm_generic_gsm_ussd_cleanup (MMGenericGsm *self)
} }
static char * 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 **items, **iter, *p;
char *str = NULL; char *str = NULL;
@@ -4799,8 +4801,42 @@ decode_ussd_response (const char *reply, MMModemCharset cur_charset)
if (p) if (p)
*p = '\0'; *p = '\0';
/* FIXME: actually use the given encoding scheme */ return mm_modem_gsm_ussd_decode (MM_MODEM_GSM_USSD (self), str,
return mm_modem_charset_hex_to_utf8 (str, cur_charset); 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 static void
@@ -4825,7 +4861,7 @@ cusd_received (MMAtSerialPort *port,
status = g_ascii_digit_value (*reply); status = g_ascii_digit_value (*reply);
switch (status) { switch (status) {
case 0: /* no further action required */ 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) { if (priv->pending_ussd_info) {
/* Response to the user's request */ /* Response to the user's request */
mm_callback_info_set_result (priv->pending_ussd_info, converted, g_free); mm_callback_info_set_result (priv->pending_ussd_info, converted, g_free);
@@ -4838,7 +4874,7 @@ cusd_received (MMAtSerialPort *port,
break; break;
case 1: /* further action required */ case 1: /* further action required */
ussd_state = MM_MODEM_GSM_USSD_STATE_USER_RESPONSE; 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) { if (priv->pending_ussd_info) {
mm_callback_info_set_result (priv->pending_ussd_info, converted, g_free); mm_callback_info_set_result (priv->pending_ussd_info, converted, g_free);
} else { } else {
@@ -4917,10 +4953,9 @@ ussd_send (MMModemGsmUssd *modem,
MMCallbackInfo *info; MMCallbackInfo *info;
char *atc_command; char *atc_command;
char *hex; char *hex;
GByteArray *ussd_command = g_byte_array_new(); guint scheme = 0;
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem); MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
MMAtSerialPort *port; MMAtSerialPort *port;
gboolean success;
g_warn_if_fail (priv->pending_ussd_info == NULL); g_warn_if_fail (priv->pending_ussd_info == NULL);
@@ -4935,14 +4970,16 @@ ussd_send (MMModemGsmUssd *modem,
/* Cache the callback info since the response is an unsolicited one */ /* Cache the callback info since the response is an unsolicited one */
priv->pending_ussd_info = info; priv->pending_ussd_info = info;
/* encode to cur_charset */ hex = mm_modem_gsm_ussd_encode (MM_MODEM_GSM_USSD (modem), command, &scheme);
success = mm_modem_charset_byte_array_append (ussd_command, command, FALSE, priv->cur_charset); if (!hex) {
g_warn_if_fail (success == TRUE); info->error = g_error_new (MM_MODEM_ERROR,
MM_MODEM_ERROR_GENERAL,
/* convert to hex representation */ "Failed to encode USSD command '%s'",
hex = utils_bin2hexstr (ussd_command->data, ussd_command->len); command);
g_byte_array_free (ussd_command, TRUE); mm_callback_info_schedule (info);
atc_command = g_strdup_printf ("+CUSD=1,\"%s\",15", hex); return;
}
atc_command = g_strdup_printf ("+CUSD=1,\"%s\",%d", hex, scheme);
g_free (hex); g_free (hex);
mm_at_serial_port_queue_command (port, atc_command, 10, ussd_send_done, info); mm_at_serial_port_queue_command (port, atc_command, 10, ussd_send_done, info);
@@ -5689,6 +5726,8 @@ modem_gsm_ussd_init (MMModemGsmUssd *class)
class->initiate = ussd_initiate; class->initiate = ussd_initiate;
class->respond = ussd_respond; class->respond = ussd_respond;
class->cancel = ussd_cancel; class->cancel = ussd_cancel;
class->encode = ussd_encode;
class->decode = ussd_decode;
} }
static void static void

View File

@@ -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 { typedef struct {

View File

@@ -54,6 +54,14 @@ struct _MMModemGsmUssd {
void (*cancel) (MMModemGsmUssd *modem, void (*cancel) (MMModemGsmUssd *modem,
MMModemFn callback, MMModemFn callback,
gpointer user_data); 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); GType mm_modem_gsm_ussd_get_type (void);
@@ -72,4 +80,12 @@ void mm_modem_gsm_ussd_cancel (MMModemGsmUssd *self,
MMModemFn callback, MMModemFn callback,
gpointer user_data); 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 */ #endif /* MM_MODEM_GSM_USSD_H */