Android Data Analyse(3)--APN & ApnSetting & ApnContext

Keywords: Mobile network xml Database

APN

Definition:
APN (access point name) can be simply understood as the access point name for data access to the Internet, which is a parameter that must be configured to access data. The configuration of this parameter directly determines the access mode of accessing data.

Parameters:

  <apn carrier="China Mobile (China Mobile) WAP"
      mcc="460"
      mnc="00"
      apn="cmwap"
      proxy="10.0.0.172"
      port="80"
      type="default,supl"
  />
Name Explain
carrier The name of the APN (you can see it on your phone)
mccmnc mccmnc for mobile phones
apn Access point
proxy agent
port port
type The type of apn accessible to the network

To configure:

apn is defined by google as a set of default configurations that can be used by operators. The default location of apn is device/sample/etc/apns-full-conf.xml. After compilation, it will copy to system/etc/apns-conf.xml. For different operators, it can be changed in apns-full-conf.xml.
In mobile phones, APNs exist in telephony.db. Specific location: content://telephony/carriers

Load:
After device detects the completion of simcard load, it undergoes a series of calls:

    protected void onRecordsLoadedOrSubIdChanged() {
    ...
        createAllApnList();//Get all standard APNs from the database
        setInitialAttachApn();//Setting the apn of the initial accach
     ...
    }
    /**
     * Based on the sim operator numeric, create a list for all possible
     * Data Connections and setup the preferredApn.
     */
    protected void createAllApnList() {
        mMvnoMatched = false;//Virtual operators are related, not yet encountered
        mAllApnSettings = new ArrayList<ApnSetting>();
        IccRecords r = mIccRecords.get();
        String operator = mPhone.getOperatorNumeric();
        if (operator != null) {
            String selection = "numeric = '" + operator + "'";
            String orderBy = "_id";
            // query only enabled apn.
            // carrier_enabled : 1 means enabled apn, 0 disabled apn.
            // selection += " and carrier_enabled = 1";
            if (DBG) log("createAllApnList: selection=" + selection);

            //Screening apn set by mccmnc
            Cursor cursor = mPhone.getContext().getContentResolver().query(
                    Telephony.Carriers.CONTENT_URI, null, selection, null, orderBy);

            if (cursor != null) {
                if (cursor.getCount() > 0) {
                //Get all the appropriate APNs
                    mAllApnSettings = createApnList(cursor);
                }
                cursor.close();
            }
        }

        //Add Emergency APN settings
        addEmergencyApnSetting();

        //Remove duplicate apn
        dedupeApnSettings();

        if (mAllApnSettings.isEmpty()) {
            if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
            mPreferredApn = null;
            // TODO: What is the right behavior?
            //notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
        } else {
            mPreferredApn = getPreferredApn();
            if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
                mPreferredApn = null;
                setPreferredApn(-1);
            }
            if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
        }
        if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);

        setDataProfilesAsNeeded();
    }

ApnSetting

ApnSetting can be simply regarded as the constructor of APN. When querying the database, it is mainly stored in the form of ApnSetting. The parameters correspond to each item in the telephony.db carrier table.
Constructor:

    public ApnSetting(int id, String numeric, String carrier, String apn,
            String proxy, String port,
            String mmsc, String mmsProxy, String mmsPort,
            String user, String password, int authType, String[] types,
            String protocol, String roamingProtocol, boolean carrierEnabled, int bearer,
            int bearerBitmask, int profileId, boolean modemCognitive, int maxConns, int waitTime,
            int maxConnsTime, int mtu, String mvnoType, String mvnoMatchData) {
        this.id = id; //Identity ID in the database
        this.numeric = numeric; // mccmnc
        this.carrier = carrier; //The name of the apn (shown in settings)
        this.apn = apn; //Access point
        this.proxy = proxy; //Agent of apn
        this.port = port; //Port number of apn
        this.mmsc = mmsc; //Address of MMS Center
        this.mmsProxy = mmsProxy; //MMS Proxy
        this.mmsPort = mmsPort; //mms port
        this.user = user; //To be updated
        this.password = password; //To be updated
        this.authType = authType; //To be updated
        this.types = new String[types.length]; //The data type applicable to the apn
        for (int i = 0; i < types.length; i++) {
            this.types[i] = types[i].toLowerCase(Locale.ROOT);
        }
        this.protocol = protocol;
        this.roamingProtocol = roamingProtocol;
        this.carrierEnabled = carrierEnabled;
        this.bearer = bearer;//The type of network that can be processed (?)
        this.bearerBitmask = (bearerBitmask | ServiceState.getBitmaskForTech(bearer));
        this.profileId = profileId;
        this.modemCognitive = modemCognitive;
        this.maxConns = maxConns;
        this.waitTime = waitTime;
        this.maxConnsTime = maxConnsTime;
        this.mtu = mtu;
        this.mvnoType = mvnoType;
        this.mvnoMatchData = mvnoMatchData;

    }

Key interface:

    /**
     * Determine whether the passed type can be processed.
     * Usually different operators have different needs, which need special treatment.
     */
    public boolean canHandleType(String type) {
        if (!carrierEnabled) return false;
        for (String t : types) {
            // DEFAULT handles all, and HIPRI is handled by DEFAULT
            if (t.equalsIgnoreCase(type) ||
                    t.equalsIgnoreCase(PhoneConstants.APN_TYPE_ALL) ||
                    (t.equalsIgnoreCase(PhoneConstants.APN_TYPE_DEFAULT) &&
                    type.equalsIgnoreCase(PhoneConstants.APN_TYPE_HIPRI))) {
                return true;
            }
        }
        return false;
    }

ApnContext

APN & ApnSetting are configuration parameters, while ApnContext is the operation of APN or ApnSetting. In Dctracker or Data Connection and other major data-related classes, the main operation is ApnContext to read or set APN-related information.

Common interface:

Interface Return value Explain
getApnSetting ApnSetting Returns all current APN s
getApnType String Returns the current APN type
getState DctConstants.State Returns the status of the corresponding network for the apn
isConnectedOrConnecting boolean Returns whether the network corresponding to the current apn is connected

System calls:

    /**
     * Determine whether the type passed in allows access to data
     */
    public boolean isDataPossible(String apnType) {
        ApnContext apnContext = mApnContexts.get(apnType);
        if (apnContext == null) {
            return false;
        }
        boolean apnContextIsEnabled = apnContext.isEnabled();
        DctConstants.State apnContextState = apnContext.getState();
        boolean apnTypePossible = !(apnContextIsEnabled &&
                (apnContextState == DctConstants.State.FAILED));
        boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY);
        // Set the emergency APN availability status as TRUE irrespective of conditions checked in
        // isDataAllowed() like IN_SERVICE, MOBILE DATA status etc.
        boolean dataAllowed = isEmergencyApn || isDataAllowed(null);
        boolean possible = dataAllowed && apnTypePossible;

        if ((apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
                    || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA))
                && (mPhone.getServiceState().getRilDataRadioTechnology()
                == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) {
            log("Default data call activation not possible in iwlan.");
            possible = false;
        }

        if (VDBG) {
            log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
                            "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
                    apnType, possible, dataAllowed, apnTypePossible,
                    apnContextIsEnabled, apnContextState));
        }
        return possible;
    }

Posted by theoph on Sun, 09 Dec 2018 22:27:17 -0800