数据业务建立流程之发起网络连接过程原.docx
- 文档编号:28390157
- 上传时间:2023-07-10
- 格式:DOCX
- 页数:9
- 大小:19.34KB
数据业务建立流程之发起网络连接过程原.docx
《数据业务建立流程之发起网络连接过程原.docx》由会员分享,可在线阅读,更多相关《数据业务建立流程之发起网络连接过程原.docx(9页珍藏版)》请在冰豆网上搜索。
数据业务建立流程之发起网络连接过程原
数据业务建立流程之发起网络连接过程(原)
经过前面这些过程,网络连接所需要的条件就全部准备就绪,接下来就是等待网络接入。
我们把网络接入过程简单分为三个阶段:
触发阶段
----该阶段是由各种不同事件触发的,比如SIM载入完毕、PS域Attach成功、通话结束、APN改变等,该阶段的最终都是要调用setupDataOnConnectableApns()方法;
准备连接阶段
----该阶段是指,在DcTracker收到建立连接的请求之后,需要进行一系列有效性检测,比如APN是否已经激活、PS是否已经就绪、用户是否打开网络开关等,然后创建DataConnection()对象,准备发起连接请求;
发送连接命令阶段
----该阶段是指,在DataConnection收到DcTracker的请求之后,将请求转交给RILJ的过程,经过该阶段后,请求就发送到了RIL以及Modem层,由底层完成信令的发送和接收;一、触发阶段有多种事件可以触发网络接入过程,具体来说分为以下几个原因:
[java]viewplaincopy//漫游相关staticfinalStringREASON_ROAMING_ON="roamingOn";staticfinalStringREASON_ROAMING_OFF="roamingOff";//PSattachstaticfinalStringREASON_DATA_ATTACHED="dataAttached";//APN改变staticfinalStringREASON_APN_CHANGED="apnChanged";//通话结束staticfinalStringREASON_VOICE_CALL_ENDED="2GVoiceCallEnded";//SIM载入完毕staticfinalStringREASON_SIM_LOADED="simLoaded";//网络模式改变staticfinalStringREASON_NW_TYPE_CHANGED="nwTypeChanged";我们挑选最常见的REASON_DATA_ATTACHED原因来分析网络连接的发起过程。
什么是DataAttach事件呢?
其实就是手机的PS域Attach成功,而PS域是和CS域相对应,简单来说,手机(2G/3G)打电话是在CS域上进行,而数据流量是在PS域上进行,PS域附着(Attach)成功之后才可以发起数据激活的信令,然后才可以上网,默认状态下,手机开机后就会发起PS附着的信令给网络,附着成功之后将会接到成功的消息,由于DcTracker当初初始化时在registerForAllEvents()中注册了Attach的监听器:
[java]viewplaincopyprotectedvoidregisterForAllEvents(){//监听是否PS域Attach状态mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,DctConstants.EVENT_DATA_CONNECTION_ATTACHED,null);}因此当PS域Attach成功之后,将会收到EVENT_DATA_CONNECTION_ATTACHED消息:
[java]viewplaincopypublicvoidhandleMessage(Messagemsg){switch(msg.what){caseDctConstants.EVENT_DATA_CONNECTION_ATTACHED:
onDataConnectionAttached();break;}}继续:
[java]viewplaincopyprivatevoidonDataConnectionAttached(){mAttached.set(true);if(getOverallState()==DctConstants.State.CONNECTED){//已经处于连接状态startNetStatPoll();startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);notifyDataConnection(Phone.REASON_DATA_ATTACHED);}else{//初始化后应该处于IDLE状态notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);}if(mAutoAttachOnCreationConfig){mAutoAttachOnCreation=true;}setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);}当前的连接状态是IDLE,因此会将REASON_DATA_ATTACHED的参数传递给notifyOffApnsOfAvailability(),里面也没什么内容,我们直接来看setupDataOnConnectableApns()的操作。
setupDataOnConnectableApns()就是发起数据连接时使用的方法,调用该方法时需要传递一个原因的参数,该参数标明当前建立数据连接的原因(其实目前也没有发现该参数的具体作用)。
其他诸如SIM载入完毕、通话结束等触发事件也都是通过该方法发起数据连接请求的。
二、准备连接阶段当由于种种原因触发网络连接请求时,就会调用到setupDataOnConnectableApns()方法,并传递各种原因的参数,接下来就需要准备APN并进行各种有效性检测,并最终将请求转交给DataConnection来处理。
[java]viewplaincopyprivatevoidsetupDataOnConnectableApns(Stringreason){//对于当前环境来说,reason为REASON_DATA_ATTACHEDfor(ApnContextapnContext:
mPrioritySortedApnContexts){if(apnContext.getState()==DctConstants.State.FAILED){apnContext.setState(DctConstants.State.IDLE);}if(apnContext.isConnectable()){apnContext.setReason(reason);trySetupData(apnContext);}}}在这个方法里面,遍历当前所有的APN参数(mPrioritySortedApnContexts其实等同于mApnContexts,只不过是按照优先级顺序排列了一下而已,项都是一样的),找到可用的APN参数,然后通过trySetupData()发起连接请求,我们来看一下这里如何判断一个APN是否可用,也就是看一下isConnectable()的判断条件:
[java]viewplaincopy@ApnContext.javapublicbooleanisConnectable(){returnisReady()&&((mState==DctConstants.State.IDLE)||(mState==DctConstants.State.SCANNING)||(mState==DctConstants.State.RETRYING)||(mState==DctConstants.State.FAILED));}前面我们说过,激活APN的时候,其实就是让isReady()的判断通过,而mState初始值也是IDLE,因此刚才我们激活的APN参数此时就被挑选出来,并进行trySetupData()的操作:
[java]viewplaincopy@DcTracker.javaprivatebooleantrySetupData(ApnContextapnContext){booleanisEmergencyApn=apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);booleandesiredPowerState=mPhone.getServiceStateTracker().getDesiredPowerState();booleancheckUserDataEnabled=!
(apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS));if(apnContext.isConnectable()&&(isEmergencyApn||(isDataAllowed(apnContext)&&getAnyDataEnabled(checkUserDataEnabled)&&!
isEmergency()))){intradioTech=mPhone.getServiceState().getRilDataRadioTechnology();if(apnContext.getState()==DctConstants.State.IDLE){ArrayList<ApnSetting>waitingApns=buildWaitingApns(apnContext.getApnType(),radioTech);if(waitingApns.isEmpty()){notifyNoData(DcFailCause.MISSING_UNKNOWN_APN,apnContext);notifyOffApnsOfAvailability(apnContext.getReason());returnfalse;}else{apnContext.setWaitingApns(waitingApns);}}//建立连接booleanretValue=setupData(apnContext,radioTech);notifyOffApnsOfAvailability(apnContext.getReason());returnretValue;}else{}}这里主要经历了有效性的检查,其中判断了四个情况:
apnContext.isConnectable()
----判断当前APN是否已经被激活;
isEmergencyApn()
----当前APN是否为紧急APN;
isDataAllowed()
----判断是否已经ATTACH成功,SIM是否初始化完毕,当前手机服务是否支持,漫游下是否允许上网等;
getAnyDataEnabled()
----该条件主要判断用户是否打开了数据开关;
这四个条件我们主要来看最后一个,他里面包含用户数据开关的判断,我们来看一下详情,其中传递的参数checkUserDataEnabled受4GIMS的影响,由于国内暂时都没有部署IMS,因此这里的参数肯定都为true:
[java]viewplaincopymUserDataEnabled=Settings.Global.getInt(mPhone.getContext().getContentResolver(),Settings.Global.MOBILE_DATA,1)==1;这说明他来自于Settings.Global.MOBILE_DATA这个属性值,而这个属性值恰恰就是当用户打开或关闭移动网络时所改变的属性值,当用户打开数据网络时,该值为1,关闭网络时,该值就是0。
回到trySetupData()中来,当前所选取的APN是可用的,而且不是紧急APN,同时假设用户打开了数据流量开关,那么在该方法中就会通过setupData的方法来发送数据连接的请求:
[java]viewplaincopyprivatebooleansetupData(ApnContextapnContext,intradioTech){ApnSettingapnSetting;DcAsyncChanneldcac=null;apnSetting=apnContext.getNextWaitingApn();intprofileId=apnSetting.profileId;if(profileId==0){profileId=getApnProfileID(apnContext.getApnType());}if(dcac==null){//创建DcAsyncChanneldcac=findFreeDataConnection();if(dcac==null){dcac=createDataConnection();}if(dcac==null){returnfalse;}}apnContext.setDataConnectionAc(dcac);apnContext.setApnSetting(apnSetting);apnContext.setState(DctConstants.State.CONNECTING);mPhone.notifyDataConnection(apnContext.getReason(),apnContext.getApnType());//通过DcAsyncChannel发起连接请求Messagemsg=obtainMessage();msg.what=DctConstants.EVENT_DATA_SETUP_COMPLETE;msg.obj=apnContext;dcac.bringUp(apnContext,getInitialMaxRetry(),profileId,radioTech,mAutoAttachOnCreation,msg);returntrue;}这个方法内部主要完成了两个任务:
1、更新当前APN参数的状态并把状态发送到系统中(还是通过notifyDataConnection()来完成);
2、通过DcAsyncChannel的bringUp()方法发起连接请求;
我们主要分析第二个任务。
这里显示通过findFreeDataConnection()方法搜索可用的DcAsyncChannel,找不到的话就通过createDataConnection()创建,我们由于第一次上网,因此就需要创建的过程:
[java]viewplaincopyprivateDcAsyncChannelcreateDataConnection(){intid=mUniqueIdGenerator.getAndIncrement();DataConnectionconn=DataConnection.makeDataConnection(mPhone,id,this,mDcTesterFailBringUpAll,mDcc);mDataConnections.put(id,conn);//创建DcAsyncChannel通道DcAsyncChanneldcac=newDcAsyncChannel(conn,LOG_TAG);//申请双向连接intstatus=dcac.fullyConnectSync(mPhone.getContext(),this,conn.getHandler());if(status==AsyncChannel.STATUS_SUCCESSFUL){mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(),dcac);}else{}returndcac;}这里我们主要完成四个步骤:
1、拿到了一个DataConnection对象;
2、创建了DcAsyncChannel对象;
3、通过fullyConnectSync对DataConnection发起双向连接请求;
4、将DcAsyncChannel返回出来;
DcAsyncChannel的属性其实是AsyncChannel:
[java]viewplaincopypublicclassDcAsyncChannelextendsAsyncChannel{}根据《AsyncChannel的使用和原理》中的介绍,通过fullyConnectSync()可以一次性申请到双向的AsyncChannel,对于当前环境来说,就是在DcTracker与DataConnection之间建立了双向的连接通道,而且把通道的地址传递出来,而在setupData()中我们看到,DcTracker拿到该通道后,就进行了bringUp()的调用;
[java]viewplaincopyprivatebooleansetupData(ApnContextapnContext,intradioTech){DcAsyncChanneldcac=null;//通过DcAsyncChannel发起连接请求Messagemsg=obtainMessage();msg.what=DctConstants.EVENT_DATA_SETUP_COMPLETE;msg.obj=apnContext;dcac.bringUp(apnContext,getInitialMaxRetry(),profileId,radioTech,mAutoAttachOnCreation,msg);returntrue;}而且在调用bringUp时传递了一个Message的参数,该参数中携带了两个参数,EVENT_DATA_SETUP_COMPLETE的消息和APN的内容。
然后我们来看bringUp:
[java]viewplaincopy@DcAsyncChannel.javapublicvoidbringUp(ApnContextapnContext,intinitialMaxRetry,intprofileId,intrilRadioTechnology,booleanretryWhenSSChange,MessageonCompletedMsg){sendMessage(DataConnection.EVENT_CONNECT,newConnectionParams(apnContext,initialMaxRetry,profileId,rilRadioTechnology,retryWhenSSChange,onCompletedMsg));}这里就是将刚才的两个参数封装后通过sendMessage()发送出去,那么这个消息是发送给谁了呢?
其实就是发送给DcAsyncChannel通道的另一端DataConnection了,那么DataConnection是如何处理该消息的呢?
三、发送连接命令阶段当消息流进入DataConnection时,网络请求的过程在上层也就进入了最后的发送阶段,接下来我们就来看这最后的阶段如何完成。
DataConnection是在刚才的createDataConnection()方法中通过makeDataConnection()方法创建的:
[java]viewplaincopy@DataConnection.javastaticDataConnectionmakeDataConnection(PhoneBasephone,intid,DcTrackerBasedct,DcTesterFailBringUpAllfailBringUpAll,DcControllerdcc){//创建DataConnection方法DataConnectiondc=newDataConnection(phone,"DC-"+mInstanceNumber.incrementAndGet(),id,dct,failBringUpAll,dcc);dc.start();returndc;}先来看该类的属性:
[java]viewplaincopypublicfinalclassDataConnectionextendsStateMachine{}然后来看该对象的构造方法:
[java]viewplaincopyprivateDataConnection(PhoneBasephone,Stringname,intid,DcTrackerBasedct,DcTesterFailBringUpAllfailBringUpAll,DcControllerdcc){super(name,dcc.getHandler());mPhone=phone;mDct=dct;mDcTesterFailBringUpAll=failBringUpAll;mDcController=dcc;mId=id;mCid=-1;mDcRetryAlarmController=newDcRetryAlarmController(mPhone,this);ServiceStatess=mPhone.getServiceState();mRilRat=ss.getRilDataRadioTechnology();mDataRegState=mPhone.getServiceState().getDataRegState();intnetworkType=ss.getDataNetworkType();mNetworkInfo=newNetworkInfo(ConnectivityManager.TYPE_MOBILE,networkType,NETWORK_TYPE,TelephonyManager.getNetworkTypeName(networkType));mNetworkInfo.setRoaming(ss.getRoaming());mNetworkInfo.setIsAvailable(true);//各种状态机初始化addState(mDefaultState);addState(mInactiveState,mDefaultState);addState(mActivatingState,mDefaultState);addState(mRetryingState,mDefaultState);addState(mActiveState,mDefaultState);addState(mDisconnectingState,mDefaultSta
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据业务 建立 流程 发起 网络 连接 过程
![提示](https://static.bdocx.com/images/bang_tan.gif)