source: mainline/uspace/app/wifi_supplicant/wifi_supplicant.c@ 963037b0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 963037b0 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * Copyright (c) 2015 Jan Kolarik
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup nic
30 * @{
31 */
32/** @file WiFi device configuration utility.
33 *
34 */
35
36#include <ieee80211_iface.h>
37
38#include <inet/inetcfg.h>
39#include <inet/dhcp.h>
40#include <errno.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <str.h>
44#include <str_error.h>
45#include <loc.h>
46
47#define NAME "wifi_supplicant"
48
49#define enum_name(name_arr, i) \
50 ((i < 0) ? "NA" : name_arr[i])
51
52static const char* ieee80211_security_type_strs[] = {
53 "OPEN", "WEP", "WPA", "WPA2"
54};
55
56static const char* ieee80211_security_alg_strs[] = {
57 "WEP40", "WEP104", "CCMP", "TKIP"
58};
59
60static const char* ieee80211_security_auth_strs[] = {
61 "PSK", "8021X"
62};
63
64static void print_syntax(void)
65{
66 printf("syntax:\n");
67 printf("\t" NAME " [<cmd> [<args...>]]\n");
68 printf("\t<cmd> is:\n");
69 printf("\tlist - list wifi devices in <index>: <name> format\n");
70 printf("\tscan <index> [-n] - output scan results (force scan "
71 "immediately)\n");
72 printf("\tconnect <index> <ssid_prefix> [<password>] - connect to "
73 "network\n");
74 printf("\tdisconnect <index> - disconnect from network\n");
75}
76
77static char *nic_addr_format(nic_address_t *addr)
78{
79 char *str;
80 int rc = asprintf(&str, "%02x:%02x:%02x:%02x:%02x:%02x",
81 addr->address[0], addr->address[1], addr->address[2],
82 addr->address[3], addr->address[4], addr->address[5]);
83
84 if (rc < 0)
85 return NULL;
86
87 return str;
88}
89
90static errno_t get_wifi_list(service_id_t **wifis, size_t *count)
91{
92 category_id_t wifi_cat;
93 errno_t rc = loc_category_get_id("ieee80211", &wifi_cat, 0);
94 if (rc != EOK) {
95 printf("Error resolving category 'ieee80211'.\n");
96 return rc;
97 }
98
99 rc = loc_category_get_svcs(wifi_cat, wifis, count);
100 if (rc != EOK) {
101 printf("Error getting list of WIFIs.\n");
102 return rc;
103 }
104
105 return EOK;
106}
107
108static async_sess_t *get_wifi_by_index(size_t i)
109{
110 service_id_t *wifis = NULL;
111 size_t count;
112
113 errno_t rc = get_wifi_list(&wifis, &count);
114 if (rc != EOK) {
115 printf("Error fetching wifi list.\n");
116 return NULL;
117 }
118
119 if (i >= count) {
120 printf("Invalid wifi index.\n");
121 free(wifis);
122 return NULL;
123 }
124
125 async_sess_t *sess =
126 loc_service_connect(wifis[i], INTERFACE_DDF, 0);
127 if (sess == NULL) {
128 printf("Error connecting to service.\n");
129 free(wifis);
130 return NULL;
131 }
132
133 return sess;
134}
135
136static errno_t wifi_list(void)
137{
138 service_id_t *wifis = NULL;
139 size_t count;
140
141 errno_t rc = get_wifi_list(&wifis, &count);
142 if (rc != EOK) {
143 printf("Error fetching wifi list: %s\n", str_error(rc));
144 return EINVAL;
145 }
146
147 printf("[Index]: [Service Name]\n");
148 for (size_t i = 0; i < count; i++) {
149 char *svc_name;
150 rc = loc_service_get_name(wifis[i], &svc_name);
151 if (rc != EOK) {
152 printf("Error getting service name: %s\n", str_error(rc));
153 free(wifis);
154 return rc;
155 }
156
157 printf("%zu: %s\n", i, svc_name);
158
159 free(svc_name);
160 }
161
162 return EOK;
163}
164
165static errno_t wifi_connect(uint32_t index, char *ssid_start, char *password)
166{
167 assert(ssid_start);
168
169 async_sess_t *sess = get_wifi_by_index(index);
170 if (sess == NULL) {
171 printf("Specified WIFI doesn't exist or cannot connect to "
172 "it.\n");
173 return EINVAL;
174 }
175
176 errno_t rc = ieee80211_disconnect(sess);
177 if(rc != EOK) {
178 if (rc == EREFUSED)
179 printf("Device is not ready yet.\n");
180 else
181 printf("Error when disconnecting device: %s\n",
182 str_error(rc));
183
184 return rc;
185 }
186
187 rc = ieee80211_connect(sess, ssid_start, password);
188 if(rc != EOK) {
189 if (rc == EREFUSED)
190 printf("Device is not ready yet.\n");
191 else if (rc == ETIMEOUT)
192 printf("Timeout when authenticating to network.\n");
193 else if (rc == ENOENT)
194 printf("Given SSID not in scan results.\n");
195 else
196 printf("Error when connecting to network: %s\n",
197 str_error(rc));
198
199 return rc;
200 }
201
202 // TODO: Wait for DHCP address?
203
204 printf("Successfully connected to network!\n");
205
206 return EOK;
207}
208
209static errno_t wifi_disconnect(uint32_t index)
210{
211 async_sess_t *sess = get_wifi_by_index(index);
212 if (sess == NULL) {
213 printf("Specified WIFI doesn't exist or cannot connect to "
214 "it.\n");
215 return EINVAL;
216 }
217
218 errno_t rc = ieee80211_disconnect(sess);
219 if (rc != EOK) {
220 if (rc == EREFUSED)
221 printf("Device is not ready yet.\n");
222 else if (rc == EINVAL)
223 printf("Not connected to any WiFi network.\n");
224 else
225 printf("Error when disconnecting from network: %s\n",
226 str_error(rc));
227
228 return rc;
229 }
230
231 printf("Successfully disconnected.\n");
232
233 return EOK;
234}
235
236static errno_t wifi_scan(uint32_t index, bool now)
237{
238 async_sess_t *sess = get_wifi_by_index(index);
239 if (sess == NULL) {
240 printf("Specified WIFI doesn't exist or cannot connect to "
241 "it.\n");
242 return EINVAL;
243 }
244
245 ieee80211_scan_results_t scan_results;
246 errno_t rc = ieee80211_get_scan_results(sess, &scan_results, now);
247 if (rc != EOK) {
248 if (rc == EREFUSED)
249 printf("Device is not ready yet.\n");
250 else
251 printf("Failed to fetch scan results: %s\n",
252 str_error(rc));
253
254 return rc;
255 }
256
257 if (scan_results.length == 0)
258 return EOK;
259
260 printf("%16.16s %17s %4s %5s %5s %7s %7s\n",
261 "SSID", "MAC", "CHAN", "TYPE", "AUTH", "UNI-ALG", "GRP-ALG");
262
263 for (uint8_t i = 0; i < scan_results.length; i++) {
264 ieee80211_scan_result_t result = scan_results.results[i];
265
266 printf("%16.16s %17s %4d %5s %5s %7s %7s\n",
267 result.ssid, nic_addr_format(&result.bssid),
268 result.channel,
269 enum_name(ieee80211_security_type_strs, result.security.type),
270 enum_name(ieee80211_security_auth_strs, result.security.auth),
271 enum_name(ieee80211_security_alg_strs, result.security.pair_alg),
272 enum_name(ieee80211_security_alg_strs, result.security.group_alg));
273 }
274
275 return EOK;
276}
277
278int main(int argc, char *argv[])
279{
280 errno_t rc = inetcfg_init();
281 if (rc != EOK) {
282 printf("%s: Failed connecting to inetcfg service: %s.\n",
283 NAME, str_error(rc));
284 return 1;
285 }
286
287 rc = dhcp_init();
288 if (rc != EOK) {
289 printf("%s: Failed connecting to dhcp service: %s.\n",
290 NAME, str_error(rc));
291 return 1;
292 }
293
294 if (argc == 2) {
295 if (!str_cmp(argv[1], "list"))
296 return wifi_list();
297 } else if (argc > 2) {
298 uint32_t index;
299 rc = str_uint32_t(argv[2], NULL, 10, false, &index);
300 if (rc != EOK) {
301 printf("%s: Invalid argument.\n", NAME);
302 print_syntax();
303 return EINVAL;
304 }
305
306 if (!str_cmp(argv[1], "scan")) {
307 bool now = false;
308 if (argc > 3)
309 if (!str_cmp(argv[3], "-n"))
310 now = true;
311
312 return wifi_scan(index, now);
313 } else if (!str_cmp(argv[1], "connect")) {
314 char *pass = NULL;
315 if (argc > 3) {
316 if (argc > 4)
317 pass = argv[4];
318
319 return wifi_connect(index, argv[3], pass);
320 }
321 } else if (!str_cmp(argv[1], "disconnect"))
322 return wifi_disconnect(index);
323 }
324
325 print_syntax();
326
327 return EOK;
328}
329
330/** @}
331 */
Note: See TracBrowser for help on using the repository browser.