gsm: retry sending SMS in PDU mode if text fails and PDU is supported

In the future we'll just default to PDU mode.
This commit is contained in:
Dan Williams
2012-03-01 17:22:56 -06:00
parent bc118aa160
commit 5f6c65e7c1

View File

@@ -139,6 +139,7 @@ typedef struct {
*/
GHashTable *sms_parts;
gboolean sms_pdu_mode;
gboolean sms_pdu_supported;
guint sms_fetch_pending;
@@ -1787,14 +1788,18 @@ sms_set_format_cb (MMAtSerialPort *port,
GError *error,
gpointer user_data)
{
MMGenericGsm *self = MM_GENERIC_GSM (user_data);
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
if (error) {
mm_warn ("(%s): failed to set SMS mode, assuming text mode",
mm_port_get_device (MM_PORT (port)));
MM_GENERIC_GSM_GET_PRIVATE (user_data)->sms_pdu_mode = FALSE;
priv->sms_pdu_mode = FALSE;
priv->sms_pdu_supported = FALSE;
} else {
mm_info ("(%s): using %s mode for SMS",
mm_port_get_device (MM_PORT (port)),
MM_GENERIC_GSM_GET_PRIVATE (user_data)->sms_pdu_mode ? "PDU" : "text");
priv->sms_pdu_mode ? "PDU" : "text");
}
}
@@ -1857,6 +1862,10 @@ sms_get_format_cb (MMAtSerialPort *port,
mm_at_serial_port_queue_command (priv->primary, "AT+CMGF=0", 3, sms_set_format_cb, self);
} else
mm_at_serial_port_queue_command (priv->primary, "AT+CMGF=1", 3, sms_set_format_cb, self);
/* Save whether PDU mode is supported so we can fall back to it if text fails */
if (min == 0)
priv->sms_pdu_supported = TRUE;
}
g_match_info_free (match_info);
@@ -4844,19 +4853,41 @@ sms_send_done (MMAtSerialPort *port,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
const char *p;
const char *p, *pdu;
unsigned long num;
GArray *indexes = NULL;
guint32 idx = 0;
guint cmgs_pdu_size;
char *command;
/* If the modem has already been removed, return without
* scheduling callback */
if (mm_callback_info_check_modem_removed (info))
return;
if (error)
if (error) {
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
/* If there was an error sending in text mode the retry with the PDU;
* text mode is pretty dumb on most devices and often fails. Later we'll
* just use text mode exclusively.
*/
pdu = mm_callback_info_get_data (info, "pdu");
if (priv->sms_pdu_mode == FALSE && priv->sms_pdu_supported && pdu) {
cmgs_pdu_size = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "cmgs-pdu-size"));
g_assert (cmgs_pdu_size);
command = g_strdup_printf ("+CMGS=%d\r%s\x1a", cmgs_pdu_size, pdu);
mm_at_serial_port_queue_command (port, command, 10, sms_send_done, info);
g_free (command);
/* Clear the PDU data so we don't keep getting here */
mm_callback_info_set_data (info, "pdu", NULL, NULL);
return;
}
/* Otherwise it's a hard error */
info->error = g_error_copy (error);
else {
} else {
/* If the response happens to have a ">" in it from the interactive
* handling of the CMGS command, skip it.
*/
@@ -4893,6 +4924,9 @@ sms_send (MMModemGsmSms *modem,
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
char *command;
MMAtSerialPort *port;
guint8 *pdu;
guint pdulen = 0, msgstart = 0;
char *hex;
info = mm_callback_info_new_full (MM_MODEM (modem),
sms_send_invoke,
@@ -4905,31 +4939,29 @@ sms_send (MMModemGsmSms *modem,
return;
}
/* Always create a PDU since we might need it for fallback from text mode */
pdu = sms_create_submit_pdu (number, text, smsc, validity, class, &pdulen, &msgstart, &info->error);
if (!pdu) {
mm_callback_info_schedule (info);
return;
}
hex = utils_bin2hexstr (pdu, pdulen);
g_free (pdu);
if (hex == NULL) {
g_set_error_literal (&info->error,
MM_MODEM_ERROR,
MM_MODEM_ERROR_GENERAL,
"Not enough memory to send SMS PDU");
mm_callback_info_schedule (info);
return;
}
mm_callback_info_set_data (info, "pdu", hex, g_free);
mm_callback_info_set_data (info, "cmgs-pdu-size", GUINT_TO_POINTER (pdulen - msgstart), NULL);
if (priv->sms_pdu_mode) {
guint8 *pdu;
guint pdulen = 0, msgstart = 0;
char *hex;
pdu = sms_create_submit_pdu (number, text, smsc, validity, class, &pdulen, &msgstart, &info->error);
if (!pdu) {
mm_callback_info_schedule (info);
return;
}
hex = utils_bin2hexstr (pdu, pdulen);
g_free (pdu);
if (hex == NULL) {
g_set_error_literal (&info->error,
MM_MODEM_ERROR,
MM_MODEM_ERROR_GENERAL,
"Not enough memory to send SMS PDU");
mm_callback_info_schedule (info);
return;
}
/* CMGS length is the size of the PDU without SMSC information */
command = g_strdup_printf ("+CMGS=%d\r%s\x1a", pdulen - msgstart, hex);
g_free (hex);
} else
command = g_strdup_printf ("+CMGS=\"%s\"\r%s\x1a", number, text);