Telephony数据连接.管理——DataConnection - __Shadow
2013-04-20 10:37:00 Author: www.cnblogs.com(查看原文) 阅读量:120 收藏

  DataConnectionTracker:控制手机APN加载,数据连接;

         包括:APN的创建,开机启动断开连接时,Radio状态改变时,Apn变化时,语音和数据业务切换时,

    连接失败及自动重连时,漫游打开关闭时……这些情况下数据连接的处理;

          

对于CDMA和GSM两种网络通信技术,处理数据连接存在着一些差异,基本流程一致,下面看看CdmaDataConnectionTracker工作流程;

1 APN概念      

  APN(Access Point Name),即“接入点名称”,用来标识GPRS的业务种类,目前分为两大类:CMWAP(通过GPRS访问WAP业务)、

CMNET(除了WAP以外的服务目前都用CMNET,比如连接因特网等)。是通过手机上网时必须配置的一个参数,它决定了您的手机通过哪种接入方式来访问网络。

业务流程GPRS专网系统终端上网登录服务器平台的流程为:

  1)用户发出GPRS登录请求,请求中包括由移动公司为GPRS专网系统专门分配的专网APN;

  2)根据请求中的APN,SGSN向DNS服务器发出查询请求,找到与企业服务器平台连接的GGSN,并将用户请求通过GTP隧道封装送给GGSN;

  3)GGSN将用户认证信息(包括手机号码、用户账号、密码等)通过专线送至Radius进行认证;

  4)Radius认证服务器看到手机号等认证信息,确认是合法用户发来的请求,向DHCP服务器请求分配用户地址;

  5)Radius认证通过后,由Radius向GGSN发送携带用户地址的确认信息;

  6)用户得到了IP地址,就可以携带数据包,对GPRS专网系统信息查询和业务处理平台进行访问。

2 APN创建

         CdmaDataConnectionTracker对象在创建的时候就会加载获取系统提供APN,CDMA中使用了专门的一个类CdmaDataProfileTracker来管理APN。

    CdmaDataConnectionTracker(CDMAPhone p) {
        super(p);
        mDpt = new CdmaDataProfileTracker(p);
        mDpt.registerForModemProfileReady(this, 
                EVENT_MODEM_DATA_PROFILE_READY, null);
        createAllDataConnectionList();
    }

CdmaDataProfileTracker加载APN过程:

public void handleMessage (Message msg) {
        switch (msg.what) {
            case EVENT_LOAD_PROFILES:
                    //从本机数据库加载
                loadProfiles();
                break;
            case EVENT_READ_MODEM_PROFILES:
                onReadDataProfilesFromModem();
                break;
            case EVENT_GET_DATA_CALL_PROFILE_DONE:
                    //当APN加载完发出通知
                onGetDataCallProfileDone((AsyncResult) msg.obj, (int)msg.arg1);
                break;
        }
    }

具体加载过程可以到函数中去看,APN生成和查看问题可以参看这篇文章:

         http://myqdroid.blog.51cto.com/2057579/389134

1 开始数据连接

数据连接都会发送消息调用:

    protected boolean onTrySetupData(String reason) {

                 return trySetupData(reason);

    }

判断当前条件下是否可以满足并进行数据连接:

private boolean trySetupData(String reason) {
    //Wifi has been connected already, ignore default type data call setup.
    if (FeatureQuery.FEATURE_CT_FMC_SUPPORT && mIsWifiConnected == true
            && mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
        setState(State.IDLE);
        
        if (dataEnabled[APN_DEFAULT_ID]) {
            dataEnabled[APN_DEFAULT_ID] = false;
            enabledCount--;
        }
        return false;
    }
    
    //满足条件则启动数据连接
    if ((mState == State.IDLE || mState == State.SCANNING) &&
            isDataAllowed() && getAnyDataEnabled() && !isEmergency()) {
        boolean retValue = setupData(reason);
        notifyOffApnsOfAvailability(reason);
        return retValue;
    } 
}

启动数据连接:

private boolean setupData(String reason) {
        CdmaDataConnection conn = findFreeDataConnection();
        mPendingDataConnection = conn;
        mActiveApn = mDpt.getDataProfile(mRequestedApnType);

        //连接完成回调消息
        Message msg = obtainMessage();
        msg.what = EVENT_DATA_SETUP_COMPLETE;
        msg.obj = reason;
        conn.bringUp(msg, mActiveApn);

        setState(State.INITING);
        notifyDataConnection(reason);
        return true;
}

2 数据连接过程

   数据连接是通过类DataConnection完成 ,看看DataConnection类结构图:

        

  从这个相关类结构图可以看出:DataConnection是一个状态机,使用State模式,这样这个过程就能很清楚了;

解决数据连接过程中,对象内部状态的变化时,进行状态切换,执行不同的行为。

启动数据连接接口:

public void bringUp(Message onCompletedMsg, DataProfile apn) {
        sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, 
                onCompletedMsg)));
    }

这里将消息发送给初始化状态进行处理:DcInactiveState     

  case EVENT_CONNECT:
                onConnect(cp);
                transitionTo(mActivatingState);
                break;
                                          

将会调用到CdmaDataConnection中进行connect:

protected void onConnect(ConnectionParams cp) {
        mApn = cp.apn;
        Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
        msg.obj = cp;
//通过RIL启动数据连接 phone.mCM.setupDataCall( Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_CDMA)), Integer.toString(dataProfile), mApn.apn, mApn.user, mApn.password, Integer.toString(mApn.authType), mApn.protocol, msg); }

连接完成会发送EVENT_DATA_SETUP_COMPLETE回调消息到DataConnectionTracker:

  case EVENT_DATA_SETUP_COMPLETE:
            mCidActive = msg.arg1;
            onDataSetupComplete((AsyncResult) msg.obj);
         break;

连接完成:

protected void onDataSetupComplete(AsyncResult ar) {
        if (isDataSetupCompleteOk(ar)) {
            DataProfileCdma mCurrentApn = (DataProfileCdma)mActiveApn;
            notifyDefaultData(reason);
        } else {
            startDelayedRetry(cause, reason, retryOverride);
        }
    }

文章来源: http://www.cnblogs.com/bastard/archive/2013/04/20/3031973.html
如有侵权请联系:admin#unsafe.sh