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