move qmi_get_error_str to into utils.c
[project/uqmi.git] / commands-wds.c
1 /*
2 * uqmi -- tiny QMI support implementation
3 *
4 * Copyright (C) 2014-2015 Felix Fietkau <nbd@openwrt.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA.
20 */
21
22 #include <stdlib.h>
23 #include <arpa/inet.h>
24
25 #include "qmi-message.h"
26
27 static const struct {
28 const char *auth_name;
29 QmiWdsAuthentication auth;
30 } auth_modes[] = {
31 { "none", QMI_WDS_AUTHENTICATION_NONE },
32 { "pap", QMI_WDS_AUTHENTICATION_PAP },
33 { "chap", QMI_WDS_AUTHENTICATION_CHAP },
34 { "both", QMI_WDS_AUTHENTICATION_PAP | QMI_WDS_AUTHENTICATION_CHAP },
35 };
36
37 static const struct {
38 const char *ipfam_name;
39 const QmiWdsIpFamily mode;
40 } ipfam_modes[] = {
41 { "ipv4", QMI_WDS_IP_FAMILY_IPV4 },
42 { "ipv6", QMI_WDS_IP_FAMILY_IPV6 },
43 { "unspecified", QMI_WDS_IP_FAMILY_UNSPECIFIED },
44 };
45
46 static const struct {
47 const char *pdp_name;
48 const QmiWdsPdpType type;
49 } pdp_types[] = {
50 { "ipv4", QMI_WDS_PDP_TYPE_IPV4 },
51 { "ppp", QMI_WDS_PDP_TYPE_PPP },
52 { "ipv6", QMI_WDS_PDP_TYPE_IPV6 },
53 { "ipv4v6", QMI_WDS_PDP_TYPE_IPV4_OR_IPV6 },
54 };
55
56 static const struct {
57 const char *profile_name;
58 const QmiWdsProfileType profile;
59 } profile_types[] = {
60 { "3gpp", QMI_WDS_PROFILE_TYPE_3GPP },
61 { "3gpp2", QMI_WDS_PROFILE_TYPE_3GPP2 },
62 };
63
64 static struct qmi_wds_start_network_request wds_sn_req = {
65 QMI_INIT(authentication_preference,
66 QMI_WDS_AUTHENTICATION_PAP | QMI_WDS_AUTHENTICATION_CHAP),
67 };
68
69 static struct qmi_wds_stop_network_request wds_stn_req;
70
71 static struct qmi_wds_modify_profile_request wds_mp_req = {
72 QMI_INIT_SEQUENCE(profile_identifier,
73 .profile_type = QMI_WDS_PROFILE_TYPE_3GPP,
74 .profile_index = 1,
75 ),
76 QMI_INIT(apn_disabled_flag, false),
77 };
78
79 static struct qmi_wds_create_profile_request wds_cp_req = {
80 QMI_INIT(profile_type,QMI_WDS_PROFILE_TYPE_3GPP),
81 QMI_INIT(apn_disabled_flag, false),
82 };
83
84 #define cmd_wds_set_apn_cb no_cb
85 static enum qmi_cmd_result
86 cmd_wds_set_apn_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
87 {
88 qmi_set_ptr(&wds_sn_req, apn, arg);
89 qmi_set_ptr(&wds_mp_req, apn_name, arg);
90 qmi_set_ptr(&wds_cp_req, apn_name, arg);
91 return QMI_CMD_DONE;
92 }
93
94 #define cmd_wds_set_auth_cb no_cb
95 static enum qmi_cmd_result
96 cmd_wds_set_auth_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
97 {
98 int i;
99 for (i = 0; i < ARRAY_SIZE(auth_modes); i++) {
100 if (strcasecmp(auth_modes[i].auth_name, arg) != 0)
101 continue;
102
103 qmi_set(&wds_sn_req, authentication_preference, auth_modes[i].auth);
104 qmi_set(&wds_mp_req, authentication, auth_modes[i].auth);
105 qmi_set(&wds_cp_req, authentication, auth_modes[i].auth);
106 return QMI_CMD_DONE;
107 }
108
109 uqmi_add_error("Invalid auth mode (valid: pap, chap, both, none)");
110 return QMI_CMD_EXIT;
111 }
112
113 #define cmd_wds_set_username_cb no_cb
114 static enum qmi_cmd_result
115 cmd_wds_set_username_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
116 {
117 qmi_set_ptr(&wds_sn_req, username, arg);
118 qmi_set_ptr(&wds_mp_req, username, arg);
119 qmi_set_ptr(&wds_cp_req, username, arg);
120 return QMI_CMD_DONE;
121 }
122
123 #define cmd_wds_set_password_cb no_cb
124 static enum qmi_cmd_result
125 cmd_wds_set_password_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
126 {
127 qmi_set_ptr(&wds_sn_req, password, arg);
128 qmi_set_ptr(&wds_mp_req, password, arg);
129 qmi_set_ptr(&wds_cp_req, password, arg);
130 return QMI_CMD_DONE;
131 }
132
133 #define cmd_wds_set_autoconnect_cb no_cb
134 static enum qmi_cmd_result
135 cmd_wds_set_autoconnect_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
136 {
137 qmi_set(&wds_sn_req, enable_autoconnect, true);
138 qmi_set(&wds_stn_req, disable_autoconnect, true);
139 return QMI_CMD_DONE;
140 }
141
142 #define cmd_wds_set_ip_family_pref_cb no_cb
143 static enum qmi_cmd_result
144 cmd_wds_set_ip_family_pref_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
145 {
146 int i;
147 for (i = 0; i < ARRAY_SIZE(ipfam_modes); i++) {
148 if (strcasecmp(ipfam_modes[i].ipfam_name, arg) != 0)
149 continue;
150
151 qmi_set(&wds_sn_req, ip_family_preference, ipfam_modes[i].mode);
152 return QMI_CMD_DONE;
153 }
154
155 uqmi_add_error("Invalid value (valid: ipv4, ipv6, unspecified)");
156 return QMI_CMD_EXIT;
157 }
158
159 #define cmd_wds_set_pdp_type_cb no_cb
160 static enum qmi_cmd_result
161 cmd_wds_set_pdp_type_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
162 {
163 int i;
164
165 for (i = 0; i < ARRAY_SIZE(pdp_types); i++) {
166 if (strcasecmp(pdp_types[i].pdp_name, arg) != 0)
167 continue;
168
169 qmi_set(&wds_mp_req, pdp_type, pdp_types[i].type);
170 qmi_set(&wds_cp_req, pdp_type, pdp_types[i].type);
171 return QMI_CMD_DONE;
172 }
173
174 uqmi_add_error("Invalid value (valid: ipv4, ipv6, ipv4v6)");
175 return QMI_CMD_EXIT;
176 }
177
178 #define cmd_wds_no_roaming_cb no_cb
179 static enum qmi_cmd_result
180 cmd_wds_no_roaming_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
181 {
182 if (strcmp(arg, "true") == 0) {
183 qmi_set(&wds_mp_req, roaming_disallowed_flag, true);
184 qmi_set(&wds_cp_req, roaming_disallowed_flag, true);
185 } else if (strcmp(arg, "false") == 0) {
186 qmi_set(&wds_mp_req, roaming_disallowed_flag, false);
187 qmi_set(&wds_cp_req, roaming_disallowed_flag, false);
188 } else {
189 uqmi_add_error("Invalid value (true or false)");
190 return QMI_CMD_EXIT;
191 }
192 return QMI_CMD_DONE;
193 }
194
195 #define cmd_wds_set_profile_cb no_cb
196 static enum qmi_cmd_result
197 cmd_wds_set_profile_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
198 {
199 uint32_t idx = strtoul(arg, NULL, 10);
200
201 qmi_set(&wds_sn_req, profile_index_3gpp, idx);
202 return QMI_CMD_DONE;
203 }
204
205 static void
206 cmd_wds_start_network_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
207 {
208 struct qmi_wds_start_network_response res;
209
210 qmi_parse_wds_start_network_response(msg, &res);
211 if (res.set.packet_data_handle)
212 blobmsg_add_u32(&status, NULL, res.data.packet_data_handle);
213 }
214
215 static enum qmi_cmd_result
216 cmd_wds_start_network_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
217 {
218 qmi_set_wds_start_network_request(msg, &wds_sn_req);
219 return QMI_CMD_REQUEST;
220 }
221
222 #define cmd_wds_stop_network_cb no_cb
223 static enum qmi_cmd_result
224 cmd_wds_stop_network_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
225 {
226 uint32_t pdh = strtoul(arg, NULL, 0);
227
228 qmi_set(&wds_stn_req, packet_data_handle, pdh);
229 qmi_set_wds_stop_network_request(msg, &wds_stn_req);
230 return QMI_CMD_REQUEST;
231 }
232
233 static void
234 cmd_wds_modify_profile_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
235 {
236 struct qmi_wds_modify_profile_response res;
237 qmi_parse_wds_modify_profile_response(msg, &res);
238 }
239
240 static enum qmi_cmd_result
241 cmd_wds_modify_profile_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
242 {
243 int id;
244 char *s;
245 char *p_type;
246
247 s = strchr(arg, ',');
248 if (!s) {
249 fprintf(stderr, "Invalid argument\n");
250 return QMI_CMD_EXIT;
251 }
252 *s = 0;
253 s++;
254
255 id = strtoul(s, &s, 0);
256 if (s && *s) {
257 fprintf(stderr, "Invalid argument\n");
258 return QMI_CMD_EXIT;
259 }
260
261 p_type = strtok(arg, ",");
262
263 int i;
264 for (i = 0; i < ARRAY_SIZE(profile_types); i++) {
265 if (strcasecmp(profile_types[i].profile_name, p_type) != 0)
266 continue;
267
268 qmi_set_ptr(&wds_mp_req, profile_identifier.profile_type, profile_types[i].profile);
269 qmi_set_ptr(&wds_mp_req, profile_identifier.profile_index, id);
270 qmi_set_wds_modify_profile_request(msg, &wds_mp_req);
271 return QMI_CMD_REQUEST;
272 }
273
274 uqmi_add_error("Invalid value (valid: 3gpp or 3gpp2)");
275 return QMI_CMD_EXIT;
276 }
277
278 static void
279 cmd_wds_create_profile_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
280 {
281 struct qmi_wds_create_profile_response res;
282 void *p;
283
284 qmi_parse_wds_create_profile_response(msg, &res);
285
286 if (res.set.profile_identifier) {
287 p = blobmsg_open_table(&status, NULL);
288 blobmsg_add_u32(&status, "created-profile", res.data.profile_identifier.profile_index);
289 blobmsg_close_table(&status, p);
290 }
291 }
292
293 static enum qmi_cmd_result
294 cmd_wds_create_profile_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
295 {
296 int i;
297 for (i = 0; i < ARRAY_SIZE(profile_types); i++) {
298 if (strcasecmp(profile_types[i].profile_name, arg) != 0)
299 continue;
300
301 qmi_set_ptr(&wds_cp_req, profile_type, profile_types[i].profile);
302
303 qmi_set_wds_create_profile_request(msg, &wds_cp_req);
304 return QMI_CMD_REQUEST;
305 }
306
307 uqmi_add_error("Invalid value (valid: 3gpp or 3gpp2)");
308 return QMI_CMD_EXIT;
309 }
310
311 static void
312 cmd_wds_get_packet_service_status_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
313 {
314 struct qmi_wds_get_packet_service_status_response res;
315 const char *data_status[] = {
316 [QMI_WDS_CONNECTION_STATUS_UNKNOWN] = "unknown",
317 [QMI_WDS_CONNECTION_STATUS_DISCONNECTED] = "disconnected",
318 [QMI_WDS_CONNECTION_STATUS_CONNECTED] = "connected",
319 [QMI_WDS_CONNECTION_STATUS_SUSPENDED] = "suspended",
320 [QMI_WDS_CONNECTION_STATUS_AUTHENTICATING] = "authenticating",
321 };
322 int s = 0;
323
324 qmi_parse_wds_get_packet_service_status_response(msg, &res);
325 if (res.set.connection_status &&
326 res.data.connection_status < ARRAY_SIZE(data_status))
327 s = res.data.connection_status;
328
329 blobmsg_add_string(&status, NULL, data_status[s]);
330 }
331
332 static enum qmi_cmd_result
333 cmd_wds_get_packet_service_status_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
334 {
335 qmi_set_wds_get_packet_service_status_request(msg);
336 return QMI_CMD_REQUEST;
337 }
338
339 #define cmd_wds_set_autoconnect_settings_cb no_cb
340 static enum qmi_cmd_result
341 cmd_wds_set_autoconnect_settings_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
342 {
343 struct qmi_wds_set_autoconnect_settings_request ac_req;
344 const char *modes[] = {
345 [QMI_WDS_AUTOCONNECT_SETTING_DISABLED] = "disabled",
346 [QMI_WDS_AUTOCONNECT_SETTING_ENABLED] = "enabled",
347 [QMI_WDS_AUTOCONNECT_SETTING_PAUSED] = "paused",
348 };
349 int i;
350
351 for (i = 0; i < ARRAY_SIZE(modes); i++) {
352 if (strcasecmp(modes[i], arg) != 0)
353 continue;
354
355 qmi_set(&ac_req, status, i);
356 qmi_set_wds_set_autoconnect_settings_request(msg, &ac_req);
357 return QMI_CMD_DONE;
358 }
359
360 uqmi_add_error("Invalid value (valid: disabled, enabled, paused)");
361 return QMI_CMD_EXIT;
362 }
363
364 #define cmd_wds_reset_cb no_cb
365 static enum qmi_cmd_result
366 cmd_wds_reset_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
367 {
368 qmi_set_wds_reset_request(msg);
369 return QMI_CMD_REQUEST;
370 }
371
372 #define cmd_wds_set_ip_family_cb no_cb
373 static enum qmi_cmd_result
374 cmd_wds_set_ip_family_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
375 {
376 struct qmi_wds_set_ip_family_request ipf_req;
377
378 int i;
379 for (i = 0; i < ARRAY_SIZE(ipfam_modes); i++) {
380 if (strcasecmp(ipfam_modes[i].ipfam_name, arg) != 0)
381 continue;
382
383 qmi_set(&ipf_req, preference, ipfam_modes[i].mode);
384 qmi_set_wds_set_ip_family_request(msg, &ipf_req);
385 return QMI_CMD_REQUEST;
386 }
387
388 uqmi_add_error("Invalid value (valid: ipv4, ipv6, unspecified)");
389 return QMI_CMD_EXIT;
390 }
391
392 static void wds_to_ipv4(const char *name, const uint32_t addr)
393 {
394 struct in_addr ip_addr;
395 char buf[INET_ADDRSTRLEN];
396
397 ip_addr.s_addr = htonl(addr);
398 blobmsg_add_string(&status, name, inet_ntop(AF_INET, &ip_addr, buf, sizeof(buf)));
399 }
400
401 static void wds_to_ipv6(const char *name, const uint16_t *addr)
402 {
403 char buf[INET6_ADDRSTRLEN];
404 uint16_t ip_addr[8];
405 int i;
406
407 for (i = 0; i < ARRAY_SIZE(ip_addr); i++)
408 ip_addr[i] = htons(addr[i]);
409
410 blobmsg_add_string(&status, name, inet_ntop(AF_INET6, &ip_addr, buf, sizeof(buf)));
411 }
412
413 static enum qmi_cmd_result
414 cmd_wds_get_profile_settings_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
415 {
416 int id;
417 char *s;
418 char *p_type;
419
420 s = strchr(arg, ',');
421 if (!s) {
422 fprintf(stderr, "Invalid argument\n");
423 return QMI_CMD_EXIT;
424 }
425 *s = 0;
426 s++;
427
428 id = strtoul(s, &s, 0);
429 if (s && *s) {
430 fprintf(stderr, "Invalid argument\n");
431 return QMI_CMD_EXIT;
432 }
433
434 p_type = strtok(arg, ",");
435
436 int i;
437 for (i = 0; i < ARRAY_SIZE(profile_types); i++) {
438 if (strcasecmp(profile_types[i].profile_name, p_type) != 0)
439 continue;
440
441 struct qmi_wds_get_profile_settings_request p_num = {
442 QMI_INIT_SEQUENCE(profile_id,
443 .profile_type = profile_types[i].profile,
444 .profile_index = id,
445 )
446 };
447 qmi_set_wds_get_profile_settings_request(msg, &p_num);
448 return QMI_CMD_REQUEST;
449 }
450
451 uqmi_add_error("Invalid value (valid: 3gpp or 3gpp2)");
452 return QMI_CMD_EXIT;
453 }
454
455 static void
456 cmd_wds_get_profile_settings_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
457 {
458 struct qmi_wds_get_profile_settings_response res;
459
460 void *p;
461
462 qmi_parse_wds_get_profile_settings_response(msg, &res);
463
464 p = blobmsg_open_table(&status, NULL);
465
466 blobmsg_add_string(&status, "apn", res.data.apn_name);
467 if (res.set.pdp_type && (int) res.data.pdp_type < ARRAY_SIZE(pdp_types))
468 blobmsg_add_string(&status, "pdp-type", pdp_types[res.data.pdp_type].pdp_name);
469 blobmsg_add_string(&status, "username", res.data.username);
470 blobmsg_add_string(&status, "password", res.data.password);
471 if (res.set.authentication && (int) res.data.authentication < ARRAY_SIZE(auth_modes))
472 blobmsg_add_string(&status, "auth", auth_modes[res.data.authentication].auth_name);
473 blobmsg_add_u8(&status, "no-roaming", res.data.roaming_disallowed_flag);
474 blobmsg_add_u8(&status, "apn-disabled", res.data.apn_disabled_flag);
475 blobmsg_close_table(&status, p);
476 }
477
478 static void
479 cmd_wds_get_current_settings_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
480 {
481 void *v4, *v6, *d, *t;
482 struct qmi_wds_get_current_settings_response res;
483 int i;
484
485 qmi_parse_wds_get_current_settings_response(msg, &res);
486
487 t = blobmsg_open_table(&status, NULL);
488
489 if (res.set.pdp_type && (int) res.data.pdp_type < ARRAY_SIZE(pdp_types))
490 blobmsg_add_string(&status, "pdp-type", pdp_types[res.data.pdp_type].pdp_name);
491
492 if (res.set.ip_family) {
493 for (i = 0; i < ARRAY_SIZE(ipfam_modes); i++) {
494 if (ipfam_modes[i].mode != res.data.ip_family)
495 continue;
496 blobmsg_add_string(&status, "ip-family", ipfam_modes[i].ipfam_name);
497 break;
498 }
499 }
500
501 if (res.set.mtu)
502 blobmsg_add_u32(&status, "mtu", res.data.mtu);
503
504 /* IPV4 */
505 v4 = blobmsg_open_table(&status, "ipv4");
506
507 if (res.set.ipv4_address)
508 wds_to_ipv4("ip", res.data.ipv4_address);
509 if (res.set.primary_ipv4_dns_address)
510 wds_to_ipv4("dns1", res.data.primary_ipv4_dns_address);
511 if (res.set.secondary_ipv4_dns_address)
512 wds_to_ipv4("dns2", res.data.secondary_ipv4_dns_address);
513 if (res.set.ipv4_gateway_address)
514 wds_to_ipv4("gateway", res.data.ipv4_gateway_address);
515 if (res.set.ipv4_gateway_subnet_mask)
516 wds_to_ipv4("subnet", res.data.ipv4_gateway_subnet_mask);
517 blobmsg_close_table(&status, v4);
518
519 /* IPV6 */
520 v6 = blobmsg_open_table(&status, "ipv6");
521
522 if (res.set.ipv6_address) {
523 wds_to_ipv6("ip", res.data.ipv6_address.address);
524 blobmsg_add_u32(&status, "ip-prefix-length", res.data.ipv6_address.prefix_length);
525 }
526 if (res.set.ipv6_gateway_address) {
527 wds_to_ipv6("gateway", res.data.ipv6_gateway_address.address);
528 blobmsg_add_u32(&status, "gw-prefix-length", res.data.ipv6_gateway_address.prefix_length);
529 }
530 if (res.set.ipv6_primary_dns_address)
531 wds_to_ipv6("dns1", res.data.ipv6_primary_dns_address);
532 if (res.set.ipv6_secondary_dns_address)
533 wds_to_ipv6("dns2", res.data.ipv6_secondary_dns_address);
534
535 blobmsg_close_table(&status, v6);
536
537 d = blobmsg_open_table(&status, "domain-names");
538 for (i = 0; i < res.data.domain_name_list_n; i++) {
539 blobmsg_add_string(&status, NULL, res.data.domain_name_list[i]);
540 }
541 blobmsg_close_table(&status, d);
542
543 blobmsg_close_table(&status, t);
544 }
545
546 static enum qmi_cmd_result
547 cmd_wds_get_current_settings_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
548 {
549 struct qmi_wds_get_current_settings_request gcs_req;
550 memset(&gcs_req, '\0', sizeof(struct qmi_wds_get_current_settings_request));
551 qmi_set(&gcs_req, requested_settings,
552 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PDP_TYPE |
553 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DNS_ADDRESS |
554 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GRANTED_QOS |
555 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_ADDRESS |
556 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GATEWAY_INFO |
557 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_MTU |
558 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DOMAIN_NAME_LIST |
559 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_FAMILY);
560 qmi_set_wds_get_current_settings_request(msg, &gcs_req);
561 return QMI_CMD_REQUEST;
562 }
563
564 static enum qmi_cmd_result
565 cmd_wds_get_default_profile_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
566 {
567 int i;
568 for (i = 0; i < ARRAY_SIZE(profile_types); i++) {
569 if (strcasecmp(profile_types[i].profile_name, arg) != 0)
570 continue;
571
572 struct qmi_wds_get_default_profile_number_request type_family = {
573 QMI_INIT_SEQUENCE(profile_type,
574 .type = profile_types[i].profile,
575 .family = QMI_WDS_PROFILE_FAMILY_TETHERED,
576 )
577 };
578
579 qmi_set_wds_get_default_profile_number_request(msg, &type_family);
580 return QMI_CMD_REQUEST;
581 }
582
583 uqmi_add_error("Invalid value (valid: 3gpp or 3gpp2)");
584 return QMI_CMD_EXIT;
585 }
586
587 static void
588 cmd_wds_get_default_profile_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
589 {
590 struct qmi_wds_get_default_profile_number_response res;
591 void *p;
592 qmi_parse_wds_get_default_profile_number_response(msg, &res);
593
594 p = blobmsg_open_table(&status, NULL);
595
596 blobmsg_add_u32(&status, "default-profile", res.data.index);
597
598 blobmsg_close_table(&status, p);
599 }