/*
* 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;
}
}
|