本文共 1686 字,大约阅读时间需要 5 分钟。
android中wifi的上下层的连接、命令发送
上层可调用的命令在JNINativeMethodgWifiMethods[]中,执行的方式大部分都相同,都是利用管道或socket等方式来传递,但在此之前要做一些准备:加载驱动,连接supplicant等。准备的方式就是访问wifi驱动的状态值,如若没有加载驱动就会执行insmod命令。在此之后的命令执行方式如下所述:
Java首先要和wpa_supplicant取得联系:
wifi_connect_to_supplicantàwpa_ctrl_open打开conn-ctrl和monitor-ctrl通道。
àwpa_ctrl_attachàwpa_ctrl_attach_helperàwpa_ctrl_requestàselect()
监听通道的状态是否为可读。如果可读,执行recv(),否则等待。
java层通过connectToSupplicant调用wifi_connect_to_supplicant函数,在该函数中,将通过wpa_ctrl_open
函数分别创建两个AF_UNIX地址族和数据报方式的socket,一个是ctrl_conn,用于向wpa_supplicant
发送命令并接收response,另一个是monitor_conn,它一直阻塞等待从wpa_supplicant过来的event。
最后,通过monitor_conn向wpa_supplicant发送命令ATTACH,用于将自己的socket信息注册到
wpa_supplicant,由于socket是数据报方式的,这一步是必须的,对于存在于wpa_supplicant的服务器端,
它是所有客户端共享的,由于它需要主动向monitor_conn客户端发送事件,所以它必须先记录下
该客户端的详细信息,wpa_supplicant就可以将EVENT发向该socket。
Attach的目的是将wpa_supplicnat与java上层连接起来,之后的命令发送完全依靠该通道。
以scan为例:
{"scanCommand", "()Z", (void*)android_net_wifi_scanCommand },
àresult =doBooleanCommand("SCAN", "OK");
àdoCommand(cmd,reply, sizeof(reply)
à::wifi_command(cmd, replybuf, &reply_len)
àwifi_send_command(ctrl_conn, command, reply, reply_len)
àwpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL);
àsend(ctrl->s,_cmd, _cmd_len, 0)
从wpa_supplicant搜索的线索如下:
wpa_supplicant_thread
àwpa_supplicant_init
àwpa_supplicant_global_ctrl_iface_init() udp |socket|name_pipe
àwpa_supplicant_global_ctrl_iface_receive() udp|socket|name_pipe
àwpa_supplicant_global_ctrl_iface_process()
àwpa_supplicant_global_iface_add
àwpa_supplicant_add_iface
àwpa_supplicant_init_iface
àwpa_supplicant_set_driver() 完成驱动指定
在wpa_supplicant_global_ctrl_iface_init()中android_get_control_socket可以与上层的通道对接。
在工作过程中上层java发送命令后wpa_supplicant的接收情况:
转载地址:http://xbngi.baihongyu.com/