• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.internal.telephony;
18 
19 import static android.telephony.TelephonyManager
20         .CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE;
21 import static android.telephony.TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED;
22 import static android.telephony.TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE;
23 import static android.telephony.TelephonyManager.CAPABILITY_SIM_PHONEBOOK_IN_MODEM;
24 import static android.telephony.TelephonyManager.CAPABILITY_SLICING_CONFIG_SUPPORTED;
25 import static android.telephony.TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING;
26 import static android.telephony.TelephonyManager.CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK;
27 import static android.telephony.TelephonyManager.RadioInterfaceCapability;
28 
29 import android.hardware.radio.V1_0.RadioError;
30 import android.hardware.radio.V1_0.RadioResponseInfo;
31 import android.hardware.radio.config.V1_1.ModemsConfig;
32 import android.hardware.radio.config.V1_3.IRadioConfigResponse;
33 import android.telephony.ModemInfo;
34 import android.telephony.PhoneCapability;
35 
36 import com.android.internal.annotations.VisibleForTesting;
37 import com.android.internal.telephony.uicc.IccSlotStatus;
38 import com.android.telephony.Rlog;
39 
40 import java.util.ArrayList;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Set;
44 
45 /**
46  * This class is the implementation of IRadioConfigResponse interface.
47  */
48 public class RadioConfigResponse extends IRadioConfigResponse.Stub {
49     private static final String TAG = "RadioConfigResponse";
50 
51     private final RadioConfig mRadioConfig;
52     private final HalVersion mRadioHalVersion;
53 
RadioConfigResponse(RadioConfig radioConfig, HalVersion radioHalVersion)54     public RadioConfigResponse(RadioConfig radioConfig, HalVersion radioHalVersion) {
55         mRadioConfig = radioConfig;
56         mRadioHalVersion = radioHalVersion;
57     }
58 
59     /**
60      * Response function for IRadioConfig.getSimSlotsStatus().
61      */
getSimSlotsStatusResponse(RadioResponseInfo responseInfo, ArrayList<android.hardware.radio.config.V1_0.SimSlotStatus> slotStatus)62     public void getSimSlotsStatusResponse(RadioResponseInfo responseInfo,
63             ArrayList<android.hardware.radio.config.V1_0.SimSlotStatus> slotStatus) {
64         RILRequest rr = mRadioConfig.processResponse(responseInfo);
65 
66         if (rr != null) {
67             ArrayList<IccSlotStatus> ret = RadioConfig.convertHalSlotStatus(slotStatus);
68             if (responseInfo.error == RadioError.NONE) {
69                 // send response
70                 RadioResponse.sendMessageResponse(rr.mResult, ret);
71                 Rlog.d(TAG, rr.serialString() + "< "
72                         + mRadioConfig.requestToString(rr.mRequest) + " " + ret.toString());
73             } else {
74                 rr.onError(responseInfo.error, ret);
75                 Rlog.e(TAG, rr.serialString() + "< "
76                         + mRadioConfig.requestToString(rr.mRequest) + " error "
77                         + responseInfo.error);
78             }
79 
80         } else {
81             Rlog.e(TAG, "getSimSlotsStatusResponse: Error " + responseInfo.toString());
82         }
83     }
84 
85     /**
86      * Response function for IRadioConfig.getSimSlotsStatus().
87      */
getSimSlotsStatusResponse_1_2(RadioResponseInfo responseInfo, ArrayList<android.hardware.radio.config.V1_2.SimSlotStatus> slotStatus)88     public void getSimSlotsStatusResponse_1_2(RadioResponseInfo responseInfo,
89             ArrayList<android.hardware.radio.config.V1_2.SimSlotStatus> slotStatus) {
90         RILRequest rr = mRadioConfig.processResponse(responseInfo);
91 
92         if (rr != null) {
93             ArrayList<IccSlotStatus> ret = RadioConfig.convertHalSlotStatus_1_2(slotStatus);
94             if (responseInfo.error == RadioError.NONE) {
95                 // send response
96                 RadioResponse.sendMessageResponse(rr.mResult, ret);
97                 Rlog.d(TAG, rr.serialString() + "< "
98                         + mRadioConfig.requestToString(rr.mRequest) + " " + ret.toString());
99             } else {
100                 rr.onError(responseInfo.error, ret);
101                 Rlog.e(TAG, rr.serialString() + "< "
102                         + mRadioConfig.requestToString(rr.mRequest) + " error "
103                         + responseInfo.error);
104             }
105         } else {
106             Rlog.e(TAG, "getSimSlotsStatusResponse_1_2: Error " + responseInfo.toString());
107         }
108     }
109 
110     /**
111      * Response function for IRadioConfig.setSimSlotsMapping().
112      */
setSimSlotsMappingResponse(RadioResponseInfo responseInfo)113     public void setSimSlotsMappingResponse(RadioResponseInfo responseInfo) {
114         RILRequest rr = mRadioConfig.processResponse(responseInfo);
115 
116         if (rr != null) {
117             if (responseInfo.error == RadioError.NONE) {
118                 // send response
119                 RadioResponse.sendMessageResponse(rr.mResult, null);
120                 Rlog.d(TAG, rr.serialString() + "< "
121                         + mRadioConfig.requestToString(rr.mRequest));
122             } else {
123                 rr.onError(responseInfo.error, null);
124                 Rlog.e(TAG, rr.serialString() + "< "
125                         + mRadioConfig.requestToString(rr.mRequest) + " error "
126                         + responseInfo.error);
127             }
128         } else {
129             Rlog.e(TAG, "setSimSlotsMappingResponse: Error " + responseInfo.toString());
130         }
131     }
132 
convertHalPhoneCapability( android.hardware.radio.config.V1_1.PhoneCapability phoneCapability)133     private PhoneCapability convertHalPhoneCapability(
134             android.hardware.radio.config.V1_1.PhoneCapability phoneCapability) {
135         // TODO b/121394331: clean up V1_1.PhoneCapability fields.
136         int maxActiveVoiceCalls = 0;
137         int maxActiveData = phoneCapability.maxActiveData;
138         boolean validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported;
139         List<ModemInfo> logicalModemList = new ArrayList();
140 
141         for (android.hardware.radio.config.V1_1.ModemInfo
142                 modemInfo : phoneCapability.logicalModemList) {
143             logicalModemList.add(new ModemInfo(modemInfo.modemId));
144         }
145 
146         return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList,
147                 validationBeforeSwitchSupported, mRadioConfig.getDeviceNrCapabilities());
148     }
149     /**
150      * Response function for IRadioConfig.getPhoneCapability().
151      */
getPhoneCapabilityResponse(RadioResponseInfo responseInfo, android.hardware.radio.config.V1_1.PhoneCapability phoneCapability)152     public void getPhoneCapabilityResponse(RadioResponseInfo responseInfo,
153             android.hardware.radio.config.V1_1.PhoneCapability phoneCapability) {
154         RILRequest rr = mRadioConfig.processResponse(responseInfo);
155 
156         if (rr != null) {
157             PhoneCapability ret = convertHalPhoneCapability(phoneCapability);
158             if (responseInfo.error == RadioError.NONE) {
159                 // send response
160                 RadioResponse.sendMessageResponse(rr.mResult, ret);
161                 Rlog.d(TAG, rr.serialString() + "< "
162                         + mRadioConfig.requestToString(rr.mRequest) + " " + ret.toString());
163             } else {
164                 rr.onError(responseInfo.error, ret);
165                 Rlog.e(TAG, rr.serialString() + "< "
166                         + mRadioConfig.requestToString(rr.mRequest) + " error "
167                         + responseInfo.error);
168             }
169         } else {
170             Rlog.e(TAG, "getPhoneCapabilityResponse: Error " + responseInfo.toString());
171         }
172     }
173 
174     /**
175      * Response function for IRadioConfig.setPreferredDataModem().
176      */
setPreferredDataModemResponse(RadioResponseInfo responseInfo)177     public void setPreferredDataModemResponse(RadioResponseInfo responseInfo) {
178         RILRequest rr = mRadioConfig.processResponse(responseInfo);
179 
180         if (rr != null) {
181             if (responseInfo.error == RadioError.NONE) {
182                 // send response
183                 RadioResponse.sendMessageResponse(rr.mResult, null);
184                 Rlog.d(TAG, rr.serialString() + "< "
185                         + mRadioConfig.requestToString(rr.mRequest));
186             } else {
187                 rr.onError(responseInfo.error, null);
188                 Rlog.e(TAG, rr.serialString() + "< "
189                         + mRadioConfig.requestToString(rr.mRequest) + " error "
190                         + responseInfo.error);
191             }
192         } else {
193             Rlog.e(TAG, "setPreferredDataModemResponse: Error " + responseInfo.toString());
194         }
195     }
196 
197     /**
198      * Response function for IRadioConfig.setModemsConfigResponse()
199      * Currently this is being used as the callback for RadioConfig.setModemsConfig() method
200      */
setModemsConfigResponse(RadioResponseInfo responseInfo)201     public void setModemsConfigResponse(RadioResponseInfo responseInfo) {
202         RILRequest rr = mRadioConfig.processResponse(responseInfo);
203 
204         if (rr != null) {
205             if (responseInfo.error == RadioError.NONE) {
206                 // send response
207                 RadioResponse.sendMessageResponse(rr.mResult, rr.mRequest);
208                 Rlog.d(TAG, rr.serialString() + "< "
209                         + mRadioConfig.requestToString(rr.mRequest));
210             } else {
211                 rr.onError(responseInfo.error, null);
212                 Rlog.e(TAG, rr.serialString() + "< "
213                         + mRadioConfig.requestToString(rr.mRequest) + " error "
214                         + responseInfo.error);
215             }
216         } else {
217             Rlog.e(TAG, "setModemsConfigResponse: Error " + responseInfo.toString());
218         }
219     }
220 
221     /**
222      * Response function for IRadioConfig.getModemsConfigResponse()
223      */
getModemsConfigResponse(RadioResponseInfo responseInfo, ModemsConfig modemsConfig)224     public void getModemsConfigResponse(RadioResponseInfo responseInfo, ModemsConfig modemsConfig) {
225         RILRequest rr = mRadioConfig.processResponse(responseInfo);
226 
227         if (rr != null) {
228             if (responseInfo.error == RadioError.NONE) {
229                 // send response
230                 RadioResponse.sendMessageResponse(rr.mResult, modemsConfig);
231                 Rlog.d(TAG, rr.serialString() + "< "
232                         + mRadioConfig.requestToString(rr.mRequest));
233             } else {
234                 rr.onError(responseInfo.error, modemsConfig);
235                 Rlog.e(TAG, rr.serialString() + "< "
236                         + mRadioConfig.requestToString(rr.mRequest) + " error "
237                         + responseInfo.error);
238             }
239         } else {
240             Rlog.e(TAG, "getModemsConfigResponse: Error " + responseInfo.toString());
241         }
242     }
243 
244     /**
245      * Response function IRadioConfig.getHalDeviceCapabilities()
246      */
getHalDeviceCapabilitiesResponse( android.hardware.radio.V1_6.RadioResponseInfo responseInfo, boolean modemReducedFeatureSet1)247     public void getHalDeviceCapabilitiesResponse(
248             android.hardware.radio.V1_6.RadioResponseInfo responseInfo,
249             boolean modemReducedFeatureSet1) {
250 
251         // convert hal device capabilities to RadioInterfaceCapabilities
252 
253         RILRequest rr = mRadioConfig.processResponse_1_6(responseInfo);
254         if (rr != null) {
255             // The response is compatible with Radio 1.6, it means the modem
256             // supports setAllowedNetworkTypeBitmap.
257 
258             final Set<String> ret = getCaps(mRadioHalVersion, modemReducedFeatureSet1);
259 
260             if (responseInfo.error == RadioError.NONE) {
261                 // send response
262                 RadioResponse.sendMessageResponse(rr.mResult, ret);
263                 Rlog.d(TAG, rr.serialString() + "< "
264                         + mRadioConfig.requestToString(rr.mRequest));
265             } else {
266                 rr.onError(responseInfo.error, ret);
267                 Rlog.e(TAG, rr.serialString() + "< "
268                         + mRadioConfig.requestToString(rr.mRequest) + " error "
269                         + responseInfo.error);
270             }
271         } else {
272             Rlog.e(TAG, "getHalDeviceCapabilities: Error " + responseInfo.toString());
273         }
274     }
275 
276     /**
277      * Returns all capabilities supported in the most recent radio hal version.
278      * <p/>
279      * Used in the {@link RILConstants.REQUEST_NOT_SUPPORTED} case.
280      *
281      * @return all capabilities
282      */
283     @RadioInterfaceCapability
getFullCapabilitySet()284     public Set<String> getFullCapabilitySet() {
285         return getCaps(mRadioHalVersion, false);
286     }
287 
288     /**
289      * Create capabilities based off of the radio hal version and feature set configurations.
290      */
291     @VisibleForTesting
getCaps(HalVersion radioHalVersion, boolean modemReducedFeatureSet1)292     public static Set<String> getCaps(HalVersion radioHalVersion,
293             boolean modemReducedFeatureSet1) {
294         final Set<String> caps = new HashSet<>();
295 
296         if (radioHalVersion.equals(RIL.RADIO_HAL_VERSION_UNKNOWN)) {
297             // If the Radio HAL is UNKNOWN, no capabilities will present themselves.
298             Rlog.e(TAG, "Radio Hal Version is UNKNOWN!");
299         }
300 
301         Rlog.d(TAG, "Radio Hal Version = " + radioHalVersion.toString());
302         if (radioHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
303             caps.add(CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK);
304             Rlog.d(TAG, "CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK");
305 
306             if (!modemReducedFeatureSet1) {
307                 caps.add(CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE);
308                 Rlog.d(TAG, "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE");
309                 caps.add(CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE);
310                 Rlog.d(TAG, "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE");
311                 caps.add(CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
312                 Rlog.d(TAG, "CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING");
313                 caps.add(CAPABILITY_SLICING_CONFIG_SUPPORTED);
314                 Rlog.d(TAG, "CAPABILITY_SLICING_CONFIG_SUPPORTED");
315                 caps.add(CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
316                 Rlog.d(TAG, "CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED");
317             } else {
318                 caps.add(CAPABILITY_SIM_PHONEBOOK_IN_MODEM);
319                 Rlog.d(TAG, "CAPABILITY_SIM_PHONEBOOK_IN_MODEM");
320             }
321         }
322         return caps;
323     }
324 }
325