Commit 4d3790a1 authored by Rob Shannon's avatar Rob Shannon

Woops missed some stuff

parent fc694730
......@@ -511,7 +511,5 @@ PRODUCT_COPY_FILES += \
###VENDOR END###
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/proprietary/bin/downloader:/system/bin/downloader \
$(LOCAL_PATH)/proprietary/bin/getnvm.sh:/system/bin/getnvm.sh \
$(LOCAL_PATH)/proprietary/bin/ds_fmc_appd:/system/bin/s_fmc_appd \
$(LOCAL_PATH)/proprietary/bin/qmuxd:/system/bin/qmuxd \
$(LOCAL_PATH)/proprietary/bin/diag_uart_log:/system/bin/diag_uart_log
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
bitrate.c \
connect.c \
cqm.c \
event.c \
genl.c \
ibss.c \
info.c \
interface.c \
iw.c \
link.c \
mesh.c \
mpath.c \
offch.c \
phy.c \
ps.c \
reason.c \
reg.c \
scan.c \
sections.c \
station.c \
status.c \
survey.c \
util.c \
roc.c \
wowlan.c \
version.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
external/libnl-headers
LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libnl-headers \
$(TARGET_PROJECT_INCLUDES) $(TARGET_C_INCLUDES)
LOCAL_CFLAGS := $(TARGET_GLOBAL_CFLAGS) $(PRIVATE_ARM_CFLAGS)
LOCAL_CFLAGS += -DCONFIG_LIBNL20=y
#LOCAL_SHARED_LIBRARIES += libnl_2
LOCAL_STATIC_LIBRARIES += libnl_2
LOCAL_MODULE := iw
LOCAL_LDFLAGS := -Wl,--no-gc-sections
LOCAL_MODULE_TAGS := debug
#LOCAL_SHARED_LIBRARIES := libnl
LOCAL_STATIC_LIBRARIES := libnl_2
LOCAL_MODULE := iw
include $(BUILD_EXECUTABLE)
Copyright (c) 2007, 2008 Johannes Berg
Copyright (c) 2007 Andy Lutomirski
Copyright (c) 2007 Mike Kershaw
Copyright (c) 2008-2009 Luis R. Rodriguez
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
This is 'iw', a tool to use nl80211.
To build iw, just enter 'make'. If that fails, set the
PKG_CONFIG_PATH environment variable to allow the Makefile
to find libnl.
'iw' is currently maintained at http://git.sipsolutions.net/iw.git/,
some more documentation is available at
http://wireless.kernel.org/en/users/Documentation/iw.
Please send all patches to Johannes Berg <johannes@sipsolutions.net>
and CC linux-wireless@vger.kernel.org for community review.
#include <errno.h>
#include "nl80211.h"
#include "iw.h"
static int handle_bitrates(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
struct nlattr *nl_rates, *nl_band;
int i;
bool have_legacy_24 = false, have_legacy_5 = false;
uint8_t legacy_24[32], legacy_5[32];
int n_legacy_24 = 0, n_legacy_5 = 0;
uint8_t *legacy = NULL;
int *n_legacy = NULL;
bool have_mcs_24 = false, have_mcs_5 = false;
#ifdef NL80211_TXRATE_MCS
uint8_t mcs_24[77], mcs_5[77];
int n_mcs_24 = 0, n_mcs_5 = 0;
uint8_t *mcs = NULL;
int *n_mcs = NULL;
#endif
enum {
S_NONE,
S_LEGACY,
S_MCS,
} parser_state = S_NONE;
for (i = 0; i < argc; i++) {
char *end;
double tmpd;
#ifdef NL80211_TXRATE_MCS
long tmpl;
#endif
if (strcmp(argv[i], "legacy-2.4") == 0) {
if (have_legacy_24)
return 1;
parser_state = S_LEGACY;
legacy = legacy_24;
n_legacy = &n_legacy_24;
have_legacy_24 = true;
} else if (strcmp(argv[i], "legacy-5") == 0) {
if (have_legacy_5)
return 1;
parser_state = S_LEGACY;
legacy = legacy_5;
n_legacy = &n_legacy_5;
have_legacy_5 = true;
}
#ifdef NL80211_TXRATE_MCS
else if (strcmp(argv[i], "mcs-2.4") == 0) {
if (have_mcs_24)
return 1;
parser_state = S_MCS;
mcs = mcs_24;
n_mcs = &n_mcs_24;
have_mcs_24 = true;
} else if (strcmp(argv[i], "mcs-5") == 0) {
if (have_mcs_5)
return 1;
parser_state = S_MCS;
mcs = mcs_5;
n_mcs = &n_mcs_5;
have_mcs_5 = true;
}
#endif
else switch (parser_state) {
case S_LEGACY:
tmpd = strtod(argv[i], &end);
if (*end != '\0')
return 1;
if (tmpd < 1 || tmpd > 255 * 2)
return 1;
legacy[(*n_legacy)++] = tmpd * 2;
break;
case S_MCS:
#ifdef NL80211_TXRATE_MCS
tmpl = strtol(argv[i], &end, 0);
if (*end != '\0')
return 1;
if (tmpl < 0 || tmpl > 255)
return 1;
mcs[(*n_mcs)++] = tmpl;
break;
#endif
default:
return 1;
}
}
nl_rates = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
if (!nl_rates)
goto nla_put_failure;
if (have_legacy_24 || have_mcs_24) {
nl_band = nla_nest_start(msg, NL80211_BAND_2GHZ);
if (!nl_band)
goto nla_put_failure;
if (have_legacy_24)
nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_24, legacy_24);
#ifdef NL80211_TXRATE_MCS
if (have_mcs_24)
nla_put(msg, NL80211_TXRATE_MCS, n_mcs_24, mcs_24);
#endif
nla_nest_end(msg, nl_band);
}
if (have_legacy_5 || have_mcs_5) {
nl_band = nla_nest_start(msg, NL80211_BAND_5GHZ);
if (!nl_band)
goto nla_put_failure;
if (have_legacy_5)
nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_5, legacy_5);
#ifdef NL80211_TXRATE_MCS
if (have_mcs_5)
nla_put(msg, NL80211_TXRATE_MCS, n_mcs_5, mcs_5);
#endif
nla_nest_end(msg, nl_band);
}
nla_nest_end(msg, nl_rates);
return 0;
nla_put_failure:
return -ENOBUFS;
}
#define DESCR_LEGACY "[legacy-<2.4|5> <legacy rate in Mbps>*]"
#ifdef NL80211_TXRATE_MCS
#define DESCR DESCR_LEGACY " [mcs-<2.4|5> <MCS index>*]"
#else
#define DESCR DESCR_LEGACY
#endif
COMMAND(set, bitrates, DESCR, NL80211_CMD_SET_TX_BITRATE_MASK, 0, CIB_NETDEV,
handle_bitrates,
"Sets up the specified rate masks.\n"
"Not passing any arguments would clear the existing mask (if any).");
#include <errno.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 "nl80211.h"
#include "iw.h"
static int iw_conn(struct nl80211_state *state, struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
char *end;
unsigned char bssid[6];
int freq;
if (argc < 1)
return 1;
/* SSID */
NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
argv++;
argc--;
/* freq */
if (argc) {
freq = strtoul(argv[0], &end, 10);
if (*end == '\0') {
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
argv++;
argc--;
}
}
/* bssid */
if (argc) {
if (mac_addr_a2n(bssid, argv[0]) == 0) {
NLA_PUT(msg, NL80211_ATTR_MAC, 6, bssid);
argv++;
argc--;
}
}
if (!argc)
return 0;
if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
return 1;
argv++;
argc--;
return parse_keys(msg, argv, argc);
nla_put_failure:
return -ENOSPC;
}
static int disconnect(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
return 0;
}
TOPLEVEL(disconnect, NULL,
NL80211_CMD_DISCONNECT, 0, CIB_NETDEV, disconnect,
"Disconnect from the current network.");
static int iw_connect(struct nl80211_state *state, struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
char **conn_argv, *dev = argv[0];
static const __u32 cmds[] = {
NL80211_CMD_CONNECT,
};
struct print_event_args printargs = { };
int conn_argc, err;
bool wait = false;
int i;
/* strip "wlan0 connect" */
argc -= 2;
argv += 2;
/* check -w */
if (argc && strcmp(argv[0], "-w") == 0) {
wait = true;
argc--;
argv++;
}
conn_argc = 3 + argc;
conn_argv = calloc(conn_argc, sizeof(*conn_argv));
if (!conn_argv)
return -ENOMEM;
err = __prepare_listen_events(state);
if (err)
return err;
conn_argv[0] = dev;
conn_argv[1] = "connect";
conn_argv[2] = "establish";
for (i = 0; i < argc; i++)
conn_argv[i + 3] = argv[i];
err = handle_cmd(state, II_NETDEV, conn_argc, conn_argv);
free(conn_argv);
if (err)
return err;
if (!wait)
return 0;
/*
* WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION
*
* This code has a bug:
*
* It is possible for a connect result message from another
* connect attempt to be processed here first, because we
* start listening to the multicast group before starting
* our own connect request, which may succeed but we get a
* fail message from a previous attempt that raced with us,
* or similar.
*
* The only proper way to fix this would be to listen to events
* before sending the command, and for the kernel to send the
* connect request or a cookie along with the event, so that you
* can match up whether the connect _you_ requested was finished
* or aborted.
*
* Alas, the kernel doesn't do that (yet).
*/
__do_listen_events(state, ARRAY_SIZE(cmds), cmds, &printargs);
return 0;
}
TOPLEVEL(connect, "[-w] <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1:6162636465]",
0, 0, CIB_NETDEV, iw_connect,
"Join the network with the given SSID (and frequency, BSSID).\n"
"With -w, wait for the connect to finish or fail.");
HIDDEN(connect, establish, "", NL80211_CMD_CONNECT, 0, CIB_NETDEV, iw_conn);
#include <errno.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 "nl80211.h"
#include "iw.h"
static int iw_cqm_rssi(struct nl80211_state *state, struct nl_cb *cb,
struct nl_msg *msg, int argc, char **argv)
{
struct nl_msg *cqm = NULL;
int thold = 0;
int hyst = 0;
int ret = -ENOSPC;
/* get the required args */
if (argc < 1 || argc > 2)
return 1;
if (strcmp(argv[0], "off")) {
thold = atoi(argv[0]);
if (thold == 0)
return -EINVAL;
if (argc == 2)
hyst = atoi(argv[1]);
}
/* connection quality monitor attributes */
cqm = nlmsg_alloc();
NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, thold);
NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hyst);
nla_put_nested(msg, NL80211_ATTR_CQM, cqm);
ret = 0;
nla_put_failure:
nlmsg_free(cqm);
return ret;
}
TOPLEVEL(cqm, "",
0, 0, CIB_NETDEV, NULL,
"Configure the WLAN connection quality monitor.\n");
COMMAND(cqm, rssi, "<threshold|off> [<hysteresis>]",
NL80211_CMD_SET_CQM, 0, CIB_NETDEV, iw_cqm_rssi,
"Set connection quality monitor RSSI threshold.\n");
This diff is collapsed.
/*
* This ought to be provided by libnl
*/
#include <asm/errno.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/genetlink.h>
#include "iw.h"
static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
void *arg)
{
int *ret = arg;
*ret = err->error;
return NL_STOP;
}
static int ack_handler(struct nl_msg *msg, void *arg)
{
int *ret = arg;
*ret = 0;
return NL_STOP;
}
struct handler_args {
const char *group;
int id;
};
static int family_handler(struct nl_msg *msg, void *arg)
{
struct handler_args *grp = arg;
struct nlattr *tb[CTRL_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *mcgrp;
int rem_mcgrp;
nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb[CTRL_ATTR_MCAST_GROUPS])
return NL_SKIP;
nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) {
struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX,
nla_data(mcgrp), nla_len(mcgrp), NULL);
if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME] ||
!tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID])
continue;
if (strncmp(nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]),
grp->group, nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])))
continue;
grp->id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]);
break;
}
return NL_SKIP;
}
int nl_get_multicast_id(struct nl_sock *sock, const char *family, const char *group)
{
struct nl_msg *msg;
struct nl_cb *cb;
int ret, ctrlid;
struct handler_args grp = {
.group = group,
.id = -ENOENT,
};
msg = nlmsg_alloc();
if (!msg)
return -ENOMEM;
cb = nl_cb_alloc(NL_CB_DEFAULT);
if (!cb) {
ret = -ENOMEM;
goto out_fail_cb;
}
ctrlid = genl_ctrl_resolve(sock, "nlctrl");
genlmsg_put(msg, 0, 0, ctrlid, 0,
0, CTRL_CMD_GETFAMILY, 0);
ret = -ENOBUFS;
NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
ret = nl_send_auto_complete(sock, msg);
if (ret < 0)
goto out;
ret = 1;
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &ret);
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &ret);
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, family_handler, &grp);
while (ret > 0)
nl_recvmsgs(sock, cb);
if (ret == 0)
ret = grp.id;
nla_put_failure:
out:
nl_cb_put(cb);
out_fail_cb:
nlmsg_free(msg);
return ret;
}
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
#include <errno.h>
#include <string.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 "nl80211.h"
#include "iw.h"
SECTION(ibss);
static int join_ibss(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
char *end;
unsigned char abssid[6];
unsigned char rates[NL80211_MAX_SUPP_RATES];
int n_rates = 0;
char *value = NULL, *sptr = NULL;
float rate;
int bintval;
if (argc < 2)
return 1;
/* SSID */
NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
argv++;
argc--;
/* freq */
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ,
strtoul(argv[0], &end, 10));
if (*end != '\0')
return 1;
argv++;
argc--;
if (argc && strcmp(argv[0], "fixed-freq") == 0) {
NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED);
argv++;
argc--;
}
if (argc) {
if (mac_addr_a2n(abssid, argv[0]) == 0) {
NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid);
argv++;
argc--;
}
}
if (argc > 1 && strcmp(argv[0], "beacon-interval") == 0) {
argv++;
argc--;
bintval = strtoul(argv[0], &end, 10);
if (*end != '\0')
return 1;
NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, bintval);
argv++;
argc--;
}
/* basic rates */
if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
argv++;
argc--;
value = strtok_r(argv[0], ",", &sptr);
while (value && n_rates < NL80211_MAX_SUPP_RATES) {
rate = strtod(value, &end);
rates[n_rates] = rate * 2;
/* filter out suspicious values */
if (*end != '\0' || !rates[n_rates] ||
rate*2 != rates[n_rates])
return 1;
n_rates++;
value = strtok_r(NULL, ",", &sptr);
}
NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, n_rates, rates);
argv++;
argc--;
}
/* multicast rate */
if (argc > 1 && strcmp(argv[0], "mcast-rate") == 0) {
argv++;
argc--;
rate = strtod(argv[0], &end);
if (*end != '\0')
return 1;
NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, (int)(rate * 10));
argv++;
argc--;
}
if (!argc)
return 0;
if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
return 1;
argv++;
argc--;
return parse_keys(msg, argv, argc);
nla_put_failure:
return -ENOSPC;
}
static int leave_ibss(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,