MMICode

39Go
前言本技术规范是由第三代合作伙伴计划(3GPP)制定的
Foreword This Technical Specification has been produced by the 3rd Generation Partnership Project (3GPP)

什么是mmi(Man-Machine-Interface):
从功能上来看,有一些从拨号盘拨出去的字符串,它的实际作用不是建立一个通话而是为了完成某种服务,这个就是MMI;从格式上来看,每一个从拨号盘输入的字符串,如果包含有*或者#,都可以称之为MMI.
MMI包括SS, USSD,Manufacturer defined MMI codes, SIM control codes等等。
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.

If the dial string contains no MMI code, we return an instance with
only “dialingNumber” set

GSM中的某些拨号字符串已定义为进行非呼叫设置
诸如修改或查询补充服务设置(例如呼叫
转发)。 这些通常称为“ MMI代码”。
我们看一下拨号字符串是否包含有效的MMI代码(可能
末尾还有拨号字符串),然后在此处返回信息。

We need to request to open these codes MMI to use with the One Net service
These codes are dialled in the phone, to get informations or do changes in a VPN service.
#21#MSISDN*
#22#MSISDN*
#23#MSISDN*
#31*
#31#COMPANY*
#32*
#32#COMPANY*
#45#MSISDN*
#46#MSISDN*
#51#INTERNATIONAL MSISDN*
#111#MSISDN*
#112#MSISDN*
#114#MSISDN*
#121#HUNT MEMBER*
#132#MSISDN*
#141*
#142*
#143*
#154*
#155*
#155#HUNT NUMBER*
#156*
#157*
#157#POSITION NUMBER*
#191PIN USER#
#194
PIN USER#

已*结尾的都是拨通的方式打出去的,已#结尾的都是USSD格式
Every Short String USSD command will end with #-key
USSD(Unstructured Supplementary Service Data)

33PIN# SEND
#33# SEND
#35# SEND
开头#结尾的字符是已MMICode (SS)Supplementary Service补充服务,比如控制号码显示,呼叫转移等服务的号码串。这些号码串是每部GSM/UMTS/LTE手机中的固定服务号码,运营商是不能对它进行修改的。当手机系统接受到这些服务号码后,先在手机内部进行处理后,再传给网络。
比如你随便拿个手机,在拨号盘输入
21*123456789#然后点击发送,这个时候你所有的来电都会直接转移到123456789。

USSD从字面上看,是非结构化的补充字符单从字符串格式上是没法区分SS和USSD
一,USSD基本都是运营商根据自己的服务自己定制的,而SS就像上面说的是每个手机固有的;
二,SS在发送给网络前,手机首先会自己处理一下,而USSD是完全透明的传送给网络。

SIM control codes
比如用来修改SIM卡PIN码的命令,在拨号键盘输入**0412346789*6789#,这将会将SIM卡的PIN码从1234修改成为6789.
目前这个码还没有客户还有提到

Manufacturer defined MMI codes
一些嵌在手机里的服务码,比如你要查询一个手机的IMEI号码,你可以在拨号键盘输入*#06#,手机的IMEI码会自动弹出来。

从源码中看到MMICode包含

 // Supp Service codes from TS 22.030 Annex B
      //Called line presentation
      protected static final String SC_CLIP    = "30";
      protected static final String SC_CLIR    = "31";
  
      // Call Forwarding
      protected static final String SC_CFU     = "21";
      protected static final String SC_CFB     = "67";
      protected static final String SC_CFNRy   = "61";
      protected static final String SC_CFNR    = "62";
  
      protected static final String SC_CF_All = "002";
      protected static final String SC_CF_All_Conditional = "004";
  
      // Call Waiting
      protected static final String SC_WAIT     = "43";
  
      // Call Barring
      protected static final String SC_BAOC         = "33";
      protected static final String SC_BAOIC        = "331";
      protected static final String SC_BAOICxH      = "332";
      protected static final String SC_BAIC         = "35";
      protected static final String SC_BAICr        = "351";
  
      protected static final String SC_BA_ALL       = "330";
      protected static final String SC_BA_MO        = "333";
      protected static final String SC_BA_MT        = "353";
  
      // Supp Service Password registration
      protected static final String SC_PWD          = "03";
  
      // PIN/PIN2/PUK/PUK2
      protected static final String SC_PIN          = "04";
      protected static final String SC_PIN2         = "042";
      protected static final String SC_PUK          = "05";
      protected static final String SC_PUK2         = "052";
  
*#33* SEND

下面就是客户反馈某些USSD不可用。

alps/frameworks/opt/telephony/src/java/com/android/internal/telephony/GsmCdmaPhone.java
alps/frameworks/opt/telephony/src/java/com/android/internal/telephony/imsphone/ImsPhone.java 	
alps/vendor/mediatek/proprietary/frameworks/opt/telephony/src/java/com/mediatek/internal/telephony/MtkGsmCdmaPhone.java
alps/vendor/mediatek/proprietary/frameworks/opt/telephony/src/java/com/mediatek/internal/telephony/imsphone/MtkImsPhone.java

为什么在这里修改,因为这个方法就是用来处理输入拨号盘的号码

@Override
    protected Connection dialInternal(String dialString, UUSInfo uusInfo, int videoState,
                                      Bundle intentExtras, ResultReceiver wrappedCallback)
            throws CallStateException {

        // Need to make sure dialString gets parsed properly
        String newDialString = PhoneNumberUtils.stripSeparators(dialString);

        if (isPhoneTypeGsm()) {
            // handle in-call MMI first if applicable
            if (handleInCallMmiCommands(newDialString)) {
                return null;
            }
            //Redmine182596 modified for MMI Codes not working muyuanyuan 2019/8/22 begin
             String pattern = "([#|(\\*)]{1,2}(\\d{2,3})[#|(\\*)](\\d{2,15}[#|(\\*)]){0,1})";
             Pattern r = Pattern.compile(pattern);
             Matcher m = r.matcher(newDialString);
             boolean isSpecialPhoneNumber = m.matches();

             //android.util.Log.d("myy","vendor mtkgsmcdmaphone  isSpecialPhoneNumber = "+isSpecialPhoneNumber+"isSpecialPhoneNumber1 = "+isSpecialPhoneNumber1);
             android.util.Log.d("myy","vendor mtkgsmcdmaphone  isSpecialPhoneNumber = "+isSpecialPhoneNumber);
             if(!isSpecialPhoneNumber){
             //Redmine182596 modified for MMI Codes not working  2019/8/22 end
                     return mCT.dial(newDialString, uusInfo, intentExtras);
             }
             //Redmine150423 One Net MMI codes  20190120 end

            // Only look at the Network portion for mmi
            String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString);
            MtkGsmMmiCode mmi = MtkGsmMmiCode.newFromDialString(networkPortion, this,
                    mUiccApplication.get(), wrappedCallback);
            if (DBG) logd("dialInternal: dialing w/ mmi '" + mmi + "'...");

            if (mmi == null) {
                /// M: CC: For 3G VT only @{
                if (videoState == VideoProfile.STATE_AUDIO_ONLY) {
                android.util.Log.d("myy","11111111111111111");
                    return mCT.dial(newDialString, uusInfo, intentExtras);
                } else {
                    if (!is3GVTEnabled()) {
                        throw new CallStateException("cannot vtDial for non-3GVT-capable device");
                    }
                    return ((MtkGsmCdmaCallTracker) mCT).vtDial(newDialString, uusInfo,
                            intentExtras);
                }
                /// @}
            } else if (mmi.isTemporaryModeCLIR()) {
                /// M: CC: For 3G VT only @{
                if (videoState == VideoProfile.STATE_AUDIO_ONLY) {
                android.util.Log.d("myy","222222222222");
                    return mCT.dial(mmi.mDialingNumber, mmi.getCLIRMode(), uusInfo, intentExtras);
                } else {
                    if (!is3GVTEnabled()) {
                        throw new CallStateException("cannot vtDial for non-3GVT-capable device");
                    }
                    return ((MtkGsmCdmaCallTracker) mCT).vtDial(mmi.mDialingNumber,
                            mmi.getCLIRMode(), uusInfo, intentExtras);
                }
                /// @}
            } else {
                mPendingMMIs.add(mmi);
                /* Print MMI content */
                Rlog.d(LOG_TAG, "dialInternal: " + dialString + ", mmi=" + mmi);
                dumpPendingMmi();
                mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
                mmi.processCode();
                return null;
            }
        } else {
        android.util.Log.d("myy","33333333333333");
            return mCT.dial(newDialString);
        }
    }

这个码走的是11111111111111111这里,说明mmi=null

39GO/alps-release-o1.mp1-default/alps/vendor/mediatek/proprietary/frameworks/opt/telephony/src/java/com/mediatek/internal/telephony/gms/MtkGsmMmiCode.java

 public static MtkGsmMmiCode newFromDialString(String dialString, MtkGsmCdmaPhone phone,
            UiccCardApplication app, ResultReceiver wrappedCallback) {
        Matcher m;
        MtkGsmMmiCode ret = null;
        m = sPatternSuppService.matcher(dialString);
        // Is this formatted like a standard supplementary service code?
        if (m.matches()) {
            ret = new MtkGsmMmiCode(phone, app);
            ret.mPoundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
            ret.mAction = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
            ret.mSc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
            ret.mSia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
            ret.mSib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
            ret.mSic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
            ret.mPwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
            ret.mDialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
            ret.mCallbackReceiver = wrappedCallback;
            // According to TS 22.030 6.5.2 "Structure of the MMI",
            // the dialing number should not ending with #.
            // The dialing number ending # is treated as unique USSD,
            // eg, *400#16 digit number# to recharge the prepaid card
            // in India operator(Mumbai MTNL)
            android.util.Log.d("myy","ccccccccccccccc");
            if(ret.mDialingNumber != null &&
                    ret.mDialingNumber.endsWith("#") &&
                    dialString.endsWith("#")){
                    
                    android.util.Log.d("myy","dddddddddddddd");
                    
                ret = new MtkGsmMmiCode(phone, app);
                ret.mPoundString = dialString;
            }
        } 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".

            android.util.Log.d("myy","eeeeeeeeeeeee");

            ret = new MtkGsmMmiCode(phone, app);
            ret.mPoundString = dialString;
        } else if (isTwoDigitShortCode(phone.getContext(), dialString)) {
        
         android.util.Log.d("myy","fffffffffffff");
        
            //Is a country-specific exception to short codes as defined in TS 22.030, 6.5.3.2
            ret = null;
        //modify for dialling 08 as normal call being initiated about GCF FT 40.2.1.1 begin
        //} else if (isShortCode(dialString, phone)) {
        } else if (isShortCode(dialString, phone) && !dialString.equals("08")) {
        //modify for dialling 08 as normal call being initiated about GCF FT 40.2.1.1 end
            // this may be a short code, as defined in TS 22.030, 6.5.3.2
            android.util.Log.d("myy","gggggggggggggggg");
            
            ret = new MtkGsmMmiCode(phone, app);
            ret.mDialingNumber = dialString;
            //如果加上此处的判断它会已USSD来处理了
        }/*else if (dialString.endsWith("*")) {
        android.util.Log.d("myy","aaaaaaaaaaaaaaaaa");
            ret = new MtkGsmMmiCode(phone, app);
            ret.mPoundString = dialString;
        }*/
        android.util.Log.d("myy","bbbbbbbbbbbbb");

        return ret;
    }

查看源代码发现它走的是"bbbbbbbbbbbbb"的路径,什么码都不是

/39O/alps/frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java

// See TS 22.030 6.5.2 "Structure of the MMI"
protected static Pattern sPatternSuppService = Pattern.compile(
          "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
  /*       1  2                    3          4  5       6   7         8    9     10  11             12
  
           1 = Full string up to and including #
           2 = action (activation/interrogation/registration/erasure)
           3 = service code
           5 = SIA
           7 = SIB
           9 = SIC
           10 = dialing number
  */

https://www.etsi.org/deliver/etsi_ts/122000_122099/122030/10.00.00_60/ts_122030v100000p.pdf

正则表达式:
“\",不用多说,用来匹配一个"“字符。
使用”(\d{2,3})”,匹配一个2位或者3位的数字(其中,"\d"用来匹配数字,{2,3}表示最少匹配2次,至多匹配3次)

如何查看你的MmiCode起作用的部分log:

./mtklog_Wrong APN supp serv/mobilelog/APLog_2019_1014_144406__1/radio_log_2__2019_1014_144704:10-14 14:44:37.967791  1049  1049 D MtkImsPhoneMmiCode: Service was enabled.
./mtklog_Wrong APN supp serv/mobilelog/APLog_2019_1014_144406__1/radio_log_2__2019_1014_144704:10-14 14:45:43.810206  1049  1049 D MtkImsPhoneMmiCode: isSupportedOverImsPhone(), return true!
./mtklog_Wrong APN supp serv/mobilelog/APLog_2019_1014_144406__1/radio_log_2__2019_1014_144704:10-14 14:45:45.649181  1049  1049 D MtkImsPhoneMmiCode: onSetComplete: mmi=ImsPhoneMmiCode {State=COMPLETE action=# sc=33 sia=1234 poundString=[****]} message=Call barring
./mtklog_Wrong APN supp serv/mobilelog/APLog_2019_1014_144406__1/radio_log_2__2019_1014_144704:10-14 14:45:45.649181  1049  1049 D MtkImsPhoneMmiCode: Service has been disabled.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值