Home | History | Annotate | Line # | Download | only in wpa_supplicant
autoscan.c revision 1.1.1.2
      1      1.1  christos /*
      2      1.1  christos  * WPA Supplicant - auto scan
      3      1.1  christos  * Copyright (c) 2012, Intel Corporation. All rights reserved.
      4  1.1.1.2  christos  * Copyright 2015	Intel Deutschland GmbH
      5      1.1  christos  *
      6      1.1  christos  * This software may be distributed under the terms of the BSD license.
      7      1.1  christos  * See README for more details.
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos #include "includes.h"
     11      1.1  christos 
     12      1.1  christos #include "common.h"
     13      1.1  christos #include "config.h"
     14      1.1  christos #include "wpa_supplicant_i.h"
     15      1.1  christos #include "bss.h"
     16      1.1  christos #include "scan.h"
     17      1.1  christos #include "autoscan.h"
     18      1.1  christos 
     19      1.1  christos 
     20      1.1  christos static const struct autoscan_ops * autoscan_modules[] = {
     21      1.1  christos #ifdef CONFIG_AUTOSCAN_EXPONENTIAL
     22      1.1  christos 	&autoscan_exponential_ops,
     23      1.1  christos #endif /* CONFIG_AUTOSCAN_EXPONENTIAL */
     24      1.1  christos #ifdef CONFIG_AUTOSCAN_PERIODIC
     25      1.1  christos 	&autoscan_periodic_ops,
     26      1.1  christos #endif /* CONFIG_AUTOSCAN_PERIODIC */
     27      1.1  christos 	NULL
     28      1.1  christos };
     29      1.1  christos 
     30      1.1  christos 
     31      1.1  christos static void request_scan(struct wpa_supplicant *wpa_s)
     32      1.1  christos {
     33      1.1  christos 	wpa_s->scan_req = MANUAL_SCAN_REQ;
     34      1.1  christos 
     35      1.1  christos 	if (wpa_supplicant_req_sched_scan(wpa_s))
     36      1.1  christos 		wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval, 0);
     37      1.1  christos }
     38      1.1  christos 
     39      1.1  christos 
     40      1.1  christos int autoscan_init(struct wpa_supplicant *wpa_s, int req_scan)
     41      1.1  christos {
     42      1.1  christos 	const char *name = wpa_s->conf->autoscan;
     43      1.1  christos 	const char *params;
     44      1.1  christos 	size_t nlen;
     45      1.1  christos 	int i;
     46      1.1  christos 	const struct autoscan_ops *ops = NULL;
     47  1.1.1.2  christos 	struct sched_scan_plan *scan_plans;
     48  1.1.1.2  christos 
     49  1.1.1.2  christos 	/* Give preference to scheduled scan plans if supported/configured */
     50  1.1.1.2  christos 	if (wpa_s->sched_scan_plans)
     51  1.1.1.2  christos 		return 0;
     52      1.1  christos 
     53      1.1  christos 	if (wpa_s->autoscan && wpa_s->autoscan_priv)
     54      1.1  christos 		return 0;
     55      1.1  christos 
     56      1.1  christos 	if (name == NULL)
     57      1.1  christos 		return 0;
     58      1.1  christos 
     59      1.1  christos 	params = os_strchr(name, ':');
     60      1.1  christos 	if (params == NULL) {
     61      1.1  christos 		params = "";
     62      1.1  christos 		nlen = os_strlen(name);
     63      1.1  christos 	} else {
     64      1.1  christos 		nlen = params - name;
     65      1.1  christos 		params++;
     66      1.1  christos 	}
     67      1.1  christos 
     68      1.1  christos 	for (i = 0; autoscan_modules[i]; i++) {
     69      1.1  christos 		if (os_strncmp(name, autoscan_modules[i]->name, nlen) == 0) {
     70      1.1  christos 			ops = autoscan_modules[i];
     71      1.1  christos 			break;
     72      1.1  christos 		}
     73      1.1  christos 	}
     74      1.1  christos 
     75      1.1  christos 	if (ops == NULL) {
     76      1.1  christos 		wpa_printf(MSG_ERROR, "autoscan: Could not find module "
     77      1.1  christos 			   "matching the parameter '%s'", name);
     78      1.1  christos 		return -1;
     79      1.1  christos 	}
     80      1.1  christos 
     81  1.1.1.2  christos 	scan_plans = os_malloc(sizeof(*wpa_s->sched_scan_plans));
     82  1.1.1.2  christos 	if (!scan_plans)
     83  1.1.1.2  christos 		return -1;
     84  1.1.1.2  christos 
     85      1.1  christos 	wpa_s->autoscan_params = NULL;
     86      1.1  christos 
     87      1.1  christos 	wpa_s->autoscan_priv = ops->init(wpa_s, params);
     88  1.1.1.2  christos 	if (!wpa_s->autoscan_priv) {
     89  1.1.1.2  christos 		os_free(scan_plans);
     90      1.1  christos 		return -1;
     91  1.1.1.2  christos 	}
     92  1.1.1.2  christos 
     93  1.1.1.2  christos 	scan_plans[0].interval = 5;
     94  1.1.1.2  christos 	scan_plans[0].iterations = 0;
     95  1.1.1.2  christos 	os_free(wpa_s->sched_scan_plans);
     96  1.1.1.2  christos 	wpa_s->sched_scan_plans = scan_plans;
     97  1.1.1.2  christos 	wpa_s->sched_scan_plans_num = 1;
     98      1.1  christos 	wpa_s->autoscan = ops;
     99      1.1  christos 
    100      1.1  christos 	wpa_printf(MSG_DEBUG, "autoscan: Initialized module '%s' with "
    101      1.1  christos 		   "parameters '%s'", ops->name, params);
    102      1.1  christos 	if (!req_scan)
    103      1.1  christos 		return 0;
    104      1.1  christos 
    105      1.1  christos 	/*
    106      1.1  christos 	 * Cancelling existing scan requests, if any.
    107      1.1  christos 	 */
    108      1.1  christos 	wpa_supplicant_cancel_sched_scan(wpa_s);
    109      1.1  christos 	wpa_supplicant_cancel_scan(wpa_s);
    110      1.1  christos 
    111      1.1  christos 	/*
    112      1.1  christos 	 * Firing first scan, which will lead to call autoscan_notify_scan.
    113      1.1  christos 	 */
    114      1.1  christos 	request_scan(wpa_s);
    115      1.1  christos 
    116      1.1  christos 	return 0;
    117      1.1  christos }
    118      1.1  christos 
    119      1.1  christos 
    120      1.1  christos void autoscan_deinit(struct wpa_supplicant *wpa_s)
    121      1.1  christos {
    122      1.1  christos 	if (wpa_s->autoscan && wpa_s->autoscan_priv) {
    123      1.1  christos 		wpa_printf(MSG_DEBUG, "autoscan: Deinitializing module '%s'",
    124      1.1  christos 			   wpa_s->autoscan->name);
    125      1.1  christos 		wpa_s->autoscan->deinit(wpa_s->autoscan_priv);
    126      1.1  christos 		wpa_s->autoscan = NULL;
    127      1.1  christos 		wpa_s->autoscan_priv = NULL;
    128      1.1  christos 
    129      1.1  christos 		wpa_s->scan_interval = 5;
    130  1.1.1.2  christos 
    131  1.1.1.2  christos 		os_free(wpa_s->sched_scan_plans);
    132  1.1.1.2  christos 		wpa_s->sched_scan_plans = NULL;
    133  1.1.1.2  christos 		wpa_s->sched_scan_plans_num = 0;
    134      1.1  christos 	}
    135      1.1  christos }
    136      1.1  christos 
    137      1.1  christos 
    138      1.1  christos int autoscan_notify_scan(struct wpa_supplicant *wpa_s,
    139      1.1  christos 			 struct wpa_scan_results *scan_res)
    140      1.1  christos {
    141      1.1  christos 	int interval;
    142      1.1  christos 
    143      1.1  christos 	if (wpa_s->autoscan && wpa_s->autoscan_priv) {
    144      1.1  christos 		interval = wpa_s->autoscan->notify_scan(wpa_s->autoscan_priv,
    145      1.1  christos 							scan_res);
    146      1.1  christos 
    147      1.1  christos 		if (interval <= 0)
    148      1.1  christos 			return -1;
    149      1.1  christos 
    150      1.1  christos 		wpa_s->scan_interval = interval;
    151  1.1.1.2  christos 		wpa_s->sched_scan_plans[0].interval = interval;
    152      1.1  christos 
    153      1.1  christos 		request_scan(wpa_s);
    154      1.1  christos 	}
    155      1.1  christos 
    156      1.1  christos 	return 0;
    157      1.1  christos }
    158