SEGFAULT on reading Unicode sms messages
[project/uqmi.git] / commands-wms.c
index 7b3b925eae061c042966a14b3d5d01e7227034a7..da4aeaff8722042504d5504367b38df840fba100 100644 (file)
@@ -3,16 +3,15 @@
 static void cmd_wms_list_messages_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
 {
        struct qmi_wms_list_messages_response res;
-       int i, len = 0;
+       void *c;
+       int i;
 
        qmi_parse_wms_list_messages_response(msg, &res);
-       blobmsg_alloc_string_buffer(&status, "messages", 1);
-       for (i = 0; i < res.data.message_list_n; i++) {
-               len += sprintf(blobmsg_realloc_string_buffer(&status, len + 12) + len,
-                              " %d" + (len ? 0 : 1),
-                                          res.data.message_list[i].memory_index);
-       }
-       blobmsg_add_string_buffer(&status);
+       c = blobmsg_open_array(&status, NULL);
+       for (i = 0; i < res.data.message_list_n; i++)
+               blobmsg_add_u32(&status, NULL, res.data.message_list[i].memory_index);
+
+       blobmsg_close_array(&status, c);
 }
 
 static enum qmi_cmd_result
@@ -48,7 +47,7 @@ put_unicode_char(char *dest, uint16_t c)
 
 
 static int
-pdu_decode_7bit_char(char *dest, int len, char c, bool *escape)
+pdu_decode_7bit_char(char *dest, int len, unsigned char c, bool *escape)
 {
        uint16_t conv_0x20[] = {
                0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC,
@@ -179,7 +178,7 @@ static void decode_udh(const unsigned char *data)
                switch (type) {
                case 0:
                        blobmsg_add_u32(&status, "concat_ref", (uint32_t) val[0]);
-                       blobmsg_add_u32(&status, "concat_part", (uint32_t) val[2] + 1);
+                       blobmsg_add_u32(&status, "concat_part", (uint32_t) val[2]);
                        blobmsg_add_u32(&status, "concat_parts", (uint32_t) val[1]);
                        break;
                default:
@@ -247,9 +246,9 @@ pdu_decode_address(char *str, unsigned char *data, int len)
        *str = 0;
 }
 
-static void wms_decode_address(char *str, char *name, unsigned char *data, int len)
+static void wms_decode_address(char *name, unsigned char *data, int len)
 {
-       str = blobmsg_alloc_string_buffer(&status, name, len * 2 + 2);
+       char *str = blobmsg_alloc_string_buffer(&status, name, len * 2 + 2);
        pdu_decode_address(str, data, len);
        blobmsg_add_string_buffer(&status);
 }
@@ -262,22 +261,24 @@ static void cmd_wms_get_message_cb(struct qmi_dev *qmi, struct qmi_request *req,
        int cur_len;
        bool sent;
        unsigned char first, dcs;
+       void *c;
 
        qmi_parse_wms_raw_read_response(msg, &res);
+       c = blobmsg_open_table(&status, NULL);
        data = (unsigned char *) res.data.raw_message_data.raw_data;
        end = data + res.data.raw_message_data.raw_data_n;
 
        cur_len = *(data++);
        if (data + cur_len >= end)
-               return;
+               goto error;
 
        if (cur_len) {
-               wms_decode_address(str, "smsc", data, cur_len - 1);
+               wms_decode_address("smsc", data, cur_len - 1);
                data += cur_len;
        }
 
        if (data + 3 >= end)
-               return;
+               goto error;
 
        first = *(data++);
        sent = (first & 0x3) == 1;
@@ -286,27 +287,27 @@ static void cmd_wms_get_message_cb(struct qmi_dev *qmi, struct qmi_request *req,
 
        cur_len = *(data++);
        if (data + cur_len >= end)
-               return;
+               goto error;
 
        if (cur_len) {
                cur_len = (cur_len + 1) / 2;
-               wms_decode_address(str, sent ? "receiver" : "sender", data, cur_len);
+               wms_decode_address(sent ? "receiver" : "sender", data, cur_len);
                data += cur_len + 1;
        }
 
        if (data + 3 >= end)
-               return;
+               goto error;
 
        /* Protocol ID */
        if (*(data++) != 0)
-               return;
+               goto error;
 
        /* Data Encoding */
        dcs = *(data++);
 
        /* only 7-bit encoding supported for now */
        if (dcs & 0x0c)
-               return;
+               goto error;
 
        if (dcs & 0x10)
                blobmsg_add_u32(&status, "class", (dcs & 3));
@@ -316,7 +317,7 @@ static void cmd_wms_get_message_cb(struct qmi_dev *qmi, struct qmi_request *req,
                data++;
        } else {
                if (data + 6 >= end)
-                       return;
+                       goto error;
 
                str = blobmsg_alloc_string_buffer(&status, "timestamp", 32);
 
@@ -349,6 +350,13 @@ static void cmd_wms_get_message_cb(struct qmi_dev *qmi, struct qmi_request *req,
 
        cur_len = *(data++);
        decode_7bit_field("text", data, end - data, !!(first & 0x40));
+       blobmsg_close_table(&status, c);
+
+       return;
+
+error:
+       blobmsg_close_table(&status, c);
+       fprintf(stderr, "There was an error reading message.\n");
 }
 
 static enum qmi_cmd_result
@@ -365,7 +373,7 @@ cmd_wms_get_message_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct
 
        id = strtoul(arg, &err, 10);
        if (err && *err) {
-               blobmsg_add_string(&status, "error", "Invalid message ID");
+               uqmi_add_error("Invalid message ID");
                return QMI_CMD_EXIT;
        }
 
@@ -385,9 +393,9 @@ static void cmd_wms_get_raw_message_cb(struct qmi_dev *qmi, struct qmi_request *
 
        qmi_parse_wms_raw_read_response(msg, &res);
        data = (unsigned char *) res.data.raw_message_data.raw_data;
-       str = blobmsg_alloc_string_buffer(&status, "data", res.data.raw_message_data.raw_data_n * 3);
+       str = blobmsg_alloc_string_buffer(&status, NULL, res.data.raw_message_data.raw_data_n * 3);
        for (i = 0; i < res.data.raw_message_data.raw_data_n; i++) {
-               str += sprintf(str, " %02x" + (i ? 0 : 1), data[i]);
+               str += sprintf(str, &" %02x"[i ? 0 : 1], data[i]);
        }
        blobmsg_add_string_buffer(&status);
 }
@@ -399,14 +407,14 @@ static struct {
        const char *smsc;
        const char *target;
        bool flash;
-} send;
+} _send;
 
 
 #define cmd_wms_send_message_smsc_cb no_cb
 static enum qmi_cmd_result
 cmd_wms_send_message_smsc_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 {
-       send.smsc = arg;
+       _send.smsc = arg;
        return QMI_CMD_DONE;
 }
 
@@ -414,7 +422,7 @@ cmd_wms_send_message_smsc_prepare(struct qmi_dev *qmi, struct qmi_request *req,
 static enum qmi_cmd_result
 cmd_wms_send_message_target_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 {
-       send.target = arg;
+       _send.target = arg;
        return QMI_CMD_DONE;
 }
 
@@ -422,7 +430,7 @@ cmd_wms_send_message_target_prepare(struct qmi_dev *qmi, struct qmi_request *req
 static enum qmi_cmd_result
 cmd_wms_send_message_flash_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 {
-       send.flash = true;
+       _send.flash = true;
        return QMI_CMD_DONE;
 }
 
@@ -469,7 +477,7 @@ pdu_encode_7bit_str(unsigned char *data, const char *str)
                        break;
                }
 
-               ofs = (ofs + 1) % 7;
+               ofs = (ofs + 1) % 8;
        }
 
        return len + 1;
@@ -544,24 +552,24 @@ cmd_wms_send_message_prepare(struct qmi_dev *qmi, struct qmi_request *req, struc
        unsigned char protocol_id = 0x00;
        unsigned char dcs = 0x00;
 
-       if (!send.smsc || !*send.smsc || !send.target || !*send.target) {
-               blobmsg_add_string(&status, "error", "Missing argument");
+       if (!_send.smsc || !*_send.smsc || !_send.target || !*_send.target) {
+               uqmi_add_error("Missing argument");
                return QMI_CMD_EXIT;
        }
 
-       if (strlen(send.smsc) > 16 || strlen(send.target) > 16 || strlen(arg) > 160) {
-               blobmsg_add_string(&status, "error", "Argument too long");
+       if (strlen(_send.smsc) > 16 || strlen(_send.target) > 16 || strlen(arg) > 160) {
+               uqmi_add_error("Argument too long");
                return QMI_CMD_EXIT;
        }
 
-       if (send.flash)
+       if (_send.flash)
                dcs |= 0x10;
 
-       cur += pdu_encode_number(cur, send.smsc, true);
+       cur += pdu_encode_number(cur, _send.smsc, true);
        *(cur++) = first_octet;
        *(cur++) = 0; /* reference */
 
-       cur += pdu_encode_number(cur, send.target, false);
+       cur += pdu_encode_number(cur, _send.target, false);
        *(cur++) = protocol_id;
        *(cur++) = dcs;