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