/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony.gsm; /** * SIM Tag-Length-Value record * TS 102 223 Annex C * * {@hide} * */ public class SimTlv { //***** Private Instance Variables byte mRecord[]; int mTlvOffset; int mTlvLength; int mCurOffset; int mCurDataOffset; int mCurDataLength; boolean mHasValidTlvObject; public SimTlv(byte[] record, int offset, int length) { mRecord = record; mTlvOffset = offset; mTlvLength = length; mCurOffset = offset; mHasValidTlvObject = parseCurrentTlvObject(); } public boolean nextObject() { if (!mHasValidTlvObject) return false; mCurOffset = mCurDataOffset + mCurDataLength; mHasValidTlvObject = parseCurrentTlvObject(); return mHasValidTlvObject; } public boolean isValidObject() { return mHasValidTlvObject; } /** * Returns the tag for the current TLV object * Return 0 if !isValidObject() * 0 and 0xff are invalid tag values * valid tags range from 1 - 0xfe */ public int getTag() { if (!mHasValidTlvObject) return 0; return mRecord[mCurOffset] & 0xff; } /** * Returns data associated with current TLV object * returns null if !isValidObject() */ public byte[] getData() { if (!mHasValidTlvObject) return null; byte[] ret = new byte[mCurDataLength]; System.arraycopy(mRecord, mCurDataOffset, ret, 0, mCurDataLength); return ret; } /** * Updates curDataLength and curDataOffset * @return false on invalid record, true on valid record */ private boolean parseCurrentTlvObject() { // 0x00 and 0xff are invalid tag values try { if (mRecord[mCurOffset] == 0 || (mRecord[mCurOffset] & 0xff) == 0xff) { return false; } if ((mRecord[mCurOffset + 1] & 0xff) < 0x80) { // one byte length 0 - 0x7f mCurDataLength = mRecord[mCurOffset + 1] & 0xff; mCurDataOffset = mCurOffset + 2; } else if ((mRecord[mCurOffset + 1] & 0xff) == 0x81) { // two byte length 0x80 - 0xff mCurDataLength = mRecord[mCurOffset + 2] & 0xff; mCurDataOffset = mCurOffset + 3; } else { return false; } } catch (ArrayIndexOutOfBoundsException ex) { return false; } if (mCurDataLength + mCurDataOffset > mTlvOffset + mTlvLength) { return false; } return true; } }