diff options
author | Denis Kenzior <denkenz@gmail.com> | 2009-09-08 16:40:56 -0500 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2009-09-08 16:40:56 -0500 |
commit | 3449b2c0b5f100c8b1838867061664dd1e117c25 (patch) | |
tree | b6d1250951f7306ac1fa5cbbb9349874020b0f78 /src | |
parent | 47bcf1ac1857b4cd7ab8a25e09a47ed7a4e3fa2d (diff) | |
download | ofono-3449b2c0b5f100c8b1838867061664dd1e117c25.tar.bz2 |
Rework SMS fragment backup storage
The SMS address can actually contain other characters than 0-9, +, *, #,
particularly when the alphanumeric address type is used. This is
commonly used by services such as Google or carrier specific SMS
services.
Rework the SMS address storage to simply re-use the SMS address pdu
format, which consists of up to 12 hex-encoded bytes.
Diffstat (limited to 'src')
-rw-r--r-- | src/smsutil.c | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/src/smsutil.c b/src/smsutil.c index 54f8aa88..71e93c7b 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -47,7 +47,7 @@ #define SMS_BACKUP_PATH_DIR SMS_BACKUP_PATH "/%s-%i-%i" #define SMS_BACKUP_PATH_FILE SMS_BACKUP_PATH_DIR "/%03i" -#define SMS_ADDR_FMT "%21[0-9+*#]" +#define SMS_ADDR_FMT "%24[0-9A-F]" static GSList *sms_assembly_add_fragment_backup(struct sms_assembly *assembly, const struct sms *sms, time_t ts, @@ -2214,11 +2214,41 @@ static gboolean sms_deserialize(const unsigned char *buf, return sms_decode(buf + 1, len - 1, FALSE, buf[0], sms); } +static gboolean sms_assembly_extract_address(const char *straddr, + struct sms_address *out) +{ + unsigned char pdu[12]; + long len; + int offset = 0; + + if (decode_hex_own_buf(straddr, -1, &len, 0, pdu) == NULL) + return FALSE; + + return sms_decode_address_field(pdu, len, &offset, FALSE, out); +} + +static gboolean sms_assembly_encode_address(const struct sms_address *in, + char *straddr) +{ + unsigned char pdu[12]; + int offset = 0; + + if (sms_encode_address_field(in, FALSE, pdu, &offset) == FALSE) + return FALSE; + + if (encode_hex_own_buf(pdu, offset, 0, straddr) == NULL) + return FALSE; + + straddr[offset * 2 + 1] = '\0'; + + return TRUE; +} + static void sms_assembly_load(struct sms_assembly *assembly, const struct dirent *dir) { struct sms_address addr; - char straddr[sizeof(addr.address) + 1]; + char straddr[25]; guint16 ref; guint8 max; guint8 seq; @@ -2235,10 +2265,13 @@ static void sms_assembly_load(struct sms_assembly *assembly, if (dir->d_type != DT_DIR) return; + /* Max of SMS address size is 12 bytes, hex encoded */ if (sscanf(dir->d_name, SMS_ADDR_FMT "-%hi-%hhi", straddr, &ref, &max) < 3) return; - sms_address_from_string(&addr, straddr); + + if (sms_assembly_extract_address(straddr, &addr) == FALSE) + return; path = g_strdup_printf(SMS_BACKUP_PATH "/%s", assembly->imsi, dir->d_name); @@ -2292,15 +2325,18 @@ static gboolean sms_assembly_store(struct sms_assembly *assembly, { unsigned char buf[177]; int len; + char straddr[25]; if (!assembly->imsi) return FALSE; + if (sms_assembly_encode_address(&node->addr, straddr) == FALSE) + return FALSE; + len = sms_serialize(buf, sms); if (write_file(buf, len, SMS_BACKUP_MODE, - SMS_BACKUP_PATH_FILE, assembly->imsi, - sms_address_to_string(&node->addr), + SMS_BACKUP_PATH_FILE, assembly->imsi, straddr, node->ref, node->max_fragments, seq) != len) return FALSE; @@ -2312,26 +2348,28 @@ static void sms_assembly_backup_free(struct sms_assembly *assembly, { char *path; int seq; + char straddr[25]; if (!assembly->imsi) return; + if (sms_assembly_encode_address(&node->addr, straddr) == FALSE) + return; + for (seq = 0; seq < node->max_fragments; seq++) { int offset = seq / 32; int bit = 1 << (seq % 32); if (node->bitmap[offset] & bit) { path = g_strdup_printf(SMS_BACKUP_PATH_FILE, - assembly->imsi, - sms_address_to_string(&node->addr), + assembly->imsi, straddr, node->ref, node->max_fragments, seq); unlink(path); g_free(path); } } - path = g_strdup_printf(SMS_BACKUP_PATH_DIR, assembly->imsi, - sms_address_to_string(&node->addr), + path = g_strdup_printf(SMS_BACKUP_PATH_DIR, assembly->imsi, straddr, node->ref, node->max_fragments); rmdir(path); g_free(path); |