smsutil: More code cleanup

- Change the flow of the code a bit, in the case that all fragments have
  been sent and an udelivered sr arrives, we can simply remove the node
  and signal undelivered up
- We ignore temporary and temporary final status reports
This commit is contained in:
Denis Kenzior 2010-06-21 12:42:23 -05:00
parent cbc27e06b3
commit 36bcae5ff1
1 changed files with 54 additions and 47 deletions

View File

@ -2645,21 +2645,46 @@ void status_report_assembly_free(struct status_report_assembly *assembly)
g_free(assembly); g_free(assembly);
} }
static gboolean sr_st_to_delivered(enum sms_st st, gboolean *delivered)
{
if (st >= SMS_ST_TEMPFINAL_CONGESTION && st <= SMS_ST_TEMPFINAL_LAST)
return FALSE;
if (st >= SMS_ST_TEMPORARY_CONGESTION && st <= SMS_ST_TEMPORARY_LAST)
return FALSE;
if (st <= SMS_ST_COMPLETED_LAST) {
*delivered = TRUE;
return TRUE;
}
if (st >= SMS_ST_PERMANENT_RP_ERROR && st <= SMS_ST_PERMANENT_LAST) {
*delivered = FALSE;
return TRUE;
}
return FALSE;
}
gboolean status_report_assembly_report(struct status_report_assembly *assembly, gboolean status_report_assembly_report(struct status_report_assembly *assembly,
const struct sms *status_report, const struct sms *status_report,
unsigned int *msg_id, unsigned int *out_id,
gboolean *msg_delivered) gboolean *out_delivered)
{ {
unsigned int offset = status_report->status_report.mr / 32; unsigned int offset = status_report->status_report.mr / 32;
unsigned int bit = 1 << (status_report->status_report.mr % 32); unsigned int bit = 1 << (status_report->status_report.mr % 32);
struct id_table_node *node = NULL; struct id_table_node *node = NULL;
GHashTable *id_table; GHashTable *id_table;
unsigned int *key; gpointer key, value;
gpointer value; gboolean delivered;
GHashTableIter iter; GHashTableIter iter;
gboolean pending;
int i; int i;
gboolean pending = FALSE;
gboolean update_history = FALSE; /* We ignore temporary or tempfinal status reports */
if (sr_st_to_delivered(status_report->status_report.st,
&delivered) == FALSE)
return FALSE;
id_table = g_hash_table_lookup(assembly->assembly_table, id_table = g_hash_table_lookup(assembly->assembly_table,
status_report->status_report.raddr.address); status_report->status_report.raddr.address);
@ -2669,7 +2694,7 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
return FALSE; return FALSE;
g_hash_table_iter_init(&iter, id_table); g_hash_table_iter_init(&iter, id_table);
while (g_hash_table_iter_next(&iter, (gpointer)&key, &value)) { while (g_hash_table_iter_next(&iter, &key, &value)) {
node = value; node = value;
if (node->mrs[offset] & bit) if (node->mrs[offset] & bit)
@ -2684,56 +2709,38 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
/* Mr belongs to this node. */ /* Mr belongs to this node. */
node->mrs[offset] ^= bit; node->mrs[offset] ^= bit;
*msg_id = *key;
for (i = 0; i < 8; i++) { node->deliverable = node->deliverable && delivered;
/* If we haven't sent the entire message yet, wait until sent */
if (node->sent_mrs < node->total_mrs)
return FALSE;
/* Figure out if we are expecting more status reports */
for (i = 0, pending = FALSE; i < 8; i++) {
/* There are still pending mr(s). */ /* There are still pending mr(s). */
if (node->mrs[i] != 0 || if (node->mrs[i] != 0) {
(node->sent_mrs < node->total_mrs)) {
pending = TRUE; pending = TRUE;
break; break;
} }
} }
/* Mr is not delivered. */ if (pending == TRUE && node->deliverable == TRUE)
if (status_report->status_report.st != SMS_ST_COMPLETED_RECEIVED) { return FALSE;
/*
* First mr which is not delivered. Update ofono history
* and mark the whole message as undeliverable. Upcoming
* mrs can not change the status to deliverable even if
* they are considered as delivered.
*/
if (node->deliverable) {
node->deliverable = FALSE;
update_history = TRUE;
}
}
/* if (out_delivered)
* If there are pending mrs that relate to this message, we do *out_delivered = node->deliverable;
* not delete the node yet.
*/
if (pending) {
*msg_delivered = FALSE;
return update_history;
} else {
*msg_delivered = node->deliverable;
g_hash_table_iter_remove(&iter); if (out_id)
*out_id = *((unsigned int *) key);
if (g_hash_table_size(id_table) == 0) g_hash_table_iter_remove(&iter);
g_hash_table_remove(assembly->assembly_table,
status_report->status_report.raddr.address); if (g_hash_table_size(id_table) == 0)
/* g_hash_table_remove(assembly->assembly_table,
* If there has not been undelivered mrs, message is status_report->status_report.raddr.address);
* delivered and the ofono history needs to be updated.
* If the message is concidered as undelivered, the return TRUE;
* ofono history has already been updated when the first
* undelivered mr arrived, unless this one is the only
* related mr and was marked undelivered.
*/
return *msg_delivered || update_history;
}
} }
void status_report_assembly_add_fragment( void status_report_assembly_add_fragment(