api: new `MessageReference' property in the SMS interface
Message reference allows to match a sent SMS with its corresponding delivery report, if requested.
This commit is contained in:
@@ -117,6 +117,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:
|
||||
|
||||
|
@@ -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++;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
77
src/mm-sms.c
77
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);
|
||||
|
||||
|
Reference in New Issue
Block a user