您的位置:首页 > 理论基础 > 计算机网络

【从应用层到Framework】移动网络开启关闭数据访问流程

2013-01-29 10:19 676 查看
本文转自:http://blog.sina.com.cn/s/blog_40d475e901016t41.html

最近整理下启用数据和关闭数据连接的代码,将流程发出来,方便查看

下面是在真机上抓到的log,机器是锐合的X9,平台厂商是Marvell。(给公司打个广告



通过log的TAG,相信各位很容易就找的到对应的源码文件,这里就不提供源码文件路径了

本文主要体现业务流程,具体函数功能就不详细介绍了,相信大家就是光看函数名也能猜到用途

D/GsmUmtsOptions( 1477): preferenceTreeClick: return false

D/NetworkSettings( 1477): onPreferenceTreeClick: preference == mButtonDataEnabled.

D/ConnectivityService( 1396): setMobileDataEnabled(false)

D/ConnectivityService( 1396): tearing down Mobile data state: CONNECTED

D/DataConnectionTracker( 1477): disableApnType(default)

D/DataConnectionTracker( 1477): setEnabled(0, false) with old state = true and enabledCount = 1

D/DataConnectionTracker( 1477): GSMDataConnTrack handleMessage { what=23 when=-30ms }

D/DataConnectionTracker( 1477): EVENT_APN_ENABLE_REQUEST 0, 0

D/DataConnectionTracker( 1477): dataEnabled = true, enabledCount = 1, isApnTypeActive = true

D/DataConnectionTracker( 1477): [GsmDataConnectionTracker] Clean up connection due to dataDisabled

D/DataConnectionTracker( 1477): [GsmDataConnectionTracker] cleanUpConnection: teardown, call conn.disconnect

D/GSM ( 1519): [GsmDataConnection-1] DcActiveState msg.what=EVENT_DISCONNECT

D/GSM ( 1519): [GsmDataConnection-1] tearDownData radio is on, call deactivateDataCall

D/RILJ ( 1519): [0100]> DEACTIVATE_DATA_CALL 1

下面就是data call的代码流程了,本文以去激活为例,即disable

1、在设置中取消“已启用数据”的选中状态

D/GsmUmtsOptions( 1477): preferenceTreeClick: return false

D/NetworkSettings( 1477): onPreferenceTreeClick: preference == mButtonDataEnabled.

cm.setMobileDataEnabled(mButtonDataEnabled.isChecked());

2、进入Framework了,如何从ConnectivityManager到ConnectivityService,请大家参考源码

D/ConnectivityService( 1396): setMobileDataEnabled(false)

public void setMobileDataEnabled(boolean enabled) {

enforceChangePermission();

if (DBG) Slog.d(TAG, "setMobileDataEnabled(" + enabled + ")");

mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,

(enabled ? ENABLED : DISABLED), 0));

}

case
EVENT_SET_MOBILE_DATA:

{

boolean enabled = (msg.arg1 == ENABLED);

handleSetMobileData(enabled);

break;

}

3、收到EVENT_SET_MOBILE_DATA消息,调用tear down

D/ConnectivityService( 1396): tearing down Mobile data state: CONNECTED

case
EVENT_SET_MOBILE_DATA:

{

boolean enabled = (msg.arg1 == ENABLED);

handleSetMobileData(enabled);

break;

}

private void handleSetMobileData(boolean enabled) {

if (getMobileDataEnabled() == enabled) return;

Settings.Secure.putInt(mContext.getContentResolver(),

Settings.Secure.MOBILE_DATA, enabled ? 1 : 0);

if (enabled) {

if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {

if (DBG) {

Slog.d(TAG, "starting up " + mNetTrackers[ConnectivityManager.TYPE_MOBILE]);

}

mNetTrackers[ConnectivityManager.TYPE_MOBILE].reconnect();

}

if (mNetTrackers[ConnectivityManager.TYPE_WIMAX] != null) {

if (DBG) {

Slog.d(TAG, "starting up " + mNetTrackers[ConnectivityManager.TYPE_WIMAX]);

}

mNetTrackers[ConnectivityManager.TYPE_WIMAX].reconnect();

}

} else {

for (NetworkStateTracker nt : mNetTrackers) {

if (nt == null) continue;

int netType = nt.getNetworkInfo().getType();

if (mNetAttributes[netType].mRadio == ConnectivityManager.TYPE_MOBILE && mNetAttributes[netType].isDefault()) {

if (DBG)
Slog.d(TAG, "tearing down " + nt);

nt.teardown();

}

}

if (mNetTrackers[ConnectivityManager.TYPE_WIMAX] != null) {

mNetTrackers[ConnectivityManager.TYPE_WIMAX].teardown();

}

}

}

4、进入MobileDataStateTracker

public class MobileDataStateTracker extends NetworkStateTracker {

public boolean teardown() {

// since we won't get a notification currently (TODO - per APN notifications)

// we won't get a disconnect message until all APN's on the current connection's

// APN list are disabled. That means privateRoutes for DNS and such will remain on -

// not a problem since that's all shared with whatever other APN is still on, but

// ugly.

setTeardownRequested(true);

return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);

}

private int setEnableApn(String apnType, boolean enable) {

getPhoneService(false);

for (int retry = 0; retry < 2; retry++) {

if (mPhoneService == null) {

Log.w(TAG,

"Ignoring feature request because could not acquire PhoneService");

break;

}

try {

if (enable) {

return mPhoneService.enableApnType(apnType);

} else {

return mPhoneService.disableApnType(apnType);

}

} catch (RemoteException e) {

if (retry == 0) getPhoneService(true);

}

}

Log.w(TAG, "Could not " + (enable ? "enable" : "disable")

+ " APN type "" + apnType + """);

return Phone.APN_REQUEST_FAILED;

}

}

5、进入DataConnectionTracker,从mPhoneService到PhoneBase,PhoneBase中调用DataConnectionTracker的disableApnType

D/DataConnectionTracker( 1477): disableApnType(default)

public synchronized int disableApnType(String type) {

if (DBG) Log.d(LOG_TAG, "disableApnType("+type+")");

int id = apnTypeToId(type);

if (id == APN_INVALID_ID) {

return Phone.APN_REQUEST_FAILED;

}

if (isEnabled(id)) {

setEnabled(id, false);

return Phone.APN_REQUEST_STARTED;

} else {

return Phone.APN_REQUEST_FAILED;

}

}

6、发送EVENT_ENABLE_NEW_APN

D/DataConnectionTracker( 1477): setEnabled(0, false) with old state = true and enabledCount = 1

private void setEnabled(int id, boolean enable) {

if (DBG) Log.d(LOG_TAG, "setEnabled(" + id + ", " + enable + ") with old state = " +

dataEnabled[id] + " and enabledCount = " + enabledCount[id]);

if(isApnTypeActive(apnIdToType(id))==false) {

enabledCount[id] = 0;

dataEnabled[id] = false;

}

Message msg = obtainMessage(EVENT_ENABLE_NEW_APN);

msg.arg1 = id;

msg.arg2 = (enable ? ENABLED : DISABLED);

sendMessage(msg);

}

7、处理EVENT_ENABLE_NEW_APN消息,调用onEnableApn,再调用onCleanUpConnection,再调用cleanUpConnection

D/DataConnectionTracker( 1477): GSMDataConnTrack handleMessage { what=23 when=-30ms }

case
EVENT_ENABLE_NEW_APN:

onEnableApn(msg.arg1, msg.arg2);

break;

D/DataConnectionTracker( 1477): EVENT_APN_ENABLE_REQUEST 0, 0

D/DataConnectionTracker( 1477): dataEnabled = true, enabledCount = 1, isApnTypeActive = true

protected synchronized void onEnableApn(int apnId, int enabled) {

if (DBG) {

Log.d(LOG_TAG, "EVENT_APN_ENABLE_REQUEST " + apnId + ", " + enabled);

Log.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] +

", enabledCount = " + enabledCount[apnId] +

", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));

}

if (enabled == ENABLED) {

if (!dataEnabled[apnId]) {

dataEnabled[apnId] = true;

enabledCount[apnId] = 1;

} else {

enabledCount[apnId]++;

}

String type = apnIdToType(apnId);

if (enabledCount[apnId] == 1) { //first time to enable this apn

onEnableNewApn(apnId);

}

Log.d(LOG_TAG, "updated after enabled: dataEnabled = " + dataEnabled[apnId] +

", enabledCount = " + enabledCount[apnId] +

", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));

} else {

// disable

if (dataEnabled[apnId]) {

enabledCount[apnId] = 0;

dataEnabled[apnId] = false;

onCleanUpConnection(apnId, Phone.REASON_DATA_DISABLED);

}

Log.d(LOG_TAG, "updated after disabled: dataEnabled = " + dataEnabled[apnId] +

", enabledCount = " + enabledCount[apnId] +

", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));

}

}

protected void onCleanUpConnection(int apnId, String reason) {

cleanUpConnection(apnId, reason);

}

8、 调用disconnect

D/DataConnectionTracker( 1477): [GsmDataConnectionTracker] Clean up connection due to dataDisabled

D/DataConnectionTracker( 1477): [GsmDataConnectionTracker] cleanUpConnection: teardown, call conn.disconnect

private void cleanUpConnection(int apnId, String reason) {

if (DBG) log("Clean up connection due to " + reason);

if (perPdpState[apnId]== State.DISCONNECTING) {

if (DBG) log("cleanUpConnection: linda check State is Disconnecting, not set disconnecting again");

return;

}

if (DBG)
log("cleanUpConnection: teardown, call conn.disconnect");

if(mActivePdp[apnId] != null) {

setState(apnId,State.DISCONNECTING);

requestParams para = new requestParams(apnId, reason);

if(!isActivePdpShared(apnId)) {

if (DBG) log("cleanUpConnection: conn.disconnect");

removeFromActiveApnList(mActivePdp[apnId].getApn());

mActivePdp[apnId].disconnect(obtainMessage(EVENT_DISCONNECT_DONE, para));

mActivePdp[apnId] = null;

} else {

if (DBG) log("cleanUpConnection: conn is shared, don't disconnect it");

setState(apnId,State.IDLE);

mActivePdp[apnId] = null;

phone.notifyDataConnection(reason);

}

} else {

setState(apnId,State.IDLE);

phone.notifyDataConnection(reason);

}

}

9、发送消息EVENT_DISCONNECT,调用tearDownData,调用deactivateDataCall

D/GSM ( 1519): [GsmDataConnection-1] DcActiveState msg.what=EVENT_DISCONNECT

D/GSM ( 1519): [GsmDataConnection-1] tearDownData radio is on, call deactivateDataCall

public abstract class DataConnection extends HierarchicalStateMachine {

public void disconnect(Message onCompletedMsg) {

sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(onCompletedMsg)));

}

case
EVENT_DISCONNECT:

if (DBG)
log("DcActiveState msg.what=EVENT_DISCONNECT");

DisconnectParams dp = (DisconnectParams) msg.obj;

dp.tag = mTag;

tearDownData(dp);

transitionTo(mDisconnectingState);

retVal = true;

break;

private void tearDownData(Object o) {

if (phone.mCM.getRadioState().isOn()) {

if (DBG)
log("tearDownData radio is on, call deactivateDataCall");

phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, o));

} else {

if (DBG) log("tearDownData radio is off sendMessage EVENT_DEACTIVATE_DONE immediately");

AsyncResult ar = new AsyncResult(o, null, null);

sendMessage(obtainMessage(EVENT_DEACTIVATE_DONE, ar));

}

}

}

10、调用RIL的deactivateDataCall,发送原语RIL_REQUEST_DEACTIVATE_DATA_CALL

D/RILJ ( 1519): [0100]> DEACTIVATE_DATA_CALL 1

public final class RIL extends BaseCommands implements CommandsInterface {

public void

deactivateDataCall(int cid, Message result) {

RILRequest rr

= RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result);

rr.mp.writeInt(1);

rr.mp.writeString(Integer.toString(cid));

if (RILJ_LOGD)
riljLog(rr.serialString() + "> " +

requestToString(rr.mRequest) + " " + cid);

send(rr);

}

}

11、下面的流程就是各个厂商要实现的RIL部分,即AT命令实现部分了,这部分代码就不放上去了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: