Skip to content

Commit

Permalink
wifi: support adding p2p0 when starting wpa_supplicant
Browse files Browse the repository at this point in the history
For TI wlan chips in p2p mode we need this omapzoom cherry-pick
to start p2p0 correctly.

http://www.omapzoom.org/?p=platform/hardware/libhardware_legacy.git;a=commit;h=ccb4c24db795059f1df365d313d80c6b269bc55e
By: Arik Nemtsov <arik@wizery.com>
On: Tue, 31 Jul 2012 21:21:20

Original commit description:
Add p2p0 using an NL80211 command when wpa_supplicant is started, and
p2p_supported is enabled.

Change-Id: Ibc0ad138513f024672642cc5764a81510aa38625
Signed-off-by: Hashcode <hashcode0f@gmail.com>

From: Barak Bercovitz <barak@wizery.com>
Date: Fri, 18 Oct 2013 12:41:32 +0300
Subject: [PATCH] wifi: remove p2p interface on supplicant stop

wifi: remove p2p interface on supplicant stop

remove p2p interface on wpa_supplicant stop
so next time it is started it won't fail when trying
to create p2p again

Change-Id: I7a4c5e9a82a013afc75548d175d5850d67fcd927
  • Loading branch information
rmcc authored and Steve Kondik committed Sep 1, 2016
1 parent 59563c2 commit e6e11ab
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include

LOCAL_CFLAGS += -DQEMU_HARDWARE -Wno-unused-parameter -Wno-gnu-designator

ifdef USES_TI_MAC80211
ifneq ($(wildcard external/libnl),)
LOCAL_SHARED_LIBRARIES += libnl
LOCAL_C_INCLUDES += external/libnl/include
else
LOCAL_STATIC_LIBRARIES := libnl_2
LOCAL_C_INCLUDES += external/libnl-headers
endif
endif

QEMU_HARDWARE := true

LOCAL_SHARED_LIBRARIES += libdl
Expand Down
247 changes: 247 additions & 0 deletions wifi/wifi.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@
#include <unistd.h>
#include <poll.h>
#include <sys/syscall.h>

#ifdef USES_TI_MAC80211
#include <dirent.h>
#include <net/if.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include <netlink/msg.h>
#include <netlink/attr.h>
#include <linux/nl80211.h>
#endif

#include "hardware_legacy/wifi.h"
#include "wifi_fst.h"
#ifdef LIBWPA_CLIENT_EXISTS
Expand Down Expand Up @@ -75,6 +87,13 @@ static char primary_iface[PROPERTY_VALUE_MAX];
// TODO: use new ANDROID_SOCKET mechanism, once support for multiple
// sockets is in

#ifdef USES_TI_MAC80211
#define P2P_INTERFACE "p2p0"
struct nl_sock *nl_soc;
struct nl_cache *nl_cache;
struct genl_family *nl80211;
#endif

#ifndef WIFI_DRIVER_MODULE_ARG
#define WIFI_DRIVER_MODULE_ARG ""
#endif
Expand Down Expand Up @@ -443,6 +462,220 @@ int ensure_config_file_exists(const char *config_file, const char *config_file_t
return 0;
}

#ifdef USES_TI_MAC80211
static int init_nl()
{
int err;

nl_soc = nl_socket_alloc();
if (!nl_soc) {
ALOGE("Failed to allocate netlink socket.");
return -ENOMEM;
}

if (genl_connect(nl_soc)) {
ALOGE("Failed to connect to generic netlink.");
err = -ENOLINK;
goto out_handle_destroy;
}

genl_ctrl_alloc_cache(nl_soc, &nl_cache);
if (!nl_cache) {
ALOGE("Failed to allocate generic netlink cache.");
err = -ENOMEM;
goto out_handle_destroy;
}

nl80211 = genl_ctrl_search_by_name(nl_cache, "nl80211");
if (!nl80211) {
ALOGE("nl80211 not found.");
err = -ENOENT;
goto out_cache_free;
}

return 0;

out_cache_free:
nl_cache_free(nl_cache);
out_handle_destroy:
nl_socket_free(nl_soc);
return err;
}

static void deinit_nl()
{
genl_family_put(nl80211);
nl_cache_free(nl_cache);
nl_socket_free(nl_soc);
}

// ignore the "." and ".." entries
static int dir_filter(const struct dirent *name)
{
if (0 == strcmp("..", name->d_name) ||
0 == strcmp(".", name->d_name))
return 0;

return 1;
}

// lookup the only active phy
int phy_lookup()
{
char buf[200];
int fd, pos;
struct dirent **namelist;
int n, i;

n = scandir("/sys/class/ieee80211", &namelist, dir_filter,
(int (*)(const struct dirent**, const struct dirent**))alphasort);
if (n != 1) {
ALOGE("unexpected - found %d phys in /sys/class/ieee80211", n);
for (i = 0; i < n; i++)
free(namelist[i]);
free(namelist);
return -1;
}

snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index",
namelist[0]->d_name);
free(namelist[0]);
free(namelist);

fd = open(buf, O_RDONLY);
if (fd < 0)
return -1;
pos = read(fd, buf, sizeof(buf) - 1);
if (pos < 0) {
close(fd);
return -1;
}
buf[pos] = '\0';
close(fd);
return atoi(buf);
}

int nl_error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
{
int *ret = (int *)arg;
*ret = err->error;
return NL_STOP;
}

int nl_finish_handler(struct nl_msg *msg, void *arg)
{
int *ret = (int *)arg;
*ret = 0;
return NL_SKIP;
}

int nl_ack_handler(struct nl_msg *msg, void *arg)
{
int *ret = (int *)arg;
*ret = 0;
return NL_STOP;
}

static int execute_nl_interface_cmd(const char *iface,
enum nl80211_iftype type,
uint8_t cmd)
{
struct nl_cb *cb;
struct nl_msg *msg;
int devidx = 0;
int err;
int add_interface = (cmd == NL80211_CMD_NEW_INTERFACE);

if (add_interface) {
devidx = phy_lookup();
} else {
devidx = if_nametoindex(iface);
if (devidx == 0) {
ALOGE("failed to translate ifname to idx");
return -errno;
}
}

msg = nlmsg_alloc();
if (!msg) {
ALOGE("failed to allocate netlink message");
return 2;
}

cb = nl_cb_alloc(NL_CB_DEFAULT);
if (!cb) {
ALOGE("failed to allocate netlink callbacks");
err = 2;
goto out_free_msg;
}

genlmsg_put(msg, 0, 0, genl_family_get_id(nl80211), 0, 0, cmd, 0);

if (add_interface) {
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx);
} else {
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
}

if (add_interface) {
NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, iface);
NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type);
}

err = nl_send_auto_complete(nl_soc, msg);
if (err < 0)
goto out;

err = 1;

nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &err);
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &err);

while (err > 0)
nl_recvmsgs(nl_soc, cb);
out:
nl_cb_put(cb);
out_free_msg:
nlmsg_free(msg);
return err;
nla_put_failure:
ALOGW("building message failed");
return 2;
}

int add_remove_p2p_interface(int add)
{
int ret;

ret = init_nl();
if (ret != 0)
return ret;

if (add) {
ret = execute_nl_interface_cmd(P2P_INTERFACE, NL80211_IFTYPE_STATION,
NL80211_CMD_NEW_INTERFACE);
if (ret != 0) {
ALOGE("could not add P2P interface: %d", ret);
goto cleanup;
}
} else {
ret = execute_nl_interface_cmd(P2P_INTERFACE, NL80211_IFTYPE_STATION,
NL80211_CMD_DEL_INTERFACE);
if (ret != 0) {
ALOGE("could not remove P2P interface: %d", ret);
goto cleanup;
}
}

ALOGD("added/removed p2p interface. add: %d", add);

cleanup:
deinit_nl();
return ret;
}
#endif /* USES_TI_MAC80211 */

int wifi_start_supplicant(int p2p_supported)
{
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
Expand Down Expand Up @@ -485,6 +718,13 @@ int wifi_start_supplicant(int p2p_supported)
ALOGE("Wi-Fi entropy file was not created");
}

#ifdef USES_TI_MAC80211
if (p2p_supported && add_remove_p2p_interface(1) < 0) {
ALOGE("Wi-Fi - could not create p2p interface");
return -1;
}
#endif

/* Clear out any stale socket files that might be left over. */
wpa_ctrl_cleanup();

Expand Down Expand Up @@ -549,6 +789,13 @@ int wifi_stop_supplicant(int p2p_supported)
return 0;
}

#ifdef USES_TI_MAC80211
if (p2p_supported && add_remove_p2p_interface(0) < 0) {
ALOGE("Wi-Fi - could not remove p2p interface");
return -1;
}
#endif

property_set("ctl.stop", supplicant_name);
sched_yield();

Expand Down

0 comments on commit e6e11ab

Please sign in to comment.