• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/uqmi/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 struct qmi_wds_start_network_request wds_sn_req = {
 28         QMI_INIT(authentication_preference,
 29                  QMI_WDS_AUTHENTICATION_PAP | QMI_WDS_AUTHENTICATION_CHAP),
 30 };
 31 static struct qmi_wds_stop_network_request wds_stn_req;
 32 
 33 #define cmd_wds_set_apn_cb no_cb
 34 static enum qmi_cmd_result
 35 cmd_wds_set_apn_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 36 {
 37         qmi_set_ptr(&wds_sn_req, apn, arg);
 38         return QMI_CMD_DONE;
 39 }
 40 
 41 #define cmd_wds_set_auth_cb no_cb
 42 static enum qmi_cmd_result
 43 cmd_wds_set_auth_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 44 {
 45         static const struct {
 46                 const char *name;
 47                 QmiWdsAuthentication auth;
 48         } modes[] = {
 49                 { "pap", QMI_WDS_AUTHENTICATION_PAP },
 50                 { "chap", QMI_WDS_AUTHENTICATION_CHAP },
 51                 { "both", QMI_WDS_AUTHENTICATION_PAP | QMI_WDS_AUTHENTICATION_CHAP },
 52                 { "none", QMI_WDS_AUTHENTICATION_NONE },
 53         };
 54         int i;
 55 
 56         for (i = 0; i < ARRAY_SIZE(modes); i++) {
 57                 if (strcasecmp(modes[i].name, arg) != 0)
 58                         continue;
 59 
 60                 qmi_set(&wds_sn_req, authentication_preference, modes[i].auth);
 61                 return QMI_CMD_DONE;
 62         }
 63 
 64         uqmi_add_error("Invalid auth mode (valid: pap, chap, both, none)");
 65         return QMI_CMD_EXIT;
 66 }
 67 
 68 #define cmd_wds_set_username_cb no_cb
 69 static enum qmi_cmd_result
 70 cmd_wds_set_username_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 71 {
 72         qmi_set_ptr(&wds_sn_req, username, arg);
 73         return QMI_CMD_DONE;
 74 }
 75 
 76 #define cmd_wds_set_password_cb no_cb
 77 static enum qmi_cmd_result
 78 cmd_wds_set_password_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 79 {
 80         qmi_set_ptr(&wds_sn_req, password, arg);
 81         return QMI_CMD_DONE;
 82 }
 83 
 84 #define cmd_wds_set_autoconnect_cb no_cb
 85 static enum qmi_cmd_result
 86 cmd_wds_set_autoconnect_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 87 {
 88         qmi_set(&wds_sn_req, enable_autoconnect, true);
 89         qmi_set(&wds_stn_req, disable_autoconnect, true);
 90         return QMI_CMD_DONE;
 91 }
 92 
 93 #define cmd_wds_set_ip_family_pref_cb no_cb
 94 static enum qmi_cmd_result
 95 cmd_wds_set_ip_family_pref_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
 96 {
 97         static const struct {
 98                 const char *name;
 99                 const QmiWdsIpFamily mode;
100         } modes[] = {
101                 { "ipv4", QMI_WDS_IP_FAMILY_IPV4 },
102                 { "ipv6", QMI_WDS_IP_FAMILY_IPV6 },
103                 { "unspecified", QMI_WDS_IP_FAMILY_UNSPECIFIED },
104         };
105         int i;
106 
107         for (i = 0; i < ARRAY_SIZE(modes); i++) {
108                 if (strcasecmp(modes[i].name, arg) != 0)
109                         continue;
110 
111                 qmi_set(&wds_sn_req, ip_family_preference, modes[i].mode);
112                 return QMI_CMD_DONE;
113         }
114 
115         uqmi_add_error("Invalid value (valid: ipv4, ipv6, unspecified)");
116         return QMI_CMD_EXIT;
117 }
118 
119 #define cmd_wds_set_profile_cb no_cb
120 static enum qmi_cmd_result
121 cmd_wds_set_profile_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
122 {
123         uint32_t idx = strtoul(arg, NULL, 10);
124 
125         qmi_set(&wds_sn_req, profile_index_3gpp, idx);
126         return QMI_CMD_DONE;
127 }
128 
129 static void
130 cmd_wds_start_network_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
131 {
132         struct qmi_wds_start_network_response res;
133 
134         qmi_parse_wds_start_network_response(msg, &res);
135         if (res.set.packet_data_handle)
136                 blobmsg_add_u32(&status, NULL, res.data.packet_data_handle);
137 }
138 
139 static enum qmi_cmd_result
140 cmd_wds_start_network_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
141 {
142         qmi_set_wds_start_network_request(msg, &wds_sn_req);
143         return QMI_CMD_REQUEST;
144 }
145 
146 #define cmd_wds_stop_network_cb no_cb
147 static enum qmi_cmd_result
148 cmd_wds_stop_network_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
149 {
150         uint32_t pdh = strtoul(arg, NULL, 0);
151 
152         qmi_set(&wds_stn_req, packet_data_handle, pdh);
153         qmi_set_wds_stop_network_request(msg, &wds_stn_req);
154         return QMI_CMD_REQUEST;
155 }
156 
157 static void
158 cmd_wds_get_packet_service_status_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
159 {
160         struct qmi_wds_get_packet_service_status_response res;
161         const char *data_status[] = {
162                 [QMI_WDS_CONNECTION_STATUS_UNKNOWN] = "unknown",
163                 [QMI_WDS_CONNECTION_STATUS_DISCONNECTED] = "disconnected",
164                 [QMI_WDS_CONNECTION_STATUS_CONNECTED] = "connected",
165                 [QMI_WDS_CONNECTION_STATUS_SUSPENDED] = "suspended",
166                 [QMI_WDS_CONNECTION_STATUS_AUTHENTICATING] = "authenticating",
167         };
168         int s = 0;
169 
170         qmi_parse_wds_get_packet_service_status_response(msg, &res);
171         if (res.set.connection_status &&
172             res.data.connection_status < ARRAY_SIZE(data_status))
173                 s = res.data.connection_status;
174 
175         blobmsg_add_string(&status, NULL, data_status[s]);
176 }
177 
178 static enum qmi_cmd_result
179 cmd_wds_get_packet_service_status_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
180 {
181         qmi_set_wds_get_packet_service_status_request(msg);
182         return QMI_CMD_REQUEST;
183 }
184 
185 #define cmd_wds_set_autoconnect_setting_cb no_cb
186 static enum qmi_cmd_result
187 cmd_wds_set_autoconnect_setting_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
188 {
189         struct qmi_wds_set_autoconnect_setting_request ac_req;
190         const char *modes[] = {
191                 [QMI_WDS_AUTOCONNECT_DISABLED] = "disabled",
192                 [QMI_WDS_AUTOCONNECT_ENABLED] = "enabled",
193                 [QMI_WDS_AUTOCONNECT_PAUSED] = "paused",
194         };
195         int i;
196 
197         for (i = 0; i < ARRAY_SIZE(modes); i++) {
198                 if (strcasecmp(modes[i], arg) != 0)
199                         continue;
200 
201                 qmi_set(&ac_req, setting, i);
202                 qmi_set_wds_set_autoconnect_setting_request(msg, &ac_req);
203                 return QMI_CMD_DONE;
204         }
205 
206         uqmi_add_error("Invalid value (valid: disabled, enabled, paused)");
207         return QMI_CMD_EXIT;
208 }
209 
210 #define cmd_wds_reset_cb no_cb
211 static enum qmi_cmd_result
212 cmd_wds_reset_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
213 {
214         qmi_set_wds_reset_request(msg);
215         return QMI_CMD_REQUEST;
216 }
217 
218 #define cmd_wds_set_ip_family_cb no_cb
219 static enum qmi_cmd_result
220 cmd_wds_set_ip_family_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
221 {
222         struct qmi_wds_set_ip_family_request ipf_req;
223         const struct ip_modes {
224                 const char *name;
225                 const QmiWdsIpFamily mode;
226         } modes[] = {
227                 { "ipv4", QMI_WDS_IP_FAMILY_IPV4 },
228                 { "ipv6", QMI_WDS_IP_FAMILY_IPV6 },
229                 { "unspecified", QMI_WDS_IP_FAMILY_UNSPECIFIED },
230         };
231         int i;
232 
233         for (i = 0; i < ARRAY_SIZE(modes); i++) {
234                 if (strcasecmp(modes[i].name, arg) != 0)
235                         continue;
236 
237                 qmi_set(&ipf_req, preference, modes[i].mode);
238                 qmi_set_wds_set_ip_family_request(msg, &ipf_req);
239                 return QMI_CMD_REQUEST;
240         }
241 
242         uqmi_add_error("Invalid value (valid: ipv4, ipv6, unspecified)");
243         return QMI_CMD_EXIT;
244 }
245 
246 static void wds_to_ipv4(const char *name, const uint32_t addr)
247 {
248         struct in_addr ip_addr;
249         char buf[INET_ADDRSTRLEN];
250 
251         ip_addr.s_addr = htonl(addr);
252         blobmsg_add_string(&status, name, inet_ntop(AF_INET, &ip_addr, buf, sizeof(buf)));
253 }
254 
255 static void wds_to_ipv6(const char *name, const uint16_t *addr)
256 {
257         char buf[INET6_ADDRSTRLEN];
258         uint16_t ip_addr[8];
259         int i;
260 
261         for (i = 0; i < ARRAY_SIZE(ip_addr); i++)
262                 ip_addr[i] = htons(addr[i]);
263 
264         blobmsg_add_string(&status, name, inet_ntop(AF_INET6, &ip_addr, buf, sizeof(buf)));
265 }
266 
267 static void
268 cmd_wds_get_current_settings_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg)
269 {
270         void *v4, *v6, *d, *t;
271         struct qmi_wds_get_current_settings_response res;
272         const char *pdptypes[] = {
273                 [QMI_WDS_PDP_TYPE_IPV4] = "ipv4",
274                 [QMI_WDS_PDP_TYPE_PPP] = "ppp",
275                 [QMI_WDS_PDP_TYPE_IPV6] = "ipv6",
276                 [QMI_WDS_PDP_TYPE_IPV4_OR_IPV6] = "ipv4-or-ipv6",
277         };
278         const struct ip_modes {
279                 const char *name;
280                 const QmiWdsIpFamily mode;
281         } modes[] = {
282                 { "ipv4", QMI_WDS_IP_FAMILY_IPV4 },
283                 { "ipv6", QMI_WDS_IP_FAMILY_IPV6 },
284                 { "unspecified", QMI_WDS_IP_FAMILY_UNSPECIFIED },
285         };
286         int i;
287 
288         qmi_parse_wds_get_current_settings_response(msg, &res);
289 
290         t = blobmsg_open_table(&status, NULL);
291 
292         if (res.set.pdp_type && (int) res.data.pdp_type < ARRAY_SIZE(pdptypes))
293                 blobmsg_add_string(&status, "pdp-type", pdptypes[res.data.pdp_type]);
294 
295         if (res.set.ip_family) {
296                 for (i = 0; i < ARRAY_SIZE(modes); i++) {
297                         if (modes[i].mode != res.data.ip_family)
298                                 continue;
299                         blobmsg_add_string(&status, "ip-family", modes[i].name);
300                         break;
301                 }
302         }
303 
304         if (res.set.mtu)
305                 blobmsg_add_u32(&status, "mtu", res.data.mtu);
306 
307         /* IPV4 */
308         v4 = blobmsg_open_table(&status, "ipv4");
309 
310         if (res.set.ipv4_address)
311                 wds_to_ipv4("ip", res.data.ipv4_address);
312         if (res.set.primary_ipv4_dns_address)
313                 wds_to_ipv4("dns1", res.data.primary_ipv4_dns_address);
314         if (res.set.secondary_ipv4_dns_address)
315                 wds_to_ipv4("dns2", res.data.secondary_ipv4_dns_address);
316         if (res.set.ipv4_gateway_address)
317                 wds_to_ipv4("gateway", res.data.ipv4_gateway_address);
318         if (res.set.ipv4_gateway_subnet_mask)
319                 wds_to_ipv4("subnet", res.data.ipv4_gateway_subnet_mask);
320         blobmsg_close_table(&status, v4);
321 
322         /* IPV6 */
323         v6 = blobmsg_open_table(&status, "ipv6");
324 
325         if (res.set.ipv6_address) {
326                 wds_to_ipv6("ip", res.data.ipv6_address.address);
327                 blobmsg_add_u32(&status, "ip-prefix-length", res.data.ipv6_address.prefix_length);
328         }
329         if (res.set.ipv6_gateway_address) {
330                 wds_to_ipv6("gateway", res.data.ipv6_gateway_address.address);
331                 blobmsg_add_u32(&status, "gw-prefix-length", res.data.ipv6_gateway_address.prefix_length);
332         }
333         if (res.set.ipv6_primary_dns_address)
334                 wds_to_ipv6("dns1", res.data.ipv6_primary_dns_address);
335         if (res.set.ipv6_secondary_dns_address)
336                 wds_to_ipv6("dns2", res.data.ipv6_secondary_dns_address);
337 
338         blobmsg_close_table(&status, v6);
339 
340         d = blobmsg_open_table(&status, "domain-names");
341         for (i = 0; i < res.data.domain_name_list_n; i++) {
342                 blobmsg_add_string(&status, NULL, res.data.domain_name_list[i]);
343         }
344         blobmsg_close_table(&status, d);
345 
346         blobmsg_close_table(&status, t);
347 }
348 
349 static enum qmi_cmd_result
350 cmd_wds_get_current_settings_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg)
351 {
352         struct qmi_wds_get_current_settings_request gcs_req;
353         memset(&gcs_req, '\0', sizeof(struct qmi_wds_get_current_settings_request));
354         qmi_set(&gcs_req, requested_settings,
355                 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PDP_TYPE |
356                 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DNS_ADDRESS |
357                 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GRANTED_QOS |
358                 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_ADDRESS |
359                 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GATEWAY_INFO |
360                 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_MTU |
361                 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DOMAIN_NAME_LIST |
362                 QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_FAMILY);
363         qmi_set_wds_get_current_settings_request(msg, &gcs_req);
364         return QMI_CMD_REQUEST;
365 }
366 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt