android手动连接wifi的过程
2013-11-14 14:59
441 查看
android手动连接wifi的过程
下面就以手动连接mtk5931的wifi为列,来说明手动连接wifi的过程。
在此之前,先说明下,手动连接的使用场景和作用:
a: 在纯linux的环境下,该手动连接过程,同样适用
b: 在wifi驱动的移植初期,可以通过手动连接来测试该款wifi的基本驱动和wpa_supplicant是否工作正常
c: 通过手动连接,你可以很容易了解wifi的工作过程
d: 通过手动连接,可以很容易的调试,可以很好的定位问题出现哪里。
先概括下wifi手动连接的几个步骤:
a:加载wifi驱动
b:给wifi上电(optional)
c:此时应该出来了网络接口(譬如wlan0),给网络接口上电(ifconfig wlan0 up)
d:对于支持sta/p2p共存的,这个时候可以通过iwpriv命令,生成p2p0网络接口
e:设定wpa_supplicant服务所需的配置文件:wpa_supplicant.conf
f:启动wpa_supplicant,在后台运行
g:启动wpa_cli,并且连接到wpa_supplicant,这个时候可以通过wpa_cli来发送命令给wpa_supplicant来执行。
譬如有时,通过android,有些ap连不上,或不能扫描,或是鉴权失败,则这个时候可以试试通过手动操作来验证问题。如果手动测试是ok的,说明问题是出现在android层的(wifi Setting, wifi framework, wifi service等层)
步骤a:加载wifi驱动
通过insmod命令加载wifi驱动模块,由于mt5931在系统启动阶段的init.rc中,就已经被加载了。所以此处不需要手动加载。见下图(高亮部分即为mt5931所需的驱动模块):
步骤b:由于mt5931的上电,是通过设备节点来控制的。如下:
步骤c:ifconfig wlan0 up
步骤d:通过iwpriv命令,生成了p2p0,通过ifconfig -a命令可以看到,此时已经有两个网络接口了。
步骤e:设置wpa_supplicant.conf文件,关键是设置ctrl_interface字段,因为该字段直接设定了控制socket的服务器端的节点位置。另外通过配置该文件,还可以在起wpa_supplicant时,让wifi直接连接上指定的AP.方法如下:
如上配置文件,是将wpa_supplicant的service端的socket节点设置在/data/misc/wpa_supplicant目录下,该service socket节点将在wpa_supplicant启动阶段根据这个配置的指定就会建立;并且还指定了自动连接wpa2加密方式的ap:ASUS_BEN_NEW
步骤f:启动wpa_supplicant,在后台运行
以上启动命令中,-i选项指定网络接口,由于是sta/p2p共存,所有需要同时指定两个网络接口了。每个接口对应的配置文件通过-c选项来指定;-D选项,用来指定wext方式还是netlink的方式跟内核进行的交互;-dd选项则是设置打印信息的级别为debug级;-N表示开始描述一个新的网络接口;&表示后台执行。
步骤g:启动wpa_cli,其中-p选项,指定该客服端程序要连接到wpa_supplicant中的service端的socket节点的位置,即控制socket的路径。该位置需要跟wpa_supplicant.conf文件中的设定要匹配
至此可以在wpa_cli的命令输入提示符后面,输入要测试的命令。还可以直接敲入help命令,可以得到wpa_cli所支持的命令。在这个下面,可以执行手动连接p2p,手动连接Ap等操作。
譬如测试pktcnt_poll命令:
以及手动执行扫描(scan),和获取扫描结果的命令(scan_results):
由于客服端程序wpa_cli连接到服务器端的控制socket,是通过wpa_ctrl_open函数实现的,该函数展开如下:
再来看下services段的socket节点,如上wpa_supplicant.conf文件所指定的,service端的控制socket节点,是在如下路径的:
service端的socket节点名字就是各自的网络接口名字。
下面就以手动连接mtk5931的wifi为列,来说明手动连接wifi的过程。
在此之前,先说明下,手动连接的使用场景和作用:
a: 在纯linux的环境下,该手动连接过程,同样适用
b: 在wifi驱动的移植初期,可以通过手动连接来测试该款wifi的基本驱动和wpa_supplicant是否工作正常
c: 通过手动连接,你可以很容易了解wifi的工作过程
d: 通过手动连接,可以很容易的调试,可以很好的定位问题出现哪里。
先概括下wifi手动连接的几个步骤:
a:加载wifi驱动
b:给wifi上电(optional)
c:此时应该出来了网络接口(譬如wlan0),给网络接口上电(ifconfig wlan0 up)
d:对于支持sta/p2p共存的,这个时候可以通过iwpriv命令,生成p2p0网络接口
e:设定wpa_supplicant服务所需的配置文件:wpa_supplicant.conf
f:启动wpa_supplicant,在后台运行
g:启动wpa_cli,并且连接到wpa_supplicant,这个时候可以通过wpa_cli来发送命令给wpa_supplicant来执行。
譬如有时,通过android,有些ap连不上,或不能扫描,或是鉴权失败,则这个时候可以试试通过手动操作来验证问题。如果手动测试是ok的,说明问题是出现在android层的(wifi Setting, wifi framework, wifi service等层)
步骤a:加载wifi驱动
通过insmod命令加载wifi驱动模块,由于mt5931在系统启动阶段的init.rc中,就已经被加载了。所以此处不需要手动加载。见下图(高亮部分即为mt5931所需的驱动模块):
步骤b:由于mt5931的上电,是通过设备节点来控制的。如下:
步骤c:ifconfig wlan0 up
步骤d:通过iwpriv命令,生成了p2p0,通过ifconfig -a命令可以看到,此时已经有两个网络接口了。
步骤e:设置wpa_supplicant.conf文件,关键是设置ctrl_interface字段,因为该字段直接设定了控制socket的服务器端的节点位置。另外通过配置该文件,还可以在起wpa_supplicant时,让wifi直接连接上指定的AP.方法如下:
如上配置文件,是将wpa_supplicant的service端的socket节点设置在/data/misc/wpa_supplicant目录下,该service socket节点将在wpa_supplicant启动阶段根据这个配置的指定就会建立;并且还指定了自动连接wpa2加密方式的ap:ASUS_BEN_NEW
步骤f:启动wpa_supplicant,在后台运行
以上启动命令中,-i选项指定网络接口,由于是sta/p2p共存,所有需要同时指定两个网络接口了。每个接口对应的配置文件通过-c选项来指定;-D选项,用来指定wext方式还是netlink的方式跟内核进行的交互;-dd选项则是设置打印信息的级别为debug级;-N表示开始描述一个新的网络接口;&表示后台执行。
步骤g:启动wpa_cli,其中-p选项,指定该客服端程序要连接到wpa_supplicant中的service端的socket节点的位置,即控制socket的路径。该位置需要跟wpa_supplicant.conf文件中的设定要匹配
至此可以在wpa_cli的命令输入提示符后面,输入要测试的命令。还可以直接敲入help命令,可以得到wpa_cli所支持的命令。在这个下面,可以执行手动连接p2p,手动连接Ap等操作。
譬如测试pktcnt_poll命令:
以及手动执行扫描(scan),和获取扫描结果的命令(scan_results):
由于客服端程序wpa_cli连接到服务器端的控制socket,是通过wpa_ctrl_open函数实现的,该函数展开如下:
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) { struct wpa_ctrl *ctrl; static int counter = 0; int ret; size_t res; int tries = 0; int flags; ctrl = os_malloc(sizeof(*ctrl)); if (ctrl == NULL) return NULL; os_memset(ctrl, 0, sizeof(*ctrl)); ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0); if (ctrl->s < 0) { os_free(ctrl); return NULL; } ctrl->local.sun_family = AF_UNIX; counter++; try_again: //如下语句指定了客服端的socket节点是在/data/misc/wifi/sockets路径下,并且节点名是有当前线程的ID和一个序号数组成。 ret = os_snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path), CONFIG_CTRL_IFACE_CLIENT_DIR "/" CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d", (int) getpid(), counter); if (ret < 0 || (size_t) ret >= sizeof(ctrl->local.sun_path)) { close(ctrl->s); os_free(ctrl); return NULL; } tries++; if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, sizeof(ctrl->local)) < 0) {//指定bind的时候,就会创建该client端的socket节点 if (errno == EADDRINUSE && tries < 2) { /* * getpid() returns unique identifier for this instance * of wpa_ctrl, so the existing socket file must have * been left by unclean termination of an earlier run. * Remove the file and try again. */ unlink(ctrl->local.sun_path); goto try_again; } close(ctrl->s); os_free(ctrl); return NULL; } #if defined(ANDROID) && !defined(PURE_LINUX) chmod(ctrl->local.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); chown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); /* * If the ctrl_path isn't an absolute pathname, assume that * it's the name of a socket in the Android reserved namespace. * Otherwise, it's a normal UNIX domain socket appearing in the * filesystem. */ if (ctrl_path != NULL && *ctrl_path != '/') { char buf[21]; os_snprintf(buf, sizeof(buf), "wpa_%s", ctrl_path); if (socket_local_client_connect( ctrl->s, buf, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM) < 0) { close(ctrl->s); unlink(ctrl->local.sun_path); os_free(ctrl); return NULL; } return ctrl; } #endif /* ANDROID */ ctrl->dest.sun_family = AF_UNIX; res = os_strlcpy(ctrl->dest.sun_path, ctrl_path, sizeof(ctrl->dest.sun_path)); if (res >= sizeof(ctrl->dest.sun_path)) { close(ctrl->s); os_free(ctrl); return NULL; }//开始发起连接到service端的socket节点 if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest, sizeof(ctrl->dest)) < 0) { close(ctrl->s); unlink(ctrl->local.sun_path); os_free(ctrl); return NULL; } /* * Make socket non-blocking so that we don't hang forever if * target dies unexpectedly. */ flags = fcntl(ctrl->s, F_GETFL); if (flags >= 0) { flags |= O_NONBLOCK; if (fcntl(ctrl->s, F_SETFL, flags) < 0) { perror("fcntl(ctrl->s, O_NONBLOCK)"); /* Not fatal, continue on.*/ } } return ctrl; }如下你可以看到wpa_cli进程号是1517,而/data/misc/wifi/sockets下的client端socket节点的名字就是以该进程ID和序号组成的。两个节点,一个用来传输控制命令,一个用来接受wpa_supplicant报上来的事件。
再来看下services段的socket节点,如上wpa_supplicant.conf文件所指定的,service端的控制socket节点,是在如下路径的:
service端的socket节点名字就是各自的网络接口名字。
相关文章推荐
- android手动连接wifi的过程
- Android WifiDisplay分析二:Wifi display连接过程
- Android WifiDisplay分析二:Wifi display连接过程
- Android WifiDisplay分析二:Wifi display连接过程
- Android Wifi驱动--底层&& WIFI手动命令行连接AP
- Android WifiDisplay分析二:Wifi display连接过程
- Android之与当前连接的wifi进行文件夹的浏览与传输
- android sutdio调试无线连接,直正的丢掉数据线 ADB WIFI
- ADB通过WIFI连接Android设备
- android 4.0 WIFI工作过程(应用层)
- Android开机启动检测和连接wifi检测
- Android连接wifi,调用系统API【转】
- Android系统中通过shell命令实现wifi的连接控制
- Android中使用代码控制Wifi及数据连接网络开关
- Android编程实现获取当前连接wifi名字的方法
- android网络的评分机制、连接国内ap wifi不回连问题
- Android通过wifi连接Intermec PB50打印机进行条码打印
- Android 连接Wifi和创建Wifi热点 demo
- android中wifi的上下层的连接、命令发送
- Android之使用wifi连接adb