1 /* 2 * Copyright (C) 2006 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.gsm; 18 19 /** 20 * SIM Tag-Length-Value record 21 * TS 102 223 Annex C 22 * 23 * {@hide} 24 * 25 */ 26 public class SimTlv 27 { 28 //***** Private Instance Variables 29 30 byte record[]; 31 int tlvOffset; 32 int tlvLength; 33 int curOffset; 34 int curDataOffset; 35 int curDataLength; 36 boolean hasValidTlvObject; 37 SimTlv(byte[] record, int offset, int length)38 public SimTlv(byte[] record, int offset, int length) { 39 this.record = record; 40 41 this.tlvOffset = offset; 42 this.tlvLength = length; 43 curOffset = offset; 44 45 hasValidTlvObject = parseCurrentTlvObject(); 46 } 47 nextObject()48 public boolean nextObject() { 49 if (!hasValidTlvObject) return false; 50 curOffset = curDataOffset + curDataLength; 51 hasValidTlvObject = parseCurrentTlvObject(); 52 return hasValidTlvObject; 53 } 54 isValidObject()55 public boolean isValidObject() { 56 return hasValidTlvObject; 57 } 58 59 /** 60 * Returns the tag for the current TLV object 61 * Return 0 if !isValidObject() 62 * 0 and 0xff are invalid tag values 63 * valid tags range from 1 - 0xfe 64 */ getTag()65 public int getTag() { 66 if (!hasValidTlvObject) return 0; 67 return record[curOffset] & 0xff; 68 } 69 70 /** 71 * Returns data associated with current TLV object 72 * returns null if !isValidObject() 73 */ 74 getData()75 public byte[] getData() { 76 if (!hasValidTlvObject) return null; 77 78 byte[] ret = new byte[curDataLength]; 79 System.arraycopy(record, curDataOffset, ret, 0, curDataLength); 80 return ret; 81 } 82 83 /** 84 * Updates curDataLength and curDataOffset 85 * @return false on invalid record, true on valid record 86 */ 87 parseCurrentTlvObject()88 private boolean parseCurrentTlvObject() { 89 // 0x00 and 0xff are invalid tag values 90 91 try { 92 if (record[curOffset] == 0 || (record[curOffset] & 0xff) == 0xff) { 93 return false; 94 } 95 96 if ((record[curOffset + 1] & 0xff) < 0x80) { 97 // one byte length 0 - 0x7f 98 curDataLength = record[curOffset + 1] & 0xff; 99 curDataOffset = curOffset + 2; 100 } else if ((record[curOffset + 1] & 0xff) == 0x81) { 101 // two byte length 0x80 - 0xff 102 curDataLength = record[curOffset + 2] & 0xff; 103 curDataOffset = curOffset + 3; 104 } else { 105 return false; 106 } 107 } catch (ArrayIndexOutOfBoundsException ex) { 108 return false; 109 } 110 111 if (curDataLength + curDataOffset > tlvOffset + tlvLength) { 112 return false; 113 } 114 115 return true; 116 } 117 118 } 119