104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/* 204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * WPA Supplicant - auto scan 304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Copyright (c) 2012, Intel Corporation. All rights reserved. 404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * This software may be distributed under the terms of the BSD license. 604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * See README for more details. 704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "includes.h" 1004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "common.h" 1204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "config.h" 1304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "wpa_supplicant_i.h" 1404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "bss.h" 1504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "scan.h" 1604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "autoscan.h" 1704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN_EXPONENTIAL 1904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtextern const struct autoscan_ops autoscan_exponential_ops; 2004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN_EXPONENTIAL */ 2104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN_PERIODIC 2304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtextern const struct autoscan_ops autoscan_periodic_ops; 2404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN_PERIODIC */ 2504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic const struct autoscan_ops * autoscan_modules[] = { 2704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN_EXPONENTIAL 2804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &autoscan_exponential_ops, 2904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN_EXPONENTIAL */ 3004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_AUTOSCAN_PERIODIC 3104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &autoscan_periodic_ops, 3204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_AUTOSCAN_PERIODIC */ 3304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt NULL 3404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}; 3504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void request_scan(struct wpa_supplicant *wpa_s) 3804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 39d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->scan_req = MANUAL_SCAN_REQ; 4004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_supplicant_req_sched_scan(wpa_s)) 4204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval, 0); 4304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 4404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint autoscan_init(struct wpa_supplicant *wpa_s, int req_scan) 4704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 4804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *name = wpa_s->conf->autoscan; 4904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *params; 5004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t nlen; 5104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int i; 5204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct autoscan_ops *ops = NULL; 5304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->autoscan && wpa_s->autoscan_priv) 5504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 5604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (name == NULL) 5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params = os_strchr(name, ':'); 6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (params == NULL) { 6204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params = ""; 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt nlen = os_strlen(name); 6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 6504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt nlen = params - name; 6604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params++; 6704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 6804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; autoscan_modules[i]; i++) { 7004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (os_strncmp(name, autoscan_modules[i]->name, nlen) == 0) { 7104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ops = autoscan_modules[i]; 7204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 7304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 7604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ops == NULL) { 7704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "autoscan: Could not find module " 7804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "matching the parameter '%s'", name); 7904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 8004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 8104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 8204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->autoscan_params = NULL; 8304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 8404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->autoscan_priv = ops->init(wpa_s, params); 8504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->autoscan_priv == NULL) 8604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 8704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->autoscan = ops; 8804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 8904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "autoscan: Initialized module '%s' with " 9004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "parameters '%s'", ops->name, params); 9104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!req_scan) 9204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 9304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 9404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 9504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Cancelling existing scan requests, if any. 9604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 9704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 9804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_cancel_scan(wpa_s); 9904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 10004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 10104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Firing first scan, which will lead to call autoscan_notify_scan. 10204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 10304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt request_scan(wpa_s); 10404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 10504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 10604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 10704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 10804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 10904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid autoscan_deinit(struct wpa_supplicant *wpa_s) 11004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 11104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->autoscan && wpa_s->autoscan_priv) { 11204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "autoscan: Deinitializing module '%s'", 11304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->autoscan->name); 11404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->autoscan->deinit(wpa_s->autoscan_priv); 11504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->autoscan = NULL; 11604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->autoscan_priv = NULL; 11704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 11804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->scan_interval = 5; 11904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sched_scan_interval = 0; 12004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 12104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 12204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 12304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 12404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint autoscan_notify_scan(struct wpa_supplicant *wpa_s, 12504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_scan_results *scan_res) 12604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 12704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int interval; 12804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 12904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->autoscan && wpa_s->autoscan_priv) { 13004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt interval = wpa_s->autoscan->notify_scan(wpa_s->autoscan_priv, 13104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt scan_res); 13204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (interval <= 0) 13404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 13504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->scan_interval = interval; 13704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sched_scan_interval = interval; 13804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt request_scan(wpa_s); 14004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 14104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 14204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 14304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 144