summaryrefslogtreecommitdiffstats
path: root/service/lib
diff options
context:
space:
mode:
authorVinit Deshapnde <vinitd@google.com>2014-05-07 16:29:44 -0700
committerVinit Deshapnde <vinitd@google.com>2014-05-07 21:16:11 -0700
commit7f9a15d554f69311a0db43347d6473a7c4c46e2e (patch)
tree7ed7762a1b97b41e208a3a65c1716f9f32ca8403 /service/lib
parentf22d23092ab37286a5ef9d257d5bb32c421d2669 (diff)
downloadandroid_frameworks_opt_net_wifi-7f9a15d554f69311a0db43347d6473a7c4c46e2e.tar.gz
android_frameworks_opt_net_wifi-7f9a15d554f69311a0db43347d6473a7c4c46e2e.tar.bz2
android_frameworks_opt_net_wifi-7f9a15d554f69311a0db43347d6473a7c4c46e2e.zip
More HAL functionality
This change implements JNI plugs for delivering events to WifiNative in framework. Also introduces a test utility. Also has updated Gscan.h which is made up-to-date with the promised functionatliy. Change-Id: I12dd6d9f171e01e4b23ce4839b4022acd5e599cb Conflicts: service/Android.mk
Diffstat (limited to 'service/lib')
-rw-r--r--service/lib/common.cpp4
-rw-r--r--service/lib/cpp_bindings.cpp186
-rw-r--r--service/lib/cpp_bindings.h6
-rw-r--r--service/lib/gscan.cpp93
-rw-r--r--service/lib/gscan.h96
-rw-r--r--service/lib/wifi_hal.cpp46
-rw-r--r--service/lib/wifi_hal.h2
7 files changed, 368 insertions, 65 deletions
diff --git a/service/lib/common.cpp b/service/lib/common.cpp
index 9a7f44757..ab99356d9 100644
--- a/service/lib/common.cpp
+++ b/service/lib/common.cpp
@@ -89,6 +89,8 @@ wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
{
hal_info *info = (hal_info *)handle;
+ ALOGD("registering command %d", id);
+
if (info->num_cmd < info->alloc_cmd) {
info->cmd[info->num_cmd].id = id;
info->cmd[info->num_cmd].cmd = cmd;
@@ -104,6 +106,8 @@ WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id)
{
hal_info *info = (hal_info *)handle;
+ ALOGD("un-registering command %d", id);
+
for (int i = 0; i < info->num_cmd; i++) {
if (info->cmd[i].id == id) {
WifiCommand *cmd = info->cmd[i].cmd;
diff --git a/service/lib/cpp_bindings.cpp b/service/lib/cpp_bindings.cpp
index 28d2552ae..08dd75424 100644
--- a/service/lib/cpp_bindings.cpp
+++ b/service/lib/cpp_bindings.cpp
@@ -17,15 +17,191 @@
#include <netlink-types.h>
#include <linux/nl80211.h>
+#include <ctype.h>
#include "wifi_hal.h"
#include "common.h"
#include "cpp_bindings.h"
+#define min(x,y) (((x) < (y)) ? (x) : (y))
+#define max(x,y) (((x) < (y)) ? (y) : (x))
+
+void appendFmt(char *buf, int &offset, const char *fmt, ...)
+{
+ va_list params;
+ va_start(params, fmt);
+ offset += vsprintf(buf + offset, fmt, params);
+ va_end(params);
+}
+
+#define C2S(x) case x: return #x;
+
+static const char *cmdToString(int cmd)
+{
+ switch (cmd) {
+ C2S(NL80211_CMD_UNSPEC)
+ C2S(NL80211_CMD_GET_WIPHY)
+ C2S(NL80211_CMD_SET_WIPHY)
+ C2S(NL80211_CMD_NEW_WIPHY)
+ C2S(NL80211_CMD_DEL_WIPHY)
+ C2S(NL80211_CMD_GET_INTERFACE)
+ C2S(NL80211_CMD_SET_INTERFACE)
+ C2S(NL80211_CMD_NEW_INTERFACE)
+ C2S(NL80211_CMD_DEL_INTERFACE)
+ C2S(NL80211_CMD_GET_KEY)
+ C2S(NL80211_CMD_SET_KEY)
+ C2S(NL80211_CMD_NEW_KEY)
+ C2S(NL80211_CMD_DEL_KEY)
+ C2S(NL80211_CMD_GET_BEACON)
+ C2S(NL80211_CMD_SET_BEACON)
+ C2S(NL80211_CMD_START_AP)
+ C2S(NL80211_CMD_STOP_AP)
+ C2S(NL80211_CMD_GET_STATION)
+ C2S(NL80211_CMD_SET_STATION)
+ C2S(NL80211_CMD_NEW_STATION)
+ C2S(NL80211_CMD_DEL_STATION)
+ C2S(NL80211_CMD_GET_MPATH)
+ C2S(NL80211_CMD_SET_MPATH)
+ C2S(NL80211_CMD_NEW_MPATH)
+ C2S(NL80211_CMD_DEL_MPATH)
+ C2S(NL80211_CMD_SET_BSS)
+ C2S(NL80211_CMD_SET_REG)
+ C2S(NL80211_CMD_REQ_SET_REG)
+ C2S(NL80211_CMD_GET_MESH_CONFIG)
+ C2S(NL80211_CMD_SET_MESH_CONFIG)
+ C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
+ C2S(NL80211_CMD_GET_REG)
+ C2S(NL80211_CMD_GET_SCAN)
+ C2S(NL80211_CMD_TRIGGER_SCAN)
+ C2S(NL80211_CMD_NEW_SCAN_RESULTS)
+ C2S(NL80211_CMD_SCAN_ABORTED)
+ C2S(NL80211_CMD_REG_CHANGE)
+ C2S(NL80211_CMD_AUTHENTICATE)
+ C2S(NL80211_CMD_ASSOCIATE)
+ C2S(NL80211_CMD_DEAUTHENTICATE)
+ C2S(NL80211_CMD_DISASSOCIATE)
+ C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
+ C2S(NL80211_CMD_REG_BEACON_HINT)
+ C2S(NL80211_CMD_JOIN_IBSS)
+ C2S(NL80211_CMD_LEAVE_IBSS)
+ C2S(NL80211_CMD_TESTMODE)
+ C2S(NL80211_CMD_CONNECT)
+ C2S(NL80211_CMD_ROAM)
+ C2S(NL80211_CMD_DISCONNECT)
+ C2S(NL80211_CMD_SET_WIPHY_NETNS)
+ C2S(NL80211_CMD_GET_SURVEY)
+ C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
+ C2S(NL80211_CMD_SET_PMKSA)
+ C2S(NL80211_CMD_DEL_PMKSA)
+ C2S(NL80211_CMD_FLUSH_PMKSA)
+ C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
+ C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
+ C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
+ C2S(NL80211_CMD_REGISTER_FRAME)
+ C2S(NL80211_CMD_FRAME)
+ C2S(NL80211_CMD_FRAME_TX_STATUS)
+ C2S(NL80211_CMD_SET_POWER_SAVE)
+ C2S(NL80211_CMD_GET_POWER_SAVE)
+ C2S(NL80211_CMD_SET_CQM)
+ C2S(NL80211_CMD_NOTIFY_CQM)
+ C2S(NL80211_CMD_SET_CHANNEL)
+ C2S(NL80211_CMD_SET_WDS_PEER)
+ C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
+ C2S(NL80211_CMD_JOIN_MESH)
+ C2S(NL80211_CMD_LEAVE_MESH)
+ C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
+ C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
+ C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
+ C2S(NL80211_CMD_GET_WOWLAN)
+ C2S(NL80211_CMD_SET_WOWLAN)
+ C2S(NL80211_CMD_START_SCHED_SCAN)
+ C2S(NL80211_CMD_STOP_SCHED_SCAN)
+ C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
+ C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
+ C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
+ C2S(NL80211_CMD_PMKSA_CANDIDATE)
+ C2S(NL80211_CMD_TDLS_OPER)
+ C2S(NL80211_CMD_TDLS_MGMT)
+ C2S(NL80211_CMD_UNEXPECTED_FRAME)
+ C2S(NL80211_CMD_PROBE_CLIENT)
+ C2S(NL80211_CMD_REGISTER_BEACONS)
+ C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
+ C2S(NL80211_CMD_SET_NOACK_MAP)
+ C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
+ C2S(NL80211_CMD_START_P2P_DEVICE)
+ C2S(NL80211_CMD_STOP_P2P_DEVICE)
+ C2S(NL80211_CMD_CONN_FAILED)
+ C2S(NL80211_CMD_SET_MCAST_RATE)
+ C2S(NL80211_CMD_SET_MAC_ACL)
+ C2S(NL80211_CMD_RADAR_DETECT)
+ C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
+ C2S(NL80211_CMD_UPDATE_FT_IES)
+ C2S(NL80211_CMD_FT_EVENT)
+ C2S(NL80211_CMD_CRIT_PROTOCOL_START)
+ C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
+ //C2S(NL80211_CMD_GET_COALESCE)
+ //C2S(NL80211_CMD_SET_COALESCE)
+ //C2S(NL80211_CMD_CHANNEL_SWITCH)
+ //C2S(NL80211_CMD_VENDOR)
+ //C2S(NL80211_CMD_SET_QOS_MAP)
+ default:
+ return "NL80211_CMD_UNKNOWN";
+ }
+}
+
+void WifiEvent::log() {
+ parse();
+
+ byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
+ int len = genlmsg_attrlen(mHeader, 0);
+ ALOGD("cmd = %s, len = %d", get_cmdString(), len);
+
+ for (int i = 0; i < len; i += 16) {
+ char line[81];
+ int linelen = min(16, len - i);
+ int offset = 0;
+ appendFmt(line, offset, "%02x", data[i]);
+ for (int j = 1; j < linelen; j++) {
+ appendFmt(line, offset, " %02x", data[i+j]);
+ }
+
+ for (int j = linelen; j < 16; j++) {
+ appendFmt(line, offset, " ");
+ }
+
+ line[23] = '-';
+
+ appendFmt(line, offset, " ");
+
+ for (int j = 0; j < linelen; j++) {
+ if (isprint(data[i+j])) {
+ appendFmt(line, offset, "%c", data[i+j]);
+ } else {
+ appendFmt(line, offset, "-");
+ }
+ }
+
+ ALOGD(line);
+ }
+
+ ALOGD("-- End of message --");
+}
+
+const char *WifiEvent::get_cmdString() {
+ return cmdToString(get_cmd());
+}
+
+
int WifiEvent::parse() {
+ if (mHeader != NULL) {
+ return WIFI_SUCCESS;
+ }
mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
- return nla_parse(mAttributes, NL80211_ATTR_MAX, genlmsg_attrdata(mHeader, 0),
+ int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
genlmsg_attrlen(mHeader, 0), NULL);
+
+ ALOGD("event len = %d", nlmsg_hdr(mMsg)->nlmsg_len);
+ return result;
}
int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
@@ -90,6 +266,9 @@ out:
}
int WifiCommand::requestEvent(int cmd) {
+
+ ALOGD("requesting event %d", cmd);
+
int res = wifi_register_handler(mInfo, cmd, event_handler, this);
if (res < 0) {
return res;
@@ -99,10 +278,13 @@ int WifiCommand::requestEvent(int cmd) {
if (res < 0)
goto out;
+ ALOGD("waiting for response %d", cmd);
+
res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
if (res < 0)
goto out;
+ ALOGD("waiting for event %d", cmd);
res = mCondition.wait();
if (res < 0)
goto out;
@@ -154,7 +336,7 @@ int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
WifiEvent event(msg);
int res = event.parse();
if (res < 0) {
- ALOGE("Failed to parse reply message = %d", res);
+ ALOGE("Failed to parse event = %d", res);
res = NL_SKIP;
} else {
res = cmd->handleEvent(event);
diff --git a/service/lib/cpp_bindings.h b/service/lib/cpp_bindings.h
index 525742cab..45db5dbe1 100644
--- a/service/lib/cpp_bindings.h
+++ b/service/lib/cpp_bindings.h
@@ -15,11 +15,15 @@ private:
public:
WifiEvent(nl_msg *msg) {
mMsg = msg;
+ mHeader = NULL;
+ memset(mAttributes, 0, sizeof(mAttributes));
}
~WifiEvent() {
/* don't destroy mMsg; it doesn't belong to us */
}
+ void log();
+
int parse();
genlmsghdr *header() {
@@ -30,6 +34,8 @@ public:
return mHeader->cmd;
}
+ const char *get_cmdString();
+
nlattr ** attributes() {
return mAttributes;
}
diff --git a/service/lib/gscan.cpp b/service/lib/gscan.cpp
index f6ce57b0b..3b2eecab7 100644
--- a/service/lib/gscan.cpp
+++ b/service/lib/gscan.cpp
@@ -71,47 +71,67 @@ typedef enum {
class ScanCommand : public WifiCommand
{
private:
- static const unsigned int MAX_CHANNELS = 64;
- int mChannels[MAX_CHANNELS];
- int mNumChannels;
- IScanResultsHandler mHandler;
- static const unsigned int MAX_RESULTS = 64;
+ static const unsigned int MAX_BUCKETS = 8;
+ wifi_scan_bucket_spec mBuckets[MAX_BUCKETS];
+ int mNumBuckets;
+ wifi_scan_result_handler mHandler;
+ static const unsigned int MAX_RESULTS = 1024;
wifi_scan_result mResults[MAX_RESULTS];
public:
- ScanCommand(wifi_handle handle, int id, int *channels, unsigned n,
- IScanResultsHandler handler)
+ ScanCommand(wifi_handle handle, int id, wifi_scan_bucket_spec *buckets, unsigned n,
+ wifi_scan_result_handler handler)
: WifiCommand(handle, id), mHandler(handler)
{
- mNumChannels = n > MAX_CHANNELS ? MAX_CHANNELS : n;
- for (int i = 0; i < mNumChannels; i++) {
- mChannels[i] = channels[i];
+ mNumBuckets = n > MAX_BUCKETS ? MAX_BUCKETS : n;
+ for (int i = 0; i < mNumBuckets; i++) {
+ mBuckets[i] = buckets[i];
}
}
virtual int create() {
- int ret = mMsg.create(NL80211_CMD_START_SCHED_SCAN, 0, 0);
+ ALOGD("Creating message to scan");
+
+ int ret = mMsg.create(NL80211_CMD_TRIGGER_SCAN, 0, 0);
if (ret < 0) {
return ret;
}
+
+ mMsg.put_u32(NL80211_ATTR_IFINDEX, 0);
+
struct nlattr * attr = mMsg.attr_start(NL80211_ATTR_SCAN_FREQUENCIES);
- for (int i = 0; i < mNumChannels; i++) {
- ret = mMsg.put_u32(i + 1, mChannels[i]);
- if (ret < 0) {
- return ret;
+ int channel_id = 0;
+ for (int i = 0; i < mNumBuckets; i++) {
+ wifi_scan_bucket_spec &bucket = mBuckets[i];
+ for (int j = 0; j < bucket.num_channels; j++) {
+ ret = mMsg.put_u32(channel_id++, bucket.channels[j].channel);
+ if (ret < 0) {
+ return ret;
+ }
}
}
+
mMsg.attr_end(attr);
- mMsg.put_u32(NL80211_ATTR_SCAN_FLAGS, NL80211_SCAN_FLAG_FLUSH);
+ // mMsg.put_u32(NL80211_ATTR_SCAN_FLAGS, NL80211_SCAN_FLAG_FLUSH);
return ret;
}
int start() {
- return requestEvent(NL80211_CMD_SCHED_SCAN_RESULTS);
+ registerHandler(NL80211_CMD_NEW_SCAN_RESULTS);
+
+ ALOGD("Requesting events to scheduled scan");
+ int result = requestResponse();
+
+ if (result != WIFI_SUCCESS) {
+ ALOGD("failed to start scan; result = %d", result);
+ }
+
+ return result;
}
virtual int cancel() {
/* TODO: send another command to the driver to cancel the scan */
- wifi_unregister_handler(mInfo, NL80211_CMD_SCHED_SCAN_RESULTS);
+ ALOGD("Cancelling scheduled scan");
+ unregisterHandler(NL80211_CMD_NEW_SCAN_RESULTS);
return WIFI_SUCCESS;
}
@@ -123,16 +143,38 @@ public:
virtual int handleEvent(WifiEvent event) {
ALOGI("Got a scan results event");
- int rem = 0, i = 0;
+ event.log();
+ nlattr **attributes = event.attributes();
+ for (int i = 0; i < NL80211_ATTR_MAX; i++) {
+ nlattr *attr = event.get_attribute(i);
+ if (attr != NULL) {
+ ALOGI("Found attribute : %d", i);
+ }
+ }
+
+ nlattr *attr = event.get_attribute(NL80211_ATTR_SCAN_SSIDS);
+ if (event.get_attribute(NL80211_ATTR_SCAN_SSIDS) == NULL) {
+ ALOGI("No SSIDs found");
+ return NL_SKIP;
+ }
+
+ ALOGI("SSID attribute size = %d", event.len(NL80211_ATTR_SCAN_SSIDS));
+
+ int rem = 0, i = 0;
nl_iterator it(event.get_attribute(NL80211_ATTR_SCAN_SSIDS));
- for ( ; it.has_next(); it.next()) {
+ for ( ; it.has_next(); it.next(), i++) {
struct nlattr *attr = it.get();
wifi_scan_result *result = &mResults[i];
char *ssid = (char *)nla_data(attr);
int len = nla_len(attr);
- memcpy(result->ssid, ssid, len);
- ssid[len] = 0;
+ if (len < (int)sizeof(result->ssid)) {
+ memcpy(result->ssid, ssid, len);
+ result->ssid[len] = 0;
+ ALOGI("Found SSID : len = %d, value = %s", len, result->ssid);
+ } else {
+ ALOGI("Ignroed SSID : len = %d", len);
+ }
}
(*mHandler.on_scan_results)(id(), i, mResults);
@@ -144,19 +186,22 @@ wifi_error wifi_start_gscan(
wifi_request_id id,
wifi_interface_handle iface,
wifi_scan_cmd_params params,
- IScanResultsHandler handler)
+ wifi_scan_result_handler handler)
{
interface_info *iinfo = (interface_info *)iface;
wifi_handle handle = iinfo->handle;
hal_info *info = (hal_info *)handle;
- ScanCommand *cmd = new ScanCommand(handle, id, params.channels, params.num_channels, handler);
+ ALOGD("Starting GScan, halHandle = %p", handle);
+
+ ScanCommand *cmd = new ScanCommand(handle, id, params.buckets, params.num_buckets, handler);
wifi_register_cmd(handle, id, cmd);
return (wifi_error)cmd->start();
}
wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface)
{
+ ALOGD("Stopping GScan");
interface_info *iinfo = (interface_info *)iface;
wifi_handle handle = iinfo->handle;
hal_info *info = (hal_info *)handle;
diff --git a/service/lib/gscan.h b/service/lib/gscan.h
index 43da69ea9..564e8f35a 100644
--- a/service/lib/gscan.h
+++ b/service/lib/gscan.h
@@ -6,11 +6,36 @@
/* AP Scans */
+typedef enum {
+ WIFI_BAND_UNSPECIFIED,
+ WIFI_BAND_BG, // 2.4 GHz
+ WIFI_BAND_A, // 5 GHz without DFS
+ WIFI_BAND_A_WITH_DFS, // 5 GHz with DFS
+ WIFI_BAND_ABG, // 2.4 GHz + 5 GHz; no DFS
+ WIFI_BAND_ABG_WITH_DFS, // 2.4 GHz + 5 GHz with DFS
+} wifi_band;
+
+wifi_error wifi_get_valid_channels(wifi_handle handle,
+ int band, int size, wifi_channel *channels, int *num);
+
+typedef struct {
+ int max_scan_cache_size; // in number of scan results??
+ int max_scan_buckets;
+ int max_ap_cache_per_scan;
+ int max_rssi_sample_size;
+ int max_scan_reporting_threshold; // in number of scan results??
+ int max_hotlist_aps;
+ int max_significant_wifi_change_aps;
+} wifi_gscan_capabilities;
+
+wifi_error wifi_get_gscan_capabilities(wifi_handle handle,
+ wifi_gscan_capabilities *capabilities);
+
typedef struct {
wifi_timestamp ts; // Time of discovery
- char ssid[32]; // May not be null terminated
+ char ssid[32+1]; // null terminated
mac_addr bssid;
- wifi_channel channel; // channel number (includes all bands)
+ wifi_channel channel; // channel frequency in MHz
wifi_rssi rssi; // in db
wifi_timespan rtt; // in nanoseconds
wifi_timespan rtt_sd; // standard deviation in rtt
@@ -20,44 +45,79 @@ typedef struct {
typedef struct {
void (*on_scan_results) (wifi_request_id id, unsigned num_results, wifi_scan_result *results);
-} IScanResultsHandler;
+} wifi_scan_result_handler;
+
+typedef struct {
+ wifi_channel channel; // frequency
+ int dwellTimeMs; // dwell time hint
+ int passive; // 0 => active, 1 => passive scan; ignored for DFS
+ /* Add channel class */
+} wifi_scan_channel_spec;
typedef struct {
+ int bucket; // bucket index, 0 based
+ wifi_band band; // when UNSPECIFIED, use channel list
int num_channels;
- wifi_channel channels[]; // channels to scan; these may include DFS channels
- int single_shot; // boolean, 0 => repeated, 1 => single
- int frequency; // desired frequency, in scans per minute; if this is too
- // high, the firmware should choose to generate results as
+ wifi_scan_channel_spec channels[8]; // channels to scan; these may include DFS channels
+ int period; // desired period, in millisecond; if this is too
+ // low, the firmware should choose to generate results as
// fast as it can instead of failing the command
+ byte report_events; // 1 => report events after each scan
+
+} wifi_scan_bucket_spec;
+
+typedef struct {
+ int period; // base timer period
+ int num_buckets; // maximum 8
+ wifi_scan_bucket_spec buckets[];
+ int max_ap_per_scan;
+ int report_threshold; // in %, when buffer is this much full, wake up AP
} wifi_scan_cmd_params;
wifi_error wifi_start_gscan(wifi_request_id id, wifi_interface_handle iface,
- wifi_scan_cmd_params params, IScanResultsHandler handler);
+ wifi_scan_cmd_params params, wifi_scan_result_handler handler);
wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface);
-/*
- * Expect multiple scans to be active at the same time; the firmware is free to schedule scans
- * as it sees fit; as long as frequency requirements are met. This will allow us to have separate
- * schedules for DFS scans versus 1/6/11 scans.
- * If any channel is supplied multiple times, then the last specification wins.
- */
+wifi_error wifi_get_cached_results(wifi_interface_handle iface, byte flush,
+ wifi_scan_result_handler handler);
-/* Background scan - it works with above API with single_shot set to '0' */
/* BSSID Hotlist */
typedef struct {
- void (*on_hotlist_ap_found)(wifi_request_id id, unsigned num_results, wifi_scan_result *results);
+ void (*on_hotlist_ap_found)(wifi_request_id id,
+ unsigned num_results, wifi_scan_result *results);
} wifi_hotlist_ap_found_handler;
+typedef struct {
+ mac_addr bssid; // AP BSSID
+ wifi_rssi low; // low threshold
+ wifi_rssi high; // high threshold
+} ap_threshold_param;
+
+typedef struct {
+ int num; // max??
+ ap_threshold_param bssids[];
+} wifi_bssid_hotlist_params;
+
wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface,
- int num_bssid, mac_addr bssid[], wifi_hotlist_ap_found_handler handler);
+ wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler);
wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface);
/* Significant wifi change*/
+
typedef struct {
- void (*on_significant_change)(wifi_request_id id, unsigned num_results, wifi_scan_result *results);
+ void (*on_significant_change)(wifi_request_id id,
+ unsigned num_results, wifi_scan_result *results);
} wifi_significant_change_handler;
+typedef struct {
+ int rssi_sample_size; // number of samples for averaging RSSI
+ int lost_ap_sample_size; // number of samples to confirm AP loss
+ int min_breaching; // number of APs breaching threshold
+ int num; // max??
+ ap_threshold_param bssids[];
+} wifi_significant_change_params;
+
wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface,
wifi_significant_change_handler handler);
wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface);
diff --git a/service/lib/wifi_hal.cpp b/service/lib/wifi_hal.cpp
index ad4650d7a..8b19a55a0 100644
--- a/service/lib/wifi_hal.cpp
+++ b/service/lib/wifi_hal.cpp
@@ -81,7 +81,7 @@ static nl_sock * wifi_create_nl_socket(int port)
}
// ALOGI("Making socket nonblocking");
- if (nl_socket_set_nonblocking(sock)) {
+ if (nl_socket_set_nonblocking(sock)) {
ALOGE("Could make socket non-blocking");
nl_socket_free(sock);
return NULL;
@@ -252,9 +252,8 @@ void wifi_event_loop(wifi_handle handle)
do {
int timeout = -1; /* Infinite timeout */
pfd.revents = 0;
- ALOGI("Polling socket");
+ //ALOGI("Polling socket");
int result = poll(&pfd, 1, -1);
- ALOGI("Poll result = %0x", result);
if (result < 0) {
ALOGE("Error polling socket");
} else if (pfd.revents & (POLLIN | POLLHUP | POLLERR)) {
@@ -281,29 +280,35 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg)
return NL_SKIP;
}
- int cmd = event.get_cmd();
- uint32_t vendor_id = 0;
+ int cmd = event.get_cmd();
+ uint32_t vendor_id = 0;
+ uint32_t subcmd = 0;
- if (cmd == NL80211_CMD_VENDOR) {
+ if (cmd == NL80211_CMD_VENDOR) {
vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID);
- // subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
- }
+ subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD);
+ ALOGI("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x",
+ event.get_cmdString(), vendor_id, subcmd);
+ } else {
+ ALOGI("event received %s", event.get_cmdString());
+ }
- ALOGI("event received %d, vendor_id = 0x%0x", cmd, vendor_id);
+ ALOGI("event received %s, vendor_id = 0x%0x", event.get_cmdString(), vendor_id);
+ event.log();
- for (int i = 0; i < info->num_event_cb; i++) {
- if (cmd == info->event_cb[i].nl_cmd) {
- if (cmd == NL80211_CMD_VENDOR && vendor_id != info->event_cb[i].vendor_id) {
- /* event for a different vendor, ignore it */
- continue;
- }
+ for (int i = 0; i < info->num_event_cb; i++) {
+ if (cmd == info->event_cb[i].nl_cmd) {
+ if (cmd == NL80211_CMD_VENDOR && vendor_id != info->event_cb[i].vendor_id) {
+ /* event for a different vendor, ignore it */
+ continue;
+ }
- cb_info *cbi = &(info->event_cb[i]);
- return (*(cbi->cb_func))(msg, cbi->cb_arg);
- }
- }
+ cb_info *cbi = &(info->event_cb[i]);
+ return (*(cbi->cb_func))(msg, cbi->cb_arg);
+ }
+ }
- return NL_OK;
+ return NL_OK;
}
///////////////////////////////////////////////////////////////////////////////////////
@@ -447,6 +452,7 @@ wifi_error wifi_init_interfaces(wifi_handle handle)
free(ifinfo);
continue;
}
+ ifinfo->handle = handle;
info->interfaces[i] = ifinfo;
i++;
}
diff --git a/service/lib/wifi_hal.h b/service/lib/wifi_hal.h
index 585252872..85a46a388 100644
--- a/service/lib/wifi_hal.h
+++ b/service/lib/wifi_hal.h
@@ -23,7 +23,7 @@ typedef uint32_t u32;
typedef uint64_t u64;
typedef void * wifi_handle;
typedef int wifi_request_id;
-typedef int wifi_channel;
+typedef int wifi_channel; // indicates channel frequency in MHz
typedef int wifi_rssi;
typedef byte mac_addr[6];
typedef int64_t wifi_timestamp; // In microseconds (us)