summaryrefslogtreecommitdiffstats
path: root/src/smsutil.c
diff options
context:
space:
mode:
authorPetteri Tikander <petteri.tikander@ixonos.com>2010-09-21 20:12:04 +0300
committerDenis Kenzior <denkenz@gmail.com>2010-09-22 12:20:52 -0500
commit6c1ec6160327681c9d4d1744c115235bf27b3aa7 (patch)
tree9c512a59c1d91ab5ee046b39d92d451c285fe2ff /src/smsutil.c
parent7596ecfbf608396e9b62cc3464100ef766cf4c3a (diff)
downloadofono-6c1ec6160327681c9d4d1744c115235bf27b3aa7.tar.bz2
smsutil: add fuzzy address check for status report
Diffstat (limited to 'src/smsutil.c')
-rw-r--r--src/smsutil.c103
1 files changed, 87 insertions, 16 deletions
diff --git a/src/smsutil.c b/src/smsutil.c
index f192ee89..89b922e8 100644
--- a/src/smsutil.c
+++ b/src/smsutil.c
@@ -2858,35 +2858,104 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
unsigned int offset = status_report->status_report.mr / 32;
unsigned int bit = 1 << (status_report->status_report.mr % 32);
struct id_table_node *node = NULL;
- const char *straddr;
+ const char *r_addr, *s_addr;
+ struct sms_address addr;
GHashTable *id_table;
gpointer key, value;
gboolean delivered;
- GHashTableIter iter;
+ GHashTableIter iter_addr, iter;
gboolean pending;
int i;
unsigned char *msgid;
+ unsigned int len, r_len, s_len;
/* We ignore temporary or tempfinal status reports */
if (sr_st_to_delivered(status_report->status_report.st,
&delivered) == FALSE)
return FALSE;
- straddr = sms_address_to_string(&status_report->status_report.raddr);
- id_table = g_hash_table_lookup(assembly->assembly_table, straddr);
+ r_addr = sms_address_to_string(&status_report->status_report.raddr);
+ id_table = g_hash_table_lookup(assembly->assembly_table, r_addr);
- /* key (receiver address) does not exist in assembly */
- if (id_table == NULL)
- return FALSE;
+ /* key (receiver address) exists in assembly */
+ if (id_table != NULL) {
- g_hash_table_iter_init(&iter, id_table);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- node = value;
+ /* Found an identical address from assembly. */
+ s_addr = r_addr;
- if (node->mrs[offset] & bit)
- break;
+ g_hash_table_iter_init(&iter, id_table);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ node = value;
+
+ if (node->mrs[offset] & bit)
+ break;
- node = NULL;
+ node = NULL;
+ }
+ }
+ /*
+ * Key (receiver address) does not exist in assembly.
+ * Some networks can change address to international format,
+ * although address is sent in the national format.
+ * Handle also change from national to international format.
+ * So notify these special cases by comparing only
+ * last six digits of the assembly addresses and received address.
+ * If address contains less than six digits,
+ * compare only existing digits.
+ */
+ else {
+ g_hash_table_iter_init(&iter_addr, assembly->assembly_table);
+
+ /*
+ * Go through all addresses using 'fuzzy' address-comparation.
+ * Each address can relate to 1-n msg_ids.
+ */
+ while (g_hash_table_iter_next(&iter_addr, (gpointer) &s_addr,
+ (gpointer) &id_table)) {
+
+ /* Notify international <-> national conversions */
+ if (((r_addr[0] == '+') && (s_addr[0] != '+')) ||
+ ((r_addr[0] != '+') && (s_addr[0] == '+'))) {
+
+ r_len = strlen(r_addr);
+ s_len = strlen(s_addr);
+
+ len = MIN(6, MIN(r_len, s_len));
+
+ for (i = 0; i < len; i++) {
+ if (s_addr[s_len - i - 1] !=
+ r_addr[r_len - i - 1])
+ break;
+ }
+
+ /* Not all digits matched. */
+ if (i < len)
+ continue;
+ }
+ /* No conversions */
+ else
+ continue;
+
+ /* Address matched. Check message reference. */
+ g_hash_table_iter_init(&iter, id_table);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ node = value;
+
+ /* Address and MR matched */
+ if (node->mrs[offset] & bit)
+ break;
+
+ node = NULL;
+ }
+
+ /*
+ * Received address with MR matched with one
+ * of the stored addresses and MR, so no need
+ * to continue searching.
+ */
+ if (node)
+ break;
+ }
}
/* Unable to find a message reference belonging to this address */
@@ -2913,13 +2982,15 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
msgid = (unsigned char *) key;
+ sms_address_from_string(&addr, s_addr);
+
if (pending == TRUE && node->deliverable == TRUE) {
/*
* More status reports expected, and already received
* reports completed. Update backup file.
*/
sr_assembly_add_fragment_backup(assembly->imsi, node,
- &status_report->status_report.raddr,
+ &addr,
msgid);
return FALSE;
@@ -2932,14 +3003,14 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
memcpy(out_msgid, msgid, SMS_MSGID_LEN);
sr_assembly_remove_fragment_backup(assembly->imsi,
- &status_report->status_report.raddr,
+ &addr,
msgid);
g_hash_table_iter_remove(&iter);
if (g_hash_table_size(id_table) == 0)
g_hash_table_remove(assembly->assembly_table,
- status_report->status_report.raddr.address);
+ s_addr);
return TRUE;
}