|
| 1 | +# -*- coding: UTF-8 -*- |
| 2 | +#/** |
| 3 | +# * Software Name : pycrate |
| 4 | +# * Version : 0.5 |
| 5 | +# * |
| 6 | +# * Copyright 2023. Laurent Ghigonis. P1Sec. |
| 7 | +# * |
| 8 | +# * This library is free software; you can redistribute it and/or |
| 9 | +# * modify it under the terms of the GNU Lesser General Public |
| 10 | +# * License as published by the Free Software Foundation; either |
| 11 | +# * version 2.1 of the License, or (at your option) any later version. |
| 12 | +# * |
| 13 | +# * This library is distributed in the hope that it will be useful, |
| 14 | +# * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | +# * Lesser General Public License for more details. |
| 17 | +# * |
| 18 | +# * You should have received a copy of the GNU Lesser General Public |
| 19 | +# * License along with this library; if not, write to the Free Software |
| 20 | +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
| 21 | +# * MA 02110-1301 USA |
| 22 | +# * |
| 23 | +# *-------------------------------------------------------- |
| 24 | +# * File Name : pycrate_mobile/TS48006_BSSAP.py |
| 25 | +# * Created : 2023-01-09 |
| 26 | +# * Authors : Laurent Ghigonis |
| 27 | +# *-------------------------------------------------------- |
| 28 | +#*/ |
| 29 | + |
| 30 | +from enum import IntEnum |
| 31 | +from struct import unpack |
| 32 | + |
| 33 | +from pycrate_core.elt import Envelope, REPR_RAW, REPR_HEX, REPR_BIN |
| 34 | +from pycrate_core.base import * |
| 35 | +from pycrate_core.repr import * |
| 36 | + |
| 37 | + |
| 38 | +#------------------------------------------------------------------------------# |
| 39 | +# BSS Application Part (BSSAP) as defined in 3GPP TS 48.006 and 3GPP TS 49.008 |
| 40 | +#------------------------------------------------------------------------------# |
| 41 | +# Implementation notes: |
| 42 | +# * Len has to be set manually in BSSAP_DirectTransfer and BSSAP_Management, |
| 43 | +# as the layer is an adaption between 2 layers, and does not *include* the upper layer (no setvalauto() in __init__()) |
| 44 | +# * procedures : TS49.008 https://www.etsi.org/deliver/etsi_ts/149000_149099/149008/09.00.00_60/ts_149008v090000p.pdf |
| 45 | +# * protocol : TS48.006 https://www.etsi.org/deliver/etsi_ts/148000_148099/148006/09.00.00_60/ts_148006v090000p.pdf |
| 46 | +# * wireshark implementation : https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-bssap.c |
| 47 | + |
| 48 | + |
| 49 | +#------------------------------------------------------------------------------# |
| 50 | +# BSSAP header elements |
| 51 | +#------------------------------------------------------------------------------# |
| 52 | + |
| 53 | +class BSSAPType(IntEnum): |
| 54 | + BSS_MANAGEMENT = 0x00 |
| 55 | + DIRECT_TRANSFER = 0x01 |
| 56 | + |
| 57 | + |
| 58 | +class DistributionUnit(Envelope): |
| 59 | + _GEN = ( |
| 60 | + Uint('RadioMessageGroup', bl=7), |
| 61 | + Uint('Discrimination', bl=1, dic={ |
| 62 | + BSSAPType.BSS_MANAGEMENT : 'Not Transparent: BSSMAP', |
| 63 | + BSSAPType.DIRECT_TRANSFER : 'Transparent: DTAP'}), |
| 64 | + ) |
| 65 | + |
| 66 | + |
| 67 | +# Service Access Point Identifier, defined in TS44.006 |
| 68 | +class BSSAP_SAPI(IntEnum): |
| 69 | + SIGNALING = 0 |
| 70 | + SMS = 3 |
| 71 | + |
| 72 | + |
| 73 | +BSSAP_SAPI_dict = { |
| 74 | + BSSAP_SAPI.SIGNALING: 'signaling information', |
| 75 | + BSSAP_SAPI.SMS: 'SMS', |
| 76 | + } |
| 77 | + |
| 78 | + |
| 79 | +#------------------------------------------------------------------------------# |
| 80 | +# BSSAP messages |
| 81 | +#------------------------------------------------------------------------------# |
| 82 | +# TS48.006, 9.3.2: Transfer of DTAP messages |
| 83 | +# TS48.006, 9.3.3: Transfer of BSSMAP messages |
| 84 | + |
| 85 | +class BSSAP(Envelope): |
| 86 | + _GEN = ( |
| 87 | + DistributionUnit('DistributionUnit', val=(0, BSSAPType.DIRECT_TRANSFER)), |
| 88 | + Envelope('DLCI', GEN=( |
| 89 | + Uint('ControlChannelIdentification', bl=2, dic={ |
| 90 | + 0: 'no further specified', |
| 91 | + 1: 'reserved', |
| 92 | + 2: 'FACCH or SDCCH', |
| 93 | + 3: 'SACCH'}), |
| 94 | + Uint('spare', bl=3), |
| 95 | + Uint('SAPI', bl=3, dic=BSSAP_SAPI_dict) |
| 96 | + )), |
| 97 | + Uint8('Len'), |
| 98 | + Buf('L3', rep=REPR_HEX) |
| 99 | + ) |
| 100 | + |
| 101 | + def __init__(self, *args, **kwargs): |
| 102 | + Envelope.__init__(self, *args, **kwargs) |
| 103 | + # DLCI only present for DIRECT_TRANSFER |
| 104 | + self['DLCI'].set_transauto(lambda: not self['DistributionUnit'].get_val()[1]) |
| 105 | + self['Len'].set_valauto(lambda: self['L3'].get_len()) |
| 106 | + self['L3'].set_blauto(lambda: self['Len'].get_val()<<3) |
| 107 | + |
0 commit comments