• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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