blob: 818b91d952a13d32549ee4e6732c05a9f43a968c [file] [log] [blame]
San Mehat82a21162009-05-12 17:26:28 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <errno.h>
18#include <string.h>
San Mehat3c5a6f02009-05-22 15:36:13 -070019#include <stdlib.h>
San Mehat82a21162009-05-12 17:26:28 -070020#include <sys/types.h>
21
San Mehat3c5a6f02009-05-22 15:36:13 -070022#define LOG_TAG "WifiNetwork"
23#include <cutils/log.h>
24
25#include "NetworkManager.h"
San Mehat82a21162009-05-12 17:26:28 -070026#include "WifiNetwork.h"
27#include "Supplicant.h"
San Mehat3c5a6f02009-05-22 15:36:13 -070028#include "WifiController.h"
29#include "InterfaceConfig.h"
San Mehat82a21162009-05-12 17:26:28 -070030
San Mehat3c5a6f02009-05-22 15:36:13 -070031const char *WifiNetwork::PropertyNames[] = { "ssid", "bssid", "psk", "wepkey.1",
32 "wepkey.2", "wepkey.3", "wepkey.4",
33 "defkeyidx", "pri", "hiddenssid",
34 "AllowedKeyManagement",
35 "AllowedProtocols",
36 "AllowedAuthAlgorithms",
37 "AllowedPairwiseCiphers",
38 "AllowedGroupCiphers",
39 "enabled", '\0' };
40WifiNetwork::WifiNetwork() {
41 // This is private to restrict copy constructors
42}
43
44WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data) {
45 mController = c;
San Mehat82a21162009-05-12 17:26:28 -070046 mSuppl = suppl;
San Mehat3c5a6f02009-05-22 15:36:13 -070047
48 char *tmp = strdup(data);
49 char *next = tmp;
50 char *id;
51 char *ssid;
52 char *bssid;
53 char *flags;
54
55 if (!(id = strsep(&next, "\t")))
56 LOGE("Failed to extract network id");
57 if (!(ssid = strsep(&next, "\t")))
58 LOGE("Failed to extract ssid");
59 if (!(bssid = strsep(&next, "\t")))
60 LOGE("Failed to extract bssid");
61 if (!(flags = strsep(&next, "\t")))
62 LOGE("Failed to extract flags");
63
64 // LOGD("id '%s', ssid '%s', bssid '%s', flags '%s'", id, ssid, bssid,
65 // flags ? flags :"null");
66
67 if (id)
68 mNetid = atoi(id);
69 if (ssid)
70 mSsid = strdup(ssid);
71 if (bssid)
72 mBssid = strdup(bssid);
73
74 mPsk = NULL;
75 memset(mWepKeys, 0, sizeof(mWepKeys));
76 mDefaultKeyIndex = -1;
77 mPriority = -1;
78 mHiddenSsid = NULL;
79 mAllowedKeyManagement = 0;
80 mAllowedProtocols = 0;
81 mAllowedAuthAlgorithms = 0;
82 mAllowedPairwiseCiphers = 0;
83 mAllowedGroupCiphers = 0;
84 mEnabled = true;
85
86 if (flags && flags[0] != '\0') {
87 if (!strcmp(flags, "[DISABLED]"))
88 mEnabled = false;
89 else
90 LOGW("Unsupported flags '%s'", flags);
91 }
92
93 char *tmp2;
94 asprintf(&tmp2, "wifi.net.%d", mNetid);
95 mIfaceCfg = new InterfaceConfig(tmp2);
96 free(tmp2);
97
98 registerProperties();
99 free(tmp);
100}
101
102WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) {
103 mController = c;
104 mSuppl = suppl;
105 mNetid = networkId;
San Mehat82a21162009-05-12 17:26:28 -0700106 mSsid = NULL;
107 mBssid = NULL;
108 mPsk = NULL;
109 memset(mWepKeys, 0, sizeof(mWepKeys));
110 mDefaultKeyIndex = -1;
111 mPriority = -1;
112 mHiddenSsid = NULL;
113 mAllowedKeyManagement = 0;
114 mAllowedProtocols = 0;
115 mAllowedAuthAlgorithms = 0;
116 mAllowedPairwiseCiphers = 0;
117 mAllowedGroupCiphers = 0;
San Mehat3c5a6f02009-05-22 15:36:13 -0700118 mEnabled = false;
119
120 char *tmp2;
121 asprintf(&tmp2, "wifi.net.%d", mNetid);
122 mIfaceCfg = new InterfaceConfig(tmp2);
123 free(tmp2);
124
125 registerProperties();
126}
127
128WifiNetwork *WifiNetwork::clone() {
129 WifiNetwork *r = new WifiNetwork();
130
131 r->mSuppl = mSuppl;
132 r->mNetid = mNetid;
133
134 if (mSsid)
135 r->mSsid = strdup(mSsid);
136 if (mBssid)
137 r->mBssid = strdup(mBssid);
138 if (mPsk)
139 r->mPsk = strdup(mPsk);
140
141 r->mController = mController;
142 memcpy(r->mWepKeys, mWepKeys, sizeof(mWepKeys));
143 r->mDefaultKeyIndex = mDefaultKeyIndex;
144 r->mPriority = mPriority;
145 if (mHiddenSsid)
146 r->mHiddenSsid = strdup(mHiddenSsid);
147 r->mAllowedKeyManagement = mAllowedKeyManagement;
148 r->mAllowedProtocols = mAllowedProtocols;
149 r->mAllowedAuthAlgorithms = mAllowedAuthAlgorithms;
150 r->mAllowedPairwiseCiphers = mAllowedPairwiseCiphers;
151 r->mAllowedGroupCiphers = mAllowedGroupCiphers;
152 return r;
San Mehat82a21162009-05-12 17:26:28 -0700153}
154
155WifiNetwork::~WifiNetwork() {
San Mehat3c5a6f02009-05-22 15:36:13 -0700156 unregisterProperties();
San Mehat82a21162009-05-12 17:26:28 -0700157 if (mSsid)
158 free(mSsid);
159 if (mBssid)
160 free(mBssid);
161 if (mPsk)
162 free(mPsk);
163 for (int i = 0; i < 4; i++) {
164 if (mWepKeys[i])
165 free(mWepKeys[i]);
166 }
San Mehat3c5a6f02009-05-22 15:36:13 -0700167
San Mehat82a21162009-05-12 17:26:28 -0700168 if (mHiddenSsid)
169 free(mHiddenSsid);
San Mehat3c5a6f02009-05-22 15:36:13 -0700170 if (mIfaceCfg)
171 delete(mIfaceCfg);
San Mehat82a21162009-05-12 17:26:28 -0700172}
173
San Mehat3c5a6f02009-05-22 15:36:13 -0700174int WifiNetwork::refresh() {
175 char buffer[255];
176 size_t len;
177
178 len = sizeof(buffer);
179 if (mSuppl->getNetworkVar(mNetid, "psk", buffer, len))
180 mPsk = strdup(buffer);
181
182 for (int i = 0; i < 4; i++) {
183 char *name;
184
185 asprintf(&name, "wep_key%d", i);
186 len = sizeof(buffer);
187 if (mSuppl->getNetworkVar(mNetid, name, buffer, len))
188 mWepKeys[i] = strdup(buffer);
189 free(name);
190 }
191
192 len = sizeof(buffer);
193 if (mSuppl->getNetworkVar(mNetid, "wep_tx_keyidx", buffer, len))
194 mDefaultKeyIndex = atoi(buffer);
195
196 len = sizeof(buffer);
197 if (mSuppl->getNetworkVar(mNetid, "priority", buffer, len))
198 mPriority = atoi(buffer);
199
200 len = sizeof(buffer);
201 if (mSuppl->getNetworkVar(mNetid, "scan_ssid", buffer, len))
202 mHiddenSsid = strdup(buffer);
203
204 len = sizeof(buffer);
205 if (mSuppl->getNetworkVar(mNetid, "key_mgmt", buffer, len)) {
206 // TODO
207 }
208
209 len = sizeof(buffer);
210 if (mSuppl->getNetworkVar(mNetid, "proto", buffer, len)) {
211 // TODO
212 }
213
214 len = sizeof(buffer);
215 if (mSuppl->getNetworkVar(mNetid, "auth_alg", buffer, len)) {
216 // TODO
217 }
218
219 len = sizeof(buffer);
220 if (mSuppl->getNetworkVar(mNetid, "pairwise", buffer, len)) {
221 // TODO
222 }
223
224 len = sizeof(buffer);
225 if (mSuppl->getNetworkVar(mNetid, "group", buffer, len)) {
226 // TODO
227 }
228
229 return 0;
230out_err:
231 LOGE("Refresh failed (%s)",strerror(errno));
San Mehat82a21162009-05-12 17:26:28 -0700232 return -1;
233}
234
San Mehat3c5a6f02009-05-22 15:36:13 -0700235int WifiNetwork::set(const char *name, const char *value) {
236 char *n_tmp = strdup(name + strlen("wifi.net."));
237 char *n_next = n_tmp;
238 char *n_local;
239 char *n_rest;
240 int rc = 0;
241
242 if (!strsep(&n_next, ".")) // skip net id
243 goto out_inval;
244
245 if (!(n_local = strsep(&n_next, ".")))
246 goto out_inval;
247
248 n_rest = n_next;
249
250// LOGD("set(): var '%s'(%s / %s) = %s", name, n_local, n_rest, value);
251 if (!strcasecmp(n_local, "enabled"))
252 rc = setEnabled(atoi(value));
253 else if (!strcmp(n_local, "ssid"))
254 rc = setSsid(value);
255 else if (!strcasecmp(n_local, "bssid"))
256 rc = setBssid(value);
257 else if (!strcasecmp(n_local, "psk"))
258 rc = setPsk(value);
259 else if (!strcasecmp(n_local, "wepkey"))
260 rc = setWepKey(atoi(n_rest) -1, value);
261 else if (!strcasecmp(n_local, "defkeyidx"))
262 rc = setDefaultKeyIndex(atoi(value));
263 else if (!strcasecmp(n_local, "pri"))
264 rc = setPriority(atoi(value));
265 else if (!strcasecmp(n_local, "hiddenssid"))
266 rc = setHiddenSsid(value);
267 else if (!strcasecmp(n_local, "AllowedKeyManagement")) {
268 uint32_t mask = 0;
269 bool none = false;
270 char *v_tmp = strdup(value);
271 char *v_next = v_tmp;
272 char *v_token;
273
274 while((v_token = strsep(&v_next, " "))) {
275 if (!strcasecmp(v_token, "NONE")) {
276 mask = 0;
277 none = true;
278 } else if (!none) {
279 if (!strcasecmp(v_token, "WPA_PSK"))
280 mask |= KeyManagementMask::WPA_PSK;
281 else if (!strcasecmp(v_token, "WPA_EAP"))
282 mask |= KeyManagementMask::WPA_EAP;
283 else if (!strcasecmp(v_token, "IEEE8021X"))
284 mask |= KeyManagementMask::IEEE8021X;
285 else {
286 errno = EINVAL;
287 rc = -1;
288 free(v_tmp);
289 goto out;
290 }
291 } else {
292 errno = EINVAL;
293 rc = -1;
294 free(v_tmp);
295 goto out;
296 }
297 }
298 free(v_tmp);
299 } else if (!strcasecmp(n_local, "AllowedProtocols")) {
300 // TODO
301 } else if (!strcasecmp(n_local, "AllowedPairwiseCiphers")) {
302 // TODO
303 } else if (!strcasecmp(n_local, "AllowedAuthAlgorithms")) {
304 // TODO
305 } else if (!strcasecmp(n_local, "AllowedGroupCiphers")) {
306 // TODO
307 } else {
308 errno = ENOENT;
309 free(n_tmp);
310 return -1;
311 }
312
313out:
314 free(n_tmp);
315 return rc;
316
317out_inval:
318 errno = EINVAL;
319 free(n_tmp);
San Mehat82a21162009-05-12 17:26:28 -0700320 return -1;
321}
322
San Mehat3c5a6f02009-05-22 15:36:13 -0700323const char *WifiNetwork::get(const char *name, char *buffer, size_t maxsize) {
324 char *n_tmp = strdup(name + strlen("wifi.net."));
325 char *n_next = n_tmp;
326 char *n_local;
327 char fc[64];
328 char rc[128];
329
330 if (!strsep(&n_next, ".")) // skip net id
331 goto out_inval;
332
333 if (!(n_local = strsep(&n_next, ".")))
334 goto out_inval;
335
336
337 strncpy(fc, n_local, sizeof(fc));
338 rc[0] = '\0';
339 if (n_next)
340 strncpy(rc, n_next, sizeof(rc));
341
342 free(n_tmp);
343
344 if (!strcasecmp(fc, "enabled"))
345 snprintf(buffer, maxsize, "%d", getEnabled());
346 else if (!strcasecmp(fc, "ssid")) {
347 strncpy(buffer,
348 getSsid() ? getSsid() : "none",
349 maxsize);
350 } else if (!strcasecmp(fc, "bssid")) {
351 strncpy(buffer,
352 getBssid() ? getBssid() : "none",
353 maxsize);
354 } else if (!strcasecmp(fc, "psk")) {
355 strncpy(buffer,
356 getPsk() ? getPsk() : "none",
357 maxsize);
358 } else if (!strcasecmp(fc, "wepkey")) {
359 strncpy(buffer,
360 getWepKey(atoi(rc)-1) ? getWepKey(atoi(rc)-1) : "none",
361 maxsize);
362 } else if (!strcasecmp(fc, "defkeyidx"))
363 snprintf(buffer, maxsize, "%d", getDefaultKeyIndex());
364 else if (!strcasecmp(fc, "pri"))
365 snprintf(buffer, maxsize, "%d", getPriority());
366 else if (!strcasecmp(fc, "hiddenssid")) {
367 strncpy(buffer,
368 getHiddenSsid() ? getHiddenSsid() : "none",
369 maxsize);
370 } else {
371 strncpy(buffer, "(internal error)", maxsize);
372 errno = ENOENT;
373 return NULL;
374 }
375
376 return buffer;
377
378out_inval:
379 errno = EINVAL;
380 free(n_tmp);
381 return NULL;
San Mehat82a21162009-05-12 17:26:28 -0700382}
383
San Mehat3c5a6f02009-05-22 15:36:13 -0700384int WifiNetwork::setSsid(const char *ssid) {
385 if (mSuppl->setNetworkVar(mNetid, "ssid", ssid))
386 return -1;
387 if (mSsid)
388 free(mSsid);
389 mSsid = strdup(ssid);
390 return 0;
391}
392
393int WifiNetwork::setBssid(const char *bssid) {
394 if (mSuppl->setNetworkVar(mNetid, "bssid", bssid))
395 return -1;
396 if (mBssid)
397 free(mBssid);
398 mBssid = strdup(bssid);
399 return 0;
400}
401
402int WifiNetwork::setPsk(const char *psk) {
403 if (mSuppl->setNetworkVar(mNetid, "psk", psk))
404 return -1;
405
406 if (mPsk)
407 free(mPsk);
408 mPsk = strdup(psk);
409 return 0;
410}
411
412int WifiNetwork::setWepKey(int idx, const char *key) {
413 char *name;
414
415 asprintf(&name, "wep_key%d", idx);
416 int rc = mSuppl->setNetworkVar(mNetid, name, key);
417 free(name);
418
419 if (rc)
420 return -1;
421
422 if (mWepKeys[idx])
423 free(mWepKeys[idx]);
424 mWepKeys[idx] = strdup(key);
425 return 0;
San Mehat82a21162009-05-12 17:26:28 -0700426}
427
428int WifiNetwork::setDefaultKeyIndex(int idx) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700429 char val[16];
430 sprintf(val, "%d", idx);
431 if (mSuppl->setNetworkVar(mNetid, "wep_tx_keyidx", val))
432 return -1;
433
434 mDefaultKeyIndex = idx;
435 return 0;
San Mehat82a21162009-05-12 17:26:28 -0700436}
437
San Mehat3c5a6f02009-05-22 15:36:13 -0700438int WifiNetwork::setPriority(int priority) {
439 char val[16];
440 sprintf(val, "%d", priority);
441 if (mSuppl->setNetworkVar(mNetid, "priority", val))
442 return -1;
443
444 mPriority = priority;
445 return 0;
San Mehat82a21162009-05-12 17:26:28 -0700446}
447
San Mehat3c5a6f02009-05-22 15:36:13 -0700448int WifiNetwork::setHiddenSsid(const char *ssid) {
449 if (mSuppl->setNetworkVar(mNetid, "scan_ssid", ssid))
450 return -1;
451
452 if (mHiddenSsid)
453 free(mHiddenSsid);
454 mHiddenSsid = strdup(ssid);
455 return 0;
San Mehat82a21162009-05-12 17:26:28 -0700456}
457
458int WifiNetwork::setAllowedKeyManagement(uint32_t mask) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700459 char accum[255];
460
461 if (mask == KeyManagementMask::NONE)
462 strcpy(accum, "NONE");
463 else {
464 if (mask & KeyManagementMask::WPA_PSK)
465 strcat(accum, "WPA_PSK ");
466 if (mask & KeyManagementMask::WPA_EAP)
467 strcat(accum, "WPA_EAP ");
468 if (mask & KeyManagementMask::IEEE8021X)
469 strcat(accum, "IEEE8021X ");
470 }
471
472 if (mSuppl->setNetworkVar(mNetid, "key_mgmt", accum))
473 return -1;
474 mAllowedKeyManagement = mask;
475 return 0;
San Mehat82a21162009-05-12 17:26:28 -0700476}
477
478int WifiNetwork::setAllowedProtocols(uint32_t mask) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700479 char accum[255];
480
481 accum[0] = '\0';
482
483 if (mask & SecurityProtocolMask::WPA)
484 strcpy(accum, "WPA ");
485
486 if (mask & SecurityProtocolMask::RSN)
487 strcat(accum, "RSN");
488
489 if (mSuppl->setNetworkVar(mNetid, "proto", accum))
490 return -1;
491 mAllowedProtocols = mask;
492 return 0;
493}
494
495int WifiNetwork::setAllowedAuthAlgorithms(uint32_t mask) {
496 char accum[255];
497
498 accum[0] = '\0';
499
500 if (mask & AuthenticationAlgorithmMask::OPEN)
501 strcpy(accum, "OPEN ");
502
503 if (mask & AuthenticationAlgorithmMask::SHARED)
504 strcat(accum, "SHARED ");
505
506 if (mask & AuthenticationAlgorithmMask::LEAP)
507 strcat(accum, "LEAP ");
508
509 if (mSuppl->setNetworkVar(mNetid, "auth_alg", accum))
510 return -1;
511
512 mAllowedAuthAlgorithms = mask;
513 return 0;
San Mehat82a21162009-05-12 17:26:28 -0700514}
515
516int WifiNetwork::setAllowedPairwiseCiphers(uint32_t mask) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700517 char accum[255];
518
519 if (mask == PairwiseCiphersMask::NONE)
520 strcpy(accum, "NONE");
521 else {
522 if (mask & PairwiseCiphersMask::TKIP)
523 strcat(accum, "TKIP ");
524 if (mask & PairwiseCiphersMask::CCMP)
525 strcat(accum, "CCMP ");
526 }
527
528 if (mSuppl->setNetworkVar(mNetid, "pairwise", accum))
529 return -1;
530
531 mAllowedPairwiseCiphers = mask;
532 return 0;
San Mehat82a21162009-05-12 17:26:28 -0700533}
534
535int WifiNetwork::setAllowedGroupCiphers(uint32_t mask) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700536 char accum[255];
537
538 if (mask & GroupCiphersMask::WEP40)
539 strcat(accum, "WEP40 ");
540 if (mask & GroupCiphersMask::WEP104)
541 strcat(accum, "WEP104 ");
542 if (mask & GroupCiphersMask::TKIP)
543 strcat(accum, "TKIP ");
544 if (mask & GroupCiphersMask::CCMP)
545 strcat(accum, "CCMP ");
546
547 if (mSuppl->setNetworkVar(mNetid, "group", accum))
548 return -1;
549 mAllowedGroupCiphers = mask;
550 return 0;
551}
552
553int WifiNetwork::setEnabled(bool enabled) {
San Mehat21e90f02009-06-01 10:04:21 -0700554
555 if (enabled) {
556 if (getPriority() == -1) {
557 LOGE("Cannot enable network when priority is not set");
558 errno = EAGAIN;
559 return -1;
560 }
561 if (getAllowedKeyManagement() == KeyManagementMask::UNKNOWN) {
562 LOGE("Cannot enable network when KeyManagement is not set");
563 errno = EAGAIN;
564 return -1;
565 }
566 }
567
San Mehat3c5a6f02009-05-22 15:36:13 -0700568 if (mSuppl->enableNetwork(mNetid, enabled))
569 return -1;
570
571 mEnabled = enabled;
572 return 0;
573}
574
575int WifiNetwork::registerProperties() {
576 for (const char **p = WifiNetwork::PropertyNames; *p != '\0'; p++) {
577 char *tmp;
578 asprintf(&tmp, "wifi.net.%d.%s", mNetid, *p);
579
580 if (NetworkManager::Instance()->getPropMngr()->registerProperty(tmp,
581 this)) {
582 free(tmp);
583 return -1;
584 }
585 free(tmp);
586 }
587 return 0;
588}
589
590int WifiNetwork::unregisterProperties() {
591 for (const char **p = WifiNetwork::PropertyNames; *p != '\0'; p++) {
592 char *tmp;
593 asprintf(&tmp, "wifi.net.%d.%s", mNetid, *p);
594
595 if (NetworkManager::Instance()->getPropMngr()->unregisterProperty(tmp))
596 LOGW("Unable to remove property '%s' (%s)", tmp, strerror(errno));
597 free(tmp);
598 }
599 return 0;
San Mehat82a21162009-05-12 17:26:28 -0700600}