~clint-fewbar/ubuntu/precise/modemmanager/fix-removed-not-purged

« back to all changes in this revision

Viewing changes to src/mm-sms-utils.c

  • Committer: Package Import Robot
  • Author(s): Artem Popov
  • Date: 2012-01-02 13:32:18 UTC
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20120102133218-f2xuil48af71xa7b
Tags: upstream-0.5+git.20111231t174444.1e332ab
ImportĀ upstreamĀ versionĀ 0.5+git.20111231t174444.1e332ab

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
 * Copyright (C) 2011 Red Hat, Inc.
14
14
 */
15
15
 
 
16
#include <ctype.h>
 
17
#include <stdio.h>
 
18
 
16
19
#include <glib.h>
17
20
 
18
21
#include "mm-charsets.h"
19
22
#include "mm-errors.h"
20
23
#include "mm-utils.h"
21
24
#include "mm-sms-utils.h"
 
25
#include "mm-log.h"
22
26
 
23
27
#define SMS_TP_MTI_MASK               0x03
24
28
#define  SMS_TP_MTI_SMS_DELIVER       0x00
200
204
        g_free (unpacked);
201
205
    } else if (encoding == MM_SMS_ENCODING_UCS2)
202
206
        utf8 = g_convert ((char *) text, len, "UTF8", "UCS-2BE", NULL, NULL, NULL);
203
 
    else if (encoding == MM_SMS_ENCODING_8BIT)
204
 
        utf8 = g_strndup ((const char *)text, len);
 
207
    else if (encoding == MM_SMS_ENCODING_8BIT) {
 
208
        /* DBus requires UTF-8 strings, so we have some sanitizing to do */
 
209
        char *p;
 
210
        int i;
 
211
        utf8 = g_malloc0 (4*len+1); /* Worst case: Every byte becomes "\xFF" */
 
212
        p = utf8;
 
213
        for (i = 0 ; i < len ; i++) {
 
214
            if (isascii (text[i]) && text[i] != '\0')
 
215
                *p++ = text[i];
 
216
            else {
 
217
                sprintf(p, "\\x%02x", text[i]);
 
218
                p += 4;
 
219
            }
 
220
        }
 
221
        *p = '\0';
 
222
    }
205
223
    else
206
224
        utf8 = g_strdup ("");
207
225
 
230
248
}
231
249
 
232
250
static GValue *
233
 
simple_boolean_value (gboolean b)
234
 
{
235
 
    GValue *val;
236
 
 
237
 
    val = g_slice_new0 (GValue);
238
 
    g_value_init (val, G_TYPE_BOOLEAN);
239
 
    g_value_set_boolean (val, b);
240
 
 
241
 
    return val;
242
 
}
243
 
 
244
 
static GValue *
245
251
simple_string_value (const char *str)
246
252
{
247
253
    GValue *val;
335
341
        return NULL;
336
342
    }
337
343
 
 
344
    properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
 
345
                                        simple_free_gvalue);
 
346
 
338
347
    smsc_addr = sms_decode_address (&pdu[1], 2 * (pdu[0] - 1));
 
348
    g_hash_table_insert (properties, "smsc",
 
349
                         simple_string_value (smsc_addr));
 
350
    g_free (smsc_addr);
 
351
 
339
352
    sender_addr = sms_decode_address (&pdu[msg_start_offset + 2],
340
353
                                      pdu[msg_start_offset + 1]);
 
354
    g_hash_table_insert (properties, "number",
 
355
                         simple_string_value (sender_addr));
 
356
    g_free (sender_addr);
 
357
 
341
358
    sc_timestamp = sms_decode_timestamp (&pdu[tp_dcs_offset + 1]);
 
359
    g_hash_table_insert (properties, "timestamp",
 
360
                         simple_string_value (sc_timestamp));
 
361
    g_free (sc_timestamp);
 
362
 
342
363
    bit_offset = 0;
343
364
    if (pdu[msg_start_offset] & SMS_TP_UDHI) {
 
365
        int udhl, end, offset;
 
366
        udhl = pdu[user_data_offset] + 1;
 
367
        end = user_data_offset + udhl;
 
368
 
 
369
        for (offset = user_data_offset + 1; offset < end;) {
 
370
            guint8 ie_id, ie_len;
 
371
 
 
372
            ie_id = pdu[offset++];
 
373
            ie_len = pdu[offset++];
 
374
 
 
375
            switch (ie_id) {
 
376
                case 0x00:
 
377
                    /*
 
378
                     * Ignore the IE if one of the following is true:
 
379
                     *  - it claims to be part 0 of M
 
380
                     *  - it claims to be part N of M, N > M
 
381
                     */
 
382
                    if (pdu[offset + 2] == 0 ||
 
383
                        pdu[offset + 2] > pdu[offset + 1])
 
384
                        break;
 
385
 
 
386
                    g_hash_table_insert (properties, "concat-reference",
 
387
                                         simple_uint_value (pdu[offset]));
 
388
                    g_hash_table_insert (properties, "concat-max",
 
389
                                         simple_uint_value (pdu[offset + 1]));
 
390
                    g_hash_table_insert (properties, "concat-sequence",
 
391
                                         simple_uint_value (pdu[offset + 2]));
 
392
                    break;
 
393
                case 0x08:
 
394
                    /* Concatenated short message, 16-bit reference */
 
395
                    if (pdu[offset + 3] == 0 ||
 
396
                        pdu[offset + 3] > pdu[offset + 2])
 
397
                        break;
 
398
 
 
399
                    g_hash_table_insert (properties, "concat-reference",
 
400
                                         simple_uint_value (
 
401
                                             (pdu[offset] << 8)
 
402
                                             | pdu[offset + 1]));
 
403
                    g_hash_table_insert (properties, "concat-max",
 
404
                                         simple_uint_value (pdu[offset + 2]));
 
405
                    g_hash_table_insert (properties, "concat-sequence",
 
406
                                         simple_uint_value (pdu[offset + 3]));
 
407
                    break;
 
408
            }
 
409
 
 
410
            offset += ie_len;
 
411
        }
 
412
 
344
413
        /*
345
 
         * Skip over the user data headers to prevent it from being
 
414
         * Move past the user data headers to prevent it from being
346
415
         * decoded into garbage text.
347
416
         */
348
 
        int udhl;
349
 
        udhl = pdu[user_data_offset] + 1;
350
417
        user_data_offset += udhl;
351
418
        if (user_data_encoding == MM_SMS_ENCODING_GSM7) {
352
419
            /*
361
428
 
362
429
    msg_text = sms_decode_text (&pdu[user_data_offset], user_data_len,
363
430
                                user_data_encoding, bit_offset);
364
 
 
365
 
    properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
366
 
                                        simple_free_gvalue);
367
 
    g_hash_table_insert (properties, "number",
368
 
                         simple_string_value (sender_addr));
369
431
    g_hash_table_insert (properties, "text",
370
432
                         simple_string_value (msg_text));
371
 
    g_hash_table_insert (properties, "smsc",
372
 
                         simple_string_value (smsc_addr));
373
 
    g_hash_table_insert (properties, "timestamp",
374
 
                         simple_string_value (sc_timestamp));
 
433
    g_free (msg_text);
 
434
 
375
435
    if (pdu[tp_dcs_offset] & SMS_DCS_CLASS_VALID)
376
436
        g_hash_table_insert (properties, "class",
377
437
                             simple_uint_value (pdu[tp_dcs_offset] &
378
438
                                                SMS_DCS_CLASS_MASK));
379
 
    g_hash_table_insert (properties, "completed", simple_boolean_value (TRUE));
380
 
 
381
 
    g_free (smsc_addr);
382
 
    g_free (sender_addr);
383
 
    g_free (sc_timestamp);
384
 
    g_free (msg_text);
385
439
    g_free (pdu);
386
440
 
387
 
 
388
441
    return properties;
389
442
}