public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { // Need to make sure dialString gets parsed properly String newDialString = PhoneNumberUtils.stripSeparators(dialString); // handle in-call MMI first if applicable if (handleInCallMmiCommands(newDialString)) { return null; } // Only look at the Network portion for mmi String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString); GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this); if (LOCAL_DEBUG) Log.d(LOG_TAG, "dialing w/ mmi '" + mmi + "'..."); if (mmi == null) { return mCT.dial(newDialString, uusInfo); } else if (mmi.isTemporaryModeCLIR()) { return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode(), uusInfo); } else { mPendingMMIs.add(mmi); mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); mmi.processCode(); // FIXME should this return null or something else? return null; } }
static GsmMmiCode newFromUssdUserInput( String ussdMessge, GSMPhone phone, UiccCardApplication app) { GsmMmiCode ret = new GsmMmiCode(phone, app); ret.message = ussdMessge; ret.state = State.PENDING; ret.isPendingUSSD = true; return ret; }
public boolean handlePinMmi(String dialString) { GsmMmiCode mmi = GsmMmiCode.newFromDialString(dialString, this); if (mmi != null && mmi.isPinCommand()) { mPendingMMIs.add(mmi); mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); mmi.processCode(); return true; } return false; }
/** * Removes the given MMI from the pending list and notifies registrants that it is complete. * * @param mmi MMI that is done */ /*package*/ void onMMIDone(GsmMmiCode mmi) { /* Only notify complete if it's on the pending list. * Otherwise, it's already been handled (eg, previously canceled). * The exception is cancellation of an incoming USSD-REQUEST, which is * not on the list. */ if (mPendingMMIs.remove(mmi) || mmi.isUssdRequest()) { mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); } }
/** ussdMode is one of CommandsInterface.USSD_MODE_* */ private void onIncomingUSSD(int ussdMode, String ussdMessage) { boolean isUssdError; boolean isUssdRequest; isUssdRequest = (ussdMode == CommandsInterface.USSD_MODE_REQUEST); isUssdError = (ussdMode != CommandsInterface.USSD_MODE_NOTIFY && ussdMode != CommandsInterface.USSD_MODE_REQUEST); // See comments in GsmMmiCode.java // USSD requests aren't finished until one // of these two events happen GsmMmiCode found = null; for (int i = 0, s = mPendingMMIs.size(); i < s; i++) { if (mPendingMMIs.get(i).isPendingUSSD()) { found = mPendingMMIs.get(i); break; } } if (found != null) { // Complete pending USSD if (isUssdError) { found.onUssdFinishedError(); } else { found.onUssdFinished(ussdMessage, isUssdRequest); } } else { // pending USSD not found // The network may initiate its own USSD request // ignore everything that isnt a Notify or a Request // also, discard if there is no message to present if (!isUssdError && ussdMessage != null) { GsmMmiCode mmi; mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage, isUssdRequest, GSMPhone.this); onNetworkInitiatedUssd(mmi); } } }
static GsmMmiCode newNetworkInitiatedUssd( String ussdMessage, boolean isUssdRequest, GSMPhone phone, UiccCardApplication app) { GsmMmiCode ret; ret = new GsmMmiCode(phone, app); ret.message = ussdMessage; ret.isUssdRequest = isUssdRequest; // If it's a request, set to PENDING so that it's cancelable. if (isUssdRequest) { ret.isPendingUSSD = true; ret.state = State.PENDING; } else { ret.state = State.COMPLETE; } return ret; }
public void sendUssdResponse(String ussdMessge) { GsmMmiCode mmi = GsmMmiCode.newFromUssdUserInput(ussdMessge, this); mPendingMMIs.add(mmi); mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); mmi.sendUssd(ussdMessge); }
/** * Some dial strings in GSM are defined to do non-call setup things, such as modify or query * supplementary service settings (eg, call forwarding). These are generally referred to as "MMI * codes". We look to see if the dial string contains a valid MMI code (potentially with a dial * string at the end as well) and return info here. * * <p>If the dial string contains no MMI code, we return an instance with only "dialingNumber" set * * <p>Please see flow chart in TS 22.030 6.5.3.2 */ static GsmMmiCode newFromDialString(String dialString, GSMPhone phone, UiccCardApplication app) { Matcher m; GsmMmiCode ret = null; if (SystemProperties.getBoolean("ro.config.multimode_cdma", false)) { m = sPatternSuppServiceGlobalDev.matcher(dialString); if (m.matches()) { ret = new GsmMmiCode(phone, app); ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION)); String DialCode = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE)); if (DialCode.equals(SC_GLOBALDEV_VM)) { ret.sc = SC_GLOBALDEV_VM; ret.dialingNumber = "+1" + phone.getMdn(); return ret; } else if (DialCode.equals(SC_GLOBALDEV_CS)) { ret.sc = SC_GLOBALDEV_CS; ret.dialingNumber = GLOBALDEV_CS; return ret; } else if (DialCode.length() >= 3 && DialCode.startsWith(SC_GLOBALDEV_CLIR_INVK)) { // Dial "#31#PhoneNum" to invoke CLIR temporarily dialString = ACTION_DEACTIVATE + SC_CLIR + ACTION_DEACTIVATE + DialCode.substring(2); } else if (DialCode.length() >= 3 && DialCode.startsWith(SC_GLOBALDEV_CLIR_SUPP)) { // Dial "*31#PhoneNum" to suppress CLIR temporarily dialString = ACTION_ACTIVATE + SC_CLIR + ACTION_DEACTIVATE + DialCode.substring(2); } } } m = sPatternSuppService.matcher(dialString); // Is this formatted like a standard supplementary service code? if (m.matches()) { ret = new GsmMmiCode(phone, app); ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING)); ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION)); ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE)); ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA)); ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB)); ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC)); ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM)); ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER)); } else if (dialString.endsWith("#")) { // TS 22.030 sec 6.5.3.2 // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet // (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND". ret = new GsmMmiCode(phone, app); ret.poundString = dialString; } else if (isTwoDigitShortCode(phone.getContext(), dialString)) { // Is a country-specific exception to short codes as defined in TS 22.030, 6.5.3.2 ret = null; } else if (isShortCode(dialString, phone)) { // this may be a short code, as defined in TS 22.030, 6.5.3.2 ret = new GsmMmiCode(phone, app); ret.dialingNumber = dialString; } return ret; }