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:
Aleksander Morgado
2012-09-11 15:41:53 +02:00
parent 320984a4a0
commit 4f1991e2ba
5 changed files with 101 additions and 5 deletions

View File

@@ -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:

View File

@@ -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++;
}

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);