base-sms: ensure send/store always uses the same port
When sending or storing an SMS, the per-part operation is itself split into two steps: first we send the AT command specifying the index, and then we send the actual PDU data with a raw command. We must ensure that the raw command is sent exactly in the same port as the AT command.
This commit is contained in:
committed by
Aleksander Morgado
parent
b855dca7f7
commit
338b299fe2
+92
-51
@@ -839,12 +839,13 @@ sms_get_store_or_send_command (MMBaseSms *self,
|
|||||||
/* Store the SMS */
|
/* Store the SMS */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MMBaseModem *modem;
|
MMBaseModem *modem;
|
||||||
MMSmsStorage storage;
|
MMPortSerialAt *port;
|
||||||
gboolean need_unlock;
|
MMSmsStorage storage;
|
||||||
gboolean use_pdu_mode;
|
gboolean need_unlock;
|
||||||
GList *current;
|
gboolean use_pdu_mode;
|
||||||
gchar *msg_data;
|
GList *current;
|
||||||
|
gchar *msg_data;
|
||||||
} SmsStoreContext;
|
} SmsStoreContext;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -853,6 +854,7 @@ sms_store_context_free (SmsStoreContext *ctx)
|
|||||||
/* Unlock mem2 storage if we had the lock */
|
/* Unlock mem2 storage if we had the lock */
|
||||||
if (ctx->need_unlock)
|
if (ctx->need_unlock)
|
||||||
mm_broadband_modem_unlock_sms_storages (MM_BROADBAND_MODEM (ctx->modem), FALSE, TRUE);
|
mm_broadband_modem_unlock_sms_storages (MM_BROADBAND_MODEM (ctx->modem), FALSE, TRUE);
|
||||||
|
g_object_unref (ctx->port);
|
||||||
g_object_unref (ctx->modem);
|
g_object_unref (ctx->modem);
|
||||||
g_free (ctx->msg_data);
|
g_free (ctx->msg_data);
|
||||||
g_slice_free (SmsStoreContext, ctx);
|
g_slice_free (SmsStoreContext, ctx);
|
||||||
@@ -879,7 +881,7 @@ store_msg_data_ready (MMBaseModem *modem,
|
|||||||
gint rv;
|
gint rv;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
|
||||||
response = mm_base_modem_at_command_finish (modem, res, &error);
|
response = mm_base_modem_at_command_full_finish (modem, res, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
@@ -916,7 +918,7 @@ store_ready (MMBaseModem *modem,
|
|||||||
SmsStoreContext *ctx;
|
SmsStoreContext *ctx;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
mm_base_modem_at_command_finish (modem, res, &error);
|
mm_base_modem_at_command_full_finish (modem, res, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
@@ -930,12 +932,15 @@ store_ready (MMBaseModem *modem,
|
|||||||
* be treated as an AT command (i.e. we don't want it prefixed
|
* be treated as an AT command (i.e. we don't want it prefixed
|
||||||
* with AT+ and suffixed with <CR><LF>), plus, we want it to be
|
* with AT+ and suffixed with <CR><LF>), plus, we want it to be
|
||||||
* sent right away (not queued after other AT commands). */
|
* sent right away (not queued after other AT commands). */
|
||||||
mm_base_modem_at_command_raw (ctx->modem,
|
mm_base_modem_at_command_full (ctx->modem,
|
||||||
ctx->msg_data,
|
ctx->port,
|
||||||
10,
|
ctx->msg_data,
|
||||||
FALSE,
|
10,
|
||||||
(GAsyncReadyCallback)store_msg_data_ready,
|
FALSE,
|
||||||
task);
|
TRUE, /* raw */
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback)store_msg_data_ready,
|
||||||
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -973,12 +978,15 @@ sms_store_next_part (GTask *task)
|
|||||||
g_assert (cmd != NULL);
|
g_assert (cmd != NULL);
|
||||||
g_assert (ctx->msg_data != NULL);
|
g_assert (ctx->msg_data != NULL);
|
||||||
|
|
||||||
mm_base_modem_at_command (ctx->modem,
|
mm_base_modem_at_command_full (ctx->modem,
|
||||||
cmd,
|
ctx->port,
|
||||||
10,
|
cmd,
|
||||||
FALSE,
|
10,
|
||||||
(GAsyncReadyCallback)store_ready,
|
FALSE,
|
||||||
task);
|
FALSE, /* raw */
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback)store_ready,
|
||||||
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1016,18 +1024,29 @@ sms_store (MMBaseSms *self,
|
|||||||
{
|
{
|
||||||
SmsStoreContext *ctx;
|
SmsStoreContext *ctx;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
|
MMPortSerialAt *port;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
/* Select port for the operation */
|
||||||
|
port = mm_base_modem_peek_best_at_port (self->priv->modem, &error);
|
||||||
|
if (!port) {
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup the context */
|
/* Setup the context */
|
||||||
ctx = g_slice_new0 (SmsStoreContext);
|
ctx = g_slice_new0 (SmsStoreContext);
|
||||||
ctx->modem = g_object_ref (self->priv->modem);
|
ctx->modem = g_object_ref (self->priv->modem);
|
||||||
|
ctx->port = g_object_ref (port);
|
||||||
ctx->storage = storage;
|
ctx->storage = storage;
|
||||||
|
|
||||||
/* Different ways to do it if on PDU or text mode */
|
/* Different ways to do it if on PDU or text mode */
|
||||||
g_object_get (self->priv->modem,
|
g_object_get (self->priv->modem,
|
||||||
MM_IFACE_MODEM_MESSAGING_SMS_PDU_MODE, &ctx->use_pdu_mode,
|
MM_IFACE_MODEM_MESSAGING_SMS_PDU_MODE, &ctx->use_pdu_mode,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
task = g_task_new (self, NULL, callback, user_data);
|
|
||||||
g_task_set_task_data (task, ctx, (GDestroyNotify)sms_store_context_free);
|
g_task_set_task_data (task, ctx, (GDestroyNotify)sms_store_context_free);
|
||||||
|
|
||||||
/* First, lock storage to use */
|
/* First, lock storage to use */
|
||||||
@@ -1044,12 +1063,13 @@ sms_store (MMBaseSms *self,
|
|||||||
/* Send the SMS */
|
/* Send the SMS */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MMBaseModem *modem;
|
MMBaseModem *modem;
|
||||||
gboolean need_unlock;
|
MMPortSerialAt *port;
|
||||||
gboolean from_storage;
|
gboolean need_unlock;
|
||||||
gboolean use_pdu_mode;
|
gboolean from_storage;
|
||||||
GList *current;
|
gboolean use_pdu_mode;
|
||||||
gchar *msg_data;
|
GList *current;
|
||||||
|
gchar *msg_data;
|
||||||
} SmsSendContext;
|
} SmsSendContext;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1058,6 +1078,7 @@ sms_send_context_free (SmsSendContext *ctx)
|
|||||||
/* Unlock mem2 storage if we had the lock */
|
/* Unlock mem2 storage if we had the lock */
|
||||||
if (ctx->need_unlock)
|
if (ctx->need_unlock)
|
||||||
mm_broadband_modem_unlock_sms_storages (MM_BROADBAND_MODEM (ctx->modem), FALSE, TRUE);
|
mm_broadband_modem_unlock_sms_storages (MM_BROADBAND_MODEM (ctx->modem), FALSE, TRUE);
|
||||||
|
g_object_unref (ctx->port);
|
||||||
g_object_unref (ctx->modem);
|
g_object_unref (ctx->modem);
|
||||||
g_free (ctx->msg_data);
|
g_free (ctx->msg_data);
|
||||||
g_slice_free (SmsSendContext, ctx);
|
g_slice_free (SmsSendContext, ctx);
|
||||||
@@ -1108,7 +1129,7 @@ send_generic_msg_data_ready (MMBaseModem *modem,
|
|||||||
const gchar *response;
|
const gchar *response;
|
||||||
gint message_reference;
|
gint message_reference;
|
||||||
|
|
||||||
response = mm_base_modem_at_command_finish (modem, res, &error);
|
response = mm_base_modem_at_command_full_finish (modem, res, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
@@ -1139,7 +1160,7 @@ send_generic_ready (MMBaseModem *modem,
|
|||||||
SmsSendContext *ctx;
|
SmsSendContext *ctx;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
mm_base_modem_at_command_finish (modem, res, &error);
|
mm_base_modem_at_command_full_finish (modem, res, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
@@ -1153,12 +1174,15 @@ send_generic_ready (MMBaseModem *modem,
|
|||||||
* be treated as an AT command (i.e. we don't want it prefixed
|
* be treated as an AT command (i.e. we don't want it prefixed
|
||||||
* with AT+ and suffixed with <CR><LF>), plus, we want it to be
|
* with AT+ and suffixed with <CR><LF>), plus, we want it to be
|
||||||
* sent right away (not queued after other AT commands). */
|
* sent right away (not queued after other AT commands). */
|
||||||
mm_base_modem_at_command_raw (ctx->modem,
|
mm_base_modem_at_command_full (ctx->modem,
|
||||||
ctx->msg_data,
|
ctx->port,
|
||||||
MM_BASE_SMS_DEFAULT_SEND_TIMEOUT,
|
ctx->msg_data,
|
||||||
FALSE,
|
MM_BASE_SMS_DEFAULT_SEND_TIMEOUT,
|
||||||
(GAsyncReadyCallback)send_generic_msg_data_ready,
|
FALSE,
|
||||||
task);
|
TRUE, /* raw */
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback)send_generic_msg_data_ready,
|
||||||
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1175,7 +1199,7 @@ send_from_storage_ready (MMBaseModem *modem,
|
|||||||
self = g_task_get_source_object (task);
|
self = g_task_get_source_object (task);
|
||||||
ctx = g_task_get_task_data (task);
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
response = mm_base_modem_at_command_finish (modem, res, &error);
|
response = mm_base_modem_at_command_full_finish (modem, res, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
|
if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
@@ -1226,12 +1250,15 @@ sms_send_next_part (GTask *task)
|
|||||||
/* Send from storage */
|
/* Send from storage */
|
||||||
if (ctx->from_storage) {
|
if (ctx->from_storage) {
|
||||||
cmd = g_strdup_printf ("+CMSS=%d", mm_sms_part_get_index ((MMSmsPart *)ctx->current->data));
|
cmd = g_strdup_printf ("+CMSS=%d", mm_sms_part_get_index ((MMSmsPart *)ctx->current->data));
|
||||||
mm_base_modem_at_command (ctx->modem,
|
mm_base_modem_at_command_full (ctx->modem,
|
||||||
cmd,
|
ctx->port,
|
||||||
MM_BASE_SMS_DEFAULT_SEND_TIMEOUT,
|
cmd,
|
||||||
FALSE,
|
MM_BASE_SMS_DEFAULT_SEND_TIMEOUT,
|
||||||
(GAsyncReadyCallback)send_from_storage_ready,
|
FALSE,
|
||||||
task);
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback)send_from_storage_ready,
|
||||||
|
task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1255,12 +1282,15 @@ sms_send_next_part (GTask *task)
|
|||||||
g_assert (ctx->msg_data != NULL);
|
g_assert (ctx->msg_data != NULL);
|
||||||
|
|
||||||
/* no network involved in this initial AT command, so lower timeout */
|
/* no network involved in this initial AT command, so lower timeout */
|
||||||
mm_base_modem_at_command (ctx->modem,
|
mm_base_modem_at_command_full (ctx->modem,
|
||||||
cmd,
|
ctx->port,
|
||||||
10,
|
cmd,
|
||||||
FALSE,
|
10,
|
||||||
(GAsyncReadyCallback)send_generic_ready,
|
FALSE,
|
||||||
task);
|
FALSE, /* raw */
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback)send_generic_ready,
|
||||||
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1297,12 +1327,23 @@ sms_send (MMBaseSms *self,
|
|||||||
{
|
{
|
||||||
SmsSendContext *ctx;
|
SmsSendContext *ctx;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
|
MMPortSerialAt *port;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
/* Select port for the operation */
|
||||||
|
port = mm_base_modem_peek_best_at_port (self->priv->modem, &error);
|
||||||
|
if (!port) {
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup the context */
|
/* Setup the context */
|
||||||
ctx = g_slice_new0 (SmsSendContext);
|
ctx = g_slice_new0 (SmsSendContext);
|
||||||
ctx->modem = g_object_ref (self->priv->modem);
|
ctx->modem = g_object_ref (self->priv->modem);
|
||||||
|
ctx->port = g_object_ref (port);
|
||||||
task = g_task_new (self, NULL, callback, user_data);
|
|
||||||
g_task_set_task_data (task, ctx, (GDestroyNotify)sms_send_context_free);
|
g_task_set_task_data (task, ctx, (GDestroyNotify)sms_send_context_free);
|
||||||
|
|
||||||
/* If the SMS is STORED, try to send from storage */
|
/* If the SMS is STORED, try to send from storage */
|
||||||
|
|||||||
Reference in New Issue
Block a user