blob: 6aa36e87590c98f846482d2522c218a3603d340c [file] [log] [blame]
San Mehatdc266072009-05-06 11:16:52 -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 */
San Mehat1441e762009-05-07 11:37:10 -070016
17#include <stdlib.h>
San Mehat69772dc2009-05-10 09:27:07 -070018#include <sys/types.h>
19#include <fcntl.h>
San Mehatdc266072009-05-06 11:16:52 -070020#include <errno.h>
21
22#define LOG_TAG "Supplicant"
23#include <cutils/log.h>
24#include <cutils/properties.h>
25
San Mehat69772dc2009-05-10 09:27:07 -070026#include "private/android_filesystem_config.h"
27
San Mehat5d6d4172009-05-14 15:00:06 -070028#include <sysutils/ServiceManager.h>
San Mehatdc266072009-05-06 11:16:52 -070029
30#include "Supplicant.h"
31#include "SupplicantListener.h"
San Mehat1441e762009-05-07 11:37:10 -070032#include "NetworkManager.h"
San Mehat3c5a6f02009-05-22 15:36:13 -070033#include "WifiController.h"
San Mehat3aff2d12009-06-15 14:10:44 -070034#include "SupplicantStatus.h"
San Mehatdc266072009-05-06 11:16:52 -070035
36#include "libwpa_client/wpa_ctrl.h"
37
38#define IFACE_DIR "/data/system/wpa_supplicant"
39#define DRIVER_PROP_NAME "wlan.driver.status"
San Mehat5d6d4172009-05-14 15:00:06 -070040#define SUPPLICANT_SERVICE_NAME "wpa_supplicant"
San Mehat69772dc2009-05-10 09:27:07 -070041#define SUPP_CONFIG_TEMPLATE "/system/etc/wifi/wpa_supplicant.conf"
42#define SUPP_CONFIG_FILE "/data/misc/wifi/wpa_supplicant.conf"
43
San Mehat3aff2d12009-06-15 14:10:44 -070044Supplicant::Supplicant(WifiController *wc, ISupplicantEventHandler *handlers) {
45 mHandlers = handlers;
San Mehat3c5a6f02009-05-22 15:36:13 -070046 mController = wc;
San Mehat3c5a6f02009-05-22 15:36:13 -070047 mInterfaceName = NULL;
San Mehatdc266072009-05-06 11:16:52 -070048 mCtrl = NULL;
49 mMonitor = NULL;
50 mListener = NULL;
San Mehat3c5a6f02009-05-22 15:36:13 -070051
San Mehat5d6d4172009-05-14 15:00:06 -070052 mServiceManager = new ServiceManager();
San Mehatdc266072009-05-06 11:16:52 -070053
San Mehat3c5a6f02009-05-22 15:36:13 -070054 mNetworks = new WifiNetworkCollection();
55 pthread_mutex_init(&mNetworksLock, NULL);
San Mehatdc266072009-05-06 11:16:52 -070056}
57
San Mehat5d6d4172009-05-14 15:00:06 -070058Supplicant::~Supplicant() {
59 delete mServiceManager;
San Mehat3c5a6f02009-05-22 15:36:13 -070060 if (mInterfaceName)
61 free(mInterfaceName);
San Mehat5d6d4172009-05-14 15:00:06 -070062}
63
San Mehatdc266072009-05-06 11:16:52 -070064int Supplicant::start() {
San Mehat69772dc2009-05-10 09:27:07 -070065
66 if (setupConfig()) {
67 LOGW("Unable to setup supplicant.conf");
68 }
San Mehat3c5a6f02009-05-22 15:36:13 -070069
San Mehat5d6d4172009-05-14 15:00:06 -070070 if (mServiceManager->start(SUPPLICANT_SERVICE_NAME)) {
71 LOGE("Error starting supplicant (%s)", strerror(errno));
72 return -1;
San Mehatdc266072009-05-06 11:16:52 -070073 }
74
75 wpa_ctrl_cleanup();
San Mehatdc266072009-05-06 11:16:52 -070076 if (connectToSupplicant()) {
77 LOGE("Error connecting to supplicant (%s)\n", strerror(errno));
78 return -1;
79 }
San Mehat3c5a6f02009-05-22 15:36:13 -070080
81 if (retrieveInterfaceName()) {
82 LOGE("Error retrieving interface name (%s)\n", strerror(errno));
83 return -1;
84 }
85
San Mehatdc266072009-05-06 11:16:52 -070086 return 0;
87}
88
89int Supplicant::stop() {
San Mehatdc266072009-05-06 11:16:52 -070090
San Mehatdc266072009-05-06 11:16:52 -070091 if (mListener->stopListener()) {
92 LOGW("Unable to stop supplicant listener (%s)", strerror(errno));
93 return -1;
94 }
95
San Mehat5d6d4172009-05-14 15:00:06 -070096 if (mServiceManager->stop(SUPPLICANT_SERVICE_NAME)) {
97 LOGW("Error stopping supplicant (%s)", strerror(errno));
San Mehatdc266072009-05-06 11:16:52 -070098 }
99
100 if (mCtrl) {
101 wpa_ctrl_close(mCtrl);
102 mCtrl = NULL;
103 }
104 if (mMonitor) {
105 wpa_ctrl_close(mMonitor);
106 mMonitor = NULL;
107 }
108
San Mehatdc266072009-05-06 11:16:52 -0700109 return 0;
110}
111
112bool Supplicant::isStarted() {
San Mehat5d6d4172009-05-14 15:00:06 -0700113 return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME);
San Mehatdc266072009-05-06 11:16:52 -0700114}
115
San Mehatc4a895b2009-06-23 21:10:57 -0700116int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) {
117
118 if (!mCtrl) {
119 errno = ENOTCONN;
120 return -1;
121 }
122
123// LOGD("sendCommand(): -> '%s'", cmd);
124
125 int rc;
126 memset(reply, 0, *reply_len);
127 if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) {
128 errno = ETIMEDOUT;
129 return -1;
130 } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) {
131 strcpy(reply, "FAIL");
132 errno = EIO;
133 return -1;
134 }
135
136 // LOGD("sendCommand(): <- '%s'", reply);
137 return 0;
138}
San Mehat3aff2d12009-06-15 14:10:44 -0700139SupplicantStatus *Supplicant::getStatus() {
140 char *reply;
141 size_t len = 4096;
142
143 if (!(reply = (char *) malloc(len))) {
144 errno = ENOMEM;
145 return NULL;
146 }
147
148 if (sendCommand("STATUS", reply, &len)) {
149 free(reply);
150 return NULL;
151 }
152
153 SupplicantStatus *ss = SupplicantStatus::createStatus(reply, len);
154
155 free (reply);
156 return ss;
157}
158
159/*
160 * Retrieves the list of networks from Supplicant
161 * and merge them into our current list
162 */
San Mehat3c5a6f02009-05-22 15:36:13 -0700163int Supplicant::refreshNetworkList() {
164 char *reply;
165 size_t len = 4096;
166
167 if (!(reply = (char *) malloc(len))) {
168 errno = ENOMEM;
San Mehatdc266072009-05-06 11:16:52 -0700169 return -1;
170 }
171
San Mehat3c5a6f02009-05-22 15:36:13 -0700172 if (sendCommand("LIST_NETWORKS", reply, &len)) {
173 free(reply);
174 return -1;
175 }
176
177 char *linep;
178 char *linep_next = NULL;
179
180 if (!strtok_r(reply, "\n", &linep_next)) {
181 LOGW("Malformatted network list\n");
San Mehat3aff2d12009-06-15 14:10:44 -0700182 free(reply);
183 errno = EIO;
184 return -1;
San Mehat3c5a6f02009-05-22 15:36:13 -0700185 }
186
San Mehatc4a895b2009-06-23 21:10:57 -0700187 PropertyManager *pm = NetworkManager::Instance()->getPropMngr();
San Mehat3aff2d12009-06-15 14:10:44 -0700188 pthread_mutex_lock(&mNetworksLock);
189
190 int num_added = 0;
191 int num_refreshed = 0;
192 int num_removed = 0;
193 while((linep = strtok_r(NULL, "\n", &linep_next))) {
194 // TODO: Move the decode into a static method so we
195 // don't create new_wn when we don't have to.
196 WifiNetwork *new_wn = new WifiNetwork(mController, this, linep);
197 WifiNetwork *merge_wn;
198
199 if ((merge_wn = this->lookupNetwork_UNLOCKED(new_wn->getNetworkId()))) {
200 num_refreshed++;
201 if (merge_wn->refresh()) {
202 LOGW("Error refreshing network %d (%s)",
203 merge_wn->getNetworkId(), strerror(errno));
204 }
205 delete new_wn;
206 } else {
207 num_added++;
San Mehatc4a895b2009-06-23 21:10:57 -0700208 char new_ns[20];
209 snprintf(new_ns, sizeof(new_ns), "wifi.net.%d", new_wn->getNetworkId());
210 new_wn->attachProperties(pm, new_ns);
San Mehat3aff2d12009-06-15 14:10:44 -0700211 mNetworks->push_back(new_wn);
212 if (new_wn->refresh()) {
213 LOGW("Unable to refresh network id %d (%s)",
214 new_wn->getNetworkId(), strerror(errno));
215 }
216 }
217 }
218
219 if (!mNetworks->empty()) {
220 // TODO: Add support for detecting removed networks
221 WifiNetworkCollection::iterator i;
222
223 for (i = mNetworks->begin(); i != mNetworks->end(); ++i) {
224 if (0) {
225 num_removed++;
San Mehatc4a895b2009-06-23 21:10:57 -0700226 char del_ns[20];
227 snprintf(del_ns, sizeof(del_ns), "wifi.net.%d", (*i)->getNetworkId());
228 (*i)->detachProperties(pm, del_ns);
San Mehat3aff2d12009-06-15 14:10:44 -0700229 delete (*i);
230 i = mNetworks->erase(i);
231 }
232 }
233 }
234
235
236 LOGD("Networks added %d, refreshed %d, removed %d\n",
237 num_added, num_refreshed, num_removed);
238 pthread_mutex_unlock(&mNetworksLock);
239
San Mehat3c5a6f02009-05-22 15:36:13 -0700240 free(reply);
241 return 0;
242}
243
244int Supplicant::connectToSupplicant() {
245 if (!isStarted())
246 LOGW("Supplicant service not running");
247
248 mCtrl = wpa_ctrl_open("tiwlan0"); // XXX:
San Mehatdc266072009-05-06 11:16:52 -0700249 if (mCtrl == NULL) {
250 LOGE("Unable to open connection to supplicant on \"%s\": %s",
251 "tiwlan0", strerror(errno));
252 return -1;
253 }
254 mMonitor = wpa_ctrl_open("tiwlan0");
255 if (mMonitor == NULL) {
256 wpa_ctrl_close(mCtrl);
257 mCtrl = NULL;
258 return -1;
259 }
260 if (wpa_ctrl_attach(mMonitor) != 0) {
261 wpa_ctrl_close(mMonitor);
262 wpa_ctrl_close(mCtrl);
263 mCtrl = mMonitor = NULL;
264 return -1;
265 }
266
San Mehat3aff2d12009-06-15 14:10:44 -0700267 mListener = new SupplicantListener(mHandlers, mMonitor);
San Mehat3c5a6f02009-05-22 15:36:13 -0700268
San Mehatdc266072009-05-06 11:16:52 -0700269 if (mListener->startListener()) {
270 LOGE("Error - unable to start supplicant listener");
271 stop();
272 return -1;
273 }
274 return 0;
275}
276
San Mehatc4a895b2009-06-23 21:10:57 -0700277int Supplicant::setScanMode(bool active) {
San Mehatdc266072009-05-06 11:16:52 -0700278 char reply[255];
279 size_t len = sizeof(reply);
280
281 if (sendCommand((active ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"),
282 reply, &len)) {
283 LOGW("triggerScan(%d): Error setting scan mode (%s)", active,
284 strerror(errno));
285 return -1;
286 }
San Mehatc4a895b2009-06-23 21:10:57 -0700287 return 0;
288}
289
290int Supplicant::triggerScan() {
291 char reply[255];
292 size_t len = sizeof(reply);
San Mehatdc266072009-05-06 11:16:52 -0700293
294 if (sendCommand("SCAN", reply, &len)) {
San Mehatc4a895b2009-06-23 21:10:57 -0700295 LOGW("triggerScan(): Error initiating scan");
296 return -1;
297 }
298 return 0;
299}
300
301int Supplicant::getRssi(int *buffer) {
302 char reply[64];
303 size_t len = sizeof(reply);
304
305 if (sendCommand("DRIVER RSSI", reply, &len)) {
306 LOGW("Failed to get RSSI (%s)", strerror(errno));
307 return -1;
308 }
309
310 char *next = reply;
311 char *s;
312 for (int i = 0; i < 3; i++) {
313 if (!(s = strsep(&next, " "))) {
314 LOGE("Error parsing RSSI");
315 errno = EIO;
316 return -1;
317 }
318 }
319 *buffer = atoi(s);
320 return 0;
321}
322
323int Supplicant::getLinkSpeed() {
324 char reply[64];
325 size_t len = sizeof(reply);
326
327 if (sendCommand("DRIVER LINKSPEED", reply, &len)) {
328 LOGW("Failed to get LINKSPEED (%s)", strerror(errno));
329 return -1;
330 }
331
332 char *next = reply;
333 char *s;
334
335 if (!(s = strsep(&next, " "))) {
336 LOGE("Error parsing LINKSPEED");
337 errno = EIO;
338 return -1;
339 }
340
341 if (!(s = strsep(&next, " "))) {
342 LOGE("Error parsing LINKSPEED");
343 errno = EIO;
344 return -1;
345 }
346 return atoi(s);
347}
348
349int Supplicant::stopDriver() {
350 char reply[64];
351 size_t len = sizeof(reply);
352
353 LOGD("stopDriver()");
354
355 if (sendCommand("DRIVER STOP", reply, &len)) {
356 LOGW("Failed to stop driver (%s)", strerror(errno));
357 return -1;
358 }
359 return 0;
360}
361
362int Supplicant::startDriver() {
363 char reply[64];
364 size_t len = sizeof(reply);
365
366 LOGD("startDriver()");
367 if (sendCommand("DRIVER START", reply, &len)) {
368 LOGW("Failed to start driver (%s)", strerror(errno));
San Mehatdc266072009-05-06 11:16:52 -0700369 return -1;
370 }
371 return 0;
372}
373
San Mehat3c5a6f02009-05-22 15:36:13 -0700374WifiNetwork *Supplicant::createNetwork() {
375 char reply[255];
San Mehat82a21162009-05-12 17:26:28 -0700376 size_t len = sizeof(reply) -1;
377
San Mehat82a21162009-05-12 17:26:28 -0700378 if (sendCommand("ADD_NETWORK", reply, &len))
San Mehat3c5a6f02009-05-22 15:36:13 -0700379 return NULL;
San Mehat82a21162009-05-12 17:26:28 -0700380
San Mehat3c5a6f02009-05-22 15:36:13 -0700381 if (reply[strlen(reply) -1] == '\n')
382 reply[strlen(reply) -1] = '\0';
383
384 WifiNetwork *wn = new WifiNetwork(mController, this, atoi(reply));
San Mehatc4a895b2009-06-23 21:10:57 -0700385 PropertyManager *pm = NetworkManager::Instance()->getPropMngr();
San Mehat3c5a6f02009-05-22 15:36:13 -0700386 pthread_mutex_lock(&mNetworksLock);
San Mehatc4a895b2009-06-23 21:10:57 -0700387 char new_ns[20];
388 snprintf(new_ns, sizeof(new_ns), "wifi.net.%d", wn->getNetworkId());
389 wn->attachProperties(pm, new_ns);
San Mehat3c5a6f02009-05-22 15:36:13 -0700390 mNetworks->push_back(wn);
391 pthread_mutex_unlock(&mNetworksLock);
392 return wn;
San Mehat82a21162009-05-12 17:26:28 -0700393}
394
San Mehat3c5a6f02009-05-22 15:36:13 -0700395int Supplicant::removeNetwork(WifiNetwork *wn) {
San Mehat82a21162009-05-12 17:26:28 -0700396 char req[64];
397
San Mehat3c5a6f02009-05-22 15:36:13 -0700398 sprintf(req, "REMOVE_NETWORK %d", wn->getNetworkId());
San Mehat82a21162009-05-12 17:26:28 -0700399 char reply[32];
400 size_t len = sizeof(reply) -1;
San Mehat3c5a6f02009-05-22 15:36:13 -0700401
San Mehat82a21162009-05-12 17:26:28 -0700402 if (sendCommand(req, reply, &len))
403 return -1;
San Mehat3c5a6f02009-05-22 15:36:13 -0700404
405 pthread_mutex_lock(&mNetworksLock);
406 WifiNetworkCollection::iterator it;
407 for (it = mNetworks->begin(); it != mNetworks->end(); ++it) {
408 if ((*it) == wn) {
409 mNetworks->erase(it);
410 break;
411 }
412 }
413 pthread_mutex_unlock(&mNetworksLock);
San Mehat82a21162009-05-12 17:26:28 -0700414 return 0;
415}
416
San Mehat3c5a6f02009-05-22 15:36:13 -0700417WifiNetwork *Supplicant::lookupNetwork(int networkId) {
418 pthread_mutex_lock(&mNetworksLock);
San Mehat3aff2d12009-06-15 14:10:44 -0700419 WifiNetwork *wn = lookupNetwork_UNLOCKED(networkId);
420 pthread_mutex_unlock(&mNetworksLock);
421 return wn;
422}
423
424WifiNetwork *Supplicant::lookupNetwork_UNLOCKED(int networkId) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700425 WifiNetworkCollection::iterator it;
426 for (it = mNetworks->begin(); it != mNetworks->end(); ++it) {
427 if ((*it)->getNetworkId() == networkId) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700428 return *it;
429 }
430 }
San Mehat3c5a6f02009-05-22 15:36:13 -0700431 errno = ENOENT;
432 return NULL;
433}
434
435WifiNetworkCollection *Supplicant::createNetworkList() {
436 WifiNetworkCollection *d = new WifiNetworkCollection();
437 WifiNetworkCollection::iterator i;
438
439 pthread_mutex_lock(&mNetworksLock);
440 for (i = mNetworks->begin(); i != mNetworks->end(); ++i)
441 d->push_back((*i)->clone());
442
443 pthread_mutex_unlock(&mNetworksLock);
444 return d;
445}
446
San Mehat69772dc2009-05-10 09:27:07 -0700447int Supplicant::setupConfig() {
448 char buf[2048];
449 int srcfd, destfd;
450 int nread;
451
452 if (access(SUPP_CONFIG_FILE, R_OK|W_OK) == 0) {
453 return 0;
454 } else if (errno != ENOENT) {
455 LOGE("Cannot access \"%s\": %s", SUPP_CONFIG_FILE, strerror(errno));
456 return -1;
457 }
458
459 srcfd = open(SUPP_CONFIG_TEMPLATE, O_RDONLY);
460 if (srcfd < 0) {
461 LOGE("Cannot open \"%s\": %s", SUPP_CONFIG_TEMPLATE, strerror(errno));
462 return -1;
463 }
464
465 destfd = open(SUPP_CONFIG_FILE, O_CREAT|O_WRONLY, 0660);
466 if (destfd < 0) {
467 close(srcfd);
468 LOGE("Cannot create \"%s\": %s", SUPP_CONFIG_FILE, strerror(errno));
469 return -1;
470 }
471
472 while ((nread = read(srcfd, buf, sizeof(buf))) != 0) {
473 if (nread < 0) {
474 LOGE("Error reading \"%s\": %s", SUPP_CONFIG_TEMPLATE, strerror(errno));
475 close(srcfd);
476 close(destfd);
477 unlink(SUPP_CONFIG_FILE);
478 return -1;
479 }
480 write(destfd, buf, nread);
481 }
482
483 close(destfd);
484 close(srcfd);
485
486 if (chown(SUPP_CONFIG_FILE, AID_SYSTEM, AID_WIFI) < 0) {
487 LOGE("Error changing group ownership of %s to %d: %s",
488 SUPP_CONFIG_FILE, AID_WIFI, strerror(errno));
489 unlink(SUPP_CONFIG_FILE);
490 return -1;
491 }
492 return 0;
493}
San Mehat3c5a6f02009-05-22 15:36:13 -0700494
495int Supplicant::setNetworkVar(int networkId, const char *var, const char *val) {
496 char reply[255];
497 size_t len = sizeof(reply) -1;
498
San Mehatc4a895b2009-06-23 21:10:57 -0700499 LOGD("netid %d, var '%s' = '%s'", networkId, var, val);
San Mehat3c5a6f02009-05-22 15:36:13 -0700500 char *tmp;
San Mehatc4a895b2009-06-23 21:10:57 -0700501 asprintf(&tmp, "SET_NETWORK %d %s %s", networkId, var, val);
San Mehat3c5a6f02009-05-22 15:36:13 -0700502 if (sendCommand(tmp, reply, &len)) {
503 free(tmp);
504 return -1;
505 }
506 free(tmp);
San Mehat3aff2d12009-06-15 14:10:44 -0700507
508 len = sizeof(reply) -1;
509 if (sendCommand("SAVE_CONFIG", reply, &len)) {
510 LOGE("Error saving config after %s = %s", var, val);
511 return -1;
512 }
San Mehat3c5a6f02009-05-22 15:36:13 -0700513 return 0;
514}
515
516const char *Supplicant::getNetworkVar(int networkId, const char *var,
517 char *buffer, size_t max) {
518 size_t len = max - 1;
519 char *tmp;
520
521 asprintf(&tmp, "GET_NETWORK %d %s", networkId, var);
522 if (sendCommand(tmp, buffer, &len)) {
523 free(tmp);
524 return NULL;
525 }
526 free(tmp);
527 return buffer;
528}
529
530int Supplicant::enableNetwork(int networkId, bool enabled) {
531 char req[64];
532
533 if (enabled)
534 sprintf(req, "ENABLE_NETWORK %d", networkId);
535 else
536 sprintf(req, "DISABLE_NETWORK %d", networkId);
537
538 char reply[16];
539 size_t len = sizeof(reply) -1;
540
541 if (sendCommand(req, reply, &len))
542 return -1;
543 return 0;
544}
545
San Mehatc4a895b2009-06-23 21:10:57 -0700546int Supplicant::enablePacketFilter() {
547 char req[128];
548 char reply[16];
549 size_t len;
550 int i;
551
552 for (i = 0; i <=3; i++) {
553 snprintf(req, sizeof(req), "DRIVER RXFILTER-ADD %d", i);
554 len = sizeof(reply);
555 if (sendCommand(req, reply, &len))
556 return -1;
557 }
558
559 len = sizeof(reply);
560 if (sendCommand("DRIVER RXFILTER-START", reply, &len))
561 return -1;
562 return 0;
563}
564
565int Supplicant::disablePacketFilter() {
566 char req[128];
567 char reply[16];
568 size_t len;
569 int i;
570
571 len = sizeof(reply);
572 if (sendCommand("DRIVER RXFILTER-STOP", reply, &len))
573 return -1;
574
575 for (i = 3; i >=0; i--) {
576 snprintf(req, sizeof(req), "DRIVER RXFILTER-REMOVE %d", i);
577 len = sizeof(reply);
578 if (sendCommand(req, reply, &len))
579 return -1;
580 }
581 return 0;
582}
583
584int Supplicant::enableBluetoothCoexistenceScan() {
585 char req[128];
586 char reply[16];
587 size_t len;
588 int i;
589
590 len = sizeof(reply);
591 if (sendCommand("DRIVER BTCOEXSCAN-START", reply, &len))
592 return -1;
593 return 0;
594}
595
596int Supplicant::disableBluetoothCoexistenceScan() {
597 char req[128];
598 char reply[16];
599 size_t len;
600 int i;
601
602 len = sizeof(reply);
603 if (sendCommand("DRIVER BTCOEXSCAN-STOP", reply, &len))
604 return -1;
605 return 0;
606}
607
608int Supplicant::setBluetoothCoexistenceMode(int mode) {
609 char req[64];
610
611 sprintf(req, "DRIVER BTCOEXMODE %d", mode);
612
613 char reply[16];
614 size_t len = sizeof(reply) -1;
615
616 if (sendCommand(req, reply, &len))
617 return -1;
618 return 0;
619}
620
621int Supplicant::setApScanMode(int mode) {
622 char req[64];
623
624// LOGD("setApScanMode(%d)", mode);
625 sprintf(req, "AP_SCAN %d", mode);
626
627 char reply[16];
628 size_t len = sizeof(reply) -1;
629
630 if (sendCommand(req, reply, &len))
631 return -1;
632 return 0;
633}
634
San Mehat3c5a6f02009-05-22 15:36:13 -0700635
636int Supplicant::retrieveInterfaceName() {
637 char reply[255];
638 size_t len = sizeof(reply) -1;
639
640 if (sendCommand("INTERFACES", reply, &len))
641 return -1;
642
643 reply[strlen(reply)-1] = '\0';
644 mInterfaceName = strdup(reply);
645 return 0;
646}
San Mehatc4a895b2009-06-23 21:10:57 -0700647
648int Supplicant::reconnect() {
649 char req[128];
650 char reply[16];
651 size_t len;
652 int i;
653
654 len = sizeof(reply);
655 if (sendCommand("RECONNECT", reply, &len))
656 return -1;
657 return 0;
658}
659
660int Supplicant::disconnect() {
661 char req[128];
662 char reply[16];
663 size_t len;
664 int i;
665
666 len = sizeof(reply);
667 if (sendCommand("DISCONNECT", reply, &len))
668 return -1;
669 return 0;
670}
671
672int Supplicant::getNetworkCount() {
673 pthread_mutex_lock(&mNetworksLock);
674 int cnt = mNetworks->size();
675 pthread_mutex_unlock(&mNetworksLock);
676 return cnt;
677}