Ad-hoc hack for Android


http://szym.net/android/adhoc-wpa-supp.html

Ad-hoc hack for Android
Suppose you want one Android phone to connect to another. Unfortunately, the WifiManager in stock Android ignores ad-hoc networks. There are a couple ways around this:

One is to modify the Android framework to support ad-hoc networks (I recall seeing some custom ROM for Samsung Moment that had this).
Another is to manually configure the wpa_supplicant to connect to an ad-hoc network.
Yet another one is to patch the wpa_supplicant to pretend that ad-hoc networks are regular access points. This was my method.
The original purpose of this patch was to enable an Android device tether to another Android phone using Barnacle Wifi Tether.

ad-hoc support in wpa_supplicant

At this time, Android does not support ad-hoc networks. That is, ad-hoc (IBSS) entries are filtered out from the scan results reported by the wpa_supplicant.

To add ad-hoc network support one could augment the WifiStateTracker to not filter IBSS entries out and set the wpa_supplicant in AP_SCAN 2 mode to establish new IBSS instead of associating with a scanned one. That would require fiddling with the Java framework on the phone.

A more crazy way to do this is to augment the wpa_supplicant to masquerade ad-hoc networks as regular infrastructure access points (APs). This makes changes only to the wpa_supplicant and allows a drop in replacement on rooted phones.

Necessary Changes

The patch below modifies the wpa_supplicant code in the external/wpa_supplicant AOSP repo to make ad-hoc networks appear as regular APs with a (*) prefix.

The patch:

removes the [IBSS] flag from scan results,
masquerades and demasquerades ad-hoc ssid with (*) prefix
sets mode 1 (ad-hoc) if the ssid is for IBSS
permits the supplicant to select an IBSS when associating to a given ssid

diff --git a/ctrl_iface.c b/ctrl_iface.c
index ef93533..5accae6 100644
--- a/ctrl_iface.c
+++ b/ctrl_iface.c
@@ -28,6 +28,13 @@
#include "wpa_ctrl.h"
#include "eap.h"

+#define ANDROID_IBSS_HACK
+
+#ifdef ANDROID_IBSS_HACK
+/// NOTE: don't confuse WifiService.parseScanResult
+#define ANDROID_IBSS_PREFIX "(*)"
+#define ANDROID_IBSS_PREFIX_LEN 3
+#endif

static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
char *buf, int len);
@@ -230,6 +237,13 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
ssid_len = _res;
_ssid = ssid_buf;
}
+#ifdef ANDROID_IBSS_HACK
+ if (ssid->mode == IEEE80211_MODE_IBSS)
+ ret = os_snprintf(pos, end - pos, "ssid=%s%s\nid=%d\n",
+ ANDROID_IBSS_PREFIX, wpa_ssid_txt(_ssid, ssid_len),
+ ssid->id);
+ else
+#endif
ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
wpa_ssid_txt(_ssid, ssid_len),
ssid->id);
@@ -574,12 +588,14 @@ static int wpa_supplicant_ctrl_iface_scan_results(
return retpos - buf;
pos += ret;
}
+#ifndef ANDROID_IBSS_HACK
if (res->caps & IEEE80211_CAP_IBSS) {
ret = os_snprintf(pos, end - pos, "[IBSS]");
if (ret < 0 || ret >= end - pos)
return retpos - buf;
pos += ret;
}
+#endif
if (!res->wpa_ie_len && !res->rsn_ie_len) {
ret = os_snprintf(pos, end - pos, "\t");
if (ret < 0 || ret >= end - pos)
@@ -587,6 +603,12 @@ static int wpa_supplicant_ctrl_iface_scan_results(
pos += ret;
}

+#ifdef ANDROID_IBSS_HACK
+ if (res->caps & IEEE80211_CAP_IBSS)
+ ret = os_snprintf(pos, end - pos, "\t%s%s",
+ ANDROID_IBSS_PREFIX, wpa_ssid_txt(res->ssid, res->ssid_len));
+ else
+#endif
ret = os_snprintf(pos, end - pos, "\t%s",
wpa_ssid_txt(res->ssid, res->ssid_len));
if (ret < 0 || ret >= end - pos)
@@ -792,6 +814,21 @@ static int wpa_supplicant_ctrl_iface_set_network(
return -1;
}

+#ifdef ANDROID_IBSS_HACK
+ if (os_strcmp(name, "ssid") == 0) {
+ // check prefix
+ if ((value[0] == '"') && (os_strncmp(value+1, ANDROID_IBSS_PREFIX,
+ ANDROID_IBSS_PREFIX_LEN) == 0)) {
+ if (wpa_config_set(ssid, "mode", "1", 0) < 0) {
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE: failed to set IBSS on '%s'",
+ value);
+ return -1;
+ }
+ value += ANDROID_IBSS_PREFIX_LEN;
+ value[0] = '"';
+ }
+ }
+#endif
if (wpa_config_set(ssid, name, value, 0) < 0) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
"variable '%s'", name);
@@ -846,6 +883,11 @@ static int wpa_supplicant_ctrl_iface_get_network(
return -1;
}

+#ifdef ANDROID_IBSS_HACK
+ if ((os_strcmp(name, "ssid") == 0) && (ssid->mode == IEEE80211_MODE_IBSS))
+ os_snprintf(buf, buflen, "\"%s%s", ANDROID_IBSS_PREFIX, value+1);
+ else
+#endif
os_snprintf(buf, buflen, "%s", value);
buf[buflen - 1] = '\0';

diff --git a/events.c b/events.c
index bb5be64..c591f30 100644
--- a/events.c
+++ b/events.c
@@ -479,9 +479,12 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
}

if (bss->caps & IEEE80211_CAP_IBSS) {
+//#ifdef ANDROID_IBSS_HACK // FIXME
+ if (ssid->mode != IEEE80211_MODE_IBSS) {
wpa_printf(MSG_DEBUG, " skip - "
"IBSS (adhoc) network");
continue;
+ }
}

selected = bss;

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. Android常用高质量框架
  2. Android(安卓)音频系统:从 AudioTrack 到
  3. android使用WebView显示sdcard的html文件
  4. android 设置背景图片
  5. Android菜单操作之创建并响应菜单
  6. Android(安卓)中自定义控件和属性(attr.x
  7. Android中图像变换Matrix的原理、代码验
  8. Android中的线程机制
  9. 亲测Android横竖屏切换小结,带测试结果
  10. addStatesFromChildren 和跑马灯