1 /* 2 * Copyright (C) 2006-2007 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.internal.telephony.cat; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.content.res.Resources; 21 import android.content.res.Resources.NotFoundException; 22 23 import com.android.internal.telephony.GsmAlphabet; 24 import com.android.internal.telephony.cat.Duration.TimeUnit; 25 import com.android.internal.telephony.uicc.IccUtils; 26 27 import java.io.UnsupportedEncodingException; 28 import java.util.ArrayList; 29 import java.util.List; 30 31 abstract class ValueParser { 32 33 /** 34 * Search for a Command Details object from a list. 35 * 36 * @param ctlv List of ComprehensionTlv objects used for search 37 * @return An CtlvCommandDetails object found from the objects. If no 38 * Command Details object is found, ResultException is thrown. 39 * @throws ResultException 40 */ retrieveCommandDetails(ComprehensionTlv ctlv)41 static CommandDetails retrieveCommandDetails(ComprehensionTlv ctlv) 42 throws ResultException { 43 44 CommandDetails cmdDet = new CommandDetails(); 45 byte[] rawValue = ctlv.getRawValue(); 46 int valueIndex = ctlv.getValueIndex(); 47 try { 48 cmdDet.compRequired = ctlv.isComprehensionRequired(); 49 cmdDet.commandNumber = rawValue[valueIndex] & 0xff; 50 cmdDet.typeOfCommand = rawValue[valueIndex + 1] & 0xff; 51 cmdDet.commandQualifier = rawValue[valueIndex + 2] & 0xff; 52 return cmdDet; 53 } catch (IndexOutOfBoundsException e) { 54 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 55 } 56 } 57 58 /** 59 * Search for a Device Identities object from a list. 60 * 61 * @param ctlv List of ComprehensionTlv objects used for search 62 * @return An CtlvDeviceIdentities object found from the objects. If no 63 * Command Details object is found, ResultException is thrown. 64 * @throws ResultException 65 */ 66 @UnsupportedAppUsage retrieveDeviceIdentities(ComprehensionTlv ctlv)67 static DeviceIdentities retrieveDeviceIdentities(ComprehensionTlv ctlv) 68 throws ResultException { 69 70 DeviceIdentities devIds = new DeviceIdentities(); 71 byte[] rawValue = ctlv.getRawValue(); 72 int valueIndex = ctlv.getValueIndex(); 73 try { 74 devIds.sourceId = rawValue[valueIndex] & 0xff; 75 devIds.destinationId = rawValue[valueIndex + 1] & 0xff; 76 return devIds; 77 } catch (IndexOutOfBoundsException e) { 78 throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); 79 } 80 } 81 82 /** 83 * Retrieves Duration information from the Duration COMPREHENSION-TLV 84 * object. 85 * 86 * @param ctlv A Text Attribute COMPREHENSION-TLV object 87 * @return A Duration object 88 * @throws ResultException 89 */ retrieveDuration(ComprehensionTlv ctlv)90 static Duration retrieveDuration(ComprehensionTlv ctlv) throws ResultException { 91 int timeInterval = 0; 92 TimeUnit timeUnit = TimeUnit.SECOND; 93 94 byte[] rawValue = ctlv.getRawValue(); 95 int valueIndex = ctlv.getValueIndex(); 96 97 try { 98 timeUnit = TimeUnit.values()[(rawValue[valueIndex] & 0xff)]; 99 timeInterval = rawValue[valueIndex + 1] & 0xff; 100 } catch (IndexOutOfBoundsException e) { 101 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 102 } 103 return new Duration(timeInterval, timeUnit); 104 } 105 106 /** 107 * Retrieves Item information from the COMPREHENSION-TLV object. 108 * 109 * @param ctlv A Text Attribute COMPREHENSION-TLV object 110 * @return An Item 111 * @throws ResultException 112 */ retrieveItem(ComprehensionTlv ctlv)113 static Item retrieveItem(ComprehensionTlv ctlv) throws ResultException { 114 Item item = null; 115 116 byte[] rawValue = ctlv.getRawValue(); 117 int valueIndex = ctlv.getValueIndex(); 118 int length = ctlv.getLength(); 119 120 if (length != 0) { 121 int textLen = length - 1; 122 123 try { 124 int id = rawValue[valueIndex] & 0xff; 125 String text = IccUtils.adnStringFieldToString(rawValue, 126 valueIndex + 1, textLen); 127 item = new Item(id, text); 128 } catch (IndexOutOfBoundsException e) { 129 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 130 } 131 } 132 133 return item; 134 } 135 136 /** 137 * Retrieves Item id information from the COMPREHENSION-TLV object. 138 * 139 * @param ctlv A Text Attribute COMPREHENSION-TLV object 140 * @return An Item id 141 * @throws ResultException 142 */ retrieveItemId(ComprehensionTlv ctlv)143 static int retrieveItemId(ComprehensionTlv ctlv) throws ResultException { 144 int id = 0; 145 146 byte[] rawValue = ctlv.getRawValue(); 147 int valueIndex = ctlv.getValueIndex(); 148 149 try { 150 id = rawValue[valueIndex] & 0xff; 151 } catch (IndexOutOfBoundsException e) { 152 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 153 } 154 155 return id; 156 } 157 158 /** 159 * Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object 160 * 161 * @param ctlv An Icon Identifier COMPREHENSION-TLV object 162 * @return IconId instance 163 * @throws ResultException 164 */ retrieveIconId(ComprehensionTlv ctlv)165 static IconId retrieveIconId(ComprehensionTlv ctlv) throws ResultException { 166 IconId id = new IconId(); 167 168 byte[] rawValue = ctlv.getRawValue(); 169 int valueIndex = ctlv.getValueIndex(); 170 try { 171 id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; 172 id.recordNumber = rawValue[valueIndex] & 0xff; 173 } catch (IndexOutOfBoundsException e) { 174 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 175 } 176 177 return id; 178 } 179 180 /** 181 * Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV 182 * object 183 * 184 * @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object 185 * @return ItemsIconId instance 186 * @throws ResultException 187 */ retrieveItemsIconId(ComprehensionTlv ctlv)188 static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv) 189 throws ResultException { 190 CatLog.d("ValueParser", "retrieveItemsIconId:"); 191 ItemsIconId id = new ItemsIconId(); 192 193 byte[] rawValue = ctlv.getRawValue(); 194 int valueIndex = ctlv.getValueIndex(); 195 int numOfItems = ctlv.getLength() - 1; 196 id.recordNumbers = new int[numOfItems]; 197 198 try { 199 // get icon self-explanatory 200 id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; 201 202 for (int index = 0; index < numOfItems;) { 203 id.recordNumbers[index++] = rawValue[valueIndex++]; 204 } 205 } catch (IndexOutOfBoundsException e) { 206 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 207 } 208 return id; 209 } 210 211 /** 212 * Retrieves text attribute information from the Text Attribute 213 * COMPREHENSION-TLV object. 214 * 215 * @param ctlv A Text Attribute COMPREHENSION-TLV object 216 * @return A list of TextAttribute objects 217 * @throws ResultException 218 */ 219 @UnsupportedAppUsage retrieveTextAttribute(ComprehensionTlv ctlv)220 static List<TextAttribute> retrieveTextAttribute(ComprehensionTlv ctlv) 221 throws ResultException { 222 ArrayList<TextAttribute> lst = new ArrayList<TextAttribute>(); 223 224 byte[] rawValue = ctlv.getRawValue(); 225 int valueIndex = ctlv.getValueIndex(); 226 int length = ctlv.getLength(); 227 228 if (length != 0) { 229 // Each attribute is consisted of four bytes 230 int itemCount = length / 4; 231 232 try { 233 for (int i = 0; i < itemCount; i++, valueIndex += 4) { 234 int start = rawValue[valueIndex] & 0xff; 235 int textLength = rawValue[valueIndex + 1] & 0xff; 236 int format = rawValue[valueIndex + 2] & 0xff; 237 int colorValue = rawValue[valueIndex + 3] & 0xff; 238 239 int alignValue = format & 0x03; 240 TextAlignment align = TextAlignment.fromInt(alignValue); 241 242 int sizeValue = (format >> 2) & 0x03; 243 FontSize size = FontSize.fromInt(sizeValue); 244 if (size == null) { 245 // Font size value is not defined. Use default. 246 size = FontSize.NORMAL; 247 } 248 249 boolean bold = (format & 0x10) != 0; 250 boolean italic = (format & 0x20) != 0; 251 boolean underlined = (format & 0x40) != 0; 252 boolean strikeThrough = (format & 0x80) != 0; 253 254 TextColor color = TextColor.fromInt(colorValue); 255 256 TextAttribute attr = new TextAttribute(start, textLength, 257 align, size, bold, italic, underlined, 258 strikeThrough, color); 259 lst.add(attr); 260 } 261 262 return lst; 263 264 } catch (IndexOutOfBoundsException e) { 265 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 266 } 267 } 268 return null; 269 } 270 271 272 /** 273 * Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV 274 * object. 275 * 276 * @param ctlv An Alpha Identifier COMPREHENSION-TLV object 277 * @return String corresponding to the alpha identifier 278 * @throws ResultException 279 */ 280 @UnsupportedAppUsage retrieveAlphaId(ComprehensionTlv ctlv)281 static String retrieveAlphaId(ComprehensionTlv ctlv) throws ResultException { 282 283 if (ctlv != null) { 284 byte[] rawValue = ctlv.getRawValue(); 285 int valueIndex = ctlv.getValueIndex(); 286 int length = ctlv.getLength(); 287 if (length != 0) { 288 try { 289 return IccUtils.adnStringFieldToString(rawValue, valueIndex, 290 length); 291 } catch (IndexOutOfBoundsException e) { 292 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 293 } 294 } else { 295 CatLog.d("ValueParser", "Alpha Id length=" + length); 296 return null; 297 } 298 } else { 299 /* Per 3GPP specification 102.223, 300 * if the alpha identifier is not provided by the UICC, 301 * the terminal MAY give information to the user 302 * noAlphaUsrCnf defines if you need to show user confirmation or not 303 */ 304 boolean noAlphaUsrCnf = false; 305 Resources resource = Resources.getSystem(); 306 try { 307 noAlphaUsrCnf = resource.getBoolean( 308 com.android.internal.R.bool.config_stkNoAlphaUsrCnf); 309 } catch (NotFoundException e) { 310 noAlphaUsrCnf = false; 311 } 312 return (noAlphaUsrCnf ? null : CatService.STK_DEFAULT); 313 } 314 } 315 316 /** 317 * Retrieves text from the Text COMPREHENSION-TLV object, and decodes it 318 * into a Java String. 319 * 320 * @param ctlv A Text COMPREHENSION-TLV object 321 * @return A Java String object decoded from the Text object 322 * @throws ResultException 323 */ 324 @UnsupportedAppUsage retrieveTextString(ComprehensionTlv ctlv)325 static String retrieveTextString(ComprehensionTlv ctlv) throws ResultException { 326 byte[] rawValue = ctlv.getRawValue(); 327 int valueIndex = ctlv.getValueIndex(); 328 byte codingScheme = 0x00; 329 String text = null; 330 int textLen = ctlv.getLength(); 331 332 // In case the text length is 0, return a null string. 333 if (textLen == 0) { 334 return text; 335 } else { 336 // one byte is coding scheme 337 textLen -= 1; 338 } 339 340 try { 341 codingScheme = (byte) (rawValue[valueIndex] & 0x0c); 342 343 if (codingScheme == 0x00) { // GSM 7-bit packed 344 text = GsmAlphabet.gsm7BitPackedToString(rawValue, 345 valueIndex + 1, (textLen * 8) / 7); 346 } else if (codingScheme == 0x04) { // GSM 8-bit unpacked 347 text = GsmAlphabet.gsm8BitUnpackedToString(rawValue, 348 valueIndex + 1, textLen); 349 } else if (codingScheme == 0x08) { // UCS2 350 text = new String(rawValue, valueIndex + 1, textLen, "UTF-16"); 351 } else { 352 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 353 } 354 355 return text; 356 } catch (IndexOutOfBoundsException e) { 357 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 358 } catch (UnsupportedEncodingException e) { 359 // This should never happen. 360 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 361 } 362 } 363 } 364