/*
* 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 record[];
int tlvOffset;
int tlvLength;
int curOffset;
int curDataOffset;
int curDataLength;
boolean hasValidTlvObject;
public SimTlv(byte[] record, int offset, int length)
{
this.record = record;
this.tlvOffset = offset;
this.tlvLength = length;
curOffset = offset;
hasValidTlvObject = parseCurrentTlvObject();
}
public boolean
nextObject()
{
if (!hasValidTlvObject) return false;
curOffset = curDataOffset + curDataLength;
hasValidTlvObject = parseCurrentTlvObject();
return hasValidTlvObject;
}
public boolean
isValidObject()
{
return hasValidTlvObject;
}
/**
* 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 (!hasValidTlvObject) return 0;
return record[curOffset] & 0xff;
}
/**
* Returns data associated with current TLV object
* returns null if !isValidObject()
*/
public byte[]
getData()
{
if (!hasValidTlvObject) return null;
byte[] ret = new byte[curDataLength];
System.arraycopy(record, curDataOffset, ret, 0, curDataLength);
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
if (record[curOffset] == 0 || (record[curOffset] & 0xff) == 0xff) {
return false;
}
try {
if ((record[curOffset + 1] & 0xff) < 0x80) {
// one byte length 0 - 0x7f
curDataLength = record[curOffset + 1] & 0xff;
curDataOffset = curOffset + 2;
} else if ((record[curOffset + 1] & 0xff) == 0x81) {
// two byte length 0x80 - 0xff
curDataLength = record[curOffset + 2] & 0xff;
curDataOffset = curOffset + 3;
} else {
return false;
}
} catch (ArrayIndexOutOfBoundsException ex) {
return false;
}
if (curDataLength + curDataOffset > tlvOffset + tlvLength) {
return false;
}
return true;
}
}
|