1214501Srpaulo/* 2214501Srpaulo * WPA Supplicant - background scan and roaming interface 3214501Srpaulo * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> 4214501Srpaulo * 5214501Srpaulo * This program is free software; you can redistribute it and/or modify 6214501Srpaulo * it under the terms of the GNU General Public License version 2 as 7214501Srpaulo * published by the Free Software Foundation. 8214501Srpaulo * 9214501Srpaulo * Alternatively, this software may be distributed under the terms of BSD 10214501Srpaulo * license. 11214501Srpaulo * 12214501Srpaulo * See README and COPYING for more details. 13214501Srpaulo */ 14214501Srpaulo 15214501Srpaulo#include "includes.h" 16214501Srpaulo 17214501Srpaulo#include "common.h" 18214501Srpaulo#include "wpa_supplicant_i.h" 19214501Srpaulo#include "config_ssid.h" 20214501Srpaulo#include "bgscan.h" 21214501Srpaulo 22214501Srpaulo#ifdef CONFIG_BGSCAN_SIMPLE 23214501Srpauloextern const struct bgscan_ops bgscan_simple_ops; 24214501Srpaulo#endif /* CONFIG_BGSCAN_SIMPLE */ 25214501Srpaulo 26214501Srpaulostatic const struct bgscan_ops * bgscan_modules[] = { 27214501Srpaulo#ifdef CONFIG_BGSCAN_SIMPLE 28214501Srpaulo &bgscan_simple_ops, 29214501Srpaulo#endif /* CONFIG_BGSCAN_SIMPLE */ 30214501Srpaulo NULL 31214501Srpaulo}; 32214501Srpaulo 33214501Srpaulo 34214501Srpauloint bgscan_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) 35214501Srpaulo{ 36214501Srpaulo const char *name = ssid->bgscan; 37214501Srpaulo const char *params; 38214501Srpaulo size_t nlen; 39214501Srpaulo int i; 40214501Srpaulo const struct bgscan_ops *ops = NULL; 41214501Srpaulo 42214501Srpaulo bgscan_deinit(wpa_s); 43214501Srpaulo if (name == NULL) 44214501Srpaulo return 0; 45214501Srpaulo 46214501Srpaulo params = os_strchr(name, ':'); 47214501Srpaulo if (params == NULL) { 48214501Srpaulo params = ""; 49214501Srpaulo nlen = os_strlen(name); 50214501Srpaulo } else { 51214501Srpaulo nlen = params - name; 52214501Srpaulo params++; 53214501Srpaulo } 54214501Srpaulo 55214501Srpaulo for (i = 0; bgscan_modules[i]; i++) { 56214501Srpaulo if (os_strncmp(name, bgscan_modules[i]->name, nlen) == 0) { 57214501Srpaulo ops = bgscan_modules[i]; 58214501Srpaulo break; 59214501Srpaulo } 60214501Srpaulo } 61214501Srpaulo 62214501Srpaulo if (ops == NULL) { 63214501Srpaulo wpa_printf(MSG_ERROR, "bgscan: Could not find module " 64214501Srpaulo "matching the parameter '%s'", name); 65214501Srpaulo return -1; 66214501Srpaulo } 67214501Srpaulo 68214501Srpaulo wpa_s->bgscan_priv = ops->init(wpa_s, params, ssid); 69214501Srpaulo if (wpa_s->bgscan_priv == NULL) 70214501Srpaulo return -1; 71214501Srpaulo wpa_s->bgscan = ops; 72214501Srpaulo wpa_printf(MSG_DEBUG, "bgscan: Initialized module '%s' with " 73214501Srpaulo "parameters '%s'", ops->name, params); 74214501Srpaulo 75214501Srpaulo return 0; 76214501Srpaulo} 77214501Srpaulo 78214501Srpaulo 79214501Srpaulovoid bgscan_deinit(struct wpa_supplicant *wpa_s) 80214501Srpaulo{ 81214501Srpaulo if (wpa_s->bgscan && wpa_s->bgscan_priv) { 82214501Srpaulo wpa_printf(MSG_DEBUG, "bgscan: Deinitializing module '%s'", 83214501Srpaulo wpa_s->bgscan->name); 84214501Srpaulo wpa_s->bgscan->deinit(wpa_s->bgscan_priv); 85214501Srpaulo wpa_s->bgscan = NULL; 86214501Srpaulo wpa_s->bgscan_priv = NULL; 87214501Srpaulo } 88214501Srpaulo} 89214501Srpaulo 90214501Srpaulo 91214501Srpauloint bgscan_notify_scan(struct wpa_supplicant *wpa_s) 92214501Srpaulo{ 93214501Srpaulo if (wpa_s->bgscan && wpa_s->bgscan_priv) 94214501Srpaulo return wpa_s->bgscan->notify_scan(wpa_s->bgscan_priv); 95214501Srpaulo return 0; 96214501Srpaulo} 97214501Srpaulo 98214501Srpaulo 99214501Srpaulovoid bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s) 100214501Srpaulo{ 101214501Srpaulo if (wpa_s->bgscan && wpa_s->bgscan_priv) 102214501Srpaulo wpa_s->bgscan->notify_beacon_loss(wpa_s->bgscan_priv); 103214501Srpaulo} 104214501Srpaulo 105214501Srpaulo 106214501Srpaulovoid bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above) 107214501Srpaulo{ 108214501Srpaulo if (wpa_s->bgscan && wpa_s->bgscan_priv) 109214501Srpaulo wpa_s->bgscan->notify_signal_change(wpa_s->bgscan_priv, above); 110214501Srpaulo} 111