aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--introspection/org.freedesktop.ModemManager1.Sms.xml11
-rw-r--r--src/mm-sms-part.c4
-rw-r--r--src/mm-sms-part.h4
-rw-r--r--src/mm-sms-qmi.c10
-rw-r--r--src/mm-sms.c77
5 files changed, 101 insertions, 5 deletions
diff --git a/introspection/org.freedesktop.ModemManager1.Sms.xml b/introspection/org.freedesktop.ModemManager1.Sms.xml
index acdd2120..0cc0f1e3 100644
--- a/introspection/org.freedesktop.ModemManager1.Sms.xml
+++ b/introspection/org.freedesktop.ModemManager1.Sms.xml
@@ -118,6 +118,17 @@
<property name="DeliveryReportRequest" type="b" access="readwrite" />
<!--
+ MessageReference:
+
+ Message Reference of the last PDU sent/received within this SMS.
+
+ If the PDU type is
+ <link linkend="MM-SMS-PDU-TYPE-STATUS-REPORT:CAPS"><constant>MM_SMS_PDU_TYPE_STATUS_REPORT</constant></link>,
+ this field identifies the Message Reference of the PDU associated to the status report.
+ -->
+ <property name="MessageReference" type="u" access="read" />
+
+ <!--
Timestamp:
Time when the first PDU of the SMS message arrived the SMSC, in
diff --git a/src/mm-sms-part.c b/src/mm-sms-part.c
index a42c8f53..a6b06ced 100644
--- a/src/mm-sms-part.c
+++ b/src/mm-sms-part.c
@@ -330,6 +330,7 @@ struct _MMSmsPart {
guint class;
guint validity;
gboolean delivery_report_request;
+ guint message_reference;
gboolean should_concat;
guint concat_reference;
@@ -410,6 +411,8 @@ PART_GET_FUNC (guint, validity)
PART_SET_FUNC (guint, validity)
PART_GET_FUNC (gboolean, delivery_report_request)
PART_SET_FUNC (gboolean, delivery_report_request)
+PART_GET_FUNC (guint, message_reference)
+PART_SET_FUNC (guint, message_reference)
PART_GET_FUNC (guint, concat_reference)
@@ -596,6 +599,7 @@ mm_sms_part_new_from_binary_pdu (guint index,
PDU_SIZE_CHECK (offset + 1, "cannot read message reference");
mm_dbg (" message reference: %u", (guint)pdu[offset]);
+ mm_sms_part_set_message_reference (sms_part, pdu[offset]);
offset++;
}
diff --git a/src/mm-sms-part.h b/src/mm-sms-part.h
index c64914c7..bfb11753 100644
--- a/src/mm-sms-part.h
+++ b/src/mm-sms-part.h
@@ -108,6 +108,10 @@ guint mm_sms_part_get_validity (MMSmsPart *part);
void mm_sms_part_set_validity (MMSmsPart *part,
guint validity);
+guint mm_sms_part_get_message_reference (MMSmsPart *part);
+void mm_sms_part_set_message_reference (MMSmsPart *part,
+ guint message_reference);
+
gboolean mm_sms_part_get_delivery_report_request (MMSmsPart *part);
void mm_sms_part_set_delivery_report_request (MMSmsPart *part,
gboolean delivery_report_request);
diff --git a/src/mm-sms-qmi.c b/src/mm-sms-qmi.c
index e60e70e1..278a0040 100644
--- a/src/mm-sms-qmi.c
+++ b/src/mm-sms-qmi.c
@@ -262,6 +262,7 @@ send_generic_ready (QmiClientWms *client,
{
QmiMessageWmsRawSendOutput *output = NULL;
GError *error = NULL;
+ guint16 message_id;
output = qmi_client_wms_raw_send_finish (client, res, &error);
if (!output) {
@@ -294,6 +295,10 @@ send_generic_ready (QmiClientWms *client,
return;
}
+ if (qmi_message_wms_raw_send_output_get_message_id (output, &message_id, NULL))
+ mm_sms_part_set_message_reference ((MMSmsPart *)ctx->current->data,
+ message_id);
+
qmi_message_wms_raw_send_output_unref (output);
/* Go on with next part */
@@ -350,6 +355,7 @@ send_from_storage_ready (QmiClientWms *client,
{
QmiMessageWmsSendFromMemoryStorageOutput *output = NULL;
GError *error = NULL;
+ guint16 message_id;
output = qmi_client_wms_send_from_memory_storage_finish (client, res, &error);
if (!output) {
@@ -405,6 +411,10 @@ send_from_storage_ready (QmiClientWms *client,
return;
}
+ if (qmi_message_wms_send_from_memory_storage_output_get_message_id (output, &message_id, NULL))
+ mm_sms_part_set_message_reference ((MMSmsPart *)ctx->current->data,
+ message_id);
+
qmi_message_wms_send_from_memory_storage_output_unref (output);
/* Go on with next part */
diff --git a/src/mm-sms.c b/src/mm-sms.c
index 20dcc0da..3912810d 100644
--- a/src/mm-sms.c
+++ b/src/mm-sms.c
@@ -230,9 +230,16 @@ handle_send_ready (MMSms *self,
else {
/* Transition from Unknown->Sent or Stored->Sent */
if (mm_gdbus_sms_get_state (MM_GDBUS_SMS (ctx->self)) == MM_SMS_STATE_UNKNOWN ||
- mm_gdbus_sms_get_state (MM_GDBUS_SMS (ctx->self)) == MM_SMS_STATE_STORED)
- mm_gdbus_sms_set_state (MM_GDBUS_SMS (ctx->self), MM_SMS_STATE_SENT);
+ mm_gdbus_sms_get_state (MM_GDBUS_SMS (ctx->self)) == MM_SMS_STATE_STORED) {
+ GList *l;
+ /* Update state */
+ mm_gdbus_sms_set_state (MM_GDBUS_SMS (ctx->self), MM_SMS_STATE_SENT);
+ /* Grab last message reference */
+ l = g_list_last (mm_sms_get_parts (ctx->self));
+ mm_gdbus_sms_set_message_reference (MM_GDBUS_SMS (ctx->self),
+ mm_sms_part_get_message_reference ((MMSmsPart *)l->data));
+ }
mm_gdbus_sms_complete_send (MM_GDBUS_SMS (ctx->self), ctx->invocation);
}
@@ -265,6 +272,16 @@ handle_send_auth_ready (MMBaseModem *modem,
return;
}
+ /* Don't allow sending the same SMS multiple times, we would lose the message reference */
+ if (state == MM_SMS_STATE_SENT) {
+ g_dbus_method_invocation_return_error (ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "This SMS was already sent, cannot send it again");
+ handle_send_context_free (ctx);
+ return;
+ }
+
/* Check if we do support doing it */
if (!MM_SMS_GET_CLASS (ctx->self)->send ||
!MM_SMS_GET_CLASS (ctx->self)->send_finish) {
@@ -713,20 +730,57 @@ sms_send_finish (MMSms *self,
static void sms_send_next_part (SmsSendContext *ctx);
+static gint
+read_message_reference_from_reply (const gchar *response,
+ GError **error)
+{
+ gint rv = 0;
+ gint idx = -1;
+
+ if (strstr (response, "+CMGS"))
+ rv = sscanf (strstr (response, "+CMGS"), "+CMGS: %d", &idx);
+ else if (strstr (response, "+CMSS"))
+ rv = sscanf (strstr (response, "+CMSS"), "+CMSS: %d", &idx);
+
+ if (rv != 1 || idx < 0) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't read message reference: "
+ "%d fields parsed from response '%s'",
+ rv, response);
+ return -1;
+ }
+
+ return idx;
+}
+
static void
send_generic_msg_data_ready (MMBaseModem *modem,
GAsyncResult *res,
SmsSendContext *ctx)
{
GError *error = NULL;
+ const gchar *response;
+ gint message_reference;
- mm_base_modem_at_command_finish (MM_BASE_MODEM (modem), res, &error);
+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (modem), res, &error);
+ if (error) {
+ g_simple_async_result_take_error (ctx->result, error);
+ sms_send_context_complete_and_free (ctx);
+ return;
+ }
+
+ message_reference = read_message_reference_from_reply (response, &error);
if (error) {
g_simple_async_result_take_error (ctx->result, error);
sms_send_context_complete_and_free (ctx);
return;
}
+ mm_sms_part_set_message_reference ((MMSmsPart *)ctx->current->data,
+ (guint)message_reference);
+
ctx->current = g_list_next (ctx->current);
sms_send_next_part (ctx);
}
@@ -760,8 +814,10 @@ send_from_storage_ready (MMBaseModem *modem,
SmsSendContext *ctx)
{
GError *error = NULL;
+ const gchar *response;
+ gint message_reference;
- mm_base_modem_at_command_finish (MM_BASE_MODEM (modem), res, &error);
+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (modem), res, &error);
if (error) {
mm_dbg ("Couldn't send SMS from storage: '%s'; trying generic send...",
error->message);
@@ -772,6 +828,16 @@ send_from_storage_ready (MMBaseModem *modem,
return;
}
+ message_reference = read_message_reference_from_reply (response, &error);
+ if (error) {
+ g_simple_async_result_take_error (ctx->result, error);
+ sms_send_context_complete_and_free (ctx);
+ return;
+ }
+
+ mm_sms_part_set_message_reference ((MMSmsPart *)ctx->current->data,
+ (guint)message_reference);
+
ctx->current = g_list_next (ctx->current);
sms_send_next_part (ctx);
}
@@ -1185,7 +1251,8 @@ assemble_sms (MMSms *self,
"validity", mm_sms_part_get_validity (sorted_parts[0]),
"timestamp", mm_sms_part_get_timestamp (sorted_parts[0]),
"discharge-timestamp", mm_sms_part_get_discharge_timestamp (sorted_parts[0]),
- /* delivery report request usually set in the last part only */
+ /* delivery report request and message reference taken always from the last part */
+ "message-reference", mm_sms_part_get_message_reference (sorted_parts[self->priv->max_parts - 1]),
"delivery-report-request", mm_sms_part_get_delivery_report_request (sorted_parts[self->priv->max_parts - 1]),
NULL);