(N) telephony Analysis (vii) of the DataConnection establishment

Source: Internet
Author: User

In front, we analyzed the initialization of dctracker, we have seen, in the Dctracker construction method, the call has the following method

private void Registerforallevents () {mPhone.mCi.registerForAvailable (this, dctconstants.event_radio_available, null
    );
    MPhone.mCi.registerForOffOrNotAvailable (this, dctconstants.event_radio_off_or_not_available, null);
    MPhone.mCi.registerForDataNetworkStateChanged (this, dctconstants.event_data_state_changed, null); Note, this is fragile-the Phone are now presenting a merged picture//of PS (VoLTE) & CS and by diving into I  TS Internals You ' re just seeing//the CS data.  This works well for the purposes, this is currently used for/-but that may and not always being the case.
    Should probably is redesigned to//accurately reflect what we ' re really interested in (registerforcsvoicecallended).
    Mphone.getcalltracker (). registerforvoicecallended (this, dctconstants.event_voice_call_ended, null);
    Mphone.getcalltracker (). registerforvoicecallstarted (this, dctconstants.event_voice_call_started, null); REgisterservicestatetrackerevents ();
    Subscriptionmanager.registerforddsswitch (this,//dctconstants.event_clean_up_all_connections, NULL);
MPhone.mCi.registerForPcoData (this, dctconstants.event_pco_data_received, null); }
Where there are calls to the Registerservicestatetrackerevents method

public void Registerservicestatetrackerevents () {///Leo, registering dataconnectionattached message Mphone.getservicestatetracker ().
    Registerfordataconnectionattached (this, dctconstants.event_data_connection_attached, null); Mphone.getservicestatetracker (). registerfordataconnectiondetached (This, dctconstants.event_data_connection_det
    ached, NULL);
    Mphone.getservicestatetracker (). Registerfordataroamingon (this, dctconstants.event_roaming_on, null);
    Mphone.getservicestatetracker (). Registerfordataroamingoff (this, dctconstants.event_roaming_off, null); Mphone.getservicestatetracker (). registerforpsrestrictedenabled (This, dctconstants.event_ps_restrict_enabled, n
    ULL);  Mphone.getservicestatetracker (). registerforpsrestricteddisabled (This, dctconstants.event_ps_restrict_disabled,
    NULL);  Mphone.getservicestatetracker (). registerfordataregstateorratchanged (This, dctconstants.event_data_rat_changed, NULL);
} 
In this way, the current dctracker and Servicestatetracker are bound together, we look at the first registration message event_data_connection_attached, then how does he activate receiving it?

I'm going to analyze the servicestatetracker. After the SIM card information is loaded, Servicestatetracker emits a event_sim_ready message, which is then processed

Case Event_sim_ready:
    //Reset The mprevioussubid so we treat a SIM power bounce
    //As a first boot.  See b/19194287
    MOnSubscriptionsChangedListener.mPreviousSubId.set ( -1);
    Pollstate ();
    Signal strength polling stops when radio is off
    queuenextsignalstrengthpoll ();
    Break
Well, the Pollstate method was called

public void Pollstate () {
    pollstate (false);
}
public void Pollstate (Boolean modemtriggered) {mpollingcontext = new int[1];

    Mpollingcontext[0] = 0; Switch (mci.getradiostate ()) {... default://Issue all poll-related commands at once the
            n count down the responses, which//is allowed to arrive out-of-order mpollingcontext[0]++;

            Mci.getoperator (Obtainmessage (Event_poll_state_operator, Mpollingcontext));
            mpollingcontext[0]++;

            Mci.getdataregistrationstate (Obtainmessage (Event_poll_state_gprs, Mpollingcontext));
            mpollingcontext[0]++;

            Mci.getvoiceregistrationstate (Obtainmessage (event_poll_state_registration, Mpollingcontext));
                if (mphone.isphonetypegsm ()) {mpollingcontext[0]++; Mci.getnetworkselectionmode (Obtainmessage (Event_poll_state_network_selection_mode, MPollingContex
            t));
    } break;
}} 
As you can see, the Getoperator,getdataregistrationstate and Getvoiceregistrationstate methods of the Ril class are called, respectively, for these three methods, Let's focus on the Getdataregistrationstate method, notice that the parameter passed in is a message object, and what the Message object is, Event_poll_state_gprs, Obj is a Mpollingcontext object

Next look at the Getdataregistrationstate method of the Ril class

public void
getdataregistrationstate (Message result) {
    rilrequest rr
            = Rilrequest.obtain (ril_request_ Data_registration_state, result);

    if (RILJ_LOGD) Riljlog (rr.serialstring () + ">" + requesttostring (rr.mrequest));

    Send (RR);
}
Well, from the previous articles, we know that this method is actually interacting with the underlying RIL, and sending ril_request_data_registration_state messages, and processing the results of the modem layer feedback in the Ril class, The incoming message Message object is then sent, as to exactly how it is passed, and subsequent re-analysis, so

Case Event_poll_state_registration: Case
Event_poll_state_gprs: Case
event_poll_state_operator:
    ar = ( AsyncResult) Msg.obj;
    Handlepollstateresult (Msg.what, AR);
    Break
Called the Handlepollstateresult method, where parameter one is the message what, parameter two is the data of the modem layer feedback

protected void Handlepollstateresult (int what, AsyncResult ar) {
    ...

    mpollingcontext[0]--;

    if (mpollingcontext[0] = = 0) {
        if (mphone.isphonetypegsm ()) {
            updateroamingstate ();
            Mnewss.setemergencyonly (memergencyonly);
        } else {
            ...
        }
        Pollstatedone ();
    }

}
Set the status information for the SIM card network and call the Pollstatedone method

private void Pollstatedone () {
    if (mphone.isphonetypegsm ()) {
        pollstatedonegsm ();
    } else if ( MPHONE.ISPHONETYPECDMA ()) {
        POLLSTATEDONECDMA ();
    } else {
        pollstatedonecdmalte ();
    }
}
Because the SIM card is in GSM format

private void pollstatedonegsm () {
    ...
    Boolean hasgprsattached =
            mss.getdataregstate ()! = Servicestate.state_in_service
                    && Mnewss.getdataregstate () = = Servicestate.state_in_service;

    ......

    if (hasgprsattached) {
        mattachedregistrants.notifyregistrants ();
    }

    if (hasgprsdetached) {
        mdetachedregistrants.notifyregistrants ();
    }
    ......
}
Therefore, the DATA attached message is sent here, and because in Dctracker, the event_data_connection_attached message is added to the mattachedregistrants, The Dctracker receives the event_data_connection_attached message and processes

Case dctconstants.event_data_connection_attached:
    ondataconnectionattached ();
    Break
Calling the Ondataconnectionattached method

private void ondataconnectionattached () {
    if (DBG) log ("ondataconnectionattached");
    Leo, set to True
    Mattached.set (true);
    Leo, conditions are not established
    if (getoverallstate () = = DctConstants.State.CONNECTED) {
        if (DBG) log ("Ondataconnectionattached: Start polling notify attached ");
        Startnetstatpoll ();
        Startdatastallalarm (data_stall_not_suspected);
        Notifydataconnection (phone.reason_data_attached);
    } else {
    	//Leo, will go directly to else, set the reason for its application dataconnection to reason_data_attached
        //update APN availability so APN can be enabled.
        Notifyoffapnsofavailability (phone.reason_data_attached);
    }
    if (mautoattachoncreationconfig) {
    	//Leo, set to True
        Mautoattachoncreation.set (true);
    }
    Leo, finally call this method
    Setupdataonconnectableapns (phone.reason_data_attached);
}
As can be seen above, there are several places set to true, combined with the initialization of the previous dataconnection, we know that these two parameters formally affect the conditions established by DataConnection

Finally, the Setupdataonconnectableapns method is called

private void Setupdataonconnectableapns (String reason) {
    Setupdataonconnectableapns (reason, retryfailures.always);
}
private void Setupdataonconnectableapns (String reason, Retryfailures retryfailures) {
    ...
    if (apncontext.isconnectable ()) {
        log ("isconnectable () call Trysetupdata");
        Apncontext.setreason (reason);
        Trysetupdata (Apncontext, Waitingapns);
    }
}
Apncontext.isconnectable () return value is true, please analyze it yourself

OK, back to the Trysetupdata method.

Private Boolean Trysetupdata (Apncontext apncontext, arraylist<apnsetting> Waitingapns) {...//all
    ow setup_data request for E-APN to being completed during emergency call//and MOBILE DATA on/off cases as well.
    Boolean ISEMERGENCYAPN = Apncontext.getapntype (). Equals (phoneconstants.apn_type_emergency);

    Final Servicestatetracker SST = Mphone.getservicestatetracker ();
    Set to False if APN type was non-metered or if we have a restricted (priveleged)/Request for the network. Todo-may want restricted requests to only apply to carrier-limited data access//rather than applying to
    User limited as well.  Exclude DUN for the purposes of the override until we get finer grained//intention in Networkrequests Boolean
                    checkuserdataenabled = Apnsetting.ismeteredapntype (Apncontext.getapntype (), Mphone.getcontext (),
 Mphone.getsubid (), Mphone.getservicestate (). getdataroaming ()) &&           Apncontext.hasnorestrictedrequests (True/*exclude DUN */);

    Dataallowfailreason Failurereason = new Dataallowfailreason (); Allow data if currently in roaming service, roaming setting disabled//and requested APN type was non-metered for R
    Oaming.
            Boolean isdataallowed = isdataallowed (Failurereason) | | (Failurereason.isfailforsinglereason (dataallowfailreasontype.roaming_disabled) &&! (Apnsetting.ismeteredapntype (Apncontext.getapntype (), Mphone.getcontext (), Mphone.getsubid (), MPhone.getServic

    EState (). getdataroaming ()));
            if (Apncontext.isconnectable () && (ISEMERGENCYAPN | | (isdataallowed && isdataallowedforapn (apncontext) && mdataenabledsettings.isdataenable
            D (checkuserdataenabled) &&!isemergency ())) {if (apncontext.getstate () = = DctConstants.State.FAILED) { String str = "Trysetupdata:make a FAILED apncontext IDLE so its reUsable ";
            if (DBG) log (str);
            Apncontext.requestlog (str);
        Apncontext.setstate (DctConstants.State.IDLE);
        } int radiotech = Mphone.getservicestate (). Getrildataradiotechnology ();
        Apncontext.setconcurrentvoiceanddataallowed (sst.isconcurrentvoiceanddataallowed ());  if (apncontext.getstate () = = DctConstants.State.IDLE) {if (Waitingapns = = null) {Waitingapns
            = Buildwaitingapns (Apncontext.getapntype (), Radiotech);
                } if (Waitingapns.isempty ()) {Notifynodata (DCFAILCAUSE.MISSING_UNKNOWN_APN, Apncontext);
                Notifyoffapnsofavailability (Apncontext.getreason ());
                String str = "trysetupdata:x No APN found Retvalue=false";
                if (DBG) log (str);
                Apncontext.requestlog (str);
            return false;
                } else {Apncontext.setwaitingapns (Waitingapns);
       if (DBG) {             Log ("Trysetupdata:create from mallapnsettings:" + apnlisttostring (MALLAPN
                Settings));
        }}} Boolean retvalue = SetupData (Apncontext, Radiotech);

        Notifyoffapnsofavailability (Apncontext.getreason ());
        if (DBG) log ("Trysetupdata:x retvalue=" + retvalue);
    return retvalue; } else {...}}
Because the previous in the Ondataconnectionattached method, the two value is set to True, the isdataallowed return value here is true, so the code will go as above

The SetupData method is eventually called to build the DataConnection

Private Boolean SetupData (Apncontext apncontext, int radiotech) {if (DBG) log ("setupdata:apncontext=" + apncontext);
    Apncontext.requestlog ("SetupData");
    Apnsetting apnsetting;

    Dcasyncchannel DCAC = null;

    apnsetting = Apncontext.getnextapnsetting ();
        if (apnsetting = = null) {if (DBG) log ("Setupdata:return for no APN found!");
    return false;
    } int profileid = Apnsetting.profileid;
    if (profileID = = 0) {profileID = Getapnprofileid (Apncontext.getapntype ()); }//On CDMA, if we ' re explicitly asking for DUN, we need has//a dun-profiled connection so we can ' t share an
    Existing one//on Gsm/lte we can share existing APN connections provided they support//this type.
            if (Apncontext.getapntype ()! = Phoneconstants.apn_type_dun | |
        Teardownfordun () = = False) {DCAC = Checkforcompatibleconnectedapncontext (Apncontext); if (DCAC! = null) {//Get the dcacapnsetting for The connection we want to share.
            Apnsetting dcacapnsetting = Dcac.getapnsettingsync ();
                if (dcacapnsetting! = null) {//Setting is good, so use it.
            apnsetting = dcacapnsetting; }}} if (DCAC = = null) {if (isonlysingledcallowed (Radiotech)) {if (ishigherpriority Apncontextactive (Apncontext)) {if (DBG) {log ("Setupdata:higher priority Apncontext  Active.
                Ignoring call ");
            } return false;  }//Only lower-calls left. Disconnect them all on this a PDP case//So, we can bring up the requested higher priority call (ONC E we receive//response for deactivate request for the calls we is about-disconnect if (clean Upallconnections (True, phone.reason_single_pdn_arbitration)) {//If any call actually requested to be dis ConnectEd, means we can ' t//Bring up this connection yet as we need to wait for those data calls
                To is disconnected.  if (DBG) log ("Setupdata:some calls is disconnecting first.
                Wait and retry ");
            return false; }//No Other calls is active, so proceed if (DBG) log ("Setupdata:single PDP.

        Continue setting up data call. ");

        DCAC = Findfreedataconnection ();
        if (DCAC = = null) {DCAC = Createdataconnection (); if (DCAC = = null) {if (DBG) log ("Setupdata:no free dataconnection and couldn ' t create one, WEIRD"
            );
        return false;
    }} final int generation = Apncontext.incandgetconnectiongeneration ();
    if (DBG) {log ("setupdata:dcac=" + DCAC + "apnsetting=" + apnsetting + "gen#=" + Generation);
    } Apncontext.setdataconnectionac (DCAC);
    Apncontext.setapnsetting (apnsetting); ApnContext.setstate (DctConstants.State.CONNECTING);

    Mphone.notifydataconnection (Apncontext.getreason (), Apncontext.getapntype ());
    Message msg = Obtainmessage ();
    Msg.what = Dctconstants.event_data_setup_complete;
    Msg.obj = new Pair<apncontext, integer> (Apncontext, Generation);

    Dcac.bringup (Apncontext, profileID, Radiotech, MSG, Generation);
    if (DBG) log ("setupdata:initing!");
return true; }
The analysis concludes that, finally, by calling the Createdataconnection method, the new Dcasyncchannel object

Private Dcasyncchannel createdataconnection () {
    if (DBG) log ("Createdataconnection E");

    int id = muniqueidgenerator.getandincrement ();
    DataConnection conn = Dataconnection.makedataconnection (Mphone, id, this
                                            , Mdctesterfailbringupall, MDCC);
    Mdataconnections.put (ID, conn);
    Dcasyncchannel DCAC = new Dcasyncchannel (conn, log_tag);
    int status = Dcac.fullyconnectsync (Mphone.getcontext (), this, Conn.gethandler ());
    if (status = = asyncchannel.status_successful) {
        mdataconnectionachashmap.put (Dcac.getdataconnectionidsync (), DCAC);
    } else {
        Loge ("Createdataconnection:could not connect to dcac=" + DCAC + "status=" + status);
    }

    if (DBG) log ("Createdataconnection () X id=" + ID + "dc=" + conn);
    return DCAC;
}
Create a new DataConnection by DataConnection's Makedataconnection method.

To this point, DataConnection has been established

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.