Add command for listing device capabilities
[project/uqmi.git] / commands-dms.c
1 #include "qmi-message.h"
2
3 static struct {
4         QmiDmsUimPinId pin_id;
5         char* pin;
6         char* new_pin;
7         char* puk;
8 } dms_req_data;
9
10 static void cmd_dms_get_capabilities_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
11 {
12         void *t, *networks;
13         int i;
14         struct qmi_dms_get_capabilities_response res;
15         const char *radio_cap[] = {
16                 [QMI_DMS_RADIO_INTERFACE_CDMA20001X] = "cdma1x",
17                 [QMI_DMS_RADIO_INTERFACE_EVDO] = "cdma1xevdo",
18                 [QMI_DMS_RADIO_INTERFACE_GSM] = "gsm",
19                 [QMI_DMS_RADIO_INTERFACE_UMTS] = "umts",
20                 [QMI_DMS_RADIO_INTERFACE_LTE] = "lte",
21         };
22         const char *service_cap[] = {
23                 [QMI_DMS_DATA_SERVICE_CAPABILITY_NONE] = "none",
24                 [QMI_DMS_DATA_SERVICE_CAPABILITY_CS] = "cs",
25                 [QMI_DMS_DATA_SERVICE_CAPABILITY_PS] = "ps",
26                 [QMI_DMS_DATA_SERVICE_CAPABILITY_SIMULTANEOUS_CS_PS] = "simultaneous_cs_ps",
27                 [QMI_DMS_DATA_SERVICE_CAPABILITY_NON_SIMULTANEOUS_CS_PS] = "non_simultaneous_cs_ps",
28         };
29
30         qmi_parse_dms_get_capabilities_response(msg, &res);
31
32         t = blobmsg_open_table(&status, NULL);
33
34         blobmsg_add_u32(&status, "max_tx_channel_rate", (int32_t) res.data.info.max_tx_channel_rate);
35         blobmsg_add_u32(&status, "max_rx_channel_rate", (int32_t) res.data.info.max_rx_channel_rate);
36         if ((int)res.data.info.data_service_capability >= 0 && res.data.info.data_service_capability < ARRAY_SIZE(service_cap))
37                 blobmsg_add_string(&status, "data_service", service_cap[res.data.info.data_service_capability]);
38
39         if(res.data.info.sim_capability == QMI_DMS_SIM_CAPABILITY_NOT_SUPPORTED)
40                 blobmsg_add_string(&status, "sim", "not supported");
41         else if(res.data.info.sim_capability == QMI_DMS_SIM_CAPABILITY_SUPPORTED)
42                 blobmsg_add_string(&status, "sim", "supported");
43
44         networks = blobmsg_open_array(&status, "networks");
45         for (i = 0; i < res.data.info.radio_interface_list_n; i++) {
46                 if ((int)res.data.info.radio_interface_list[i] >= 0 && res.data.info.radio_interface_list[i] < ARRAY_SIZE(radio_cap))
47                         blobmsg_add_string(&status, NULL, radio_cap[res.data.info.radio_interface_list[i]]);
48                 else
49                         blobmsg_add_string(&status, NULL, "unknown");
50         }
51         blobmsg_close_array(&status, networks);
52
53         blobmsg_close_table(&status, t);
54 }
55
56 static enum qmi_cmd_result
57 cmd_dms_get_capabilities_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
58 {
59         qmi_set_dms_get_capabilities_request(msg);
60         return QMI_CMD_REQUEST;
61 }
62
63 static const char *get_pin_status(int status)
64 {
65         static const char *pin_status[] = {
66                 [QMI_DMS_UIM_PIN_STATUS_NOT_INITIALIZED] = "not_initialized",
67                 [QMI_DMS_UIM_PIN_STATUS_ENABLED_NOT_VERIFIED] = "not_verified",
68                 [QMI_DMS_UIM_PIN_STATUS_ENABLED_VERIFIED] = "verified",
69                 [QMI_DMS_UIM_PIN_STATUS_DISABLED] = "disabled",
70                 [QMI_DMS_UIM_PIN_STATUS_BLOCKED] = "blocked",
71                 [QMI_DMS_UIM_PIN_STATUS_PERMANENTLY_BLOCKED] = "permanently_blocked",
72                 [QMI_DMS_UIM_PIN_STATUS_UNBLOCKED] = "unblocked",
73                 [QMI_DMS_UIM_PIN_STATUS_CHANGED] = "changed",
74         };
75         const char *res = "Unknown";
76
77         if (status < ARRAY_SIZE(pin_status) && pin_status[status])
78                 res = pin_status[status];
79
80         return res;
81 }
82
83 static void cmd_dms_get_pin_status_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
84 {
85         struct qmi_dms_uim_get_pin_status_response res;
86         void *c;
87
88         qmi_parse_dms_uim_get_pin_status_response(msg, &res);
89         c = blobmsg_open_table(&status, NULL);
90         if (res.set.pin1_status) {
91                 blobmsg_add_string(&status, "pin1_status", get_pin_status(res.data.pin1_status.current_status));
92                 blobmsg_add_u32(&status, "pin1_verify_tries", (int32_t) res.data.pin1_status.verify_retries_left);
93                 blobmsg_add_u32(&status, "pin1_unblock_tries", (int32_t) res.data.pin1_status.unblock_retries_left);
94         }
95         if (res.set.pin2_status) {
96                 blobmsg_add_string(&status, "pin2_status", get_pin_status(res.data.pin2_status.current_status));
97                 blobmsg_add_u32(&status, "pin2_verify_tries", (int32_t) res.data.pin2_status.verify_retries_left);
98                 blobmsg_add_u32(&status, "pin2_unblock_tries", (int32_t) res.data.pin2_status.unblock_retries_left);
99         }
100         blobmsg_close_table(&status, c);
101 }
102
103 static enum qmi_cmd_result
104 cmd_dms_get_pin_status_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
105 {
106         qmi_set_dms_uim_get_pin_status_request(msg);
107         return QMI_CMD_REQUEST;
108 }
109
110 #define cmd_dms_verify_pin1_cb no_cb
111 static enum qmi_cmd_result
112 cmd_dms_verify_pin1_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
113 {
114         struct qmi_dms_uim_verify_pin_request data = {
115                 QMI_INIT_SEQUENCE(info,
116                         .pin_id = QMI_DMS_UIM_PIN_ID_PIN,
117                         .pin = arg
118                 )
119         };
120         qmi_set_dms_uim_verify_pin_request(msg, &data);
121         return QMI_CMD_REQUEST;
122 }
123
124 #define cmd_dms_verify_pin2_cb no_cb
125 static enum qmi_cmd_result
126 cmd_dms_verify_pin2_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
127 {
128         struct qmi_dms_uim_verify_pin_request data = {
129                 QMI_INIT_SEQUENCE(info,
130                         .pin_id = QMI_DMS_UIM_PIN_ID_PIN2,
131                         .pin = arg
132                 )
133         };
134         qmi_set_dms_uim_verify_pin_request(msg, &data);
135         return QMI_CMD_REQUEST;
136 }
137
138 #define cmd_dms_set_pin_cb no_cb
139 static enum qmi_cmd_result
140 cmd_dms_set_pin_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
141 {
142         dms_req_data.pin = arg;
143         return QMI_CMD_DONE;
144 }
145
146 static enum qmi_cmd_result
147 cmd_dms_set_pin_protection_prepare(struct qmi_msg *msg, char *arg)
148 {
149         if (!dms_req_data.pin) {
150                 uqmi_add_error("Missing argument");
151                 return QMI_CMD_EXIT;
152         }
153
154         int is_enabled;
155         if (strcasecmp(arg, "disabled") == 0)
156                 is_enabled = false;
157         else if (strcasecmp(arg, "enabled") == 0)
158                 is_enabled = true;
159         else {
160                 uqmi_add_error("Invalid value (valid: disabled, enabled)");
161                 return QMI_CMD_EXIT;
162         }
163
164         struct qmi_dms_uim_set_pin_protection_request dms_pin_protection_req = {
165                 QMI_INIT_SEQUENCE(info,
166                         .pin_id = dms_req_data.pin_id
167                 ),
168                 QMI_INIT_PTR(info.pin, dms_req_data.pin),
169                 QMI_INIT_PTR(info.protection_enabled, is_enabled)
170         };
171
172         qmi_set_dms_uim_set_pin_protection_request(msg, &dms_pin_protection_req);
173         return QMI_CMD_REQUEST;
174 }
175
176 #define cmd_dms_set_pin1_protection_cb no_cb
177 static enum qmi_cmd_result
178 cmd_dms_set_pin1_protection_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
179 {
180         dms_req_data.pin_id = QMI_DMS_UIM_PIN_ID_PIN;
181         return cmd_dms_set_pin_protection_prepare(msg, arg);
182 }
183
184 #define cmd_dms_set_pin2_protection_cb no_cb
185 static enum qmi_cmd_result
186 cmd_dms_set_pin2_protection_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
187 {
188         dms_req_data.pin_id = QMI_DMS_UIM_PIN_ID_PIN2;
189         return cmd_dms_set_pin_protection_prepare(msg, arg);
190 }
191
192 static enum qmi_cmd_result
193 cmd_dms_change_pin_prepare(struct qmi_msg *msg, char *arg)
194 {
195         if (!dms_req_data.pin || !dms_req_data.new_pin) {
196                 uqmi_add_error("Missing argument");
197                 return QMI_CMD_EXIT;
198         }
199
200         struct qmi_dms_uim_change_pin_request dms_change_pin_req = {
201                 QMI_INIT_SEQUENCE(info,
202                         .pin_id = dms_req_data.pin_id
203                 ),
204                 QMI_INIT_PTR(info.old_pin, dms_req_data.pin),
205                 QMI_INIT_PTR(info.new_pin, dms_req_data.new_pin)
206         };
207
208         qmi_set_dms_uim_change_pin_request(msg, &dms_change_pin_req);
209         return QMI_CMD_REQUEST;
210 }
211
212 #define cmd_dms_change_pin1_cb no_cb
213 static enum qmi_cmd_result
214 cmd_dms_change_pin1_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
215 {
216         dms_req_data.pin_id = QMI_DMS_UIM_PIN_ID_PIN;
217         return cmd_dms_change_pin_prepare(msg, arg);
218 }
219
220 #define cmd_dms_change_pin2_cb no_cb
221 static enum qmi_cmd_result
222 cmd_dms_change_pin2_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
223 {
224         dms_req_data.pin_id = QMI_DMS_UIM_PIN_ID_PIN2;
225         return cmd_dms_change_pin_prepare(msg, arg);
226 }
227
228 #define cmd_dms_set_new_pin_cb no_cb
229 static enum qmi_cmd_result
230 cmd_dms_set_new_pin_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
231 {
232         dms_req_data.new_pin = arg;
233         return QMI_CMD_DONE;
234 }
235
236 #define cmd_dms_set_puk_cb no_cb
237 static enum qmi_cmd_result
238 cmd_dms_set_puk_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
239 {
240         dms_req_data.puk = arg;
241         return QMI_CMD_DONE;
242 }
243
244 #define cmd_dms_unblock_pin1_cb no_cb
245 static enum qmi_cmd_result
246 cmd_dms_unblock_pin1_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
247 {
248         if (!dms_req_data.puk || !dms_req_data.new_pin) {
249                 uqmi_add_error("Missing argument");
250                 return QMI_CMD_EXIT;
251         }
252
253         struct qmi_dms_uim_unblock_pin_request dms_unlock_pin_req = {
254                 QMI_INIT_SEQUENCE(info,
255                                 .pin_id = QMI_DMS_UIM_PIN_ID_PIN
256                         ),
257                 QMI_INIT_PTR(info.puk, dms_req_data.puk),
258                 QMI_INIT_PTR(info.new_pin, dms_req_data.new_pin)
259                 };
260
261         qmi_set_dms_uim_unblock_pin_request(msg, &dms_unlock_pin_req);
262         return QMI_CMD_REQUEST;
263 }
264
265 #define cmd_dms_unblock_pin2_cb no_cb
266 static enum qmi_cmd_result
267 cmd_dms_unblock_pin2_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
268 {
269         if (!dms_req_data.puk || !dms_req_data.new_pin) {
270                 uqmi_add_error("Missing argument");
271                 return QMI_CMD_EXIT;
272         }
273
274         struct qmi_dms_uim_unblock_pin_request dms_unlock_pin_req = {
275                 QMI_INIT_SEQUENCE(info,
276                         .pin_id = QMI_DMS_UIM_PIN_ID_PIN2
277                 ),
278                 QMI_INIT_PTR(info.puk, dms_req_data.puk),
279                 QMI_INIT_PTR(info.new_pin, dms_req_data.new_pin)
280         };
281
282         qmi_set_dms_uim_unblock_pin_request(msg, &dms_unlock_pin_req);
283         return QMI_CMD_REQUEST;
284 }
285
286 static void cmd_dms_get_iccid_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
287 {
288         struct qmi_dms_uim_get_iccid_response res;
289
290         qmi_parse_dms_uim_get_iccid_response(msg, &res);
291         if (res.data.iccid)
292                 blobmsg_add_string(&status, NULL, res.data.iccid);
293 }
294
295 static enum qmi_cmd_result
296 cmd_dms_get_iccid_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
297 {
298         qmi_set_dms_uim_get_iccid_request(msg);
299         return QMI_CMD_REQUEST;
300 }
301
302 static void cmd_dms_get_imsi_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
303 {
304         struct qmi_dms_uim_get_imsi_response res;
305
306         qmi_parse_dms_uim_get_imsi_response(msg, &res);
307         if (res.data.imsi)
308                 blobmsg_add_string(&status, NULL, res.data.imsi);
309 }
310
311 static enum qmi_cmd_result
312 cmd_dms_get_imsi_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
313 {
314         qmi_set_dms_uim_get_imsi_request(msg);
315         return QMI_CMD_REQUEST;
316 }
317
318 static void cmd_dms_get_msisdn_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
319 {
320         struct qmi_dms_get_msisdn_response res;
321
322         qmi_parse_dms_get_msisdn_response(msg, &res);
323         if (res.data.msisdn)
324                 blobmsg_add_string(&status, NULL, res.data.msisdn);
325 }
326
327 static enum qmi_cmd_result
328 cmd_dms_get_msisdn_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
329 {
330         qmi_set_dms_get_msisdn_request(msg);
331         return QMI_CMD_REQUEST;
332 }
333
334 #define cmd_dms_reset_cb no_cb
335 static enum qmi_cmd_result
336 cmd_dms_reset_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
337 {
338         qmi_set_dms_reset_request(msg);
339         return QMI_CMD_REQUEST;
340 }
341
342 #define cmd_dms_set_operating_mode_cb no_cb
343 static enum qmi_cmd_result
344 cmd_dms_set_operating_mode_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
345 {
346         static const char *modes[] = {
347                 [QMI_DMS_OPERATING_MODE_ONLINE] = "online",
348                 [QMI_DMS_OPERATING_MODE_LOW_POWER] = "low_power",
349                 [QMI_DMS_OPERATING_MODE_FACTORY_TEST] = "factory_test",
350                 [QMI_DMS_OPERATING_MODE_OFFLINE] = "offline",
351                 [QMI_DMS_OPERATING_MODE_RESET] = "reset",
352                 [QMI_DMS_OPERATING_MODE_SHUTTING_DOWN] = "shutting_down",
353                 [QMI_DMS_OPERATING_MODE_PERSISTENT_LOW_POWER] = "persistent_low_power",
354                 [QMI_DMS_OPERATING_MODE_MODE_ONLY_LOW_POWER] = "mode_only_low_power",
355         };
356         static struct qmi_dms_set_operating_mode_request sreq = {
357                 QMI_INIT(mode, QMI_DMS_OPERATING_MODE_ONLINE),
358         };
359         int i;
360
361         for (i = 0; i < ARRAY_SIZE(modes); i++) {
362                 if (!modes[i])
363                         continue;
364
365                 if (strcmp(arg, modes[i]) != 0)
366                         continue;
367
368                 sreq.data.mode = i;
369                 qmi_set_dms_set_operating_mode_request(msg, &sreq);
370                 return QMI_CMD_REQUEST;
371         }
372
373         return uqmi_add_error("Invalid argument");
374 }