1/*
2 * Copyright (C) 2016 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
17package com.android.server.wifi.util;
18
19import android.content.Context;
20import android.net.wifi.WifiConfiguration;
21import android.net.wifi.WifiEnterpriseConfig;
22import android.telephony.TelephonyManager;
23
24/**
25 * Utilities for the Wifi Service to interact with telephony.
26 */
27public class TelephonyUtil {
28
29    /**
30     * Get the identity for the current SIM or null if the sim is not available
31     */
32    public static String getSimIdentity(Context context, int eapMethod) {
33        TelephonyManager tm = TelephonyManager.from(context);
34        if (tm != null) {
35            String imsi = tm.getSubscriberId();
36            String mccMnc = "";
37
38            if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
39                mccMnc = tm.getSimOperator();
40            }
41
42            return buildIdentity(eapMethod, imsi, mccMnc);
43        } else {
44            return null;
45        }
46    }
47
48    /**
49     * create Permanent Identity base on IMSI,
50     *
51     * rfc4186 & rfc4187:
52     * identity = usernam@realm
53     * with username = prefix | IMSI
54     * and realm is derived MMC/MNC tuple according 3GGP spec(TS23.003)
55     */
56    private static String buildIdentity(int eapMethod, String imsi, String mccMnc) {
57        if (imsi == null || imsi.isEmpty()) {
58            return null;
59        }
60
61        String prefix;
62        if (eapMethod == WifiEnterpriseConfig.Eap.SIM) {
63            prefix = "1";
64        } else if (eapMethod == WifiEnterpriseConfig.Eap.AKA) {
65            prefix = "0";
66        } else if (eapMethod == WifiEnterpriseConfig.Eap.AKA_PRIME) {
67            prefix = "6";
68        } else {  // not a valide EapMethod
69            return null;
70        }
71
72        /* extract mcc & mnc from mccMnc */
73        String mcc;
74        String mnc;
75        if (mccMnc != null && !mccMnc.isEmpty()) {
76            mcc = mccMnc.substring(0, 3);
77            mnc = mccMnc.substring(3);
78            if (mnc.length() == 2) {
79                mnc = "0" + mnc;
80            }
81        } else {
82            // extract mcc & mnc from IMSI, assume mnc size is 3
83            mcc = imsi.substring(0, 3);
84            mnc = imsi.substring(3, 6);
85        }
86
87        return prefix + imsi + "@wlan.mnc" + mnc + ".mcc" + mcc + ".3gppnetwork.org";
88    }
89
90    /**
91     * Checks if the network is a sim config.
92     *
93     * @param config Config corresponding to the network.
94     * @return true if it is a sim config, false otherwise.
95     */
96    public static boolean isSimConfig(WifiConfiguration config) {
97        if (config == null || config.enterpriseConfig == null) {
98            return false;
99        }
100
101        return isSimEapMethod(config.enterpriseConfig.getEapMethod());
102    }
103
104    /**
105     * Checks if the network is a sim config.
106     *
107     * @param method
108     * @return true if it is a sim config, false otherwise.
109     */
110    public static boolean isSimEapMethod(int eapMethod) {
111        return eapMethod == WifiEnterpriseConfig.Eap.SIM
112                || eapMethod == WifiEnterpriseConfig.Eap.AKA
113                || eapMethod == WifiEnterpriseConfig.Eap.AKA_PRIME;
114    }
115}
116