1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.services.telephony;
18 
19 import java.util.regex.Matcher;
20 import java.util.regex.Pattern;
21 
22 public final class MmiCodeUtil {
23     //***** Constants
24 
25     // Supp Service codes from TS 22.030 Annex B
26 
27     //Called line presentation
28     static final String SC_CLIP    = "30";
29     static final String SC_CLIR    = "31";
30 
31     // Call Forwarding
32     static final String SC_CFU     = "21";
33     static final String SC_CFB     = "67";
34     static final String SC_CFNRy   = "61";
35     static final String SC_CFNR    = "62";
36 
37     static final String SC_CF_All = "002";
38     static final String SC_CF_All_Conditional = "004";
39 
40     // Call Waiting
41     static final String SC_WAIT     = "43";
42 
43     // Call Barring
44     static final String SC_BAOC         = "33";
45     static final String SC_BAOIC        = "331";
46     static final String SC_BAOICxH      = "332";
47     static final String SC_BAIC         = "35";
48     static final String SC_BAICr        = "351";
49 
50     static final String SC_BA_ALL       = "330";
51     static final String SC_BA_MO        = "333";
52     static final String SC_BA_MT        = "353";
53 
54     // Supp Service Password registration
55     static final String SC_PWD          = "03";
56 
57     // PIN/PIN2/PUK/PUK2
58     static final String SC_PIN          = "04";
59     static final String SC_PIN2         = "042";
60     static final String SC_PUK          = "05";
61     static final String SC_PUK2         = "052";
62 
63     // See TS 22.030 6.5.2 "Structure of the MMI"
64 
65     static Pattern sPatternSuppService = Pattern.compile(
66         "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
67 /*       1  2                    3          4  5       6   7         8    9     10  11             12
68 
69          1 = Full string up to and including #
70          2 = action (activation/interrogation/registration/erasure)
71          3 = service code
72          5 = SIA
73          7 = SIB
74          9 = SIC
75          10 = dialing number
76 */
77 
78     static final int MATCH_GROUP_SERVICE_CODE = 3;
79 
80     public static final String BUTTON_CLIR_KEY  = "button_clir_key";
81     public static final String BUTTON_CW_KEY    = "button_cw_key";
82     public static final String CALL_FORWARDING_KEY = "call_forwarding_key";
83     public static final String CALL_BARRING_KEY = "call_barring_key";
84 
85     //***** Public Class methods
getMmiServiceCode(String dialString)86     public static String getMmiServiceCode(String dialString) {
87         Matcher m;
88         String ret = null;
89 
90         m = sPatternSuppService.matcher(dialString);
91 
92         if (m.matches()) {
93             ret = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
94         }
95 
96         return ret;
97     }
98 
makeEmptyNull(String s)99     private static String makeEmptyNull(String s) {
100         if (s != null && s.length() == 0) return null;
101 
102         return s;
103     }
104 
isServiceCodeCallForwarding(String sc)105     static boolean isServiceCodeCallForwarding(String sc) {
106         return sc != null &&
107                 (sc.equals(SC_CFU)
108                 || sc.equals(SC_CFB) || sc.equals(SC_CFNRy)
109                 || sc.equals(SC_CFNR) || sc.equals(SC_CF_All)
110                 || sc.equals(SC_CF_All_Conditional));
111     }
112 
isServiceCodeCallBarring(String sc)113     static boolean isServiceCodeCallBarring(String sc) {
114         return sc != null &&
115             (sc.equals(SC_BAOC)
116              || sc.equals(SC_BAOIC) || sc.equals(SC_BAOICxH)
117              || sc.equals(SC_BAIC) || sc.equals(SC_BAICr)
118              || sc.equals(SC_BA_ALL) || sc.equals(SC_BA_MO)
119              || sc.equals(SC_BA_MT));
120     }
121 
isPinPukCommand(String sc)122     static boolean isPinPukCommand(String sc) {
123         return sc != null && (sc.equals(SC_PIN) || sc.equals(SC_PIN2)
124                               || sc.equals(SC_PUK) || sc.equals(SC_PUK2));
125      }
126 
getSuppServiceKey(String dialString)127     public static String getSuppServiceKey(String dialString) {
128         String sc = getMmiServiceCode(dialString);
129         if (sc != null && sc.equals(SC_CLIP)) {
130             return "";
131         } else if (sc != null && sc.equals(SC_CLIR)) {
132             return BUTTON_CLIR_KEY;
133         } else if (isServiceCodeCallForwarding(sc)) {
134             return CALL_FORWARDING_KEY;
135         } else if (isServiceCodeCallBarring(sc)) {
136             return CALL_BARRING_KEY;
137         } else if (sc != null && sc.equals(SC_PWD)) {
138             return "";
139         } else if (sc != null && sc.equals(SC_WAIT)) {
140             return BUTTON_CW_KEY;
141         } else if (isPinPukCommand(sc)) {
142             return "";
143         } else {
144             return null;
145         }
146     }
147 }
148