mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 13:02:44 +01:00
ap: Add AP mode api
Very basic WPA2-PSK only access point mode API with stubs of the start and stop functions.
This commit is contained in:
parent
275cc2789d
commit
212bc08104
@ -87,7 +87,8 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h \
|
||||
src/watchlist.h src/watchlist.c \
|
||||
src/ftutil.h src/ftutil.c \
|
||||
src/iwd.h src/eap-sim.c src/eap-aka.c \
|
||||
src/simutil.h src/simutil.c
|
||||
src/simutil.h src/simutil.c \
|
||||
src/ap.h src/ap.c
|
||||
src_iwd_LDADD = ell/libell-internal.la -ldl
|
||||
|
||||
dist_sysconf_DATA = src/iwd.conf
|
||||
|
142
src/ap.c
Normal file
142
src/ap.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
*
|
||||
* Wireless daemon for Linux
|
||||
*
|
||||
* Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#include <ell/ell.h>
|
||||
|
||||
#include "src/iwd.h"
|
||||
#include "src/device.h"
|
||||
#include "src/wiphy.h"
|
||||
#include "src/ie.h"
|
||||
#include "src/ap.h"
|
||||
|
||||
struct ap_state {
|
||||
struct device *device;
|
||||
char *ssid;
|
||||
char *psk;
|
||||
ap_event_cb_t event_cb;
|
||||
int channel;
|
||||
unsigned int ciphers;
|
||||
uint32_t beacon_interval;
|
||||
struct l_uintset *rates;
|
||||
};
|
||||
|
||||
static struct l_genl_family *nl80211 = NULL;
|
||||
|
||||
static struct l_queue *ap_list = NULL;
|
||||
|
||||
static void ap_free(void *data)
|
||||
{
|
||||
struct ap_state *ap = data;
|
||||
|
||||
l_free(ap->ssid);
|
||||
memset(ap->psk, 0, strlen(ap->psk));
|
||||
l_free(ap->psk);
|
||||
|
||||
if (ap->rates)
|
||||
l_uintset_free(ap->rates);
|
||||
|
||||
l_free(ap);
|
||||
}
|
||||
|
||||
static void ap_stopped(struct ap_state *ap)
|
||||
{
|
||||
ap->event_cb(ap->device, AP_EVENT_STOPPED);
|
||||
|
||||
ap_free(ap);
|
||||
|
||||
l_queue_remove(ap_list, ap);
|
||||
}
|
||||
|
||||
static bool ap_match_device(const void *a, const void *b)
|
||||
{
|
||||
const struct ap_state *ap = a;
|
||||
|
||||
return ap->device == b;
|
||||
}
|
||||
|
||||
int ap_start(struct device *device, const char *ssid, const char *psk,
|
||||
ap_event_cb_t event_cb)
|
||||
{
|
||||
struct wiphy *wiphy = device_get_wiphy(device);
|
||||
struct ap_state *ap;
|
||||
|
||||
if (l_queue_find(ap_list, ap_match_device, device))
|
||||
return -EEXIST;
|
||||
|
||||
ap = l_new(struct ap_state, 1);
|
||||
ap->device = device;
|
||||
ap->ssid = l_strdup(ssid);
|
||||
ap->psk = l_strdup(psk);
|
||||
ap->event_cb = event_cb;
|
||||
/* TODO: Start a Get Survey to decide the channel */
|
||||
ap->channel = 6;
|
||||
/* TODO: Add all ciphers supported by wiphy */
|
||||
ap->ciphers = wiphy_select_cipher(wiphy, 0xffff);
|
||||
ap->beacon_interval = 100;
|
||||
/* TODO: Use actual supported rates */
|
||||
ap->rates = l_uintset_new(200);
|
||||
l_uintset_put(ap->rates, 2); /* 1 Mbps*/
|
||||
l_uintset_put(ap->rates, 11); /* 5.5 Mbps*/
|
||||
l_uintset_put(ap->rates, 22); /* 11 Mbps*/
|
||||
|
||||
if (!ap_list)
|
||||
ap_list = l_queue_new();
|
||||
|
||||
l_queue_push_tail(ap_list, ap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ap_stop(struct device *device)
|
||||
{
|
||||
struct ap_state *ap = l_queue_find(ap_list, ap_match_device, device);
|
||||
|
||||
if (!ap)
|
||||
return -ENODEV;
|
||||
|
||||
/* TODO: Send NL80211_CMD_STOP_AP */
|
||||
ap_stopped(ap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ap_init(struct l_genl_family *in)
|
||||
{
|
||||
nl80211 = in;
|
||||
|
||||
/*
|
||||
* TODO: Check wiphy supports AP mode, supported channels,
|
||||
* check wiphy's NL80211_ATTR_TX_FRAME_TYPES.
|
||||
*/
|
||||
}
|
||||
|
||||
void ap_exit(void)
|
||||
{
|
||||
l_queue_destroy(ap_list, ap_free);
|
||||
}
|
37
src/ap.h
Normal file
37
src/ap.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
*
|
||||
* Wireless daemon for Linux
|
||||
*
|
||||
* Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
enum ap_event {
|
||||
AP_EVENT_STARTED,
|
||||
AP_EVENT_STOPPED,
|
||||
};
|
||||
|
||||
struct device;
|
||||
|
||||
typedef void (*ap_event_cb_t)(struct device *device, enum ap_event event_type);
|
||||
|
||||
int ap_start(struct device *device, const char *ssid, const char *psk,
|
||||
ap_event_cb_t event_cb);
|
||||
int ap_stop(struct device *device);
|
||||
|
||||
void ap_init(struct l_genl_family *in);
|
||||
void ap_exit(void);
|
@ -43,6 +43,7 @@
|
||||
#include "src/wsc.h"
|
||||
#include "src/knownnetworks.h"
|
||||
#include "src/rfkill.h"
|
||||
#include "src/ap.h"
|
||||
|
||||
#include "src/backtrace.h"
|
||||
|
||||
@ -144,12 +145,15 @@ static void nl80211_appeared(void *user_data)
|
||||
|
||||
if (!wsc_init(nl80211))
|
||||
l_error("Unable to init WSC functionality");
|
||||
|
||||
ap_init(nl80211);
|
||||
}
|
||||
|
||||
static void nl80211_vanished(void *user_data)
|
||||
{
|
||||
l_debug("Lost nl80211 interface");
|
||||
|
||||
ap_exit();
|
||||
wsc_exit();
|
||||
scan_exit();
|
||||
netdev_exit();
|
||||
|
Loading…
Reference in New Issue
Block a user