mirror of git://git.sysmocom.de/ofono
smsutil: add fuzzy address check for status report
This commit is contained in:
parent
7596ecfbf6
commit
6c1ec61603
103
src/smsutil.c
103
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;
|
||||
|
||||
node = NULL;
|
||||
if (node->mrs[offset] & bit)
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue