- 浏览: 263453 次
- 性别:
- 来自: 济南
文章分类
- 全部博客 (303)
- c (31)
- c++ (16)
- java (18)
- c# (1)
- python (3)
- java web (6)
- oracle (7)
- sqlserver (2)
- mysql (2)
- android (24)
- android系统 (15)
- android多媒体部分 (15)
- android游戏 (12)
- linux (26)
- javaScript (1)
- ajax (1)
- node JS (2)
- html (5)
- apache (3)
- jboss (1)
- weblogic (0)
- 通信协议 (10)
- 云计算 (1)
- 分布式 (5)
- ejb (1)
- webservice (5)
- 设计模式 (16)
- JNI (6)
- swing (13)
- 版本控制 (1)
- UML (1)
- xml (4)
- spring (5)
- hibernate (5)
- struts1 (3)
- struts2 (4)
- ibatis (0)
- tomcat (2)
- 心得体会 (1)
- css (1)
- 嵌入式 (41)
- arm体系结构 (10)
Android的联接部分
Wifi部分
Wifi的基本架构
自上而下包括的一些内容:
Linux内核的标准wifi驱动程序和协议
Wap_supplicant可执行程序(WAP应用层认证客户端)
Wifi的HAL
WIFI的JNI接口
Wifi的java框架
Wifi的相关应用
Wifi的结构图如下:
Wifi的本地实现(主要包括wap_supplicant和wap_supplicant适配层)
WAP是wifiprotectedAccess
Wap_supplicant是WAP应用层认证客户端,负责认证完成相关的登陆和加密工作,他是一个开源的
代码路径为:\external\wpa_supplicant文件名为:wpq_ctrl.c
部分代码如下:
最终生成动态库libwap_client.so
Wap_supplicant是一个独立的守护进程,其通信是通过socket协议定完成
Wap_supplicant和wext驱动接口的联系
在driver.h头文件中,部分代码如下:
//该结构体是扫描结果的通用格式
structwpa_scan_result{
u8bssid[ETH_ALEN];
u8ssid[32];
size_tssid_len;
u8wpa_ie[SSID_MAX_WPA_IE_LEN];
size_twpa_ie_len;
u8rsn_ie[SSID_MAX_WPA_IE_LEN];
size_trsn_ie_len;
intfreq;
u16caps;
intqual;
intnoise;
intlevel;
intmaxrate;
};
//操作函数集合,所有驱动类型的一个接口封装包
structwpa_driver_ops{
constchar*name;
constchar*desc;
int(*get_bssid)(void*priv,u8*bssid);
}
Driver_wext.h:声明了该驱动的一些对应驱动API接口的函数
Driver_wext.c:最后初始化了一个wpa_drv_pos变量
Drivers.c文件:主要定义了不同驱动操作接口的集合
Driver_xxx.h:是不同驱动接口头文件声明了操作接口
Driver_xxx.c:实现操作接口
Wpq_supplicant守护进程是为不同驱动和操作系统具有更好的移植性而设计的,以便在wpa_supplicant层不用实现驱动的具体接口就可以添加新的驱动程序
Wpa_supplicant_xxx函数传递wpa_supplicant实例指针wpa_s参数给wpa_drv_xxx来调用他,
Wpa_drv_xx会通过wpa_s->driver->xxx()来调用通用驱动接口
Wpa_ctrl.h:声明了几个用于socket通信的函数接口
Wpq_ctrl.c:定义了一个wpa_ctrl结构
//根据UDPUNIX和命名管道三种domain类型来定义通信实体
structwpa_ctrl*wpa_ctrl_open(constchar*ctrl_path)
{
structwpa_ctrl*ctrl;
staticintcounter=0;
ctrl=os_malloc(sizeof(*ctrl));
if(ctrl==NULL)
returnNULL;
os_memset(ctrl,0,sizeof(*ctrl));
ctrl->s=socket(PF_UNIX,SOCK_DGRAM,0);
if(ctrl->s<0){
os_free(ctrl);
returnNULL;
}
ctrl->local.sun_family=AF_UNIX;
os_snprintf(ctrl->local.sun_path,sizeof(ctrl->local.sun_path),
#ifdefANDROID
"%s/%s%d-%d",local_socket_dir,local_socket_prefix,
getpid(),counter++);
#else/*ANDROID*/
"/tmp/wpa_ctrl_%d-%d",getpid(),counter++);
#endif
if(bind(ctrl->s,(structsockaddr*)&ctrl->local,
sizeof(ctrl->local))<0){
close(ctrl->s);
os_free(ctrl);
returnNULL;
}
Wpa_supplicant.h:
部分代码如下:
//wpa的事件类型
typedefenumwpa_event_type{}
Wpa_supplicant_i.h:
Wpq_suppliant.c文件中定义的很多函数是在该头文件中声明的,而不是在wpa_supplicant.h中
Wap_supplicant的结构如下:
Wpa-_supplicant适配层
在android中作为wifi部分的硬件抽像层来使用,主要用于封装与wpa_supplicant守护进程的通信(加载、控制、消息监控)
Wpa_supplicant适配层的头文件路径为:
\hardware\libhardware_legacy\include\hardware_legacy\wifi.h
头文件中定义了以下几个重要的方法:
//事件的进入通道,这个函数被阻塞,直到收到一个wifi事件,并以字符串的形式返回
intwifi_wait_for_event(char*buf,size_tlen);
//将命令发送到wifi系统下层的功能,
intwifi_command(constchar*command,char*reply,size_t*reply_len);
实现文件路径为:\hardware\libhardware_legacy\wifi
在实现文件中
//
intwifi_wait_for_event(char*buf,size_tbuflen)
{
size_tnread=buflen-1;
intfd;
fd_setrfds;
intresult;
structtimevaltval;
structtimeval*tptr;
if(monitor_conn==NULL){
LOGD("Connectionclosed\n");
strncpy(buf,WPA_EVENT_TERMINATING"-connectionclosed",buflen-1);
buf[buflen-1]='\0';
returnstrlen(buf);
}
//调用此方法来接收一次wpa_supplication
result=wpa_ctrl_recv(monitor_conn,buf,&nread);
if(result<0){
LOGD("wpa_ctrl_recvfailed:%s\n",strerror(errno));
strncpy(buf,WPA_EVENT_TERMINATING"-recverror",buflen-1);
buf[buflen-1]='\0';
returnstrlen(buf);
}
buf[nread]='\0';
/*LOGD("wait_for_event:result=%dnread=%dstring=\"%s\"\n",result,nread,buf);*/
/*CheckforEOFonthesocket*/
if(result==0&&nread==0){
/*Fabricateaneventtopassup*/
LOGD("ReceivedEOFonsupplicantsocket\n");
strncpy(buf,WPA_EVENT_TERMINATING"-signal0received",buflen-1);
buf[buflen-1]='\0';
returnstrlen(buf);
}
/*
*Eventsstringsareintheformat
*
*<N>CTRL-EVENT-XXX
*
*whereNisthemessagelevelinnumericalform(0=VERBOSE,1=DEBUG,
*etc.)andXXXistheeventname.Thelevelinformationisnotuseful
*tous,sostripitoff.
*/
if(buf[0]=='<'){
char*match=strchr(buf,'>');
if(match!=NULL){
nread-=(match+1-buf);
memmove(buf,match+1,nread+1);
}
}
returnnread;
}
//wifi_command是wifi_send_command的封装
intwifi_send_command(structwpa_ctrl*ctrl,constchar*cmd,char*reply,size_t*reply_len)
{
intret;
if(ctrl_conn==NULL){
LOGV("Notconnectedtowpa_supplicant-\"%s\"commanddropped.\n",cmd);
return-1;
}
//通过此方法发送命令给wpa_supplicant
ret=wpa_ctrl_request(ctrl,cmd,strlen(cmd),reply,reply_len,NULL);
if(ret==-2){
LOGD("'%s'commandtimedout.\n",cmd);
return-2;
}elseif(ret<0||strncmp(reply,"FAIL",4)==0){
return-1;
}
if(strncmp(cmd,"PING",4)==0){
reply[*reply_len]='\0';
}
return0;
}
WIFI的适配层是libhardware_legacy.so的一部分
Wifi的java部分jni部分
JNI部分的源程代码路径为下:
\frameworks\base\core\jni\android_net_wifi_wifi.cpp
在这里实现的本地函数,都是通过调用wpa_supplicant适配层的接口实现的
Java部分实现代码路径为:
\frameworks\base\services\java\com\android\server//wifi服务层的内容
\frameworks\base\wifi\java\android\net\wifi//wifi服务的接口
由上图可以看出:wifiNative.java类提供wifiService类、wifiStateTracker类和wifiMonitor类的底层操作支持
Wifi系统的核心部分是根据IWifiManager接口所创建的Binder服务器端(wifiService)和客户端(wifiManager)
IWifiManager.aidl编译后生成IWifiManager.java。并生成IWifiManager.Stub(服务器端抽象类)和IWifiManager.Stub.Proxy(客户端代理类)
wifiService通过继承IWifiManager.Stub实现,
客户端通过getService()取得IWifiManager.Stub.Proxy,将其作为参数传递给wifiManager
wifiManager是wifi部分与外界的接口wifiwatchDogService也是使用wifiManager来进行具体操作
wifiService是服务器端的实现,处理实际的驱动加载\、扫描,连接,断开
根据客户端的不同命令,调用相应的nativeWifi底层实现 当接收到客户端消息命令后,转换成对应的自身消息加入消息队列,方便客户端调用,在wifiHandler的handlerMessage中来处理对应的消息
对于底层上报的事件,wifiService一般调用wifiStateTracker
wifiStateTracker负责电源控制,设置电源管理模式,其核心是wifiMonitor所实现的事件轮询机制(关键函数是wifiNative..waitForEvent阻塞式函数),该类也是与外部的接口,通过发送广播来完成消息的传递
wifiMontor的通知机制是将底层事件转换成wifistateTracker能识别的消息
wifiWatchDogService是connectivityService启动的服务,它的作用是监控同一网络内的接入点(AccessPoint),如果当前接入点的DNS无法ping通,就自动切入到下一个接入点
在初始化时,通过registerForWifiBroadcasts注册广播接收,捕获wifiStateTracker发出的通知,
开启一个wifiWatchdogThread线程来处理消息
Settings中的wifi设置
原代码的路径为:\packages\apps\Settings\src\com\android\settings\wifi
网络设置的实际功能还是调用wifiManager来实现的,同样注册一个广播接收者来接收wifistateTracker发出的消息
wifiEnable是用来设置wifi的开关
Wifi工作流程实例
例;一个AP的联接流程
1开启wifi
在wifiEnable中调用wifiManager。setwifiEnagled(null,true);
wifimanager.setwifiEnable()通过Binder机制调用wifiService.setWifiEnabled
wifiService.setWifiService.setWifiEnabled将MESSAGE_ENABLE_WIFI消息发送到自已的消息队列
wifiService通过wifHandler的handleMessage处理MESSAGE_ENABLE_WIFI,
调用setWifiEnableBlocking
setWifiEnableBlocking调用setWifiEnabledState,向外发送WIFI_STATE_CHANGED_ACTIONT通知消息
另外一些初始化工作
设置当前状态、加载wifi驱动、开启wpa_supplicant、开启wifiStateTracker、注册广播接收者接收wifiStateTracker的消息
wifiService.java的代码路径为:\frameworks\base\services\java\com\android\server
部分代码如下:
privatebooleansetWifiEnabledBlocking(booleanenable,booleanpersist,intuid){
finalinteventualWifiState=enable?WIFI_STATE_ENABLED:WIFI_STATE_DISABLED;
finalintwifiState=mWifiStateTracker.getWifiState();
if(wifiState==eventualWifiState){
returntrue;
}
if(enable&&isAirplaneModeOn()&&!mAirplaneModeOverwridden){
returnfalse;
}
/**
*MultiplecallstounregisterReceiver()causeexceptionandasystemcrash.
*Thiscanhappenifasupplicantislost(orfirmwarecrashoccurs)anduserindicates
*disablewifiatthesametime.
*AvoiddoingadisablewhenthecurrentWifistateisUNKNOWN
*TODO:Handledriverloadfailandsupplicantlostasseperatestates
*/
if((wifiState==WIFI_STATE_UNKNOWN)&&!enable){
returnfalse;
}
/**
*FailWifiifAPisenabled
*TODO:DeprecateWIFI_STATE_UNKNOWNandrenameit
*WIFI_STATE_FAILED
*/
if((mWifiApState==WIFI_AP_STATE_ENABLED)&&enable){
setWifiEnabledState(WIFI_STATE_UNKNOWN,uid);
returnfalse;
}
setWifiEnabledState(enable?WIFI_STATE_ENABLING:WIFI_STATE_DISABLING,uid);
if(enable){
//调用JNI层,加载wifi驱动
if(!mWifiStateTracker.loadDriver()){
Slog.e(TAG,"FailedtoloadWi-Fidriver.");
setWifiEnabledState(WIFI_STATE_UNKNOWN,uid);
returnfalse;
}
//调用JNI层开启supplicant
if(!mWifiStateTracker.startSupplicant()){
mWifiStateTracker.unloadDriver();
Slog.e(TAG,"Failedtostartsupplicantdaemon.");
setWifiEnabledState(WIFI_STATE_UNKNOWN,uid);
returnfalse;
}
registerForBroadcasts();
mWifiStateTracker.startEventLoop();
}else{
mContext.unregisterReceiver(mReceiver);
//Removenotification(itwillno-opifitisn'tvisible)
mWifiStateTracker.setNotificationVisible(false,0,false,0);
booleanfailedToStopSupplicantOrUnloadDriver=false;
if(!mWifiStateTracker.stopSupplicant()){
Slog.e(TAG,"Failedtostopsupplicantdaemon.");
setWifiEnabledState(WIFI_STATE_UNKNOWN,uid);
failedToStopSupplicantOrUnloadDriver=true;
}
/**
*Resetconnectionsanddisableinterface
*beforeweunloadthedriver
*/
mWifiStateTracker.resetConnections(true);
if(!mWifiStateTracker.unloadDriver()){
Slog.e(TAG,"FailedtounloadWi-Fidriver.");
if(!failedToStopSupplicantOrUnloadDriver){
setWifiEnabledState(WIFI_STATE_UNKNOWN,uid);
failedToStopSupplicantOrUnloadDriver=true;
}
}
if(failedToStopSupplicantOrUnloadDriver){
returnfalse;
}
}
//Success!
if(persist){
persistWifiEnabled(enable);
}
setWifiEnabledState(eventualWifiState,uid);
returntrue;
}
2在wifi开启完成后,接下就是搜索AP
启动supplient守护进程,启动MonitorThread开始监听supplient的事件。
****Setting中wifiLayer.attemptScan()调用wifiManager.startScan();*****
在wifi2.3之后就没有wifiLayer类了,取而代之的是wifiSetting在wifiSetting中有一个扫描类,Scanner,用于扫搜索AP
wifimanager.startScan()通过Binder机制调用wifiService.starScan();
首先MonitorThread会收到DRIVER_STATE事件,wifiNative.scanCommand()向supplient发送搜索AP的命令给wpa_supplicant,中间经过JNI实现的doCommand,最终调用wap_supplicant适配层的wifiCommand来完成发送过程
命令的最终响应由wpa_supplicant上报"SCAN-RESULT"消息,wifiStateTracker开启的wifiMonitor的monitorThread可以获取此消息,
handlerEvent的处理方式是调用wifiStateTracker.notifyScanResultsAvailable;
发送广播:mContext.sendBroadcast(newIntent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
wifiSetting中会得到这个消息.作相关的处理操作
连接AP
在supplient搜索AP结束时,monitorThread会收到SCAN_RESULTS
接下来会调用wifiNative.setScanResultHandlingCommand(normalMode)来让supplient自行去连接哪个AP,首先会去挑选信号强并没有密码的AP进行联接
wifiSettings会收到wifiManager.SCAN_RESULTE_AVAILABLE_ACTION广播
当supplient联接到一个AP时,monitorThread会收到CONNECTED事件,配置IP地址,
如果配置成功会发送EVENT_STATE_CHANGED,ConnectivityService就会根据网络优先级决定关掉以太网,android为了省电会将之前的网络设为desable
mWifiManager.enableNetwork(networkId,false);
发表评论
-
android系统学习笔记一
2012-09-03 15:01 9161.android的系统架构(linux2.6内核) Lin ... -
android系统学习笔记二
2012-09-03 15:03 920android的linux内核和驱动程序 Androidr专 ... -
android系统学习笔记三
2012-09-03 15:05 842第四章android的底层库和程序 知识点: And ... -
android系统学习笔记四
2012-09-03 15:07 1141Android的GUI系统 AndroidGUI系统综 ... -
android系统学习笔记五
2012-09-03 15:12 2205android中的audio系统 Audo系统主要分如下几 ... -
android系统学习笔记六
2012-09-03 15:16 2229android的多媒体系统 ... -
android系统学习笔记七
2012-09-03 15:18 747Android电话部分综述 主 ... -
android系统学习笔记九
2012-09-03 15:21 740蓝牙部分 蓝牙协议栈1.11.22.02.13.0 异步数 ... -
android系统学习笔记十一
2012-09-03 15:22 1513Gps(globalPositionSystem全球定位系统) ... -
android系统学习笔记十二
2012-09-03 15:23 1022Android的传感器系统 ... -
Android编译系统详解(一)
2012-09-10 13:45 840+++++++++++++++++++++++++++++ ... -
android----ServiceManager
2012-09-18 00:33 4324serviceManager 在c++层如何使用servi ... -
android 自定义核心服务
2012-09-18 23:27 803native service zygote 服务 kern ... -
android系统移植学习笔记一
2012-09-21 16:08 635系统框架 applicationjava应用程序 ...
相关推荐
总结,通过解析和学习"安卓Android源码——安卓Android系统日历日程操作.rar"中的CalendarDemo,我们可以了解到Android系统日历API的使用,包括添加、查询、更新和删除日历事件的方法,以及权限处理和数据操作的流程...
Android内核基于Linux平台,有着较快的处理速度和较好的系统性能,使用平台无关的Java语言作为其开发语言,可移植性好,可以广泛支持智能手机、平板电脑等移动设备,是移动学习软件研究和开发的首选平台。...
Android 项目是使用 Android 操作系统和相关开发工具开发的一款移动应用程序。Android 平台提供了丰富的功能和接口,开发人员可以使用 Java 或 Kotlin 等编程语言编写 Android 应用程序。Android 项目也可以是针对...
Android系统源代码情景分析 [罗升阳著][电子工业出版社][2012.10][840页].pdf Android官方API文档完整版.chm ANDROID的设计与实现 卷1_13259533.pdf Android(卷2)(带全目录完整版)邓凡平.pdf Android源码设计模式...
在安卓Android系统中,开发一个相册应用是常见的任务,涉及到图像处理、UI设计以及数据管理等多个方面。这个压缩包“安卓Android源码——android相册系统(用Matrix实现).rar”显然提供了一个使用Matrix类来实现相册...
安卓Android精品课程在线学习系统app设计 系统开发环境: Windows + Myclipse(服务器端) + Eclipse(手机客户端) + mysql数据库 服务器也可以用Eclipse或者idea等工具,客户端也可以采用android studio工具! 系统...
【毕业设计-基于安卓Android销售管理系统】是一款专为学习者和开发者设计的实践项目,它提供了全面的课程指导以及源代码,旨在帮助学生和新手掌握Android平台上的销售管理系统的开发技术。这个系统能够帮助企业或...
Android系统学习文档
【安卓Android开发学习文档API.CHM】是一份针对Android应用开发者的重要参考资料,它包含了全面的Android SDK信息,帮助开发者深入理解和实践Android平台的开发工作。这份文档主要由两个CHM(Compiled HTML Help)...
本压缩包文件"安卓Android源码——安卓Android学习——数据存储.rar"显然是针对安卓数据存储机制的学习资料,其中可能包含了相关的源代码示例和讲解。下面我们将深入探讨安卓中的数据存储方法。 1. **Shared ...
高质量Android系统化技术学习脑图,是作者多年Android开发经验的结晶,你值得拥有!
"安卓Android商品销售管理系统源码.zip" 这个标题表明这是一个与安卓应用开发相关的项目,特别是一个商品销售管理系统的源代码。在Android平台上,开发人员经常使用Java或Kotlin语言编写应用程序,而这个系统可能...
在“android系统函数大全”文档中,你可能会找到这些领域的详细函数解析和示例代码,对于深入学习Android编程非常有帮助。开发者应根据实际需求,结合文档,灵活运用这些函数,构建高效且功能丰富的Android应用。
这份"安卓Android源码——安卓Android系统访问串口设备源码.rar"压缩包提供了相关的源代码和资料,帮助开发者理解和实现这一功能。 首先,我们需要了解的是Android系统对串口的支持。在Linux内核的基础上构建的...
总之,《深入理解Android系统》是一本全面覆盖Android系统各层次的书籍,不仅适合有经验的Android开发者进行深入学习,也适合初学者作为理解Android系统原理的入门教材。通过阅读这本书,读者可以提升自己的Android...
本源码是一个基于Android平台的新闻发布系统,旨在提供一个集新闻浏览、分类筛选、文章详情展示等功能于一体的移动应用程序。通过分析这个源码,我们可以深入理解Android开发中的关键技术和设计模式。 1. **...
Android中、高级开发者:通过本书的引导,学习系统架构,关注开发要点,并尽量使用手机系统的通用设计思想、软件工程思想、系统工程思想来指导Android系统学习。 嵌入式Linux系统学习者:将Android作为一个集...
摘要中的内容提到了一个基于Android的在线考试系统的设计与实现,该系统利用JSP技术、MySQL数据库、Java编程语言和Android系统,旨在管理和处理考试相关信息。系统分为三个主要模块,分别对应服务端管理员、客户端...
《Android系统原理及开发要点详解》全面介绍开放的移动电话平台Android系统,包括Android...《Android系统原理及开发要点详解》既适合从事Android各个层次开发的工程师阅读,也适合通用嵌入式Linux系统的学习者使用。