Harald Welte | bb3b5df | 2021-05-24 23:15:54 +0200 | [diff] [blame] | 1 | """Code related to the Card Application Toolkit (CAT) as described in |
| 2 | mainly) ETSI TS 102 223, ETSI TS 101 220 and 3GPP TS 31.111.""" |
| 3 | |
| 4 | # (C) 2021 by Harald Welte <laforge@osmocom.org> |
| 5 | # |
| 6 | # This program is free software: you can redistribute it and/or modify |
| 7 | # it under the terms of the GNU General Public License as published by |
| 8 | # the Free Software Foundation, either version 2 of the License, or |
| 9 | # (at your option) any later version. |
| 10 | # |
| 11 | # This program is distributed in the hope that it will be useful, |
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | # GNU General Public License for more details. |
| 15 | # |
| 16 | # You should have received a copy of the GNU General Public License |
| 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | |
| 19 | |
| 20 | from pySim.tlv import * |
| 21 | from pySim.construct import * |
| 22 | from construct import * |
| 23 | |
| 24 | # Tag values as per TS 101 220 Table 7.23 |
| 25 | |
| 26 | # TS 102 223 Section 8.1 |
| 27 | class Address(COMPR_TLV_IE, tag=0x06): |
| 28 | _construct = Struct('ton_npi'/Int8ub, |
| 29 | 'call_number'/BcdAdapter(Bytes(this._.total_len-1))) |
| 30 | |
| 31 | # TS 102 223 Section 8.2 |
| 32 | class AlphaIdentifier(COMPR_TLV_IE, tag=0x05): |
| 33 | # FIXME: like EF.ADN |
| 34 | pass |
| 35 | |
| 36 | # TS 102 223 Section 8.3 |
| 37 | class Subaddress(COMPR_TLV_IE, tag=0x08): |
| 38 | pass |
| 39 | |
| 40 | # TS 102 223 Section 8.4 |
| 41 | class CapabilityConfigParams(COMPR_TLV_IE, tag=0x07): |
| 42 | pass |
| 43 | |
| 44 | # TS 31.111 Section 8.5 |
| 45 | class CBSPage(COMPR_TLV_IE, tag=0x0C): |
| 46 | pass |
| 47 | |
| 48 | # TS 102 223 Section 8.6 |
| 49 | class CommandDetails(COMPR_TLV_IE, tag=0x01): |
| 50 | _construct = Struct('command_number'/Int8ub, |
| 51 | 'type_of_command'/Int8ub, |
| 52 | 'command_qualifier'/Int8ub) |
| 53 | |
| 54 | # TS 102 223 Section 8.7 |
| 55 | class DeviceIdentities(COMPR_TLV_IE, tag=0x02): |
| 56 | DEV_IDS = bidict({ |
| 57 | 0x01: 'keypad', |
| 58 | 0x02: 'display', |
| 59 | 0x03: 'earpiece', |
| 60 | 0x10: 'addl_card_reader_0', |
| 61 | 0x11: 'addl_card_reader_1', |
| 62 | 0x12: 'addl_card_reader_2', |
| 63 | 0x13: 'addl_card_reader_3', |
| 64 | 0x14: 'addl_card_reader_4', |
| 65 | 0x15: 'addl_card_reader_5', |
| 66 | 0x16: 'addl_card_reader_6', |
| 67 | 0x17: 'addl_card_reader_7', |
| 68 | 0x21: 'channel_1', |
| 69 | 0x22: 'channel_2', |
| 70 | 0x23: 'channel_3', |
| 71 | 0x24: 'channel_4', |
| 72 | 0x25: 'channel_5', |
| 73 | 0x26: 'channel_6', |
| 74 | 0x27: 'channel_7', |
| 75 | 0x31: 'ecat_client_1', |
| 76 | 0x32: 'ecat_client_2', |
| 77 | 0x33: 'ecat_client_3', |
| 78 | 0x34: 'ecat_client_4', |
| 79 | 0x35: 'ecat_client_5', |
| 80 | 0x36: 'ecat_client_6', |
| 81 | 0x37: 'ecat_client_7', |
| 82 | 0x38: 'ecat_client_8', |
| 83 | 0x39: 'ecat_client_9', |
| 84 | 0x3a: 'ecat_client_a', |
| 85 | 0x3b: 'ecat_client_b', |
| 86 | 0x3c: 'ecat_client_c', |
| 87 | 0x3d: 'ecat_client_d', |
| 88 | 0x3e: 'ecat_client_e', |
| 89 | 0x3f: 'ecat_client_f', |
| 90 | 0x81: 'uicc', |
| 91 | 0x82: 'terminal', |
| 92 | 0x83: 'network', |
| 93 | }) |
| 94 | def _from_bytes(self, do:bytes): |
| 95 | return {'source_dev_id': self.DEV_IDS[do[0]], 'dest_dev_id': self.DEV_IDS[do[1]]} |
| 96 | |
| 97 | def _to_bytes(self): |
| 98 | src = self.DEV_IDS.inverse[self.decoded['source_dev_id']] |
| 99 | dst = self.DEV_IDS.inverse[self.decoded['dest_dev_id']] |
| 100 | return bytes([src, dst]) |
| 101 | |
| 102 | # TS 102 223 Section 8.8 |
| 103 | class Duration(COMPR_TLV_IE, tag=0x04): |
| 104 | _construct = Struct('time_unit'/Int8ub, |
| 105 | 'time_interval'/Int8ub) |
| 106 | |
| 107 | # TS 102 223 Section 8.9 |
| 108 | class Item(COMPR_TLV_IE, tag=0x0f): |
| 109 | _construct = Struct('identifier'/Int8ub, |
| 110 | 'text_string'/GsmStringAdapter(GreedyBytes)) |
| 111 | |
| 112 | # TS 102 223 Section 8.10 |
| 113 | class ItemIdentifier(COMPR_TLV_IE, tag=0x10): |
| 114 | _construct = Struct('identifier'/Int8ub) |
| 115 | |
| 116 | # TS 102 223 Section 8.11 |
| 117 | class ResponseLength(COMPR_TLV_IE, tag=0x11): |
| 118 | _construct = Struct('minimum_length'/Int8ub, |
| 119 | 'maximum_length'/Int8ub) |
| 120 | |
| 121 | # TS 102 223 Section 8.12 |
| 122 | class Result(COMPR_TLV_IE, tag=0x03): |
| 123 | _construct = Struct('general_result'/Int8ub, |
| 124 | 'additional_information'/HexAdapter(GreedyBytes)) |
| 125 | |
| 126 | |
| 127 | |
| 128 | # TS 102 223 Section 8.13 + TS 31.111 Section 8.13 |
| 129 | class SMS_TPDU(COMPR_TLV_IE, tag=0x0B): |
| 130 | pass |
| 131 | |
| 132 | # TS 102 223 Section 8.15 |
| 133 | class TextString(COMPR_TLV_IE, tag=0x0d): |
| 134 | _construct = Struct('dcs'/Int8ub, |
| 135 | 'text_string'/HexAdapter(GreedyBytes)) |
| 136 | |
| 137 | # TS 102 223 Section 8.16 |
| 138 | class Tone(COMPR_TLV_IE, tag=0x0e): |
| 139 | _construct = Struct('tone'/Int8ub) |
| 140 | |
| 141 | # TS 31 111 Section 8.17 |
| 142 | class USSDString(COMPR_TLV_IE, tag=0x0a): |
| 143 | _construct = Struct('dcs'/Int8ub, |
| 144 | 'ussd_string'/HexAdapter(GreedyBytes)) |
| 145 | |
| 146 | |
| 147 | |
| 148 | # TS 101 220 Table 7.17 |
| 149 | class ProactiveCommand(BER_TLV_IE, tag=0xD0): |
| 150 | pass |
| 151 | |
| 152 | # TS 101 220 Table 7.17 + 31.111 7.1.1.2 |
| 153 | class SMSPPDownload(BER_TLV_IE, tag=0xD1, |
| 154 | nested=[DeviceIdentities, Address, SMS_TPDU]): |
| 155 | pass |
| 156 | |
| 157 | # TS 101 220 Table 7.17 + 31.111 7.1.1.3 |
| 158 | class SMSCBDownload(BER_TLV_IE, tag=0xD2, |
| 159 | nested=[DeviceIdentities, CBSPage]): |
| 160 | pass |
| 161 | |
| 162 | class USSDDownload(BER_TLV_IE, tag=0xD9, |
| 163 | nested=[DeviceIdentities, USSDString]): |
| 164 | pass |
| 165 | |
| 166 | term_prof_bits = { |
| 167 | 1: 'Profile download', |
| 168 | 2: 'SMS-PP data doanload', |
| 169 | 3: 'Cell Broadcast data download', |
| 170 | 4: 'Menu selection', |
| 171 | 5: 'SMS-PP data download', |
| 172 | 6: 'Timer expiration', |
| 173 | 7: 'USSD string DO support in CC by USIM', |
| 174 | 8: 'Call Control by NAA', |
| 175 | |
| 176 | 9: 'Command result', |
| 177 | 10: 'Call Controll by NAA', |
| 178 | 11: 'Call Control by NAA', |
| 179 | 12: 'MO short message control support', |
| 180 | 13: 'Call Control by NAA', |
| 181 | 14: 'UCS2 Entry supported', |
| 182 | 15: 'UCS2 Display supported', |
| 183 | 16: 'Display Text', |
| 184 | |
| 185 | 17: 'Proactive UICC: DISPLAY TEXT', |
| 186 | 18: 'Proactive UICC: GET INKEY', |
| 187 | 19: 'Proactive UICC: GET INPUT', |
| 188 | 20: 'Proactive UICC: MORE TIME', |
| 189 | 21: 'Proactive UICC: PLAY TONE', |
| 190 | 22: 'Proactive UICC: POLL INTERVAL', |
| 191 | 23: 'Proactive UICC: POLLING OFF', |
| 192 | 24: 'Proactive UICC: REFRESH', |
| 193 | |
| 194 | 25: 'Proactive UICC: SELECT ITEM', |
| 195 | 26: 'Proactive UICC: SEND SHORT MESSAGE with 3GPP-SMS-TPDU', |
| 196 | 27: 'Proactive UICC: SEND SS', |
| 197 | 28: 'Proactive UICC: SEND USSD', |
| 198 | 29: 'Proactive UICC: SET UP CALL', |
| 199 | 30: 'Proactive UICC: SET UP MENU', |
| 200 | 31: 'Proactive UICC: PROVIDE LOCAL INFORMATION (MCC, MNC, LAC, Cell ID & IMEI)', |
| 201 | 32: 'Proactive UICC: PROVIDE LOCAL INFORMATION (NMR)', |
| 202 | |
| 203 | 33: 'Proactive UICC: SET UP EVENT LIST', |
| 204 | 34: 'Event: MT call', |
| 205 | 35: 'Event: Call connected', |
| 206 | 36: 'Event: Call disconnected', |
| 207 | 37: 'Event: Location status', |
| 208 | 38: 'Event: User activity', |
| 209 | 39: 'Event: Idle screen available', |
| 210 | 40: 'Event: Card reader status', |
| 211 | |
| 212 | 41: 'Event: Language selection', |
| 213 | 42: 'Event: Browser Termination', |
| 214 | 43: 'Event: Data aailable', |
| 215 | 44: 'Event: Channel status', |
| 216 | 45: 'Event: Access Technology Change', |
| 217 | 46: 'Event: Display parameters changed', |
| 218 | 47: 'Event: Local Connection', |
| 219 | 48: 'Event: Network Search Mode Change', |
| 220 | |
| 221 | # FIXME: remainder |
| 222 | } |