一天又过去了,台风也走了有些时候了。想了想,自己还是冲动了一把,不该发那个邮件的,既然发了,也不后悔了。知道了所有也未必不是一件好事。恩,剩下的就好好做自己要做的事情吧。对于usb wifi,老早就在调试了,只是碰到了很多问题,加上其他的事情也迎面而来,从而导致很多的困难,也就搁置着了。上上周,工作计划一周内要搞定,郁闷着了,这个涉及到的太多太多了,不好移植啊。只能加班了,天天看代码了。在移植完bluetooth后,马上开始wifi的移植。终于,功夫不负有心人,前天晚上解决了可恶的权限问题导致不能socket通信。可以连上路由器,但是分配IP地址还是要命令的。还有就是nfs挂载的时候,网络貌似只是通过本地连接的,而不是从wifi来的,所以只能ping通路由和本地的连接,至于外网,要用SD卡启动才可以连接。下面对于整个移植过程做下简单的记录。
首先那肯定是要在linux kernel下选上相应的选项了,在此之前要有wifi的驱动。
在Networking support下选上
上面主要是选上相关的通信的协议,802.11啊什么的。
然后wifi的设备也要选上
选上自己的wifi设备驱动,我是选择编译进内核的,不是编译成模块的,而按照android源码中可以知道,其实是要编译成模块,不断去加载什么的。不过编译进内核后,修改下android下的源码也是可以解决问题的。
好了,准备好了linux kernel后,那么基本上如果跑linux的话,用wireless-tools这个工具就可以测试了
[html] view plain copy print ?
- ./iwlist wlan0 scanning
-
- ./iwconfig wlan0 mode managed
-
- ./iwconfig wlan0 essid “你要连接的路由”
-
- ./ifconfig wlan0 要为wifi设置的静态IP netmask 255.255.255.0 up
./iwlist wlan0 scanning
./iwconfig wlan0 mode managed
./iwconfig wlan0 essid “你要连接的路由”
./ifconfig wlan0 要为wifi设置的静态IP netmask 255.255.255.0 up
然后就可以ping通你的路由了,如果成功了,那么说明wifi的驱动没多大的问题,接着就可以上android去调试了。
现在想想,其实android的wifi适配其实也算简单的,只是对于网络不是很懂,所以才觉得有难度。先讲讲android中wifi的一些代码主要的目录吧。
1、 wpa_supplicant: 这个最最纠结了,主要也就是这个东东了,这个好了,那基本上就没什么问题了。Wpa就是应
用层认证客户端,负责完成认证相关登陆,加密等工作。
external/wpa_supplicant_8/下,通过mm后可以生成动态库libwpa_client.so和可执行的程序wpa_supplicant和wpa_cli
2、 wpa_supplicant适配层:封装与wpa_supplicant守护进程的通信,以提供给android框架使用,实现加载,控制和消
息监控等功能。
hardware/libhardware_legacy/wifi/下,而我用的是厂家提供的,所以是修改过的,其实都一样的。
3、 wifi的JNI: frameworks//base/core/jni/android_net_wifi_wifi.cpp
wifi的服务层: frameworks/base/services/java/com/android/server/WifiService.java
wifi的部分接口:frameworks/base/wifi/java/android/net/wifi
对于android层,本人没有做任何修改,上层基本上是好的,只要wpa_supplicant和底层通信好了,那么整个适配就没什么问题了。
接下来就开始真正的移植吧。
主要是android有那个什么破权限,搞得我很是郁闷。其实还是自己经验不足啊,刚刚毕业也在所难免啊。先改下权限吧,在init.rc里
[html] view plain copy print ?
- mkdir /data/misc/wifi 0777 wifi wifi
-
- chmod 0777 /data/misc/wifi/wpa_supplicant.conf
-
- mkdir /wlan0 0777 wifi wifi
mkdir /data/misc/wifi 0777 wifi wifi
chmod 0777 /data/misc/wifi/wpa_supplicant.conf
mkdir /wlan0 0777 wifi wifi
因为编译进内核的,所以加上下面两句
[html] view plain copy print ?
- #prepare for wifi
-
- setprop wifi.interface “wlan0”
-
- setprop wlan.driver.status “ok”
#prepare for wifi
setprop wifi.interface “wlan0”
setprop wlan.driver.status “ok”
在init.xxx.rc中添加下面的
[html] view plain copy print ?
- mkdir /data/misc/wifi/sockets 0777 wifi wifi
-
- mkdir /data/misc/dhcp 0777 dhcp dhcp
-
- chmod 0777 /dev/rfkill
mkdir /data/misc/wifi/sockets 0777 wifi wifi
mkdir /data/misc/dhcp 0777 dhcp dhcp
chmod 0777 /dev/rfkill
又和蓝牙一样,有一个rfkill,所以得给他修改下权限。
[html] view plain copy print ?
- service wpa_supplicant /system/bin/wpa_supplicant –dd –Dwext –iwlan0 –c/data/misc/wifi/wpa_supplicant.conf
-
- class main
-
- #socket wpa_wpa_wlan0 dgram 0777 wifi wifi
-
- group system inet
-
- disabled
-
- oneshot
service wpa_supplicant /system/bin/wpa_supplicant –dd –Dwext –iwlan0 –c/data/misc/wifi/wpa_supplicant.conf
class main
#socket wpa_wpa_wlan0 dgram 0777 wifi wifi
group system inet
disabled
oneshot
[html] view plain copy print ?
- service dhcpcd_wlan0 /system/bin/dhcpcd –d –B wlan0
-
- class main
-
- disabled
-
- oneshot
service dhcpcd_wlan0 /system/bin/dhcpcd –d –B wlan0
class main
disabled
oneshot
好了,主要修改这些,基本上没有什么提示权限问题了。接着要把那个
wpa_supplicant.conf加进去,里面的内容一般可以如下:
[html] view plain copy print ?
- ctrl_interface=wlan0
-
- update_config=1
-
- ap_scan=1
-
- fast_reauth=1
ctrl_interface=wlan0
update_config=1
ap_scan=1
fast_reauth=1
接着在修改下wifi.c中的代码
[html] view plain copy print ?
- static const char IFACE_DIR[] = "/data/system/wpa_supplicant";
static const char IFACE_DIR[] = "/data/system/wpa_supplicant";
这个修改为
[html] view plain copy print ?
- static const char IFACE_DIR[] = "/wlan0";
static const char IFACE_DIR[] = "/wlan0";
[html] view plain copy print ?
- static int insmod(const char *filename, const char *args)
static int insmod(const char *filename, const char *args)
这个函数第一行就return 0。因为编译进内核,没有模块。
[html] view plain copy print ?
- static int rmmod(const char *modname)
static int rmmod(const char *modname)
这个函数同上。
恩,基本上搞定了,还有就是要在相应的平台下把wifi的相关宏定义给选上。举个例子,比如说你的平台是samsung的Tuna平台,那么在device/Samsung/Tuna/BoardConfig.mk中有几个宏必须选上
[html] view plain copy print ?
- BOARD_WIFI_VENDOR :=realtek
-
- WPA_SUPPLICANT_VERSION := VER_0_8_X
-
- BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_drivercmd_wext
-
- BOARD_WLAN_DEVICE := rtl8192cu
BOARD_WIFI_VENDOR :=realtek
WPA_SUPPLICANT_VERSION := VER_0_8_X
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_drivercmd_wext
BOARD_WLAN_DEVICE := rtl8192cu
好了,然后就到相应的目录下去编译生成相关的.so和可执行应用程序吧
Hardware/libhardware_legacy/下mm后得到了libhardware_legacy.so
然后再到
external/wpa_supplicant_8/下mm后得到了wpa_cli, wpa_supplicant和libwpa_client.so
好了,接着可以启动了,在此,还是先用命令行,上面的那两个服务先注释掉,然后开始去启动。
启动后,首先就是查看下底层驱动有没有运行,主要就是cat /proc/net/dev有wlan0的话,那么就说明ok了。接着就是要连接上wpa_supplicant了
[html] view plain copy print ?
- wpa_supplicant –dd –Dwext –iwlan0 –c/data/misc/wifi/wpa_supplicant.conf &
wpa_supplicant –dd –Dwext –iwlan0 –c/data/misc/wifi/wpa_supplicant.conf &
让他后台运行着就好了。
就这就
[html] view plain copy print ?
- wpa_cli –iwlan0 –p/wlan0
wpa_cli –iwlan0 –p/wlan0
然后再
Scan (搜索网络)
接着scan_res(显示搜索结果,如果可以搜到网络的话,那么几乎就可以说是成功了)
接着就
[html] view plain copy print ?
- add_net
-
- set_net 0 ssid “相应搜到的网络”
-
- set_net 0 key_mgmt NONE
-
- set_net 0 priority 0
-
- list_net
-
- save_config
-
- enable_net 0
add_net
set_net 0 ssid “相应搜到的网络”
set_net 0 key_mgmt NONE
set_net 0 priority 0
list_net
save_config
enable_net 0
这样就可以启动了,然后再
[html] view plain copy print ?
- dhcpcd wlan0
dhcpcd wlan0
分配一个ip地址,接着去ping路由,就可以ping的通了,那么一直基本上告一段落。
不过这个是命令行的,得让他在UI界面出来,于是还是启动服务吧,可是一直wpa_supplicant的时候就不成功,老是有问题。跟进代码,当上层开关打开后就会调用到下面这个函数去连接wpa_supplicant
[html] view plain copy print ?
- /hardware/libhardware_legacy/wifi.c
-
- int wifi_connect_to_supplicant()
-
- {
-
- char ifname[256];
-
- char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
-
-
-
- /* Make sure supplicant is running */
-
- if (!property_get(SUPP_PROP_NAME, supp_status, NULL)
-
- || strcmp(supp_status, "running") != 0) {
-
- LOGE("Supplicant not running, cannot connect");
-
- return -1;
-
- }
-
-
-
- if (access(IFACE_DIR, F_OK) == 0) {
-
- snprintf(ifname, sizeof(ifname), "%s/%s", IFACE_DIR, iface);
-
- } else {
-
- strlcpy(ifname, iface, sizeof(ifname));
-
- }
-
-
-
- ctrl_conn = wpa_ctrl_open(ifname);
-
- if (ctrl_conn == NULL) {
-
- LOGE("Unable to open connection to supplicant on \"%s\": %s",
-
- ifname, strerror(errno));
-
- return -1;
-
- }
-
- monitor_conn = wpa_ctrl_open(ifname);
-
- if (monitor_conn == NULL) {
-
- wpa_ctrl_close(ctrl_conn);
-
- ctrl_conn = NULL;
-
- return -1;
-
- }
-
- if (wpa_ctrl_attach(monitor_conn) != 0) {
-
- wpa_ctrl_close(monitor_conn);
-
- wpa_ctrl_close(ctrl_conn);
-
- ctrl_conn = monitor_conn = NULL;
-
- return -1;
-
- }
-
-
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {
-
- wpa_ctrl_close(monitor_conn);
-
- wpa_ctrl_close(ctrl_conn);
-
- ctrl_conn = monitor_conn = NULL;
-
- return -1;
-
- }
-
-
-
- return 0;
-
- }
/hardware/libhardware_legacy/wifi.c
int wifi_connect_to_supplicant()
{
char ifname[256];
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
/* Make sure supplicant is running */
if (!property_get(SUPP_PROP_NAME, supp_status, NULL)
|| strcmp(supp_status, "running") != 0) {
LOGE("Supplicant not running, cannot connect");
return -1;
}
if (access(IFACE_DIR, F_OK) == 0) {
snprintf(ifname, sizeof(ifname), "%s/%s", IFACE_DIR, iface);
} else {
strlcpy(ifname, iface, sizeof(ifname));
}
ctrl_conn = wpa_ctrl_open(ifname);
if (ctrl_conn == NULL) {
LOGE("Unable to open connection to supplicant on \"%s\": %s",
ifname, strerror(errno));
return -1;
}
monitor_conn = wpa_ctrl_open(ifname);
if (monitor_conn == NULL) {
wpa_ctrl_close(ctrl_conn);
ctrl_conn = NULL;
return -1;
}
if (wpa_ctrl_attach(monitor_conn) != 0) {
wpa_ctrl_close(monitor_conn);
wpa_ctrl_close(ctrl_conn);
ctrl_conn = monitor_conn = NULL;
return -1;
}
if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {
wpa_ctrl_close(monitor_conn);
wpa_ctrl_close(ctrl_conn);
ctrl_conn = monitor_conn = NULL;
return -1;
}
return 0;
}
这里的ifname=/wlan0/wlan0,这样,两个接口ctrl_conn,monitor_conn都可以正常打开,可是到了wpa_ctrl_attach(monitor_conn)的时候就一直不可以,而用命令行的时候都是可以的
继续跟进代码
[html] view plain copy print ?
- external/wpa_supplicant_8/src/common/wpa_ctrl.c
-
-
-
- #ifdef CTRL_IFACE_SOCKET
-
- int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
-
- char *reply, size_t *reply_len,
-
- void (*msg_cb)(char *msg, size_t len))
-
- {
-
- struct timeval tv;
-
- int res;
-
- fd_set rfds;
-
- const char *_cmd;
-
- char *cmd_buf = NULL;
-
- size_t _cmd_len;
-
-
-
- #ifdef CONFIG_CTRL_IFACE_UDP
-
- if (ctrl->cookie) {
-
- char *pos;
-
- _cmd_len = os_strlen(ctrl->cookie) + 1 + cmd_len;
-
- cmd_buf = os_malloc(_cmd_len);
-
- if (cmd_buf == NULL)
-
- return -1;
-
- _cmd = cmd_buf;
-
- pos = cmd_buf;
-
- os_strlcpy(pos, ctrl->cookie, _cmd_len);
-
- pos += os_strlen(ctrl->cookie);
-
- *pos++ = ' ';
-
- os_memcpy(pos, cmd, cmd_len);
-
- } else
-
- #endif /* CONFIG_CTRL_IFACE_UDP */
-
- {
-
- _cmd = cmd;
-
- _cmd_len = cmd_len;
-
- }
-
-
-
- if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
-
- os_free(cmd_buf);
-
- return -1;
-
- }
-
- os_free(cmd_buf);
-
-
-
- for (;;) {
-
- tv.tv_sec = 10;
-
- tv.tv_usec = 0;
-
- FD_ZERO(&rfds);
-
- FD_SET(ctrl->s, &rfds);
-
- res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
-
- if (res < 0)
-
- return res;
-
- if (FD_ISSET(ctrl->s, &rfds)) {
-
- res = recv(ctrl->s, reply, *reply_len, 0);
-
- if (res < 0)
-
- return res;
-
- if (res > 0 && reply[0] == '<') {
-
- /* This is an unsolicited message from
-
- * wpa_supplicant, not the reply to the
-
- * request. Use msg_cb to report this to the
-
- * caller. */
-
- if (msg_cb) {
-
- /* Make sure the message is nul
-
- * terminated. */
-
- if ((size_t) res == *reply_len)
-
- res = (*reply_len) - 1;
-
- reply[res] = '\0';
-
- msg_cb(reply, res);
-
- }
-
- continue;
-
- }
-
- *reply_len = res;
-
- break;
-
- } else {
-
- return -2;
-
- }
-
- }
-
- return 0;
-
- }
-
- #endif /* CTRL_IFACE_SOCKET */
-
-
external/wpa_supplicant_8/src/common/wpa_ctrl.c
#ifdef CTRL_IFACE_SOCKET
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
char *reply, size_t *reply_len,
void (*msg_cb)(char *msg, size_t len))
{
struct timeval tv;
int res;
fd_set rfds;
const char *_cmd;
char *cmd_buf = NULL;
size_t _cmd_len;
#ifdef CONFIG_CTRL_IFACE_UDP
if (ctrl->cookie) {
char *pos;
_cmd_len = os_strlen(ctrl->cookie) + 1 + cmd_len;
cmd_buf = os_malloc(_cmd_len);
if (cmd_buf == NULL)
return -1;
_cmd = cmd_buf;
pos = cmd_buf;
os_strlcpy(pos, ctrl->cookie, _cmd_len);
pos += os_strlen(ctrl->cookie);
*pos++ = ' ';
os_memcpy(pos, cmd, cmd_len);
} else
#endif /* CONFIG_CTRL_IFACE_UDP */
{
_cmd = cmd;
_cmd_len = cmd_len;
}
if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
os_free(cmd_buf);
return -1;
}
os_free(cmd_buf);
for (;;) {
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(ctrl->s, &rfds);
res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
if (res < 0)
return res;
if (FD_ISSET(ctrl->s, &rfds)) {
res = recv(ctrl->s, reply, *reply_len, 0);
if (res < 0)
return res;
if (res > 0 && reply[0] == '<') {
/* This is an unsolicited message from
* wpa_supplicant, not the reply to the
* request. Use msg_cb to report this to the
* caller. */
if (msg_cb) {
/* Make sure the message is nul
* terminated. */
if ((size_t) res == *reply_len)
res = (*reply_len) - 1;
reply[res] = '\0';
msg_cb(reply, res);
}
continue;
}
*reply_len = res;
break;
} else {
return -2;
}
}
return 0;
}
#endif /* CTRL_IFACE_SOCKET */
也没有什么不同啊,不过在res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
这个函数的时候就出问题了,看传的参数什么的也都没有问题啊,为什么命令行可以,这个服务启动就有问题呢,继续看看,那个wpa_supplicant有收到发的命令吗?怀疑通信有问题。
好吧,那就继续跟进吧。。。
[html] view plain copy print ?
- external/wpa_supplicant_8/wpa_supplicant/ctrl_iface_unix.c
-
-
-
- static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
-
- void *sock_ctx)
-
- {
-
- struct wpa_supplicant *wpa_s = eloop_ctx;
-
- struct ctrl_iface_priv *priv = sock_ctx;
-
- char buf[4096];
-
- int res;
-
- struct sockaddr_un from;
-
- socklen_t fromlen = sizeof(from);
-
- char *reply = NULL;
-
- size_t reply_len = 0;
-
- int new_attached = 0;
-
-
-
- res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
-
- (struct sockaddr *) &from, &fromlen);
-
- if (res < 0) {
-
- perror("recvfrom(ctrl_iface)");
-
- return;
-
- }
-
- buf[res] = '\0';
-
-
-
- if (os_strcmp(buf, "ATTACH") == 0) {
-
- if (wpa_supplicant_ctrl_iface_attach(priv, &from, fromlen))
-
- reply_len = 1;
-
- else {
-
- new_attached = 1;
-
- reply_len = 2;
-
- }
-
- } else if (os_strcmp(buf, "DETACH") == 0) {
-
- if (wpa_supplicant_ctrl_iface_detach(priv, &from, fromlen))
-
- reply_len = 1;
-
- else
-
- reply_len = 2;
-
- } else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
-
- if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen,
-
- buf + 6))
-
- reply_len = 1;
-
- else
-
- reply_len = 2;
-
- } else {
-
- reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
-
- &reply_len);
-
- }
-
-
-
- if (reply) {
-
- sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
-
- fromlen);
-
- os_free(reply);
-
- } else if (reply_len == 1) {
-
- sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
-
- fromlen);
-
- } else if (reply_len == 2) {
-
- sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from,
-
- fromlen);
-
- }
-
-
-
- if (new_attached)
-
- eapol_sm_notify_ctrl_attached(wpa_s->eapol);
-
- }
external/wpa_supplicant_8/wpa_supplicant/ctrl_iface_unix.c
static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
void *sock_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct ctrl_iface_priv *priv = sock_ctx;
char buf[4096];
int res;
struct sockaddr_un from;
socklen_t fromlen = sizeof(from);
char *reply = NULL;
size_t reply_len = 0;
int new_attached = 0;
res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
(struct sockaddr *) &from, &fromlen);
if (res < 0) {
perror("recvfrom(ctrl_iface)");
return;
}
buf[res] = '\0';
if (os_strcmp(buf, "ATTACH") == 0) {
if (wpa_supplicant_ctrl_iface_attach(priv, &from, fromlen))
reply_len = 1;
else {
new_attached = 1;
reply_len = 2;
}
} else if (os_strcmp(buf, "DETACH") == 0) {
if (wpa_supplicant_ctrl_iface_detach(priv, &from, fromlen))
reply_len = 1;
else
reply_len = 2;
} else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen,
buf + 6))
reply_len = 1;
else
reply_len = 2;
} else {
reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
&reply_len);
}
if (reply) {
sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
fromlen);
os_free(reply);
} else if (reply_len == 1) {
sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
fromlen);
} else if (reply_len == 2) {
sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from,
fromlen);
}
if (new_attached)
eapol_sm_notify_ctrl_attached(wpa_s->eapol);
}
这回彻底无语了。收到的buf也是"ATTACH",也运行到了sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from,fromlen); 为什么呢?明明一模一样的啊,可是命令行可以,android启动个服务就死在这里了。纠结了一天也不知道什么原因。
想想不对啊,最后看了下生成的那个用来通信的接口,/data/misc/wifi/sockets/下的权限是system,而/wlan0/wlan0这个接口的权限是wifi,难道是这个问题?而命令行的时候/data/misc/wifi/sockets/下的权限是wifi,好吧,看来就是这个问题了,有了定位,那么事情就好办多了,接着想想那个权限到底怎么给设置上去的呢?找了好久发现了一个小问题。
[html] view plain copy print ?
- external/wpa_supplicant_8/hostapd/src/utrls/os-unix.c
-
-
-
- int os_program_init(void)
-
- {
-
- #ifdef ANDROID
-
- /*
-
- * We ignore errors here since errors are normal if we
-
- * are already running as non-root.
-
- */
-
- gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE };
-
- struct __user_cap_header_struct header;
-
- struct __user_cap_data_struct cap;
-
-
-
- setgroups(sizeof(groups)/sizeof(groups[0]), groups);
-
-
-
- prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
-
-
-
- setgid(AID_WIFI);
-
- setuid(AID_WIFI);
-
-
-
- header.version = _LINUX_CAPABILITY_VERSION;
-
- header.pid = 0;
-
- cap.effective = cap.permitted =
-
- (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
-
- cap.inheritable = 0;
-
- capset(&header, &cap);
-
- #endif /* ANDROID */
-
-
-
- #ifdef WPA_TRACE
-
- dl_list_init(&alloc_list);
-
- #endif /* WPA_TRACE */
-
- return 0;
-
- }
external/wpa_supplicant_8/hostapd/src/utrls/os-unix.c
int os_program_init(void)
{
#ifdef ANDROID
/*
* We ignore errors here since errors are normal if we
* are already running as non-root.
*/
gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE };
struct __user_cap_header_struct header;
struct __user_cap_data_struct cap;
setgroups(sizeof(groups)/sizeof(groups[0]), groups);
prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
setgid(AID_WIFI);
setuid(AID_WIFI);
header.version = _LINUX_CAPABILITY_VERSION;
header.pid = 0;
cap.effective = cap.permitted =
(1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
cap.inheritable = 0;
capset(&header, &cap);
#endif /* ANDROID */
#ifdef WPA_TRACE
dl_list_init(&alloc_list);
#endif /* WPA_TRACE */
return 0;
}
可恶的,应该就是这了 gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE然后把#ifdef ANDROID改为#if 0重新编译,启动,终于可以在android UI界面里搜索到网络并且连接上了。OK,调试完成,接着就是整理完善了。
坎坎坷坷,总算把wifi给适配好了,主要还是经验不足啊,相信通过不断的努力,我可以很快进步,相信把所做的总结下来,记录下来,不仅可以帮到别人,也可以不断提高自己,完善自己。
补充:
关于IP的自动获取不成功的问题,下午找了下原因还是那个恶心的权限问题,因为我是用的unix标准的sockets,而不是android内部的sockets,所以出问题了。只要在
External/dhcpcd/dhcpcd.c中头文件的位置加上以下几句,然后再mm生成的dhcpcd就可以了
[html] view plain copy print ?
- #ifdef ANDROID
-
- #undef ANDROID
-
- #endif
#ifdef ANDROID
#undef ANDROID
#endif
ok,至此,USB wifi的移植就完全成功了。好好回去休息吧,又是周末了。。