一 DataConnectionTracker
DataConnectionTracker:控制手機APN載入,資料連線;
包括:APN的建立,開機啟動中斷連線時,Radio狀態改變時,Apn變化時,語音和資料業務切換時,
串連失敗及自動重連時,漫遊開啟關閉時……這些情況下資料連線的處理;
對於CDMA和GSM兩種網路通訊技術,處理資料連線存在著一些差異,基本流程一致,下面看看CdmaDataConnectionTracker工作流程;
二 APN載入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); } }