WEXT driver的执行过程实现(iwpriv部分/softapcontroller)
前言
之前在看wifi driver源代码时一直有一个疑惑就是net dev的wireless_handlers中(WEXT类型的接口)提供两个iw_handler接口,怎么知道上层是调用的是private中的函数还是standard中的SIOCSIWPRIV接口和SIOCGIWPRIV接口。
问Wifi的FAE,人家也不清楚,后来没办法只好在源代码中找,现在终于有点头绪与大家分享一下。
android 中有个system/netd/目录,在netd下有个softapController.cpp文件实际上该文件实现了程序iwpriv的功能,那么这个程序是干嘛的呢?嘿嘿从名字就可看出啦是给softap下control 命令的。至于这些命令从哪里来,待后续有机会再与大家分享netd部分时再讨论。
分析代码的从入口函数开始,构造函数
SoftapController::SoftapController()
mSock = socket(AF_INET,SOCK_DGRAM, 0); //socket调用,这个我们之前有分析过,这个mSock很重要,这就是socket关联的文件描述符接口,上层通过该接口与内核沟通。
其它函数除了getPrivFuncNum外基本都是开给上层的函数接口,用于和底层沟通。我们就分析打开softap执行的第一个函数startDriver
fnum = getPrivFuncNum(iface,"START");//函数用START作为参数,并返回该函数在driver中private中的第几个
ret = ioctl(mSock, fnum, &wrq);//执行指定的(”START”所对应的)程序
getPrivFuncNum函数
strncpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name));//指定net device 比如wlan0/eth0
wrq.u.data.pointer = mBuf;
wrq.u.data.length = sizeof(mBuf) /sizeof(struct iw_priv_args);
wrq.u.data.flags = 0;
if ((ret = ioctl(mSock,SIOCGIWPRIV, &wrq)) < 0) {//获得driver private handler的iw_priv_args
LOGE("SIOCGIPRIV failed: %d",ret);
return ret;
}
priv_ptr = (struct iw_priv_args*)wrq.u.data.pointer;
for(i=0;(i < wrq.u.data.length);i++) {
if (strcmp(priv_ptr[i].name, fname) ==0)//找出指定CMD
return priv_ptr[i].cmd;
}
之前看这段代码时真是困惑死了,SIOCGIWPRIV明明是standard提供的一个标准接口且在我要调用的wifi driver中并没有实现怎么会调用结果是获得private 的iw_priv_args,目前我先将该疑问留着到后面自然会明白。
如下我只分析ioctl(mSock, SIOCGIWPRIV,&wrq)的流程,其它的ioctl流程基本一致只是过程中调用不同的函数。
如上调用实际上该函数最终通过系统调用调用到kernel space.如下所示
kernel/fs/Ioctl.c
SYSCALL_DEFINE3(ioctl, unsigned int, fd,unsigned int, cmd, unsigned long, arg)
{
……………………………………………………………………..
error= do_vfs_ioctl(filp, fd, cmd, arg);//调用虚拟文件系统的ioctl
……………………………………………………………..
}
如上系统调用ioctl
int do_vfs_ioctl(struct file *filp,unsigned int fd, unsigned int cmd,
unsigned long arg)
switch (cmd) {
…………………………………………..
default:
if(S_ISREG(filp->f_path.dentry->d_inode->i_mode))
error= file_ioctl(filp, cmd, arg);
else
error= vfs_ioctl(filp, cmd, arg);
break;
staticlong vfs_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int error = -ENOTTY;