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:

committed by
Dan Williams

parent
94e717b854
commit
b82cec8c7e
@@ -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
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user