Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4a84af1 authored by Ling Li's avatar Ling Li Committed by Wink Saville
Browse files

Implement the carrier specified OTASP numbers

It defines a new system property for carrier defined OTASP number.
It also includes the change to check the dial string against the OTASP
number.
parent 03cc5581
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -109,4 +109,10 @@ public interface TelephonyProperties

    /** The international dialing prefix conversion string */
    static final String PROPERTY_IDP_STRING = "ro.cdma.idpstring";

    /**
     * Defines the schema for the carrier specified OTASP number
     */
    static final String PROPERTY_OTASP_NUM_SCHEMA = "ro.cdma.otaspnumschema";

}
+157 −37
Original line number Diff line number Diff line
@@ -60,12 +60,16 @@ import com.android.internal.telephony.TelephonyProperties;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * {@hide}
 */
public class CDMAPhone extends PhoneBase {
    static final String LOG_TAG = "CDMA";
    private static final boolean LOCAL_DEBUG = true;
    private static final boolean DBG = true;

    // Default Emergency Callback Mode exit timer
    private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000;
@@ -100,6 +104,8 @@ public class CDMAPhone extends PhoneBase {
    private Registrant mECMExitRespRegistrant;
    private String mEsn;
    private String mMeid;
    // string to define how the carrier specifies its own ota sp number
    private String mCarrierOtaSpNumSchema;

    // A runnable which is used to automatically exit from ECM after a period of time.
    private Runnable mExitEcmRunnable = new Runnable() {
@@ -155,6 +161,10 @@ public class CDMAPhone extends PhoneBase {
        String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
        mIsPhoneInECMState = inEcm.equals("true");

        // get the string that specifies the carrier OTA Sp number
        mCarrierOtaSpNumSchema = SystemProperties.get(
                TelephonyProperties.PROPERTY_OTASP_NUM_SCHEMA,"");

        // Notify voicemails.
        notifier.notifyMessageWaitingChanged(this);
    }
@@ -203,7 +213,7 @@ public class CDMAPhone extends PhoneBase {
    }

    protected void finalize() {
        if(LOCAL_DEBUG) Log.d(LOG_TAG, "CDMAPhone finalized");
        if(DBG) Log.d(LOG_TAG, "CDMAPhone finalized");
    }


@@ -935,7 +945,7 @@ public class CDMAPhone extends PhoneBase {
                        break;
                    }

                    if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
                    if (DBG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
                    setSystemProperty(TelephonyProperties.PROPERTY_BASEBAND_VERSION, (String)ar.result);
                }
                break;
@@ -1129,10 +1139,10 @@ public class CDMAPhone extends PhoneBase {
        mSMS.setCellBroadcastConfig(configValuesArray, response);
    }

    public static final String IS683A_FEATURE_CODE = "*228" ;
    public static final int IS683A_FEATURE_CODE_NUM_DIGITS = 4 ;
    public static final int IS683A_SYS_SEL_CODE_NUM_DIGITS = 2 ;
    public static final int IS683A_SYS_SEL_CODE_OFFSET = 4;
    private static final String IS683A_FEATURE_CODE = "*228";
    private static final int IS683A_FEATURE_CODE_NUM_DIGITS = 4;
    private static final int IS683A_SYS_SEL_CODE_NUM_DIGITS = 2;
    private static final int IS683A_SYS_SEL_CODE_OFFSET = 4;

    private static final int IS683_CONST_800MHZ_A_BAND = 0;
    private static final int IS683_CONST_800MHZ_B_BAND = 1;
@@ -1142,6 +1152,7 @@ public class CDMAPhone extends PhoneBase {
    private static final int IS683_CONST_1900MHZ_D_BLOCK = 5;
    private static final int IS683_CONST_1900MHZ_E_BLOCK = 6;
    private static final int IS683_CONST_1900MHZ_F_BLOCK = 7;
    private static final int INVALID_SYSTEM_SELECTION_CODE = -1;

    private boolean isIs683OtaSpDialStr(String dialStr) {
        int sysSelCodeInt;
@@ -1152,20 +1163,8 @@ public class CDMAPhone extends PhoneBase {
            if (dialStr.equals(IS683A_FEATURE_CODE)) {
                isOtaspDialString = true;
            }
        } else if ((dialStr.regionMatches(0, IS683A_FEATURE_CODE, 0,
                                          IS683A_FEATURE_CODE_NUM_DIGITS) == true)
                    && (dialStrLen >=
                        (IS683A_FEATURE_CODE_NUM_DIGITS + IS683A_SYS_SEL_CODE_NUM_DIGITS))) {
            StringBuilder sb = new StringBuilder(dialStr);
            // Separate the System Selection Code into its own string
            char[] sysSel = new char[2];
            sb.delete(0, IS683A_SYS_SEL_CODE_OFFSET);
            sb.getChars(0, IS683A_SYS_SEL_CODE_NUM_DIGITS, sysSel, 0);

            if ((PhoneNumberUtils.isISODigit(sysSel[0]))
                    && (PhoneNumberUtils.isISODigit(sysSel[1]))) {
                String sysSelCode = new String(sysSel);
                sysSelCodeInt = Integer.parseInt((String)sysSelCode);
        } else {
            sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr);
            switch (sysSelCodeInt) {
                case IS683_CONST_800MHZ_A_BAND:
                case IS683_CONST_800MHZ_B_BAND:
@@ -1177,14 +1176,134 @@ public class CDMAPhone extends PhoneBase {
                case IS683_CONST_1900MHZ_F_BLOCK:
                    isOtaspDialString = true;
                    break;

                default:
                    break;
            }
        }
        }
        return isOtaspDialString;
    }
    /**
     * This function extracts the system selection code from the dial string.
     */
    private int extractSelCodeFromOtaSpNum(String dialStr) {
        int dialStrLen = dialStr.length();
        int sysSelCodeInt = INVALID_SYSTEM_SELECTION_CODE;

        if ((dialStr.regionMatches(0, IS683A_FEATURE_CODE,
                                   0, IS683A_FEATURE_CODE_NUM_DIGITS)) &&
            (dialStrLen >= (IS683A_FEATURE_CODE_NUM_DIGITS +
                            IS683A_SYS_SEL_CODE_NUM_DIGITS))) {
                // Since we checked the condition above, the system selection code
                // extracted from dialStr will not cause any exception
                sysSelCodeInt = Integer.parseInt (
                                dialStr.substring (IS683A_FEATURE_CODE_NUM_DIGITS,
                                IS683A_FEATURE_CODE_NUM_DIGITS + IS683A_SYS_SEL_CODE_NUM_DIGITS));
        }
        if (DBG) Log.d(LOG_TAG, "extractSelCodeFromOtaSpNum " + sysSelCodeInt);
        return sysSelCodeInt;
    }

    /**
     * This function checks if the system selection code extracted from
     * the dial string "sysSelCodeInt' is the system selection code specified
     * in the carrier ota sp number schema "sch".
     */
    private boolean
    checkOtaSpNumBasedOnSysSelCode (int sysSelCodeInt, String sch[]) {
        boolean isOtaSpNum = false;
        try {
            // Get how many number of system selection code ranges
            int selRc = Integer.parseInt((String)sch[1]);
            for (int i = 0; i < selRc; i++) {
                if (!TextUtils.isEmpty(sch[i+2]) && !TextUtils.isEmpty(sch[i+3])) {
                    int selMin = Integer.parseInt((String)sch[i+2]);
                    int selMax = Integer.parseInt((String)sch[i+3]);
                    // Check if the selection code extracted from the dial string falls
                    // within any of the range pairs specified in the schema.
                    if ((sysSelCodeInt >= selMin) && (sysSelCodeInt <= selMax)) {
                        isOtaSpNum = true;
                        break;
                    }
                }
            }
        } catch (NumberFormatException ex) {
            // If the carrier ota sp number schema is not correct, we still allow dial
            // and only log the error:
            Log.e(LOG_TAG, "checkOtaSpNumBasedOnSysSelCode, error", ex);
        }
        return isOtaSpNum;
    }

    // Define the pattern/format for carrier specified OTASP number schema.
    // It separates by comma and/or whitespace.
    private static Pattern pOtaSpNumSchema = Pattern.compile("[,\\s]+");

    /**
     * The following function checks if a dial string is a carrier specified
     * OTASP number or not by checking against the OTASP number schema stored
     * in PROPERTY_OTASP_NUM_SCHEMA.
     *
     * Currently, there are 2 schemas for carriers to specify the OTASP number:
     * 1) Use system selection code:
     *    The schema is:
     *    SELC,the # of code pairs,min1,max1,min2,max2,...
     *    e.g "SELC,3,10,20,30,40,60,70" indicates that there are 3 pairs of
     *    selection codes, and they are {10,20}, {30,40} and {60,70} respectively.
     *
     * 2) Use feature code:
     *    The schema is:
     *    "FC,length of feature code,feature code".
     *     e.g "FC,2,*2" indicates that the length of the feature code is 2,
     *     and the code itself is "*2".
     */
    private boolean isCarrierOtaSpNum(String dialStr) {
        boolean isOtaSpNum = false;
        int sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr);
        if (sysSelCodeInt == INVALID_SYSTEM_SELECTION_CODE) {
            return isOtaSpNum;
        }
        // mCarrierOtaSpNumSchema is retrieved from PROPERTY_OTASP_NUM_SCHEMA:
        if (!TextUtils.isEmpty(mCarrierOtaSpNumSchema)) {
            Matcher m = pOtaSpNumSchema.matcher(mCarrierOtaSpNumSchema);
            if (DBG) {
                Log.d(LOG_TAG, "isCarrierOtaSpNum,schema" + mCarrierOtaSpNumSchema);
            }

            if (m.find()) {
                String sch[] = pOtaSpNumSchema.split(mCarrierOtaSpNumSchema);
                // If carrier uses system selection code mechanism
                if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("SELC")) {
                    if (sysSelCodeInt!=INVALID_SYSTEM_SELECTION_CODE) {
                        isOtaSpNum=checkOtaSpNumBasedOnSysSelCode(sysSelCodeInt,sch);
                    } else {
                        if (DBG) {
                            Log.d(LOG_TAG, "isCarrierOtaSpNum,sysSelCodeInt is invalid");
                        }
                    }
                } else if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("FC")) {
                    int fcLen =  Integer.parseInt((String)sch[1]);
                    String fc = (String)sch[2];
                    if (dialStr.regionMatches(0,fc,0,fcLen)) {
                        isOtaSpNum = true;
                    } else {
                        if (DBG) Log.d(LOG_TAG, "isCarrierOtaSpNum,not otasp number");
                    }
                } else {
                    if (DBG) {
                        Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema not supported" + sch[0]);
                    }
                }
            } else {
                if (DBG) {
                    Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern not right" +
                          mCarrierOtaSpNumSchema);
                }
            }
        } else {
            if (DBG) Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern empty");
        }
        return isOtaSpNum;
    }

     /**
      * isOTASPNumber: checks a given number against the IS-683A OTASP dial string and carrier
@@ -1199,9 +1318,10 @@ public class CDMAPhone extends PhoneBase {
         if (dialStr != null) {
             isOtaSpNum = isIs683OtaSpDialStr(dialStr);
             if(isOtaSpNum == false){
             //TO DO:Add carrier specific OTASP number detection here.
                 isOtaSpNum = isCarrierOtaSpNum(dialStr);
             }
         }
         if (DBG) Log.d(LOG_TAG, "isOtaSpNumber " + isOtaSpNum);
         return isOtaSpNum;
     }