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