5.3 RIL_REQUEST_DATA_REGISTRATION_STATE
In the construction method of GsmService StateTracker, some listening events are registered.
mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); mCi.registerForVoiceNetworkStateChanged(this,EVENT_NETWORK_STATE_CHANGED, null);
When the ril daemon reports some messages, such as UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, they are sent
The EVENT_NETWORK_STATE_CHANGED message is processed by GsmService StateTracker as follows.
case EVENT_NETWORK_STATE_CHANGED: pollState(); break;
5.3.1 Message Sending
For example, in the process of data network mode switching, GsmServiceStateTracker's pollState method is called to obtain the state before mode switching.
mPollingContext[0]++; mCi.getDataRegistrationState( obtainMessage(EVENT_POLL_STATE_GPRS, mPollingContext));
The processing of EVENT_POLL_STATE_GPRS messages will be invoked later when processing message callbacks.
The getData RegistrationState method in RIL is as follows.
@Override public void getDataRegistrationState (Message result) { //Message Encapsulation RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr);//Send RIL_REQUEST_DATA_REGISTRATION_STATE to ril through socket }
3.3.2 Message Callback Processing
In RIL, the RIL_REQUEST_DATA_REGISTRATION_STATE message is processed as follows.
First, the responseStrings method is called to retrieve the returned data.
case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break;
Then call back GsmService StateTracker for processing.
if (rr.mResult != null) { AsyncResult.forMessage(rr.mResult, ret, null); rr.mResult.sendToTarget(); }
The handleMessage method of GsmService StateTracker handles EVENT_POLL_STATE_GPRS messages as follows.
1. First, the CS/PS value of the data schema is saved in the ServiceState object.
states = (String[])ar.result;//Get the reported results int type = 0; int regState = ServiceState.RIL_REG_STATE_UNKNOWN; mNewReasonDataDenied = -1; mNewMaxDataCalls = 1; if (states.length > 0) { //Resolve CS/PS values based on the length of string groups, usually 4. try { regState = Integer.parseInt(states[0]);//Getting CS // states[3] (if present) is the current radio technology if (states.length >= 4 && states[3] != null) { //Get PS type = Integer.parseInt(states[3]); } if ((states.length >= 5 ) && (regState == ServiceState.RIL_REG_STATE_DENIED)) { mNewReasonDataDenied = Integer.parseInt(states[4]); } if (states.length >= 6) { mNewMaxDataCalls = Integer.parseInt(states[5]); } } catch (NumberFormatException ex) { loge("error parsing GprsRegistrationState: " + ex); } } // Save CS/PS values in ServiceState objects int dataRegState = regCodeToServiceState(regState); mNewSS.setDataRegState(dataRegState); mDataRoaming = regCodeIsRoaming(regState); mNewSS.setRilDataRadioTechnology(type);
2. Call pollStateDone method to initiate dial-up Internet access.
The pollStateDone method has the following code for dial-up access.
//Compare the CS values of the last and current network data patterns boolean hasDataRegStateChanged =mSS.getDataRegState() != mNewSS.getDataRegState(); //Compare PS values of the last and current network data patterns boolean hasRilDataRadioTechnologyChanged = mSS.getRilDataRadioTechnology() != mNewSS.getRilDataRadioTechnology(); if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) { notifyDataRegStateRilRadioTechnologyChanged(); mPhone.notifyDataConnection(null); }
If the last CS/PS value is different from the current one, the notifyDataRegStateRilRadioTechnologyChanged method is called.
Finally, RIL's setupDataCall method is called to send RIL_REQUEST_SETUP_DATA_CALL message to RIL library for dial-up.
5.4 RIL_REQUEST_SETUP_DATA_CALL
Upper initiation dialing typically calls RIL to send RIL_REQUEST_SETUP_DATA_CALL messages to the RIL daemon.
Continuing with the previous section, the notifyDataRegteRilRadioTechnologyChanged method of GsmServiceStateTracker is actually in the parent class
It is implemented in Service State Tracker as follows.
protected void notifyDataRegStateRilRadioTechnologyChanged() { int rat = mSS.getRilDataRadioTechnology(); int drs = mSS.getDataRegState(); if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat); mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, ServiceState.rilRadioTechnologyToString(rat)); mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat)); }
How can the sentence mDataRegteOrRatChangedRegistrants. notifyResult continue to be invoked?
mDataRegStateOrRatChangedRegistrants are also RegistrantList objects.
protected RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
The key is to see who registers, who registers is who calls, registration methods are as follows.
public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) { Registrant r = new Registrant(h, what, obj); mDataRegStateOrRatChangedRegistrants.add(r); notifyDataRegStateRilRadioTechnologyChanged(); }
This method is called in two places throughout the android system, DcTracker.java and DataConnection.java.
First, look at Data Connection, in the enter method of the inner class DcDefaultState of Data Connection.
mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(getHandler(), DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null);
The phrase mDataRegStateOrRatChangedRegistrants. notify Result is actually sent to DataConnection
EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED message.
Another thing to note here is that the DcDefaultState state machine is the parent state machine of all other state machines in Data Connection.
But it is not a parent class, which is different, although the function is similar to that of the parent class.
Then look at DcTracker. java. The constructor of DcTracker. Java calls the update method, and the update method calls the registerForAllEvents method.
In this method, there are the following codes in the concern book.
mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this, DctConstants.EVENT_DATA_RAT_CHANGED, null);
Similarly, mDataRegStateOrRatChangedRegistrants.notifyResult sent EVENT_DATA_RAT_CHANGED message to DcTracker.java.
DcTracker.java handleMessage handles this message as follows.
case DctConstants.EVENT_DATA_RAT_CHANGED: //May new Network allow setupData, so try it here setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED, RetryFailures.ONLY_ON_CHANGE); break;
The setup Data On Connectable Apns process is described in detail at the beginning of Chapter 2. The subsequent process is exactly the same as the process of opening data business. List the steps again.
1. Create Data Connection and DcAsyncChannel objects, bind the two objects through Handler, and communicate between processes through AsyncChannel mechanism.
2. Send RIL_REQUEST_SETUP_DATA_CALL message to RIL for dialing
3. The transition from DcInactiveState to DcActivating State and finally to DcActiveState
4. Construct Connectivity Service object and register. Connectivity Service will communicate with Network Agent of phone process through AsyncChannel.
5. Interacting with the network management service and the network daemon process, completing the addition of network attributes, thus completing the dial-up Internet.
Moreover, every time the data network is switched, the ril database will report RIL_UNSOL_DATA_CALL_LIST_CHANGED message, and the data that is not reported or reported is incorrect, so it is definitely impossible to access the internet.
Each time the data network is switched, AP will actively query the registration status. The ril library will return RIL_REQUEST_DATA_REGISTRATION_STATE information and the registration status of the data network.
The information returned is an array, more important is the first and fourth, if these two values have problems, it will not be able to dial up the Internet.
Summary:
In fact, data service switching includes data service closing and opening, and the process of interaction with ril daemon is as follows.
1. The phone process sends RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE messages to the ril daemon.
2. The RIL daemon first disconnects the network and reports the RIL_UNSOL_DATA_CALL_LIST_CHANGED message.
3. Phone process updates the network status of Network Agent and interacts with the network daemon.
4. The RIL daemon reports a large number of messages, such as UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED messages.
5. The phone process sends RIL_REQUEST_DATA_REGISTRATION_STATE messages to query the network registration status.
6. The phone process sends RIL_REQUEST_DATA_REGISTRATION_STATE message to the ril daemon to initiate dialing based on the RIL_REQUEST_SETUP_DATA_CALL message that the ril daemon responds to.
7. The phone process receives RIL_UNSOL_DATA_CALL_LIST_CHANGED message update status and so on.