android wifi †
手順 †以下の手順は、bc9/bc9-oe-sdk setup や bc9/bc9-android-sdk setup に従って 無線LAN driverを有効にした Kernel の作成 †
まず driver をモジュールとして build し、OpenEmbedded Linux 上で使用できることを確認します。 $ wpa_passphrase SSID PASS_PHRASE の出力結果を /etc/wpa_supplicant.conf に書いて使用しますが、これだけでは暗号化方式などの指定が足りないため接続できません。 network={
ssid="hoge"
key_mgmt=WPA-PSK
proto=WPA WPA2
pairwise=CCMP TKIP
group=CCMP TKIP WEP104 WEP40
# psk="beatcraft"
psk=1954c17037ac0255e310e30377008d5e732edb603bb4b27ee92d14e4b0d91919
}
これを正しく記述したら以下のコマンドで接続を確認します。 $ wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf OpenEmbedded の場合はこれで wlan0 が up し dhcp で IPアドレスを取得します。 wpa_supplicant を含む android build †wpa_supplicant 有効にして android を build し、コマンドラインで 無線接続を確認します。 wpa_supplicant の build †android-1.5r3/external/wpa_supplicant/.config を以下のように修正します。 $ diff -u .config.orig .config --- .config.orig 2009-08-05 22:00:52.000000000 +0900 +++ .config 2009-08-11 16:22:36.000000000 +0900 @@ -19,13 +19,13 @@ CONFIG_PKCS12=y # CONFIG_PCSC=y CONFIG_SMARTCARD=y -# CONFIG_WIRELESS_EXTENSION=y +CONFIG_WIRELESS_EXTENSION=y CONFIG_CTRL_IFACE=y # CONFIG_DRIVER_HOSTAP=y # CONFIG_DRIVER_HERMES=y # CONFIG_DRIVER_MADWIFI=y # CONFIG_DRIVER_ATMEL=y -# CONFIG_DRIVER_WEXT=y +CONFIG_DRIVER_WEXT=y # CONFIG_DRIVER_NDISWRAPPER=y # CONFIG_DRIVER_BROADCOM=y # CONFIG_DRIVER_IPW=y android-1.5r3/build/target/board/generic/BoardConfig.mk に以下を追加します。 WPA_BUILD_SUPPLICANT := true BOARD_WPA_SUPPLICANT_DRIVER := WEXT android-1.5r3/external/wpa_supplicant/wpa_supplicant.conf を以下のように修正します。 ~/android-1.5r3$ diff -u external/wpa_supplicant/wpa_supplicant.conf.orig external/wpa_supplicant/wpa_supplicant.conf --- external/wpa_supplicant/wpa_supplicant.conf.orig 2009-08-11 16:31:15.000000000 +0900 +++ external/wpa_supplicant/wpa_supplicant.conf 2009-08-11 16:31:58.000000000 +0900 @@ -72,7 +72,8 @@ # DACL (which will reject all connections). See README-Windows.txt for more # information about SDDL string format. # -ctrl_interface=tiwlan0 +#ctrl_interface=wlan0 +ctrl_interface=DIR=/data/system/wpa_supplicant GROUP=system # IEEE 802.1X/EAPOL version # wpa_supplicant is implemented based on IEEE Std 802.1X-2004 which defines これで make を実行すると out/target/product/generic/system/bin/ に wpa_supplicant と wpa_cli が build されているので # system/bin/wpa_supplicant -Dwext -iwlan0 -c/system/etc/wpa_supplicant.conf # netcfg wlan0 dhcp と入力し dhcp によるアドレス取得もコマンドで行う必要があります。 wifi.c の修正 †wifi.c を修正して android の GUI から操作可能にします。 --- wifi.c.orig 2009-08-11 10:56:03.000000000 +0900
+++ wifi.c 2009-08-12 17:02:49.000000000 +0900
@@ -48,10 +48,16 @@
// TODO: use new ANDROID_SOCKET mechanism, once support for multiple
// sockets is in
-static const char IFACE_DIR[] = "/data/system/wpa_supplicant";
-static const char DRIVER_MODULE_NAME[] = "wlan";
-static const char DRIVER_MODULE_TAG[] = "wlan ";
-static const char DRIVER_MODULE_PATH[] = "/system/lib/modules/wlan.ko";
+static const char IFACE_DIR[] = "/data/system/wpa_supplicant";
+static const char DRIVER_MODULE_NAME[] = "rt73usb";
+static const char DRIVER_MODULE_TAG[] = "rt73usb ";
+static const char DRIVER_MODULE_PATH[] = "/system/lib/modules/rt73usb.ko";
+static const char RT2X00_LIB_DRIVER_MODULE_NAME[] = "rt2x00lib";
+static const char RT2X00_LIB_DRIVER_MODULE_TAG[] = "rt2x00lib ";
+static const char RT2X00_LIB_DRIVER_MODULE_PATH[] = "/system/lib/modules/rt2x00lib.ko";
+static const char RT2X00_LIB_USB_DRIVER_MODULE_NAME[] = "rt2x00usb";
+static const char RT2X00_LIB_USB_DRIVER_MODULE_TAG[] = "rt2x00usb";
+static const char RT2X00_LIB_USB_DRIVER_MODULE_PATH[] = "/system/lib/modules/rt2x00usb.ko";
static const char FIRMWARE_LOADER[] = "wlan_loader";
static const char DRIVER_PROP_NAME[] = "wlan.driver.status";
static const char SUPPLICANT_NAME[] = "wpa_supplicant";
@@ -66,6 +72,7 @@
unsigned int size;
int ret;
+ LOGI("%s\n", __FUNCTION__);
module = load_file(filename, &size);
if (!module)
return -1;
@@ -82,6 +89,7 @@
int ret = -1;
int maxtry = 10;
+ LOGI("%s\n", __FUNCTION__);
while (maxtry-- > 0) {
ret = delete_module(modname, O_NONBLOCK | O_EXCL);
if (ret < 0 && errno == EAGAIN)
@@ -91,30 +99,35 @@
}
if (ret != 0)
- LOGD("Unable to unload driver module \"%s\": %s\n",
+ LOGE("Unable to unload driver module \"%s\": %s\n",
modname, strerror(errno));
return ret;
}
int do_dhcp_request(int *ipaddr, int *gateway, int *mask,
int *dns1, int *dns2, int *server, int *lease) {
+ LOGI("1. inside %s\n", __FUNCTION__);
/* For test driver, always report success */
- if (strcmp(iface, "sta") == 0)
+ if (strcmp(iface, "wlan0") == 0)
return 0;
+ LOGI("2. inside %s\n", __FUNCTION__);
if (ifc_init() < 0)
return -1;
+ LOGI("3. inside %s\n", __FUNCTION__);
if (do_dhcp(iface) < 0) {
ifc_close();
return -1;
}
ifc_close();
get_dhcp_info(ipaddr, gateway, mask, dns1, dns2, server, lease);
+ LOGI("4. inside %s\n", __FUNCTION__);
return 0;
}
const char *get_dhcp_error_string() {
+ LOGI("Inside %s\n", __FUNCTION__);
return dhcp_lasterror();
}
@@ -123,8 +136,10 @@
FILE *proc;
char line[sizeof(DRIVER_MODULE_TAG)+10];
+ LOGI("%s\n", __FUNCTION__);
if (!property_get(DRIVER_PROP_NAME, driver_status, NULL)
|| strcmp(driver_status, "ok") != 0) {
+ LOGE("driver %s has NOT been installed",DRIVER_MODULE_TAG);
return 0; /* driver not loaded */
}
/*
@@ -140,10 +155,12 @@
}
while ((fgets(line, sizeof(line), proc)) != NULL) {
if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) {
+ LOGI("driver %s has been installed\n",DRIVER_MODULE_TAG);
fclose(proc);
return 1;
}
}
+ LOGE("Cannot find driver %s in proc",DRIVER_MODULE_TAG);
fclose(proc);
property_set(DRIVER_PROP_NAME, "unloaded");
return 0;
@@ -154,23 +171,34 @@
char driver_status[PROPERTY_VALUE_MAX];
int count = 100; /* wait at most 20 seconds for completion */
+ LOGI("Loading WiFi Modules\n");
+ sleep(1);
+
+ // Hack taken from EEPC WiFi path. We have statically linked the WiFi driver
+ // into the kernel, so we simply return and don't attempt to load the driver.
+ // So we set the driver property to ok, since we have already installed it.
+ property_set(DRIVER_PROP_NAME, "ok");
if (check_driver_loaded()) {
return 0;
}
-
- if (insmod(DRIVER_MODULE_PATH) < 0)
- return -1;
-
- property_set("ctl.start", FIRMWARE_LOADER);
+ insmod(RT2X00_LIB_DRIVER_MODULE_PATH);
+ insmod(RT2X00_LIB_USB_DRIVER_MODULE_PATH);
+ insmod(DRIVER_MODULE_PATH);
+ property_set("ctl.start", 0);
sched_yield();
while (count-- > 0) {
+ usleep(500000);
if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
- if (strcmp(driver_status, "ok") == 0)
+ if (strcmp(driver_status, "ok") == 0) {
+ property_set("ctl.start", "ifcfg_ralink");
+ usleep(1000000);
+ //property_set("ctl.start", "dhcpcd");
return 0;
- else if (strcmp(DRIVER_PROP_NAME, "failed") == 0)
+ }
+ else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) {
return -1;
+ }
}
- usleep(200000);
}
property_set(DRIVER_PROP_NAME, "timeout");
return -1;
@@ -178,20 +206,31 @@
int wifi_unload_driver()
{
- int count = 20; /* wait at most 10 seconds for completion */
-
+ LOGI("Unloading WiFi Modules\n");
+ sleep(1);
+
if (rmmod(DRIVER_MODULE_NAME) == 0) {
- while (count-- > 0) {
- if (!check_driver_loaded())
- break;
- usleep(500000);
- }
- if (count) {
- return 0;
- }
- return -1;
- } else
+ usleep(1000000);
+ } else {
+ LOGE("Unloading Ralink RT73USB WLAN Module Failed\n");
+ return -1;
+ }
+
+ if (rmmod(RT2X00_LIB_USB_DRIVER_MODULE_NAME) == 0) {
+ usleep(1000000);
+ } else {
+ LOGE("Unloading RT2X00_LIB_USB Module Failed\n");
return -1;
+ }
+
+ if (rmmod(RT2X00_LIB_DRIVER_MODULE_NAME) == 0) {
+ usleep(1000000);
+ } else {
+ LOGE("Unloading RT2X00_LIB Module Failed\n");
+ return -1;
+ }
+
+ return 0;
}
int ensure_config_file_exists()
@@ -200,6 +239,7 @@
int srcfd, destfd;
int nread;
+ LOGE("%s\n", __FUNCTION__);
if (access(SUPP_CONFIG_FILE, R_OK|W_OK) == 0) {
return 0;
} else if (errno != ENOENT) {
@@ -252,6 +292,7 @@
unsigned serial = 0;
#endif
+ LOGI("start %s",__FUNCTION__);
/* Check whether already running */
if (property_get(SUPP_PROP_NAME, supp_status, NULL)
&& strcmp(supp_status, "running") == 0) {
@@ -260,7 +301,7 @@
/* Before starting the daemon, make sure its config file exists */
if (ensure_config_file_exists() < 0) {
- LOGE("Wi-Fi will not be enabled");
+ LOGE("Configuration file does not exis. Wi-Fi will not be enabled");
return -1;
}
@@ -291,9 +332,11 @@
if (pi != NULL) {
__system_property_read(pi, NULL, supp_status);
if (strcmp(supp_status, "running") == 0) {
+ LOGI("Wi-Fi is running\n");
return 0;
} else if (pi->serial != serial &&
strcmp(supp_status, "stopped") == 0) {
+ LOGI("Wi-Fi has been stopped");
return -1;
}
}
@@ -313,6 +356,7 @@
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 50; /* wait at most 5 seconds for completion */
+ LOGI("%s called",__func__);
/* Check whether supplicant already stopped */
if (property_get(SUPP_PROP_NAME, supp_status, NULL)
&& strcmp(supp_status, "stopped") == 0) {
@@ -337,6 +381,7 @@
char ifname[256];
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
+ LOGI("%s called",__func__);
/* Make sure supplicant is running */
if (!property_get(SUPP_PROP_NAME, supp_status, NULL)
|| strcmp(supp_status, "running") != 0) {
@@ -344,7 +389,7 @@
return -1;
}
- property_get("wifi.interface", iface, "sta");
+ property_get("wifi.interface", iface, "wlan0");
if (access(IFACE_DIR, F_OK) == 0) {
snprintf(ifname, sizeof(ifname), "%s/%s", IFACE_DIR, iface);
@@ -352,6 +397,8 @@
strlcpy(ifname, iface, sizeof(ifname));
}
+ LOGI("Interface directory = %s", IFACE_DIR);
+ LOGI("Interface name = %s", ifname);
ctrl_conn = wpa_ctrl_open(ifname);
if (ctrl_conn == NULL) {
LOGE("Unable to open connection to supplicant on \"%s\": %s",
@@ -370,6 +417,7 @@
ctrl_conn = monitor_conn = NULL;
return -1;
}
+ LOGI("Connect to Supplicant done\n");
return 0;
}
@@ -377,20 +425,26 @@
{
int ret;
+ LOGI("%s, cmd = %s\n", __FUNCTION__, cmd);
if (ctrl_conn == NULL) {
LOGV("Not connected to wpa_supplicant - \"%s\" command dropped.\n", cmd);
return -1;
}
+
+ memset(reply, 0, *reply_len);
ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL);
if (ret == -2) {
LOGD("'%s' command timed out.\n", cmd);
return -2;
} else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) {
+ LOGI("reply:%s\n",reply);
return -1;
}
if (strncmp(cmd, "PING", 4) == 0) {
reply[*reply_len] = '\0';
}
+
+ LOGI("returning reply %s for cmd %s\n", reply, cmd);
return 0;
}
@@ -402,10 +456,13 @@
int result;
struct timeval tval;
struct timeval *tptr;
-
+
+ LOGI("%s called",__func__);
+ LOGI("monitor_conn checking \n");
if (monitor_conn == NULL)
return 0;
+ LOGI("calling wpa_ctrl_recv\n");
result = wpa_ctrl_recv(monitor_conn, buf, &nread);
if (result < 0) {
LOGD("wpa_ctrl_recv failed: %s\n", strerror(errno));
@@ -413,6 +470,7 @@
}
buf[nread] = '\0';
/* LOGD("wait_for_event: result=%d nread=%d string=\"%s\"\n", result, nread, buf); */
+ LOGI("wait_for_event: result=%d nread=%d string=\"%s\"\n", result, nread, buf);
/* Check for EOF on the socket */
if (result == 0 && nread == 0) {
/* Fabricate an event to pass up */
@@ -437,11 +495,13 @@
memmove(buf, match+1, nread+1);
}
}
+ LOGI("returning nread\n");
return nread;
}
void wifi_close_supplicant_connection()
{
+ LOGI("%s called",__func__);
if (ctrl_conn != NULL) {
wpa_ctrl_close(ctrl_conn);
ctrl_conn = NULL;
@@ -454,5 +514,6 @@
int wifi_command(const char *command, char *reply, size_t *reply_len)
{
+ LOGI("%s called, cmd:%s",__func__,command);
return wifi_send_command(ctrl_conn, command, reply, reply_len);
}
この他、android-1.5r3 のソースコード内で tiwlan0 になっている箇所 android userland の調整 †android の GUI から wifi の on/off ができるよう、rt73usb の kernel module と rt73.bin を /system/lib/modules/rt2x00lib.ko /system/lib/modules/rt2x00usb.ko /system/lib/modules/rt73usb.ko /system/etc/firmware/rt73.bin wifi interface 名を設定するため、/system/build.prop に以下を追加します。 # WiFi settings wifi.interface = wlan0 GUI から insmod した時、自動で wlan0 が up し dhcp によるアドレス取得ができるよう、init.rc に以下の項目を加えます。 setprop wifi.interface wlan0
setprop wlan.driver.status ok
service ifcfg_ralink /system/bin/ifconfig wlan0 up
# disabled
# oneshot
service wpa_supplicant /system/bin/logwrapper /system/bin/wpa_supplicant -Dwext -iwlan0 -c /system/etc/wifi/wpa_supplicant.conf -dd
disabled
group system
service dhcpcd /system/bin/logwrapper /system/bin/dhcpcd -d wlan0
disabled
oneshot
#group system dhcp
on property:init.svc.wpa_supplicant=stopped
stop dhcpcd
参考URL † |