blob: e165e92004a764c1f7c19477b0f1a98dbd23e5bc [file] [log] [blame]
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +02001/* csn1_enc.c
Ivan Kluchnikov487a1412011-12-21 13:17:53 +03002 * Routines for CSN1 dissection in wireshark.
3 *
4 * Copyright (C) 2011 Ivan Klyuchnikov
5 *
6 * By Vincent Helfre, based on original code by Jari Sassi
7 * with the gracious authorization of STE
8 * Copyright (c) 2011 ST-Ericsson
9 *
10 * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */
30
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040031#include <assert.h>
32#include <string.h>
Holger Hans Peter Freythercf0265a2013-07-28 15:57:20 +020033#define __STDC_FORMAT_MACROS
34#include <inttypes.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030035#include "csn1.h"
Ivan Kluchnikova9f1ff22012-05-24 22:25:06 +040036#include <gprs_debug.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030037
Pau Espin Pedrold636f742020-02-03 15:37:08 +010038#include <osmocom/core/logging.h>
39#include <osmocom/core/utils.h>
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030040
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +020041const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030042
43/* Returns no_of_bits (up to 8) masked with 0x2B */
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +020044guint8
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070045get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030046{
47 static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
48 //gint byte_offset = bit_offset >> 3; /* divide by 8 */
49 gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */
50 guint8 result;
51 gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits;
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070052 *readIndex -= relative_bit_offset;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030053 if (bit_shift >= 0)
54 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070055 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift;
56 *readIndex-= bit_shift;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030057 result &= maskBits[no_of_bits];
58 }
59 else
Pau Espin Pedrolf960d5b2020-01-23 19:05:00 +010060 {
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070061 guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset];
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030062 hight_part = (guint8) (hight_part << (-bit_shift));
Vadim Yanitskiy39a65052020-01-25 01:24:59 +070063 result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift);
64 *readIndex = *readIndex - (8 - (-bit_shift));
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030065 result |= hight_part;
66 }
67 return result;
68}
69
70/**
71 * ================================================================================================
72 * set initial/start values in help data structure used for packing/unpacking operation
73 * ================================================================================================
74 */
75void
76csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len)
77{
78 ar->remaining_bits_len = remaining_bits_len;
79 ar->bit_offset = bit_offset;
Ivan Kluchnikov1b517342013-12-30 14:26:06 +040080 ar->direction = 0;
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030081}
82
Pau Espin Pedrold636f742020-02-03 15:37:08 +010083static const struct value_string csn1_error_names[] = {
84 { CSN_OK, "General 0" },
85 { CSN_ERROR_GENERAL, "General -1" },
86 { CSN_ERROR_DATA_NOT_VALID, "DATA_NOT VALID" },
87 { CSN_ERROR_IN_SCRIPT, "IN SCRIPT" },
88 { CSN_ERROR_INVALID_UNION_INDEX, "INVALID UNION INDEX" },
89 { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "NEED_MORE BITS TO UNPACK" },
Vadim Yanitskiyfee767f2020-02-11 05:28:02 +070090 { CSN_ERROR_ILLEGAL_BIT_VALUE, "ILLEGAL BIT VALUE" },
91 { CSN_ERROR_INTERNAL, "INTERNAL" },
Pau Espin Pedrold636f742020-02-03 15:37:08 +010092 { CSN_ERROR_STREAM_NOT_SUPPORTED, "STREAM_NOT_SUPPORTED" },
93 { CSN_ERROR_MESSAGE_TOO_LONG, "MESSAGE_TOO_LONG" },
94 { 0, NULL }
Ivan Kluchnikov487a1412011-12-21 13:17:53 +030095};
96
Pau Espin Pedrold636f742020-02-03 15:37:08 +010097
Pau Espin Pedrolc90e6f82021-10-19 14:45:17 +020098gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex,
Pau Espin Pedrold636f742020-02-03 15:37:08 +010099 const char* sz, gint16 err, const CSN_DESCR* pDescr)
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300100{
Pau Espin Pedrolac2b8662020-02-03 18:58:24 +0100101 /* Don't add trailing newline, top caller is responsible for appending it */
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100102 if (err != CSN_OK)
Vadim Yanitskiy15530492020-02-17 19:38:22 +0700103 LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %u)",
Pau Espin Pedrold636f742020-02-03 15:37:08 +0100104 sz, get_value_string(csn1_error_names, err), err,
Vadim Yanitskiy39a65052020-01-25 01:24:59 +0700105 pDescr ? pDescr->sz : "-", *readIndex);
Ivan Kluchnikov487a1412011-12-21 13:17:53 +0300106 return err;
107}