add sms read access
[project/uqmi.git] / commands-wms.c
1 #include "qmi-message.h"
2
3 static void cmd_wms_list_messages_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
4 {
5 struct qmi_wms_list_messages_response res;
6 int i, len = 0;
7
8 qmi_parse_wms_list_messages_response(msg, &res);
9 blobmsg_alloc_string_buffer(&status, "messages", 1);
10 for (i = 0; i < res.data.message_list_n; i++) {
11 len += sprintf(blobmsg_realloc_string_buffer(&status, len + 12) + len,
12 " %d" + (len ? 0 : 1),
13 res.data.message_list[i].memory_index);
14 }
15 blobmsg_add_string_buffer(&status);
16 }
17
18 static enum qmi_cmd_result
19 cmd_wms_list_messages_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
20 {
21 static struct qmi_wms_list_messages_request mreq = {
22 QMI_INIT(storage_type, QMI_WMS_STORAGE_TYPE_UIM),
23 QMI_INIT(message_tag, QMI_WMS_MESSAGE_TAG_TYPE_MT_NOT_READ),
24 };
25
26 qmi_set_wms_list_messages_request(msg, &mreq);
27
28 return QMI_CMD_REQUEST;
29 }
30
31 static void decode_7bit(char *name, const unsigned char *data, int data_len)
32 {
33 bool multipart = false;
34 char *dest;
35 int part = 0, n_parts = 0;
36 int len, pos_offset = 0;
37 int i;
38
39 if (data[0] == 5 && data[1] == 0 && data[2] == 3) {
40 multipart = true;
41 n_parts = data[4];
42 part = data[5];
43 } else if (data[0] == 6 && data[1] == 8 && data[2] == 4) {
44 multipart = true;
45 n_parts = data[5];
46 part = data[6];
47 }
48
49 if (multipart) {
50 len = data[0] + 1;
51 data += len;
52 data_len -= len;
53 pos_offset = 6;
54 }
55
56 dest = blobmsg_alloc_string_buffer(&status, name, data_len * 8 / 7 + 2);
57 for (i = 0; i < data_len; i++) {
58 int pos = (i + pos_offset) % 7;
59
60 if (pos == 0) {
61 *(dest++) = data[i] & 0x7f;
62 } else {
63 if (i)
64 *(dest++) = (data[i - 1] >> (7 + 1 - pos)) |
65 ((data[i] << pos) & 0x7f);
66
67 if (pos == 6)
68 *(dest++) = (data[i] >> 1) & 0x7f;
69 }
70 }
71 *dest = 0;
72 blobmsg_add_string_buffer(&status);
73
74 if (multipart) {
75 blobmsg_add_u32(&status, "part", part + 1);
76 blobmsg_add_u32(&status, "parts", n_parts);
77 }
78 }
79
80 static char *add_semioctet(char *str, char val)
81 {
82 *str = '0' + (val & 0xf);
83 if (*str <= '9')
84 str++;
85
86 *str = '0' + ((val >> 4) & 0xf);
87 if (*str <= '9')
88 str++;
89
90 return str;
91 }
92
93 static unsigned char *
94 decode_semioctet_number(char *str, char *name, unsigned char *data, int len)
95 {
96 str = blobmsg_alloc_string_buffer(&status, name, len * 2 + 2);
97 if (*data == 0x91) {
98 len--;
99 *(str++) = '+';
100 }
101 data++;
102 while (len) {
103 str = add_semioctet(str, *data);
104 data++;
105 len--;
106 }
107
108 *str = 0;
109 blobmsg_add_string_buffer(&status);
110
111 return data;
112 }
113
114 static void cmd_wms_get_message_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
115 {
116 struct qmi_wms_raw_read_response res;
117 unsigned char *data, *end;
118 char *str;
119 int i, cur_len;
120 bool sent;
121
122 qmi_parse_wms_raw_read_response(msg, &res);
123 data = (unsigned char *) res.data.raw_message_data.raw_data;
124 end = data + res.data.raw_message_data.raw_data_n;
125
126 do {
127 cur_len = *(data++);
128 if (data + cur_len >= end)
129 break;
130
131 if (cur_len)
132 data = decode_semioctet_number(str, "smsc", data, cur_len);
133
134 if (data + 3 >= end)
135 break;
136
137 sent = (*data & 0x3) == 1;
138 data++;
139 if (sent)
140 data++;
141
142 cur_len = *(data++);
143 if (data + cur_len >= end)
144 break;
145
146 if (cur_len)
147 data = decode_semioctet_number(str, sent ? "receiver" : "sender", data, (cur_len + 1) / 2);
148
149 if (data + 3 >= end)
150 break;
151
152 /* Protocol ID */
153 if (*(data++) != 0)
154 break;
155
156 /* Data Encoding */
157 if (*(data++) != 0)
158 break;
159
160 if (sent) {
161 /* Message validity */
162 data++;
163 } else {
164 if (data + 6 >= end)
165 break;
166
167 str = blobmsg_alloc_string_buffer(&status, "timestamp", 32);
168
169 /* year */
170 *(str++) = '2';
171 *(str++) = '0';
172 str = add_semioctet(str, data[0]);
173 /* month */
174 *(str++) = '-';
175 str = add_semioctet(str, data[1]);
176 /* day */
177 *(str++) = '-';
178 str = add_semioctet(str, data[2]);
179
180 /* hour */
181 *(str++) = ' ';
182 str = add_semioctet(str, data[3]);
183 /* minute */
184 *(str++) = ':';
185 str = add_semioctet(str, data[4]);
186 /* second */
187 *(str++) = ':';
188 str = add_semioctet(str, data[5]);
189 *str = 0;
190
191 blobmsg_add_string_buffer(&status);
192
193 data += 7;
194 }
195
196 cur_len = *(data++);
197 decode_7bit("text", data, end - data);
198 } while (0);
199 }
200
201 static enum qmi_cmd_result
202 cmd_wms_get_message_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
203 {
204 static struct qmi_wms_raw_read_request mreq = {
205 QMI_INIT_SEQUENCE(message_memory_storage_id,
206 .storage_type = QMI_WMS_STORAGE_TYPE_UIM,
207 ),
208 QMI_INIT(message_mode, QMI_WMS_MESSAGE_MODE_GSM_WCDMA),
209 };
210 char *err;
211 int id;
212
213 id = strtoul(arg, &err, 10);
214 if (err && *err) {
215 blobmsg_add_string(&status, "error", "Invalid message ID");
216 return QMI_CMD_EXIT;
217 }
218
219 mreq.data.message_memory_storage_id.memory_index = id;
220 qmi_set_wms_raw_read_request(msg, &mreq);
221
222 return QMI_CMD_REQUEST;
223 }