diff options
author | Philipp Maier <pmaier@sysmocom.de> | 2022-09-01 17:48:38 +0200 |
---|---|---|
committer | Philipp Maier <pmaier@sysmocom.de> | 2023-01-03 12:24:29 +0100 |
commit | b057535512046101250278c416b0ae5a1b41e251 (patch) | |
tree | 29c689a2f4e0871a9e1e860e5366b671b400c51b | |
parent | f2649502fdb0546752b4e338bd69cf9ba7816a9d (diff) |
GPRS Trau frame encoder/decoder for Ericsson RBS
The Ericsson RBS BTS family is using a propritary TRAU frame dialect to
communicate with the GPRS/EGPRS part of their CCU. There are essentially
two implementations available:
- GPRS over 16kbps I.460 subslots (very limited, supports only CS1 and CS4)
- GPRS/EGPRS over full 64kbps timeslots (supports CS1-4 and MCS1-9)
Change-Id: Ib2b232a76588c32cde75b987a7e5fdfddf099cd7
Related: OS#5198
-rw-r--r-- | include/Makefile.am | 1 | ||||
-rw-r--r-- | include/osmocom/trau/trau_pcu_ericsson.h | 280 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/trau/trau_pcu_ericsson.c | 2000 | ||||
-rw-r--r-- | tests/Makefile.am | 9 | ||||
-rw-r--r-- | tests/testsuite.at | 6 | ||||
-rw-r--r-- | tests/trau_pcu_ericsson/trau_pcu_ericsson_test.c | 1392 | ||||
-rw-r--r-- | tests/trau_pcu_ericsson/trau_pcu_ericsson_test.ok | 2579 |
8 files changed, 6266 insertions, 2 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index 70f1cd6..a167ef2 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -7,4 +7,5 @@ nobase_include_HEADERS = osmocom/abis/ipa.h osmocom/abis/trau_frame.h \ osmocom/abis/unixsocket_proto.h \ osmocom/trau/trau_frame.h \ osmocom/trau/trau_sync.h \ + osmocom/trau/trau_pcu_ericsson.h \ osmocom/trau/trau_rtp.h diff --git a/include/osmocom/trau/trau_pcu_ericsson.h b/include/osmocom/trau/trau_pcu_ericsson.h new file mode 100644 index 0000000..03a446f --- /dev/null +++ b/include/osmocom/trau/trau_pcu_ericsson.h @@ -0,0 +1,280 @@ +#pragma once + +enum time_adj_val { + TIME_ADJ_NONE, + TIME_ADJ_DELAY_250us, + TIME_ADJ_ADVANCE_250us, +}; + +enum er_cs_or_hdr { + CS_OR_HDR_AB = 0, + CS_OR_HDR_CS1 = 1, + CS_OR_HDR_CS2 = 2, + CS_OR_HDR_CS3 = 3, + CS_OR_HDR_CS4 = 4, + CS_OR_HDR_HDR1 = 5, + CS_OR_HDR_HDR2 = 6, + CS_OR_HDR_HDR3 = 7, +}; + +/* Block Quality / Soft Frame Quality */ +enum er_block_qual { + ER_SFQ_00_09 = 0, + ER_SFQ_10_19 = 1, + ER_SFQ_20_29 = 2, + ER_SFQ_30_39 = 3, + ER_SFQ_40_49 = 4, + ER_SFQ_50_59 = 5, + ER_SFQ_60_69 = 6, + ER_SFQ_70_MORE = 7, +}; + +enum er_ul_chan_mode { + /* no demodulation, ignore uplink */ + ER_UL_CHMOD_VOID = 0, + + /* normal burst, GMSK only */ + ER_UL_CHMOD_NB_GMSK = 1, + + /* normal burst, MCS1..MCS9 or CS1 */ + ER_UL_CHMOD_NB_UNKN = 2, + + /* Access Burst (only TS0 and 8bit) */ + ER_UL_CHMOD_AB = 3, + + /* Access Burst (TS0/1/2) */ + ER_UL_CHMOD_AB_UNKN = 4, +}; + +/* Access burst data */ +struct er_gprs_ab { + uint8_t ab_type; + uint8_t rxlev; + uint16_t acc_delay; + uint16_t data; + + union { + struct { + uint8_t crc; + uint8_t burst_qual; + uint8_t frame_qual; + } type_1; + struct { + uint8_t abi; + uint8_t type; + } type_2; + } u; +}; + +/* CCU->PCU SYNC */ +struct er_ccu_sync_ind { + /* Time Adjustment Value (requested) */ + enum time_adj_val tav; + + /* Downlink Frame Error */ + bool dfe; + + /* Downlink Block Error (bad MAC block from PCU) */ + bool dbe; + + /* PCU Sequene Counter (will lag, must be compensated) */ + uint32_t pseq; + + /* Adjusted Frame Number, Uplink */ + uint32_t afn_ul; + + /* Adjusted Frame Number, Downlink */ + uint32_t afn_dl; +}; + +/* PCU->CCU SYNC */ +struct er_pcu_sync_ind { + /* Time Adjustment Value (acknowledged) */ + enum time_adj_val tav; + bool ul_frame_err; + + /* PCU Sequene Counter (PCU will sync to this value) */ + uint32_t pseq; + + /* Optional, ignored by CCU */ + uint32_t ss; + + /* Optional, ignored by CCU */ + uint32_t fn_ul; + + /* Optional, ignored by CCU */ + uint32_t fn_ss; + + /* Optional, ignored by CCU */ + uint32_t fn_dl; + + /* Optional, ignored by CCU */ + uint32_t ls; +}; + +/* PCU->CCU DATA */ +struct er_pcu_data_ind { + /* Time Adjustment Value (acknowledged) */ + enum time_adj_val tav; + + /* Uplink Frame Error */ + bool ul_frame_err; + + /* Coding Scheme */ + enum er_cs_or_hdr cs_hdr; + + /* Modulation to be applied on coresponding uplink frame, also used to retrieve + * extraordinary ccu_sync_ind frames and ccu_data_ind frames wth Access bursts data. */ + enum er_ul_chan_mode ul_chan_mode; + + /* Attenuation of transmission power, 16 steps, 2dB each */ + uint8_t atten_db; + + /* Timing offset (timing advance) */ + uint8_t timing_offset; + + /* MAC block */ + uint8_t data[155]; +}; + +/* CCU->PCU DATA */ +struct er_ccu_data_ind { + /* Time Adjustment Value (requested) */ + enum time_adj_val tav; + + /* Downlink Block Error (bad MAC block from PCU) */ + bool dbe; + + /* Coding Scheme */ + enum er_cs_or_hdr cs_hdr; + + /* Receive level 63 steps, see also GSM 05.08, section 8.1.4 */ + uint8_t rx_lev; + + /* Estimated Access Delay Deviation (bits, uplink only) */ + int8_t est_acc_del_dev; + + /* Data integrity checks (uplink only) */ + union { + struct { + /* Soft Frame Quality */ + enum er_block_qual block_qual; + /* Parity Check */ + bool parity_ok; + } gprs; + struct { + uint8_t mean_bep; + uint8_t cv_bep; + bool hdr_good; + bool data_good[2]; + } egprs; + } u; + + /* MAC block */ + uint8_t data[155]; + + /* MAC block length + * (uplink only, for downlink cs_hdr and MAC block header will be used + * to determine the length.) */ + uint8_t data_len; + + /* Access burst data (in case an access block was received) */ + struct er_gprs_ab ab[4]; +}; + +enum er_gprs_trau_frame_type { + ER_GPRS_TRAU_FT_NONE, + ER_GPRS_TRAU_FT_SYNC, + ER_GPRS_TRAU_FT_DATA, +}; + +struct er_gprs_trau_frame { + enum er_gprs_trau_frame_type type; + union { + struct er_ccu_sync_ind ccu_sync_ind; + struct er_ccu_data_ind ccu_data_ind; + struct er_pcu_sync_ind pcu_sync_ind; + struct er_pcu_data_ind pcu_data_ind; + } u; +}; + +#define ER_GPRS_TRAU_FRAME_LEN_16K 324 /* 320 +/-4 bit for time alignment */ +#define ER_GPRS_TRAU_FRAME_LEN_64K 1296 /* 1280 +/-16 bit for time alignment */ +int er_gprs_trau_frame_encode_16k(ubit_t *bits, struct er_gprs_trau_frame *fr); +int er_gprs_trau_frame_decode_16k(struct er_gprs_trau_frame *fr, const ubit_t *bits); +int er_gprs_trau_frame_encode_64k(ubit_t *bits, struct er_gprs_trau_frame *fr); +int er_gprs_trau_frame_decode_64k(struct er_gprs_trau_frame *fr, const ubit_t *bits); + +/* + * Idle pattern + * ============ + * An inactive CCU will send an idle pattern, which is a sequence of alternating ones and zeros (101010101...) The + * idle pattern indicates that the CCU available but in idle state. To leave the idle state a channel activation + * via RSL must be carried out. It is not possible to "wake up" an idle CCU by just sending TRAU frames to it. + * + * + * Synchronization procedure + * ========================= + * When the PDCH is activated, the CCU becomes active at its designated E1 timeslot/subslot. It sends out ccu_sync_ind + * frames and expects pcu_sync_ind frames from the PCU. When the CCU does not receive any pcu_sync_ind frames, the CCU + * becomes inactive until the PDCH is activated again. + * + * CCU is synchronized to the PCU by sending pcu_sync_ind frames with an incrementing PSEQ sequence number to the CCU. + * The PSEQ has no relation to the actual frame number. It just counts the TRAU frames sent over the E1 link. When + * the CCU receives a valid pcu_sync_ind it will synchronize its local PSEQ counter to the received PSEQ and respond + * back with a ccu_sync_ind that echos the PSEQ and also contains the current GSM frame numbers. The synchronization + * is then complete and the PCU may start sending pcu_data_ind. + * + * PCU CCU + * | | + * |--------pcu_sync_ind-------->| + * |<-------idle pattern---------| + * |--------pcu_sync_ind-------->| + * |<-------idle pattern---------| + * |--------pcu_sync_ind-------->| + * |<-------idle pattern---------| + * |--------pcu_sync_ind-------->| + * |<-------ccu_sync_ind---------| + * |--------pcu_sync_ind-------->| + * |<-------ccu_sync_ind---------| + * |--------pcu_sync_ind-------->| + * |<-------ccu_sync_ind---------| + * |--------pcu_data_ind-------->| + * |<-------ccu_data_ind---------| + * |--------pcu_data_ind-------->| + * |<-------ccu_data_ind---------| + * + * While pcu_data_ind and ccu_data_ind frames are passed over the link the PCU has no way to get the current PSEQ or + * any GSM frame number from the CCU. It must calculate those values locally. However, it is possible to request + * a ccu_sync_ind from the CCU at any time by setting the requested demodulation to ER_UL_CHMOD_VOID in one + * pcu_data_ind. It should be pointed out that the requested ccu_sync_ind will steal one pcu_data_ind. The requested + * ccu_sync_ind message will also only contain the GSM frame numbers but not the PSEQ value. If the GSM frame numbers + * in the received ccu_sync_ind are deviating from the local frame numbers, the synchronization procedure can be + * carried out again. + * + * PCU CCU + * | | + * |--------pcu_data_ind-------->| + * |<-------ccu_data_ind---------| + * |--------pcu_data_ind-------->| + * |<-------ccu_data_ind---------| + * |--------pcu_data_ind-------->| (ER_UL_CHMOD_VOID) + * |<-------ccu_sync_ind---------| + * |--------pcu_data_ind-------->| + * |<-------ccu_data_ind---------| + * + * It also should be mentioned that due to link latency, there will naturally be a gap between the PCU local PSEQ and + * the PSEQ reported by the CCU. This information is important since it must be used to compensate the GSM frame + * numbers. + * + * The procedure is very similar to what is described in US Patent No. 5,978,368 from Nov.2, 1999 + * + * Usage of Timing Adjustment (TAV) parameter + * ========================================== + * The time adjustment is controlled by the CCU. The TAV value received in TRAU frames that originate from the CCU is + * the ordered timing adjustment. The TAV value in TRAU frames that originate from the PCU is the acknowledged time + * adjustment. When a timing adjustment is requested by the CCU, the PCU acknowledges it by sending the requested + * value back. The timing adjustment is performed immediately within the same frame by appending or removing bits + * at the end. This delays or advances the timing of the subsequent frame. + * + * The procedure is very similar to the one described in: GSM 08.60, section 4.6.1.2 */ diff --git a/src/Makefile.am b/src/Makefile.am index cf8de47..600ed54 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,7 @@ libosmotrau_la_LDFLAGS = $(AM_LDFLAGS) \ libosmotrau_la_LIBADD = $(COMMONLIBS) $(ORTP_LIBS) libosmotrau_la_SOURCES = trau/osmo_ortp.c \ trau/trau_frame.c \ + trau/trau_pcu_ericsson.c \ trau/trau_sync.c \ trau/trau_rtp_conv.c diff --git a/src/trau/trau_pcu_ericsson.c b/src/trau/trau_pcu_ericsson.c new file mode 100644 index 0000000..9292f23 --- /dev/null +++ b/src/trau/trau_pcu_ericsson.c @@ -0,0 +1,2000 @@ +/* + * (C) 2022 by sysmocom - s.f.m.c. GmbH + * Author: Philipp Maier <pmaier@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <stdio.h> +#include <stdint.h> +#include <errno.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/bitvec.h> +#include <osmocom/core/crc16gen.h> +#include <osmocom/core/logging.h> +#include <arpa/inet.h> +#include <osmocom/trau/trau_pcu_ericsson.h> +#include <osmocom/gsm/gsm0502.h> + +#define E1_TRAU_BITS_MSGB 2048 + +/* CRC polynom for CS1 TRAU frame protection: X^16+X^12+X^5+1 */ +const struct osmo_crc16gen_code cs1_crc16 = { 16, 0x1021, 0, 0xffff }; + +/* Frame Type C-bits: C1..C5 */ +#define PCU_TRAU_ER_FT_PCU_SYNC_IND 0x0F +#define PCU_TRAU_ER_FT_CCU_SYNC_IND 0x15 +#define PCU_TRAU_ER_FT_DATA_IND 0x1A +#define PCU_TRAU_ER_FT_DATA9_IND 0x04 + +const ubit_t T_bits_16[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* (+8 variable bits) */ +}; + +const ubit_t T_bits_64[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* (+16 variable bits) */ +}; + +/* Calc an odd parity bit over a given number of bits */ +static ubit_t calc_parity(const ubit_t *bits, size_t len) +{ + size_t i; + ubit_t par = 1; + for (i = 0; i < len; i++) + par ^= bits[i]; + return par; +} + +/* Put data to TRAU frame, skip T bits */ +static int put_trau_data(ubit_t *bits, size_t bits_len, + const ubit_t *bits_map, size_t bits_map_len, const ubit_t *bits_in, size_t offs, size_t len) +{ + size_t bit_count = 0; + size_t i = 0; + + /* The bits map must always cover all bits, so it must not be shorter + * then the bits we are about to parse. Also the offset must not be + * greater then the length of the bits */ + if (bits_len > bits_map_len) + return -EINVAL; + if (bits_len - offs < 0) + return -EINVAL; + + /* Advance to the position where the data is stored */ + bits += offs; + bits_len -= offs; + bits_map += offs; + bits_map_len -= offs; + + do { + /* Do not exceed bits or bits_map */ + if (bit_count > bits_len) + return -EINVAL; + if (bit_count > bits_map_len) + return -EINVAL; + + /* Do not exceed output buffer */ + if (i > bits_len) + return -EINVAL; + + /* skip positions that have already bits set. */ + if (*bits_map == 0) { + *bits = *bits_in; + bits_in++; + i++; + } + + bit_count++; + bits++; + bits_map++; + + } while (i < len); + + return 0; +} + +/* Put an uint32 value to TRAU frame */ +static int put_trau_uint32(ubit_t *bits, size_t bits_len, + const ubit_t *bits_map, size_t bits_map_len, uint32_t value, size_t offs, size_t len) +{ + ubit_t buf[32]; + + OSMO_ASSERT(len < 32); + + memset(buf, 0, sizeof(buf)); + value = htonl(value); + osmo_pbit2ubit_ext(buf, 0, (ubit_t *) &value, 32 - len, len, 0); + return put_trau_data(bits, bits_len, bits_map, bits_map_len, buf, offs, len); +} + +/* Get data from TRAU frame, ignore T bits */ +static int get_trau_data(ubit_t *bits_out, size_t bits_out_len, + const ubit_t *bits, size_t bits_len, + const ubit_t *bits_map, size_t bits_map_len, size_t offs, size_t len) +{ + size_t bit_count = 0; + size_t i = 0; + + /* (see above) */ + if (bits_len > bits_map_len) + return -EINVAL; + if (bits_len - offs < 0) + return -EINVAL; + + /* Advance to the position where the data is located */ + bits += offs; + bits_map += offs; + bits_len -= offs; + bits_map_len -= offs; + + /* Extract bits from TRAU frame */ + do { + /* Do not exceed bits or bits_map */ + if (bit_count > bits_len) + return -EINVAL; + if (bit_count > bits_map_len) + return -EINVAL; + + /* Do not exceed output buffer */ + if (i > bits_out_len) + return -EINVAL; + + if (*bits_map == 0) { + *bits_out = *bits; + bits_out++; + i++; + } + + bit_count++; + bits++; + bits_map++; + + } while (i < len); + + return 0; +} + +/* Get an uint32 value from TRAU frame */ +static uint32_t get_trau_uint32(const ubit_t *bits, size_t bits_len, + const ubit_t *bits_map, size_t bits_map_len, size_t offs, uint8_t len) +{ + ubit_t buf[32]; + uint32_t result = 0; + int rc; + + OSMO_ASSERT(len < 32); + + memset(buf, 0, sizeof(buf)); + rc = get_trau_data(buf, sizeof(buf), bits, bits_len, bits_map, bits_map_len, offs, len); + + if (rc < 0) + return 0; + + osmo_ubit2pbit_ext((pbit_t *) &result, 32 - len, buf, 0, len, 0); + result = ntohl(result); + + return result; +} + +/* Set Time adjustment bits, add 4 more bits in case of delay */ +static int set_timing_ajustment_bits_16(ubit_t *trau_bits, enum time_adj_val tav) +{ + /* Note: This sets the tail bits and returns the final length of the final length of the TRAU frame. The caller + * must then make sure that the frame is transitted with the returned length to achieve correct timing + * alignment. */ + + switch (tav) { + case TIME_ADJ_NONE: + return 320; + case TIME_ADJ_DELAY_250us: + return 320 + 4; + case TIME_ADJ_ADVANCE_250us: + /* Note: the 16 removed bits are not transmitted. */ + return 320 - 4; + } + + return -EINVAL; +} + +/* Set Time adjustment bits, add 16 more bits in case of delay */ +static int set_timing_ajustment_bits_64(ubit_t *trau_bits, enum time_adj_val tav) +{ + /* (see comment above) */ + + switch (tav) { + case TIME_ADJ_NONE: + return 1280; + case TIME_ADJ_DELAY_250us: + return 1280 + 16; + case TIME_ADJ_ADVANCE_250us: + /* Note: the 16 removed bits are not transmitted. */ + return 1280 - 16; + } + + return -EINVAL; +} + +/* Decode an 8-byte access burst data structure */ +static int decode_ab(struct er_gprs_ab *ab, uint8_t *ab_bytes) +{ + memset(ab, 0, sizeof(*ab)); + + /* Type 1/2 specific fields */ + if ((ab_bytes[0] & 0x1f) == 0x1f) { + ab->ab_type = 1; + ab->u.type_1.crc = ab_bytes[0] >> 5 & 0x07; + ab->u.type_1.burst_qual = ab_bytes[2]; + ab->u.type_1.frame_qual = ab_bytes[3]; + } else if ((ab_bytes[0] & 0x1f) == 0) { + ab->ab_type = 2; + ab->u.type_2.abi = ab_bytes[0] >> 5 & 0x07; + ab->u.type_2.type = ab_bytes[3] >> 6 & 0x03; + } else + return -EINVAL; + + /* Common fields */ + ab->rxlev = ab_bytes[1]; + ab->acc_delay = (ab_bytes[4] << 2) & 0x0300; + ab->acc_delay |= ab_bytes[5]; + ab->data = (ab_bytes[6] << 3) & 0x0700; + ab->data |= ab_bytes[7]; + + return 0; +} + +static int enc_pcu_sync_ind_16(ubit_t *trau_bits, struct er_pcu_sync_ind *ind) +{ + /* 16kbps PCU-SYNC-IND TRAU frame format: + * Direction: PCU => CCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 C1 C2 C3 C4 C5 C6 C7 + * C8 PC 0. 0 0 0 0 0 + * 1 0 0 0 0 0 0 0 + * 0 D15 D16 D17 D18 D19 D20 D21 PSEQ (offset 41) + * 1 D22 D23 D24 D25 D26 D27 D28 + * D29 D30 D31 D32 D33 D34 D35 D36 + * 1 D37 D38 D39 D40 D41 D42 D43 SS (offset 65) + * D44 D45 D46 D47 D48 D49 D50 D51 + * 1 1 1 1 1 1 1 1 + * 1 D60 D61 D62 D63 D64 D65 D66 FN UL (offset 89) + * 1 D67 D68 D69 D70 D71 D72 D73 + * D74 D75 D76 D77 D78 D79 D80 D81 + * 1 D82 D83 D84 D85 D86 D87 D88 FN SS (offset 113) + * D89 D90 D91 D92 D93 D94 D95 D96 + * 1 1 1 1 1 1 1 1 + * 1 D105 D106 D107 D108 D109 D110 D111 FN DL (offset 137) + * 1 D112 D113 D114 D115 D116 D117 D118 + * D119 D120 D121 D122 D123 D124 D125 D126 + * 1 D127 D128 D129 D130 D131 D132 D133 LS (offset 161) + * D134 D135 D136 D137 D138 D139 D140 D141 + * 1 1 1 1 1 1 1 1 + * 1 1 1 ... + * ... 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 TA1 TA2 TA3 TA4 (bit 319) + * TA5* TA6* TA7* TA8* + * + * "*" = additional TA bits to delay the frame + * C = Control bits + * D = Data bits + * PC = Parity over C-Bits (odd) */ + + pbit_t c_1_5 = PCU_TRAU_ER_FT_PCU_SYNC_IND; + int rc; + + /* C-Bits */ + osmo_pbit2ubit_ext(trau_bits, 17, &c_1_5, 0, 5, 1); + osmo_pbit2ubit_ext(trau_bits, 22, (pbit_t *) &ind->tav, 0, 2, 1); + if (ind->ul_frame_err == false) + trau_bits[24] = 1; + trau_bits[25] = calc_parity(trau_bits + 17, 8); + + /* D-Bits */ + rc = put_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), ind->pseq, 41, 22); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), ind->ss, 65, 15); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), ind->fn_ul, 89, 22); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), ind->fn_ss, 113, 15); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), ind->fn_dl, 137, 22); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), ind->ls, 161, 15); + if (rc < 0) + return -EINVAL; + + return set_timing_ajustment_bits_16(trau_bits, ind->tav); +} + +int enc_pcu_data_ind_16(ubit_t *trau_bits, struct er_pcu_data_ind *ind) +{ + /* 16kbps PCU-DATA-IND TRAU frame format: + * Direction: PCU => CCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 C1 C2 C3 C4 C5 C6 C7 + * C8 PC E1 E2 E3 E4 E5 E6 + * E7 E8 E9 E10 E11 E12 E13 E14 + * E15 E16 PE D1 D2 D3 D4 D5 + * D6 D7 D8 D9 D10 D11 D12 D13 + * D14 D15 D16 ... + * ... D267 D268 D269 + * D270 D271 D272 D273 TA1 TA2 TA3 TA4 (bit 319) + * TA5* TA6* TA7* TA8* + * + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + + pbit_t c_1_5 = PCU_TRAU_ER_FT_DATA_IND; + + /* C-Bits */ + osmo_pbit2ubit_ext(trau_bits, 17, &c_1_5, 0, 5, 1); + osmo_pbit2ubit_ext(trau_bits, 22, (pbit_t *) &ind->tav, 0, 2, 1); + if (ind->ul_frame_err == false) + trau_bits[24] = 1; + trau_bits[25] = calc_parity(trau_bits + 17, 8); + + /* Set coding scheme (E1-E2) */ + switch (ind->cs_hdr) { + case CS_OR_HDR_CS1: + trau_bits[26] = 0; + trau_bits[27] = 0; + break; + case CS_OR_HDR_CS2: + trau_bits[26] = 0; + trau_bits[27] = 1; + break; + default: + /* NOTE: The 16K TRAU frames do not have enough bandwidth to + * support coding schemes other than CS1 and CS2 */ + /* NOTE: Access bursts (AB) are uplink-only. */ + return -EINVAL; + } + + /* Set demodulation in uplink (E3-E4) */ + switch (ind->ul_chan_mode) { + case ER_UL_CHMOD_NB_GMSK: + trau_bits[28] = 0; + trau_bits[29] = 0; + break; + case ER_UL_CHMOD_AB: + trau_bits[28] = 0; + trau_bits[29] = 1; + break; + case ER_UL_CHMOD_AB_UNKN: + trau_bits[28] = 1; + trau_bits[29] = 0; + break; + case ER_UL_CHMOD_VOID: + trau_bits[28] = 1; + trau_bits[29] = 1; + break; + default: + return -EINVAL; + } + + /* Timing offset (E5-E12, 8 bit value, MSB first) */ + osmo_pbit2ubit_ext(trau_bits, 30, (pbit_t *) &ind->timing_offset, 0, 8, 0); + + /* Power control (E13-E16, 4 bit value, MSB first, 2dB steps) */ + osmo_pbit2ubit_ext(trau_bits, 38, (pbit_t *) &ind->atten_db, 4, 4, 0); + + /* Parity (odd) over coding scheme, demodulation, timing offset and + * power control bits (E1-E16) */ + trau_bits[42] = calc_parity(trau_bits + 26, 16); + + /* Data bits */ + switch (ind->cs_hdr) { + case CS_OR_HDR_CS1: + osmo_pbit2ubit_ext(trau_bits, 43, (pbit_t *) ind->data, 0, 184, 1); + osmo_crc16gen_set_bits(&cs1_crc16, trau_bits + 43, 184, trau_bits + 43 + 184); + break; + case CS_OR_HDR_CS2: + osmo_pbit2ubit_ext(trau_bits, 43, (pbit_t *) ind->data, 0, 271, 1); + break; + default: + /* NOTE: The 16K TRAU frames do not have enough bandwidth to + * support coding schemes other than CS1 and CS2 */ + return -EINVAL; + } + + return set_timing_ajustment_bits_16(trau_bits, ind->tav); +} + +/*! encode an 16k Ericsson GPRS (GSL) TRAU frame. + * \param[out] bits caller-allocated memory for unpacked output bits (320+4). + * \param[in] fr input data structure describing TRAU frame. + * \return number of bits encoded. */ +int er_gprs_trau_frame_encode_16k(ubit_t *bits, struct er_gprs_trau_frame *fr) +{ + /* Prepare frame: first 16 bits set 0, remaining bits set to 1 */ + memset(bits, 0, 16); + memset(bits + 16, 1, 320 + 4 - 16); + + switch (fr->type) { + case ER_GPRS_TRAU_FT_SYNC: + return enc_pcu_sync_ind_16(bits, &fr->u.pcu_sync_ind); + case ER_GPRS_TRAU_FT_DATA: + return enc_pcu_data_ind_16(bits, &fr->u.pcu_data_ind); + default: + return -EINVAL; + } + + return -EINVAL; +} + +static int dec_ccu_sync_ind_16(struct er_ccu_sync_ind *ind, const ubit_t *trau_bits) +{ + /* 16kbps CCU-SYNC-IND TRAU frame format: + * Direction: CCU => PCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 C1 C2 C3 C4 C5 C6 C7 + * C8 PC E1 PE 1 1 1 1 + * 1 0 0 0 0 0 0 0 + * 0 D13 D14 D15 D16 D17 D18 D19 PSEQ (offset 41) + * 1 D20 D21 D22 D23 D24 D25 D26 + * D27 D28 D29 D30 D31 D32 D33 D34 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 D58 D59 D60 D61 D62 D63 D64 AFN UL (offset 89) + * 1 D65 D66 D67 D68 D69 D70 D71 + * D72 D73 D74 D75 D76 D77 D78 D79 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 D103 D104 D105 D106 D107 D108 D109 AFN DL (offset 137) + * 1 D110 D111 D112 D113 D114 D115 D116 + * D117 D118 D119 D120 D121 D122 D123 D124 + * 1 1 1 1 1 1 1 1 + * 1 1 1 ... + * ... 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 TA1 TA2 (bit 319) + * TA3* TA4* + * + * "*" = additional TA bits to delay the frame + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + + size_t i; + + /* Validate sync pattern (extended) */ + for (i = 0; i < 19; i++) { + if (trau_bits[16 + i * 16] != 1) { + LOGP(DLINP, LOGL_ERROR, "CCU-SYNC-IND-16: invalid sync pattern (T1 at position %zu != 1)\n", i); + return -EINVAL; + } + } + + /* Validate C-Bits */ + if (calc_parity(trau_bits + 17, 8) != trau_bits[25]) { + LOGP(DLINP, LOGL_ERROR, "CCU-SYNC-IND-16: invalid parity (C1-C8)\n"); + return -EINVAL; + } + + /* TAV (C7-C9) */ + osmo_ubit2pbit_ext((pbit_t *) &ind->tav, 0, trau_bits, 22, 2, 1); + + /* Downlink frame error, DFE (C8) */ + if (trau_bits[24] == 0) + ind->dfe = true; + + /* Check (odd) parity of E1 bit */ + if (trau_bits[26] != ((~trau_bits[27]) & 1)) { + LOGP(DLINP, LOGL_ERROR, "CCU-SYNC-IND-16: invalid parity (E1)\n"); + return -EINVAL; + } + + /* Downlink Block error, DBE (E1) */ + if (trau_bits[26] == 0) + ind->dbe = true; + + /* D bits */ + ind->pseq = get_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), 41, 22); + ind->afn_ul = get_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), 89, 22); + ind->afn_dl = get_trau_uint32(trau_bits, 320, T_bits_16, sizeof(T_bits_16), 137, 22); + + return 0; +} + +static int dec_ccu_data_ind_16(struct er_ccu_data_ind *ind, const ubit_t *trau_bits) +{ + /* 16kbps CCU-DATA-IND TRAU frame format: + * Direction: CCU => PCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 C1 C2 C3 C4 C5 C6 C7 + * PC E1 E2 E3 E4 E5 E6 E7 + * E8 E9 E10 E11 E12 E13 E14 E15 + * E16 E17 E18 E19 PE D1 D2 D3 + * D4 D5 D6 D7 D8 D9 D10 D11 + * D12 D13 D14 ... + * ... D267 D268 D269 + * D270 D271 D272 D273 TA1 TA2 TA3 TA4 (bit 319) + * TA5* TA6* TA7* TA8* + * + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + + uint8_t sfq = 0; + uint8_t eadd = 0; + uint8_t e_2_4 = 0; + int rc; + int i; + + /* Validate C-Bits */ + if (calc_parity(trau_bits + 17, 7) != trau_bits[24]) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-16: invalid parity (C1-C7)\n"); + return -EINVAL; + } + + /* TAV (C6-C7) */ + osmo_ubit2pbit_ext((pbit_t *) &ind->tav, 0, trau_bits, 22, 2, 1); + + /* Validate E-Bits */ + if (calc_parity(trau_bits + 25, 19) != trau_bits[44]) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-16: invalid parity (E1-E19)\n"); + return -EINVAL; + } + + /* Downlink block error (E1) */ + if (trau_bits[25] == 0) + ind->dbe = true; + + /* Coding scheme (E2-E4) */ + osmo_ubit2pbit_ext((pbit_t *) &e_2_4, 5, trau_bits, 26, 3, 0); + switch (e_2_4) { + case 0: + ind->cs_hdr = CS_OR_HDR_CS1; + break; + case 1: + ind->cs_hdr = CS_OR_HDR_CS2; + break; + case 4: + ind->cs_hdr = CS_OR_HDR_AB; + break; + default: + /* 16kbps timeslots only support CS1, CS2 and AB are supported, + * due to bandwidth limitations. */ + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-16: invalid codec status (E2-E4)\n"); + return -EINVAL; + } + + /* Soft frame quality SFQ (E5-E7, 0 in case of AB) */ + osmo_ubit2pbit_ext((pbit_t *) &sfq, 5, trau_bits, 29, 3, 0); + ind->u.gprs.block_qual = sfq; + + /* Parity Check (E8, 1 in case of AB) */ + ind->u.gprs.parity_ok = trau_bits[32]; + + /* RX-LEV (E9-E14, 63 in case of AB) */ + osmo_ubit2pbit_ext((pbit_t *) &ind->rx_lev, 2, trau_bits, 33, 6, 0); + + /* Estimated access delay (E15-E17, 0 in case of AB) */ + osmo_ubit2pbit_ext((pbit_t *) &eadd, 5, trau_bits, 39, 3, 0); + switch (eadd) { + case 0: + /* <2 or less */ + ind->est_acc_del_dev = -3; + break; + case 1: + ind->est_acc_del_dev = -1; + break; + case 2: + ind->est_acc_del_dev = 1; + break; + case 4: + ind->est_acc_del_dev = 2; + break; + case 5: + /* >2 or more */ + ind->est_acc_del_dev = 3; + break; + case 6: + ind->est_acc_del_dev = 0; + break; + case 7: + ind->est_acc_del_dev = -2; + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-16: invalid estimated access delay (E15-E17)\n"); + return -EINVAL; + } + + /* Data bits */ + switch (ind->cs_hdr) { + case CS_OR_HDR_CS1: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 45, 184, 1); + rc = osmo_crc16gen_check_bits(&cs1_crc16, trau_bits + 45, 184, trau_bits + 45 + 184); + if (rc != 0) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-16: CRC error in CS1 block\n"); + return -EINVAL; + } + ind->data_len = 23; + break; + case CS_OR_HDR_CS2: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 45, 271, 1); + ind->data_len = 34; + break; + case CS_OR_HDR_AB: + /* Note: The useful data starts at D4 and is byte-aligned inside the TRAU frame. + * The data string contains 4 items, each 8 bytes long, 32 bytes total. */ + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 48, 256, 1); + ind->data_len = 32; + + for (i = 0; i < 4; i++) { + rc = decode_ab(&ind->ab[i], ind->data + i * 8); + if (rc < 0) + return -EINVAL; + } + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-16: invalid cs_hdr set\n"); + return -EINVAL; + } + + return 0; +}; + +/*! decode an 16k Ericsson GPRS (GSL) TRAU frame. + * \param[out] fr caller-allocated output data structure. + * \param[in] bits unpacked input bits (320). + * \return 0 on success; negative in case of error. */ +int er_gprs_trau_frame_decode_16k(struct er_gprs_trau_frame *fr, const ubit_t *bits) +{ + uint8_t c_1_5 = 0; + const ubit_t expected_sync_pattern[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + int rc; + + memset(fr, 0, sizeof(*fr)); + + /* Validate sync pattern */ + if (memcmp(bits, expected_sync_pattern, ARRAY_SIZE(expected_sync_pattern)) != 0) { + LOGP(DLINP, LOGL_ERROR, "CCU-XXXX-IND-16: invalid sync pattern (T0)\n"); + return -EINVAL; + } + + /* Determine frame type */ + osmo_ubit2pbit_ext((pbit_t *) &c_1_5, 0, bits, 17, 5, 1); + + switch (c_1_5) { + case PCU_TRAU_ER_FT_CCU_SYNC_IND: + fr->type = ER_GPRS_TRAU_FT_SYNC; + rc = dec_ccu_sync_ind_16(&fr->u.ccu_sync_ind, bits); + break; + case PCU_TRAU_ER_FT_DATA_IND: + fr->type = ER_GPRS_TRAU_FT_DATA; + rc = dec_ccu_data_ind_16(&fr->u.ccu_data_ind, bits); + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-XXXX-IND-16: invalid frame type (%02x)\n", c_1_5); + rc = -EINVAL; + } + + /* Ensure that we exit with predictable data in case of error. */ + if (rc < 0) + memset(fr, 0, sizeof(*fr)); + + return rc; +} + +/* Extract the CPS field from a given block, block must have minimum length of 5 bytes. + * See also: 3GPP TS 44.060, section 10.3a.3 and section 10.3a.4 */ +static int cps_from_mcs_block(uint8_t *block, enum er_cs_or_hdr cs_hdr, bool uplink) +{ + uint8_t cps; + + if (uplink) { + switch (cs_hdr) { + case CS_OR_HDR_HDR1: + cps = block[4] & 0x1f; + break; + case CS_OR_HDR_HDR2: + cps = (block[2] >> 6) & 0x3; + cps |= block[3] << 2 & 0x4; + break; + case CS_OR_HDR_HDR3: + cps = (block[2] >> 6) & 0x3; + cps |= block[3] << 2 & 0xC; + break; + default: + return -EINVAL; + } + } else { + switch (cs_hdr) { + case CS_OR_HDR_HDR1: + cps = (block[4] >> 3) & 0x1f; + break; + case CS_OR_HDR_HDR2: + cps = (block[3] >> 1) & 0x07; + break; + case CS_OR_HDR_HDR3: + cps = (block[3] >> 1) & 0x0f; + break; + default: + return -EINVAL; + } + } + + return cps; +} + +/* Determine the MCS block type from a given CPS value. + * See also: 3GPP TS 44.060, section 10.4.8a */ +static int mcs_from_cps(uint8_t cps, enum er_cs_or_hdr cs_hdr) +{ + switch (cs_hdr) { + case CS_OR_HDR_HDR1: + if (cps <= 0x0A) + return 9; + if (cps <= 0x13) + return 8; + if (cps <= 0x1C) + return 7; + return -EINVAL; + break; + case CS_OR_HDR_HDR2: + if (cps <= 0x03 || cps == 0x06 || cps == 0x07) + return 6; + if (cps == 4 || cps == 5) + return 5; + return -EINVAL; + break; + case CS_OR_HDR_HDR3: + if (cps <= 0x02) + return 4; + if (cps <= 0x08) + return 3; + if (cps == 0x09 || cps == 0x0A || cps == 0x0D || cps == 0x0E) + return 2; + if (cps == 0x0B || cps == 0x0C) + return 1; + return -EINVAL; + break; + default: + return -EINVAL; + } +} + +static int enc_pcu_sync_ind_64(ubit_t *trau_bits, struct er_pcu_sync_ind *ind) +{ + /* 64kbps PCU-SYNC-IND TRAU frame format: + * Direction: PCU => CCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 C1 C2 C3 C4 C5 C6 C7 + * C8 PC 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 D96 D97 D98 D99 D100 D101 + * D102 D103 D104 D105 D106 D107 D108 D109 + * D110 D111 D112 D113 D114 D115 D116 D117 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * D133 D134 D135 D136 D137 D138 D139 D140 + * D141 D142 D143 D144 D145 D146 D147 D148 + * 1 1 1 1 1 1 1 1 + * 1 1 D159 D160 D161 D162 D163 D164 + * D165 D166 D167 D168 D169 D170 D171 D172 + * D173 D174 D175 D176 D177 D178 D179 D180 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * D196 D197 D198 D199 D200 D201 D202 D203 + * D204 D205 D206 D207 D208 D209 D210 D211 + * 1 1 1 1 1 1 1 1 + * 1 1 D222 D223 D224 D225 D226 D227 + * D228 D229 D230 D231 D232 D233 D234 D235 + * D236 D237 D238 D239 D340 D241 D242 D243 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * D259 D260 D261 D262 D263 D264 D265 D266 + * D267 D268 D269 D270 D271 D272 D273 D274 + * 1 1 1 1 1 1 1 1 + * 1 1 1 ... + * ... 1 1 1 + * 1 1 1 1 1 1 1 1 + * TA1 TA2 TA3 TA4 TA5 TA6 TA7 TA8 + * TA9 TA10 TA11 TA12 TA13 TA14 TA15 TA16 (bit 1279) + * TA17* TA18* TA19* TA20* TA21* TA22* TA23* TA24* + * TA25* TA26* TA27* TA28* TA29* TA30* TA31* TA32* + * + * "*" = additional TA bits to delay the frame + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + + pbit_t c_1_5 = PCU_TRAU_ER_FT_PCU_SYNC_IND; + int rc; + + /* C-Bits */ + osmo_pbit2ubit_ext(trau_bits, 65, &c_1_5, 0, 5, 1); + osmo_pbit2ubit_ext(trau_bits, 70, (pbit_t *) &ind->tav, 0, 2, 1); + if (ind->ul_frame_err == false) + trau_bits[73] = 1; + trau_bits[74] = calc_parity(trau_bits + 65, 8); + + /* Set unused D-Bits to 1 */ + memset(trau_bits + 76, 1, 1280 - 76 - 16); + + /* D-Bits */ + rc = put_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), ind->pseq, 170, 22); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), ind->ss, 208, 16); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), ind->fn_ul, 234, 22); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), ind->fn_ss, 272, 15); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), ind->fn_dl, 298, 22); + if (rc < 0) + return -EINVAL; + rc = put_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), ind->ls, 336, 16); + if (rc < 0) + return -EINVAL; + + return set_timing_ajustment_bits_64(trau_bits, ind->tav); +} + +int enc_pcu_data_ind_64(ubit_t *trau_bits, struct er_pcu_data_ind *ind, uint8_t mcs) +{ + /* 64kbps PCU-DATA-IND TRAU frame format: + * Direction: PCU => CCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 C1 C2 C3 C4 C5 C6 C7 + * C8 PC E1 E2 E3 E4 E5 E6 + * E7 E8 E9 E10 E11 E12 E13 E14 + * E15 E16 E17 E18 E19 E20 E21 E22 + * E23 E24 E25 E26 E27 E28 E29 E30 + * E31 E32 E33 E34 E35 E36 PE S1 + * S2 S3 S4 S5 S6 S7 S8 S9 + * S10 S11 S12 S13 S14 S15 S16 S17 + * S18 S19 S20 S21 D1 D2 D3 D4 + * D5 D6 D7 D8 D9 D10 D11 D12 + * D13 D14 D15 D16 D17 D18 D19 D20 + * D21 D22 D23 ... + * ... D1130 D1131 D1132 + * TA1 TA2 TA3 TA4 TA5 TA6 TA7 TA8 + * TA9 TA10 TA11 TA12 TA13 TA14 TA15 TA16 (bit 1279) + * TA17* TA18* TA19* TA20* TA21* TA22* TA23* TA24* + * TA25* TA26* TA27* TA28* TA29* TA30* TA31* TA32* + * + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + + pbit_t c_1_5 = PCU_TRAU_ER_FT_DATA_IND; + + /* C-Bits */ + osmo_pbit2ubit_ext(trau_bits, 65, &c_1_5, 0, 5, 1); + osmo_pbit2ubit_ext(trau_bits, 70, (pbit_t *) &ind->tav, 0, 2, 1); + if (ind->ul_frame_err == false) + trau_bits[73] = 1; + trau_bits[74] = calc_parity(trau_bits + 65, 8); + + /* Set coding scheme (E1-E3) */ + switch (ind->cs_hdr) { + case CS_OR_HDR_CS1: + trau_bits[74] = 0; + trau_bits[75] = 0; + trau_bits[76] = 1; + break; + case CS_OR_HDR_CS2: + trau_bits[74] = 0; + trau_bits[75] = 1; + trau_bits[76] = 0; + break; + case CS_OR_HDR_CS3: + trau_bits[74] = 0; + trau_bits[75] = 1; + trau_bits[76] = 1; + break; + case CS_OR_HDR_CS4: + trau_bits[74] = 1; + trau_bits[75] = 0; + trau_bits[76] = 0; + break; + case CS_OR_HDR_HDR1: + trau_bits[74] = 1; + trau_bits[75] = 0; + trau_bits[76] = 1; + break; + case CS_OR_HDR_HDR2: + trau_bits[74] = 1; + trau_bits[75] = 1; + trau_bits[76] = 0; + break; + case CS_OR_HDR_HDR3: + trau_bits[74] = 1; + trau_bits[75] = 1; + trau_bits[76] = 1; + break; + default: + /* NOTE: Access bursts (AB) are uplink-only. */ + return -EINVAL; + } + + /* Set demodulation in uplink (E4-E6) */ + switch (ind->ul_chan_mode) { + case ER_UL_CHMOD_VOID: + trau_bits[77] = 0; + trau_bits[78] = 0; + trau_bits[79] = 0; + break; + case ER_UL_CHMOD_NB_GMSK: + trau_bits[77] = 0; + trau_bits[78] = 0; + trau_bits[79] = 1; + break; + case ER_UL_CHMOD_NB_UNKN: + trau_bits[77] = 0; + trau_bits[78] = 1; + trau_bits[79] = 0; + break; + case ER_UL_CHMOD_AB: + trau_bits[77] = 0; + trau_bits[78] = 1; + trau_bits[79] = 1; + break; + case ER_UL_CHMOD_AB_UNKN: + trau_bits[77] = 1; + trau_bits[78] = 0; + trau_bits[79] = 0; + break; + default: + return -EINVAL; + } + + /* Timing offset (E7-E14, 8 bit value, MSB first) */ + osmo_pbit2ubit_ext(trau_bits, 80, (pbit_t *) &ind->timing_offset, 0, 8, 0); + + /* Power control (E33-E36, 4 bit value, MSB first, 2dB steps) */ + osmo_pbit2ubit_ext(trau_bits, 106, (pbit_t *) &ind->atten_db, 4, 4, 0); + + /* Parity (odd) over coding scheme, demodulation, timing offset and + * power control bits (E1-E36) */ + trau_bits[110] = calc_parity(trau_bits + 74, 36); + + /* Data bits */ + switch (ind->cs_hdr) { + case CS_OR_HDR_CS1: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 184, 1); + osmo_crc16gen_set_bits(&cs1_crc16, trau_bits + 132, 184, trau_bits + 132 + 184); + break; + case CS_OR_HDR_CS2: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 271, 1); + break; + case CS_OR_HDR_CS3: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 315, 1); + break; + case CS_OR_HDR_CS4: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 431, 1); + break; + case CS_OR_HDR_HDR1: + case CS_OR_HDR_HDR2: + case CS_OR_HDR_HDR3: + switch (mcs) { + case 1: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 209, 1); + break; + case 2: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 257, 1); + break; + case 3: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 329, 1); + break; + case 4: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 385, 1); + break; + case 5: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 478, 1); + break; + case 6: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 622, 1); + break; + case 7: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 940, 1); + break; + case 8: + osmo_pbit2ubit_ext(trau_bits, 132, (pbit_t *) ind->data, 0, 1132, 1); + break; + } + break; + default: + /* NOTE: The 16K TRAU frames do not have enough bandwidth to + * support coding schemes other than CS1 and CS2 */ + return -EINVAL; + } + + return set_timing_ajustment_bits_64(trau_bits, ind->tav); +} + +int enc_pcu_data_ind_64_mcs9(ubit_t *trau_bits, struct er_pcu_data_ind *ind) +{ + /* 64kbps PCU-DATA-IND (MCS9) TRAU frame format: + * Direction: PCU => CCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 D1 D2 D3 D4 D5 D6 D7 + * D8 D9 D10 D11 D12 D13 D14 D15 + * D16 D17 D18 D19 D20 D21 D22 D23 + * D24 D25 D26 D27 D28 D29 D30 D31 + * D32 D33 D34 D35 D36 D37 D38 D39 + * D40 D41 D42 D43 D44 D45 D46 D47 + * D48 C1 C2 C3 C4 C5 C6 C7 + * C8 PC E1 E2 E3 E4 E5 E6 + * E7 E8 E9 PE D49 D50 D51 D52 + * D53 D54 D55 D56 D57 D58 D59 D60 + * D61 D62 D63 D64 D65 D66 D67 D68 + * D69 D70 D71 ... + * ... D1226 D1227 D1228 + * TA1 TA2 TA3 TA4 TA5 TA6 TA7 TA8 + * TA9 TA10 TA11 TA12 TA13 TA14 TA15 TA16 (bit 1279) + * TA17* TA18* TA19* TA20* TA21* TA22* TA23* TA24* + * TA25* TA26* TA27* TA28* TA29* TA30* TA31* TA32* + * + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + + pbit_t c_1_5 = PCU_TRAU_ER_FT_DATA9_IND; + + /* NOTE: The ericsson MCS9 64K TRAU format uses a different sync + * pattern than the other 64K TRAU frame formats. To make room for + * the additional bits in MCS9 only the first 16 bits are T0 bits. */ + trau_bits[16] = 1; + + /* Fill headroom that normally would have T0 and T1 bits with data + * bits */ + osmo_pbit2ubit_ext(trau_bits, 17, (pbit_t *) ind->data, 0, 48, 1); + + /* C-Bits */ + osmo_pbit2ubit_ext(trau_bits, 65, &c_1_5, 0, 5, 1); + osmo_pbit2ubit_ext(trau_bits, 70, (pbit_t *) &ind->tav, 0, 2, 1); + if (ind->ul_frame_err == false) + trau_bits[73] = 1; + trau_bits[74] = calc_parity(trau_bits + 65, 8); + + /* Set demodulation in uplink (E1-E3) */ + switch (ind->ul_chan_mode) { + case ER_UL_CHMOD_VOID: + trau_bits[74] = 0; + trau_bits[75] = 0; + trau_bits[76] = 0; + break; + case ER_UL_CHMOD_NB_GMSK: + trau_bits[74] = 0; + trau_bits[75] = 0; + trau_bits[76] = 1; + break; + case ER_UL_CHMOD_NB_UNKN: + trau_bits[74] = 0; + trau_bits[75] = 1; + trau_bits[76] = 0; + break; + case ER_UL_CHMOD_AB: + trau_bits[74] = 0; + trau_bits[75] = 1; + trau_bits[76] = 1; + break; + case ER_UL_CHMOD_AB_UNKN: + trau_bits[74] = 1; + trau_bits[75] = 0; + trau_bits[76] = 0; + break; + default: + return -EINVAL; + } + + /* E4-E5 are spare bits? */ + + /* Power control (E6-E9, 4 bit value, MSB first, 2dB steps) */ + osmo_pbit2ubit_ext(trau_bits, 79, (pbit_t *) &ind->atten_db, 4, 4, 0); + + /* Parity (odd) over coding scheme, demodulation, timing offset and + * power control bits (E1-E9) */ + trau_bits[83] = calc_parity(trau_bits + 74, 9); + + /* Fill the rest of the block with data bits */ + osmo_pbit2ubit_ext(trau_bits, 84, (pbit_t *) ind->data + 6, 0, 1180, 1); + + return set_timing_ajustment_bits_64(trau_bits, ind->tav); +} + +/*! encode an 64k Ericsson GPRS (GSL) TRAU frame. + * \param[out] bits caller-allocated memory for unpacked output bits (1280+16). + * \param[in] fr input data structure describing TRAU frame. + * \return number of bits encoded. */ +int er_gprs_trau_frame_encode_64k(ubit_t *bits, struct er_gprs_trau_frame *fr) +{ + int cps; + int mcs = 0; + enum er_cs_or_hdr cs; + + /* Prepare frame: first 16 bits set 0, remaining bits set to 1 */ + memset(bits, 0, 64); + memset(bits + 64, 1, 1280 + 16 - 64); + + switch (fr->type) { + case ER_GPRS_TRAU_FT_SYNC: + return enc_pcu_sync_ind_64(bits, &fr->u.pcu_sync_ind); + case ER_GPRS_TRAU_FT_DATA: + cs = fr->u.pcu_data_ind.cs_hdr; + if (cs == CS_OR_HDR_HDR1 || cs == CS_OR_HDR_HDR2 || cs == CS_OR_HDR_HDR3) { + cps = cps_from_mcs_block(fr->u.pcu_data_ind.data, cs, false); + if (cps < 0) + return -EINVAL; + mcs = mcs_from_cps((uint8_t) cps, cs); + if (mcs < 0) + return -EINVAL; + } + + if (mcs < 9) + return enc_pcu_data_ind_64(bits, &fr->u.pcu_data_ind, mcs); + else + return enc_pcu_data_ind_64_mcs9(bits, &fr->u.pcu_data_ind); + default: + return -EINVAL; + } + + return -EINVAL; +} + +static int dec_ccu_sync_ind_64(struct er_ccu_sync_ind *ind, const ubit_t *trau_bits) +{ + /* 64kbps CCU-SYNC-IND TRAU frame format: + * Direction: CCU => PCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 C1 C2 C3 C4 C5 C6 C7 + * C8 PC E1 PE 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 D94 D95 D96 D97 D98 D99 + * D100 D101 D102 D103 D104 D105 D106 D107 + * D108 D109 D110 D111 D112 D113 D114 D115 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 D157 D158 D159 D160 D161 D162 + * D163 D164 D165 D166 D167 D168 D169 D170 + * D171 D172 D173 D174 D175 D176 D177 D178 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 1 1 1 1 1 1 + * 1 1 D220 D221 D222 D223 D224 D225 + * D226 D227 D228 D229 D230 D231 D232 D233 + * D234 D235 D236 D237 D238 D239 D240 D241 + * 1 1 1 1 1 1 1 1 + * 1 1 1 ... + * ... 1 1 1 + * 1 1 1 1 1 1 1 1 + * TA1 TA2 TA3 TA4 TA5 TA6 TA7 TA8 + * TA9 TA10 TA11 TA12 TA13 TA14 TA15 TA16 (bit 1279) + * TA17* TA18* TA19* TA20* TA21* TA22* TA23* TA24* + * TA25* TA26* TA27* TA28* TA29* TA30* TA31* TA32* + * + * "*" = additional TA bits to delay the frame + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + + size_t i; + + /* Validate sync pattern (extended) */ + for (i = 0; i < 19; i++) { + if (trau_bits[64 + i * 64] != 1) { + LOGP(DLINP, LOGL_ERROR, "CCU-SYNC-IND-64: invalid sync pattern (T1 at position %zu != 1)\n", i); + return -EINVAL; + } + } + + /* Validate C-Bits */ + if (calc_parity(trau_bits + 65, 8) != trau_bits[73]) { + LOGP(DLINP, LOGL_ERROR, "CCU-SYNC-IND-64: invalid parity (C1-C8)\n"); + return -EINVAL; + } + + /* TAV (C6-C7) */ + osmo_ubit2pbit_ext((pbit_t *) &ind->tav, 0, trau_bits, 70, 2, 1); + + /* Downlink frame error, DFE (C8) */ + if (trau_bits[72] == 0) + ind->dfe = true; + + /* Check (odd) parity of E1 bit */ + if (trau_bits[74] != ((~trau_bits[75]) & 1)) { + LOGP(DLINP, LOGL_ERROR, "CCU-SYNC-IND-64: invalid parity (E1)\n"); + return -EINVAL; + } + + /* Downlink Block error, DBE (E1) */ + if (trau_bits[74] == 0) + ind->dbe = true; + + /* D bits */ + ind->pseq = get_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), 170, 22); + ind->afn_ul = get_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), 234, 22); + ind->afn_dl = get_trau_uint32(trau_bits, 1280, T_bits_64, sizeof(T_bits_64), 298, 22); + + return 0; +} + +static int dec_ccu_data_ind_64(struct er_ccu_data_ind *ind, const ubit_t *trau_bits) +{ + /* 64kbps CCU-DATA-IND TRAU frame format: + * Direction: CCU => PCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 C1 C2 C3 C4 C5 C6 C7 + * PC E1 E2 E3 E4 E5 E6 E7 + * E8 E9 E10 E11 E12 E13 E14 E15 + * E16 E17 E18 E19 E20 E21 E22 E23 + * E24 E25 E26 E27 E28 E29 E30 E31 + * E32 E33 E34 E35 E36 E37 E38 E39 + * E40 E41 E42 E43 E44 E45 E46 E47 + * E48 E49 E50 E51 E52 E53 E54 E55 + * E56 E57 PE S1 S2 S3 D1 D2 + * D3 D4 D5 D6 D7 D8 D9 D10 + * D11 D12 D13 D14 D15 D16 D17 D18 + * D19 D20 D21 ... + * ... D1136 D1137 D1138 + * TA1 TA2 TA3 TA4 TA5 TA6 TA7 TA8 + * TA9 TA10 TA11 TA12 TA13 TA14 TA15 TA16 (bit 1279) + * TA17* TA18* TA19* TA20* TA21* TA22* TA23* TA24* + * TA25* TA26* TA27* TA28* TA29* TA30* TA31* TA32* + * + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + uint8_t sfq = 0; + uint8_t eadd = 0; + uint8_t e_2_4 = 0; + uint8_t mean_bep = 0; + uint8_t cv_bep = 0; + int cps; + int mcs = 0; + int rc; + int i; + + /* Validate C-Bits */ + if (calc_parity(trau_bits + 65, 7) != trau_bits[72]) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid parity (C1-C7)\n"); + return -EINVAL; + } + + /* TAV (C6-C7) */ + osmo_ubit2pbit_ext((pbit_t *) &ind->tav, 0, trau_bits, 70, 2, 1); + + /* Validate E-Bits */ + if (calc_parity(trau_bits + 73, 57) != trau_bits[130]) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid parity (E1-E57)\n"); + return -EINVAL; + } + + /* Downlink block error (E1) */ + if (trau_bits[73] == 0) + ind->dbe = true; + + /* Coding scheme (E2-E4) */ + osmo_ubit2pbit_ext((pbit_t *) &e_2_4, 5, trau_bits, 74, 3, 0); + switch (e_2_4) { + case 0: + ind->cs_hdr = CS_OR_HDR_AB; + break; + case 1: + ind->cs_hdr = CS_OR_HDR_CS1; + break; + case 2: + ind->cs_hdr = CS_OR_HDR_CS2; + break; + case 3: + ind->cs_hdr = CS_OR_HDR_CS3; + break; + case 4: + ind->cs_hdr = CS_OR_HDR_CS4; + break; + case 5: + ind->cs_hdr = CS_OR_HDR_HDR1; + break; + case 6: + ind->cs_hdr = CS_OR_HDR_HDR2; + break; + case 7: + ind->cs_hdr = CS_OR_HDR_HDR3; + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid codec status (E2-E4)\n"); + return -EINVAL; + } + + /* RX-LEV (E5-E10, 63 in case of AB) */ + osmo_ubit2pbit_ext((pbit_t *) &ind->rx_lev, 2, trau_bits, 77, 6, 0); + + /* Estimated access delay (E11-E13, 0 in case of AB) */ + osmo_ubit2pbit_ext((pbit_t *) &eadd, 5, trau_bits, 83, 3, 0); + switch (eadd) { + case 0: + /* <2 or less */ + ind->est_acc_del_dev = -3; + break; + case 1: + ind->est_acc_del_dev = -1; + break; + case 2: + ind->est_acc_del_dev = 1; + break; + case 4: + ind->est_acc_del_dev = 2; + break; + case 5: + /* >2 or more */ + ind->est_acc_del_dev = 3; + break; + case 6: + ind->est_acc_del_dev = 0; + break; + case 7: + ind->est_acc_del_dev = -2; + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid estimated access delay (E11-E13)\n"); + return -EINVAL; + } + + if (ind->cs_hdr == CS_OR_HDR_CS1 || ind->cs_hdr == CS_OR_HDR_CS2 || ind->cs_hdr == CS_OR_HDR_CS3 + || ind->cs_hdr == CS_OR_HDR_CS4) { + /* Soft frame quality SFQ (E14-E16, 0 in case of AB) */ + osmo_ubit2pbit_ext((pbit_t *) &sfq, 5, trau_bits, 86, 3, 0); + ind->u.gprs.block_qual = sfq; + + /* Parity Check (E17, 1 in case of AB) */ + ind->u.gprs.parity_ok = trau_bits[89]; + + } else { + /* Mean BEP (E14-E20) */ + osmo_ubit2pbit_ext((pbit_t *) &mean_bep, 1, trau_bits, 86, 7, 0); + ind->u.egprs.mean_bep = mean_bep; + + /* CV BEP (E21-E23) */ + osmo_ubit2pbit_ext((pbit_t *) &cv_bep, 5, trau_bits, 93, 3, 0); + ind->u.egprs.mean_bep = cv_bep; + + /* RLC/MAC header quality (E24) */ + if (trau_bits[96] == 0) { + ind->u.egprs.hdr_good = true; + + /* Data block quality (E25/E26) */ + if (trau_bits[97] == 0) + ind->u.egprs.data_good[0] = true; + if (trau_bits[98] == 0) + ind->u.egprs.data_good[1] = true; + } else { + /* A bad RLC/MAC header always means that the the data blocks + * cannot be valid. */ + ind->u.egprs.data_good[0] = false; + ind->u.egprs.data_good[1] = false; + } + + } + + /* Data bits */ + switch (ind->cs_hdr) { + case CS_OR_HDR_CS1: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 184, 1); + rc = osmo_crc16gen_check_bits(&cs1_crc16, trau_bits + 134, 184, trau_bits + 134 + 184); + if (rc != 0) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: CRC error in CS1 block\n"); + return -EINVAL; + } + ind->data_len = 23; + break; + case CS_OR_HDR_CS2: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 271, 1); + ind->data_len = 34; + break; + case CS_OR_HDR_CS3: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 315, 1); + ind->data_len = 40; + break; + case CS_OR_HDR_CS4: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 431, 1); + ind->data_len = 54; + break; + case CS_OR_HDR_HDR1: + case CS_OR_HDR_HDR2: + case CS_OR_HDR_HDR3: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 40, 1); + cps = cps_from_mcs_block(ind->data, ind->cs_hdr, true); + if (cps < 0) { + LOGP(DLINP, LOGL_NOTICE, + "CCU-DATA-IND-64: unable to read CPS from data block, bad data block received?\n"); + break; + } + mcs = mcs_from_cps((uint8_t) cps, ind->cs_hdr); + if (mcs < 0) { + LOGP(DLINP, LOGL_NOTICE, + "CCU-DATA-IND-64: unable to determine coding scheme (MCS) from CPS, bad data block received?\n"); + break; + } + + /* Note: receiving noise (and eventually bad CPS field, may + * happen from time to time and is not an error condition. */ + + switch (mcs) { + case 1: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 209, 1); + ind->data_len = 27; + break; + case 2: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 257, 1); + ind->data_len = 33; + break; + case 3: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 329, 1); + ind->data_len = 42; + break; + case 4: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 385, 1); + ind->data_len = 49; + break; + case 5: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 487, 1); + ind->data_len = 61; + break; + case 6: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 631, 1); + ind->data_len = 79; + break; + case 7: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 946, 1); + ind->data_len = 119; + break; + case 8: + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 134, 1138, 1); + ind->data_len = 143; + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid cs_hdr set\n"); + return -EINVAL; + } + break; + case CS_OR_HDR_AB: + /* Note: The useful data starts at D13 and is byte-aligned inside the TRAU frame. + * The data string contains 4 items, each 8 bytes long, 32 bytes total. */ + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, trau_bits, 144, 256, 1); + ind->data_len = 32; + + for (i = 0; i < 4; i++) { + rc = decode_ab(&ind->ab[i], ind->data + i * 8); + if (rc < 0) + return -EINVAL; + } + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid cs_hdr set\n"); + return -EINVAL; + } + + return 0; +}; + +static int dec_ccu_data_ind_64_mcs9(struct er_ccu_data_ind *ind, const ubit_t *trau_bits) +{ + /* 64kbps CCU-DATA-IND (MCS9) TRAU frame format: + * Direction: CCU => PCU + * + * (bit 0) 0 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 0 + * 1 D1 D2 D3 D4 D5 D6 D7 + * D8 D9 D10 D11 D12 D13 D14 D15 + * D16 D17 D18 D19 D20 D21 D22 D23 + * D24 D25 D26 D27 D28 D29 D30 D31 + * D32 D33 D34 D35 D36 D37 D38 D39 + * D40 D41 D42 D43 D44 D45 D46 D47 + * D48 C1 C2 C3 C4 C5 C6 C7 + * PC E1 E2 E3 E4 E5 E6 E7 + * E8 E9 E10 E11 E12 E13 E14 E15 + * E16 E17 E18 E19 E20 E21 E22 E23 + * PE S1 S2 D49 D50 D51 D52 D53 + * D54 D55 D56 D57 D58 D59 D60 D61 + * D62 D63 D64 ... + * ... D1219 D1220 D1221 + * TA1 TA2 TA3 TA4 TA5 TA6 TA7 TA8 + * TA9 TA10 TA11 TA12 TA13 TA14 TA15 TA16 (bit 1279) + * TA17* TA18* TA19* TA20* TA21* TA22* TA23* TA24* + * TA25* TA26* TA27* TA28* TA29* TA30* TA31* TA32* + * + * C = Control bits + * D = Data bits + * E = Extended control bits + * PC = Parity over C-Bits (odd) + * PE = Parity over extended control bits (odd) */ + + ubit_t block[1234]; + uint8_t eadd = 0; + uint8_t mean_bep = 0; + uint8_t cv_bep = 0; + + /* Validate C-Bits */ + if (calc_parity(trau_bits + 65, 7) != trau_bits[72]) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid parity (C1-C7)\n"); + return -EINVAL; + } + + /* TAV (C6-C7) */ + osmo_ubit2pbit_ext((pbit_t *) &ind->tav, 0, trau_bits, 70, 2, 1); + + /* Validate E-Bits */ + if (calc_parity(trau_bits + 73, 23) != trau_bits[96]) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid parity (E1-E23)\n"); + return -EINVAL; + } + + /* Downlink block error (E1) */ + if (trau_bits[73] == 0) + ind->dbe = true; + + /* MCS9 uses CS header type 1 */ + ind->cs_hdr = CS_OR_HDR_HDR1; + + /* RX-LEV (E2-E7) */ + osmo_ubit2pbit_ext((pbit_t *) &ind->rx_lev, 2, trau_bits, 74, 6, 0); + + /* Estimated access delay (E8-E10) */ + osmo_ubit2pbit_ext((pbit_t *) &eadd, 5, trau_bits, 80, 3, 0); + switch (eadd) { + case 0: + /* <2 or less */ + ind->est_acc_del_dev = -3; + break; + case 1: + ind->est_acc_del_dev = -1; + break; + case 2: + ind->est_acc_del_dev = 1; + break; + case 4: + ind->est_acc_del_dev = 2; + break; + case 5: + /* >2 or more */ + ind->est_acc_del_dev = 3; + break; + case 6: + ind->est_acc_del_dev = 0; + break; + case 7: + ind->est_acc_del_dev = -2; + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid estimated access delay (E11-E13)\n"); + return -EINVAL; + } + + /* Mean BEP (E11-E17) */ + osmo_ubit2pbit_ext((pbit_t *) &mean_bep, 1, trau_bits, 83, 7, 0); + ind->u.egprs.mean_bep = mean_bep; + + /* CV BEP (E18-E20) */ + osmo_ubit2pbit_ext((pbit_t *) &cv_bep, 5, trau_bits, 90, 3, 0); + ind->u.egprs.mean_bep = cv_bep; + + /* RLC/MAC header quality (E21) */ + if (trau_bits[93] == 0) { + ind->u.egprs.hdr_good = true; + + /* Data block quality (E22/E23) */ + if (trau_bits[94] == 0) + ind->u.egprs.data_good[0] = true; + if (trau_bits[95] == 0) + ind->u.egprs.data_good[1] = true; + } else { + /* A bad RLC/MAC header always means that the the data blocks + * cannot be valid. */ + ind->u.egprs.data_good[0] = false; + ind->u.egprs.data_good[1] = false; + } + + /* For capacity reasons the following fields are stripped from the + * header: Spare, RSB, CPS. This means we have to restore those + * fields to get a valid MCS9 block. See also: 3GPP TS 44.060, + * section 10.3a.4.1 */ + memcpy(block, trau_bits + 17, 32); + block[32] = 0; /* CPS 0 */ + block[33] = 0; /* CPS 1 */ + block[34] = 0; /* CPS 2 */ + block[35] = 0; /* CPS 3 */ + block[36] = 0; /* CPS 4 */ + block[37] = 0; /* RSB (not a resent block - guessed) */ + block[38] = trau_bits[49]; /* PI */ + block[39] = 0; /* Spare */ + block[40] = 0; /* Spare */ + block[41] = 0; /* Spare */ + block[42] = 0; /* Spare */ + block[43] = 0; /* Spare */ + block[44] = 0; /* Spare */ + block[45] = 0; /* Spare */ + memcpy(block + 45, trau_bits + 50, 15); + memcpy(block + 45, trau_bits + 99, 1173); + + osmo_ubit2pbit_ext((pbit_t *) &ind->data, 0, block, 0, sizeof(block), 1); + + return 0; +} + +/*! decode an 64k Ericsson GPRS (GSL) TRAU frame. + * \param[out] fr caller-allocated output data structure. + * \param[in] bits unpacked input bits (1280). + * \return 0 on success; negative in case of error. */ +int er_gprs_trau_frame_decode_64k(struct er_gprs_trau_frame *fr, const ubit_t *bits) +{ + uint8_t c_1_5 = 0; + const ubit_t expected_sync_pattern[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, + }; + const ubit_t expected_sync_pattern_mcs9[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, + }; + int rc; + + memset(fr, 0, sizeof(*fr)); + + /* Determine frame type */ + osmo_ubit2pbit_ext((pbit_t *) &c_1_5, 0, bits, 65, 5, 1); + + /* Validate sync patern */ + switch (c_1_5) { + case PCU_TRAU_ER_FT_CCU_SYNC_IND: + case PCU_TRAU_ER_FT_DATA_IND: + if (memcmp(bits, expected_sync_pattern, ARRAY_SIZE(expected_sync_pattern)) != 0) { + LOGP(DLINP, LOGL_ERROR, "CCU-XXXX-IND-64: invalid sync pattern (T0,T1)\n"); + return -EINVAL; + } + break; + case PCU_TRAU_ER_FT_DATA9_IND: + if (memcmp(bits, expected_sync_pattern_mcs9, ARRAY_SIZE(expected_sync_pattern_mcs9)) != 0) { + LOGP(DLINP, LOGL_ERROR, "CCU-DATA-IND-64: invalid sync pattern (T0,T1)\n"); + return -EINVAL; + } + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-XXXX-IND-64: invalid frame type (%02x)\n", c_1_5); + rc = -EINVAL; + } + + /* Decode frame */ + switch (c_1_5) { + case PCU_TRAU_ER_FT_CCU_SYNC_IND: + fr->type = ER_GPRS_TRAU_FT_SYNC; + rc = dec_ccu_sync_ind_64(&fr->u.ccu_sync_ind, bits); + break; + case PCU_TRAU_ER_FT_DATA_IND: + fr->type = ER_GPRS_TRAU_FT_DATA; + rc = dec_ccu_data_ind_64(&fr->u.ccu_data_ind, bits); + break; + case PCU_TRAU_ER_FT_DATA9_IND: + fr->type = ER_GPRS_TRAU_FT_DATA; + rc = dec_ccu_data_ind_64_mcs9(&fr->u.ccu_data_ind, bits); + break; + default: + LOGP(DLINP, LOGL_ERROR, "CCU-XXXX-IND-64: invalid frame type (%02x)\n", c_1_5); + rc = -EINVAL; + } + + /* Ensure that we exit with predictable data in case of error. */ + if (rc < 0) + memset(fr, 0, sizeof(*fr)); + + return rc; +} diff --git a/tests/Makefile.am b/tests/Makefile.am index dcd9a4f..580c38b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,7 +8,8 @@ check_PROGRAMS = e1inp_ipa_bsc_test \ subchan_demux/subchan_demux_test \ ipa_recv/ipa_recv_test \ rtp_test/rtp_test \ - trau_sync/trau_sync_test + trau_sync/trau_sync_test \ + trau_pcu_ericsson/trau_pcu_ericsson_test e1inp_ipa_bsc_test_SOURCES = e1inp_ipa_bsc_test.c e1inp_ipa_bsc_test_LDADD = $(top_builddir)/src/libosmoabis.la \ @@ -41,6 +42,9 @@ trau_sync_trau_sync_test_SOURCES = trau_sync/trau_sync_test.c trau_sync_trau_sync_test_LDADD = $(top_builddir)/src/libosmotrau.la \ $(LIBOSMOCORE_LIBS) +trau_pcu_ericsson_trau_pcu_ericsson_test_SOURCES = trau_pcu_ericsson/trau_pcu_ericsson_test.c +trau_pcu_ericsson_trau_pcu_ericsson_test_LDADD = $(top_builddir)/src/libosmotrau.la \ + $(LIBOSMOCORE_LIBS) # boilerplate for the tests # The `:;' works around a Bash 3.2 bug when the output is not writeable. @@ -65,7 +69,8 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ subchan_demux/subchan_demux_test.ok \ ipa_recv/ipa_recv_test.ok \ rtp_test/rtp_test.ok \ - trau_sync/trau_sync_test.ok trau_sync/trau_sync_test.err + trau_sync/trau_sync_test.ok trau_sync/trau_sync_test.err \ + trau_pcu_ericsson/trau_pcu_ericsson_test.ok TESTSUITE = $(srcdir)/testsuite diff --git a/tests/testsuite.at b/tests/testsuite.at index 4faf429..4dfb793 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -35,3 +35,9 @@ cat $abs_srcdir/trau_sync/trau_sync_test.ok > expout cat $abs_srcdir/trau_sync/trau_sync_test.err > experr AT_CHECK([$abs_top_builddir/tests/trau_sync/trau_sync_test], [0], [expout], [experr]) AT_CLEANUP + +AT_SETUP([trau_pcu_ericsson]) +AT_KEYWORDS([trau_pcu_ericsson]) +cat $abs_srcdir/trau_pcu_ericsson/trau_pcu_ericsson_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/trau_pcu_ericsson/trau_pcu_ericsson_test], [0], [expout], [ignore]) +AT_CLEANUP diff --git a/tests/trau_pcu_ericsson/trau_pcu_ericsson_test.c b/tests/trau_pcu_ericsson/trau_pcu_ericsson_test.c new file mode 100644 index 0000000..986ab79 --- /dev/null +++ b/tests/trau_pcu_ericsson/trau_pcu_ericsson_test.c @@ -0,0 +1,1392 @@ + +#include <osmocom/core/application.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/bits.h> +#include <osmocom/core/utils.h> +#include <osmocom/trau/trau_pcu_ericsson.h> + +void dump_frame(ubit_t *trau_frame, size_t len) +{ + uint16_t i; + printf(" "); + for (i = 0; i < len; i++) { + if (i % 8 == 0 && i > 0) + printf("\n "); + printf("%u ", trau_frame[i]); + } + + printf("\n"); +} + +static void dump_ab(struct er_gprs_ab *ab) +{ + printf(" ab->ab_type=%u\n", ab->ab_type); + printf(" ab->rxlev=%u\n", ab->rxlev); + printf(" ab->acc_delay=%u\n", ab->acc_delay); + printf(" ab->data=%04x\n", ab->data); + + if (ab->ab_type == 1) { + printf(" ab->u.type_1.crc=%u\n", ab->u.type_1.crc); + printf(" ab->u.type_1.burst_qual=%u\n", ab->u.type_1.burst_qual); + printf(" ab->u.type_1.frame_qual=%u\n", ab->u.type_1.frame_qual); + } else if (ab->ab_type == 2) { + printf(" ab->u.type_2.abi=%u\n", ab->u.type_2.abi); + printf(" ab->u.type_2.type=%u\n", ab->u.type_2.type); + } else + printf(" bad data\n"); +} + +void er_gprs_trau_frame_encode_16k_FT_SYNC_test(void) +{ + struct er_gprs_trau_frame frame; + ubit_t trau_frame[ER_GPRS_TRAU_FRAME_LEN_16K]; + int rc; + + printf("\n==> %s\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_sync_ind.pseq = 1234; + frame.u.pcu_sync_ind.tav = 0; + frame.u.pcu_sync_ind.fn_ul = 0xFFFFFFFF; /* optional, not included */ + frame.u.pcu_sync_ind.fn_dl = 0xFFFFFFFF; /* optional, not included */ + frame.u.pcu_sync_ind.fn_ss = 0xFFFFFFFF; /* optional, not included */ + frame.u.pcu_sync_ind.ls = 0xFFFFFFFF; /* optional, not included */ + frame.u.pcu_sync_ind.ss = 0xFFFFFFFF; /* optional, not included */ + frame.type = ER_GPRS_TRAU_FT_SYNC; + + rc = er_gprs_trau_frame_encode_16k(trau_frame, &frame); + OSMO_ASSERT(rc == 320); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_16K); +} + +void er_gprs_trau_frame_encode_16k_FT_DATA_test(void) +{ + struct er_gprs_trau_frame frame; + ubit_t trau_frame[ER_GPRS_TRAU_FRAME_LEN_16K]; + int rc; + + uint8_t data_cs1[] = { + 0x07, 0x00, 0x05, 0x01, 0xc0, 0x05, 0x08, 0x02, + 0x01, 0x2a, 0x44, 0x00, 0xf1, 0x10, 0x23, 0x6e, + 0x00, 0x17, 0x16, 0x18, 0x05, 0xf4, 0xf5 + }; + + uint8_t data_cs2[] = { + 0x0f, 0x00, 0x08, 0x69, 0x01, 0xc0, 0x09, 0x08, + 0x02, 0x01, 0x2a, 0x44, 0x00, 0xf1, 0x10, 0x23, + 0x6e, 0x00, 0x17, 0x16, 0x18, 0x05, 0xf4, 0xd9, + 0xa1, 0x82, 0xdd, 0xd6, 0xee, 0xaa, 0x2b, 0x2b, + 0x2b, 0x00 + }; + + printf("\n==> %s (CS1)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_CS1; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x01; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_cs1, sizeof(data_cs1)); + rc = er_gprs_trau_frame_encode_16k(trau_frame, &frame); + OSMO_ASSERT(rc == 320); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_16K); + + printf("\n==> %s (CS2)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_CS2; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x08; + frame.u.pcu_data_ind.timing_offset = 0x80; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_cs2, sizeof(data_cs2)); + rc = er_gprs_trau_frame_encode_16k(trau_frame, &frame); + OSMO_ASSERT(rc == 320); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_16K); +} + +void er_gprs_trau_frame_decode_16k_FT_SYNC_test(void) +{ + int rc; + struct er_gprs_trau_frame frame; + + /* TRAU frame as received from BTS when no PCU-SYNC-IND was sent yet. + * The PSEQ value is not yet available */ + const ubit_t bits_1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 0, 1, 0, 0, + 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 1, 0, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 1, 1, + 0, 1, 1, 1, 1, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 1, 0, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 1, 1, + 0, 1, 1, 1, 0, 0, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }; + + /* TRAU frame as received from BTS after a few PCU-SYNC-IND frames + * were sent. The PSEQ value is now known to the BTS. */ + const ubit_t bits_2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 0, 1, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }; + + printf("\n==> %s (not yet synced)\n", __func__); + rc = er_gprs_trau_frame_decode_16k(&frame, bits_1); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_SYNC); + printf(" ccu_sync_ind.tav=%02x\n", frame.u.ccu_sync_ind.tav); + printf(" ccu_sync_ind.dfe=%02x\n", frame.u.ccu_sync_ind.dfe); + printf(" ccu_sync_ind.dbe=%02x\n", frame.u.ccu_sync_ind.dbe); + printf(" ccu_sync_ind.pseq=%u\n", frame.u.ccu_sync_ind.pseq); + printf(" ccu_sync_ind.afn_ul=%u\n", frame.u.ccu_sync_ind.afn_ul); + printf(" ccu_sync_ind.afn_dl=%u\n", frame.u.ccu_sync_ind.afn_dl); + + printf("\n==> %s (synced)\n", __func__); + rc = er_gprs_trau_frame_decode_16k(&frame, bits_2); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_SYNC); + printf(" ccu_sync_ind.tav=%02x\n", frame.u.ccu_sync_ind.tav); + printf(" ccu_sync_ind.dfe=%02x\n", frame.u.ccu_sync_ind.dfe); + printf(" ccu_sync_ind.dbe=%02x\n", frame.u.ccu_sync_ind.dbe); + printf(" ccu_sync_ind.pseq=%u\n", frame.u.ccu_sync_ind.pseq); + printf(" ccu_sync_ind.afn_ul=%u\n", frame.u.ccu_sync_ind.afn_ul); + printf(" ccu_sync_ind.afn_dl=%u\n", frame.u.ccu_sync_ind.afn_dl); +} + +void er_gprs_trau_frame_decode_16k_FT_DATA_test(void) +{ + int rc; + struct er_gprs_trau_frame frame; + + /* TRAU frame with valid CS1 block and correct CRC. */ + const ubit_t bits_cs1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 1, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 0, 1, + 0, 1, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 1, 1, 1, 1, 0, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 0, 1, + 1, 0, 0, 1, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 0, 1, 0, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 1, 1, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 1, 1, + 0, 1, 1, 0, 1, 0, 1, 1, + 0, 1, 0, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }; + + /* TRAU frame with valid CS2 block. */ + const ubit_t bits_cs2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 1, 0, 0, + 0, 1, 0, 0, 1, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, 0, 0, + 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 1, 1, 1, + 0, 0, 1, 1, 0, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, + 0, 0, 1, 1, 0, 0, 0, 1, + 1, 0, 1, 1, 0, 1, 0, 1, + 0, 0, 1, 1, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 1, 1, 0, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 0, 1, + 1, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + }; + + /* TRAU frame with AB data (noise). */ + const ubit_t bits_ab[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }; + + printf("\n==> %s (CS1)\n", __func__); + rc = er_gprs_trau_frame_decode_16k(&frame, bits_cs1); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_DATA); + printf(" ccu_data_ind.tav=%02x\n", frame.u.ccu_data_ind.tav); + printf(" ccu_data_ind.dbe=%u\n", frame.u.ccu_data_ind.dbe); + printf(" ccu_data_ind.cs_hdr=%u\n", frame.u.ccu_data_ind.cs_hdr); + printf(" ccu_data_ind.gprs.rx_lev=%u\n", frame.u.ccu_data_ind.rx_lev); + printf(" ccu_data_ind.gprs.est_acc_del_dev=%d\n", frame.u.ccu_data_ind.est_acc_del_dev); + printf(" ccu_data_ind.u.gprs.block_qual=%u\n", frame.u.ccu_data_ind.u.gprs.block_qual); + printf(" ccu_data_ind.u.gprs.parity_ok=%u\n", frame.u.ccu_data_ind.u.gprs.parity_ok); + printf(" ccu_data_ind.u.data_len=%u\n", frame.u.ccu_data_ind.data_len); + printf(" ccu_data_ind.data=%s\n", osmo_hexdump_nospc(frame.u.ccu_data_ind.data, frame.u.ccu_data_ind.data_len)); + + printf("\n==> %s (CS2)\n", __func__); + rc = er_gprs_trau_frame_decode_16k(&frame, bits_cs2); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_DATA); + printf(" ccu_data_ind.tav=%02x\n", frame.u.ccu_data_ind.tav); + printf(" ccu_data_ind.dbe=%u\n", frame.u.ccu_data_ind.dbe); + printf(" ccu_data_ind.cs_hdr=%u\n", frame.u.ccu_data_ind.cs_hdr); + printf(" ccu_data_ind.gprs.rx_lev=%u\n", frame.u.ccu_data_ind.rx_lev); + printf(" ccu_data_ind.gprs.est_acc_del_dev=%d\n", frame.u.ccu_data_ind.est_acc_del_dev); + printf(" ccu_data_ind.u.gprs.block_qual=%u\n", frame.u.ccu_data_ind.u.gprs.block_qual); + printf(" ccu_data_ind.u.gprs.parity_ok=%u\n", frame.u.ccu_data_ind.u.gprs.parity_ok); + printf(" ccu_data_ind.u.data_len=%u\n", frame.u.ccu_data_ind.data_len); + printf(" ccu_data_ind.data=%s\n", osmo_hexdump_nospc(frame.u.ccu_data_ind.data, frame.u.ccu_data_ind.data_len)); + + printf("\n==> %s (AB)\n", __func__); + rc = er_gprs_trau_frame_decode_16k(&frame, bits_ab); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_DATA); + printf(" ccu_data_ind.tav=%02x\n", frame.u.ccu_data_ind.tav); + printf(" ccu_data_ind.dbe=%u\n", frame.u.ccu_data_ind.dbe); + printf(" ccu_data_ind.cs_hdr=%u\n", frame.u.ccu_data_ind.cs_hdr); + printf(" ccu_data_ind.gprs.rx_lev=%u\n", frame.u.ccu_data_ind.rx_lev); + printf(" ccu_data_ind.gprs.est_acc_del_dev=%d\n", frame.u.ccu_data_ind.est_acc_del_dev); + printf(" ccu_data_ind.u.gprs.block_qual=%u\n", frame.u.ccu_data_ind.u.gprs.block_qual); + printf(" ccu_data_ind.u.gprs.parity_ok=%u\n", frame.u.ccu_data_ind.u.gprs.parity_ok); + printf(" ccu_data_ind.u.data_len=%u\n", frame.u.ccu_data_ind.data_len); + printf(" ccu_data_ind.data=%s\n", osmo_hexdump_nospc(frame.u.ccu_data_ind.data, frame.u.ccu_data_ind.data_len)); + printf(" ccu_data_ind.ab[0]=\n"); + dump_ab(&frame.u.ccu_data_ind.ab[0]); + printf(" ccu_data_ind.ab[1]=\n"); + dump_ab(&frame.u.ccu_data_ind.ab[1]); + printf(" ccu_data_ind.ab[2]=\n"); + dump_ab(&frame.u.ccu_data_ind.ab[2]); + printf(" ccu_data_ind.ab[3]=\n"); + dump_ab(&frame.u.ccu_data_ind.ab[3]); +} + +void er_gprs_trau_frame_encode_64k_FT_SYNC_test(void) +{ + struct er_gprs_trau_frame frame; + ubit_t trau_frame[ER_GPRS_TRAU_FRAME_LEN_64K]; + int rc; + + printf("\n==> %s\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_sync_ind.pseq = 1234; + frame.u.pcu_sync_ind.tav = 0; + frame.u.pcu_sync_ind.fn_ul = 0xFFFFFFFF; /* optional, not included */ + frame.u.pcu_sync_ind.fn_dl = 0xFFFFFFFF; /* optional, not included */ + frame.u.pcu_sync_ind.fn_ss = 0xFFFFFFFF; /* optional, not included */ + frame.u.pcu_sync_ind.ls = 0xFFFFFFFF; /* optional, not included */ + frame.u.pcu_sync_ind.ss = 0xFFFFFFFF; /* optional, not included */ + frame.type = ER_GPRS_TRAU_FT_SYNC; + + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); +} + +void er_gprs_trau_frame_encode_64k_FT_DATA_test(void) +{ + struct er_gprs_trau_frame frame; + ubit_t trau_frame[ER_GPRS_TRAU_FRAME_LEN_64K]; + int rc; + + uint8_t data_cs1[] = { + 0x07, 0x00, 0x05, 0x01, 0xc0, 0x05, 0x08, 0x02, + 0x01, 0x2a, 0x44, 0x00, 0xf1, 0x10, 0x23, 0x6e, + 0x00, 0x17, 0x16, 0x18, 0x05, 0xf4, 0xf5 + }; + + uint8_t data_cs2[] = { + 0x0f, 0x00, 0x08, 0x69, 0x01, 0xc0, 0x09, 0x08, + 0x02, 0x01, 0x2a, 0x44, 0x00, 0xf1, 0x10, 0x23, + 0x6e, 0x00, 0x17, 0x16, 0x18, 0x05, 0xf4, 0xd9, + 0xa1, 0x82, 0xdd, 0xd6, 0xee, 0xaa, 0x2b, 0x2b, + 0x2b, 0x00 + }; + + uint8_t data_cs3[] = { + 0x07, 0x00, 0x01, 0x01, 0xc0, 0x0d, 0x8a, 0x42, + 0x03, 0x0e, 0x23, 0x62, 0x1f, 0x72, 0x99, 0x3f, + 0x3f, 0x11, 0x43, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x04, 0x2b, 0x06, 0x01, 0x21, 0xc0, 0xa8, 0x00, + 0x05, 0x27, 0x22, 0x80, 0x80, 0x21, 0x10, 0x00 + }; + + uint8_t data_cs4[] = { + 0x07, 0x00, 0x01, 0x01, 0xc0, 0x09, 0x8a, 0x42, + 0x03, 0x0e, 0x23, 0x62, 0x1f, 0x72, 0x99, 0x3f, + 0x3f, 0x11, 0x43, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x04, 0x2b, 0x06, 0x01, 0x21, 0xc0, 0xa8, 0x00, + 0x05, 0x27, 0x22, 0x80, 0x80, 0x21, 0x10, 0x02, + 0x00, 0x00, 0x10, 0x81, 0x06, 0x08, 0x08, 0x08, + 0x08, 0x83, 0x06, 0x08, 0x08, 0x00 + }; + + uint8_t data_mcs1[] = { + 0x07, 0x80, 0x01, 0x18, 0x2c, 0xfe, 0x07, 0xf6, + 0x35, 0x0a, 0xe0, 0x2d, 0x0a, 0xe0, 0x63, 0x31, + 0xa3, 0x57, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x00 + }; + + uint8_t data_mcs2[] = { + 0x07, 0x80, 0x00, 0x12, 0x36, 0x10, 0x10, 0x10, + 0x00, 0x1a, 0x08, 0x10, 0x10, 0x10, 0x10, 0x2c, + 0xbd, 0xb2, 0x87, 0xf6, 0x03, 0x00, 0x2c, 0x02, + 0xe8, 0x35, 0x0a, 0xbe, 0x59, 0xc1, 0x00, 0x02, + 0x00 + }; + + uint8_t data_mcs3[] = { + 0x0f, 0x80, 0x00, 0x06, 0x68, 0xfe, 0x03, 0x80, + 0x0b, 0x10, 0x04, 0x02, 0x54, 0x88, 0x00, 0xe2, + 0x21, 0x46, 0xdc, 0x00, 0x2e, 0x2c, 0x30, 0x0a, + 0xe8, 0xd7, 0x6f, 0x4e, 0x55, 0xbd, 0xb0, 0xfe, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x00 + }; + + uint8_t data_mcs4[] = { + 0x07, 0x80, 0x00, 0x04, 0x68, 0xfe, 0x03, 0x80, + 0x0b, 0x10, 0x04, 0x02, 0x54, 0x88, 0x00, 0xe2, + 0x21, 0x46, 0xdc, 0x00, 0x2e, 0x2c, 0x30, 0x0a, + 0xe8, 0xfd, 0xe1, 0xb7, 0x79, 0x6c, 0xe7, 0xd8, + 0x57, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x00 + }; + + uint8_t data_mcs5[] = { + 0x07, 0x40, 0x00, 0x88, 0x86, 0xd3, 0x3f, 0x02, + 0x02, 0x02, 0x40, 0x03, 0x01, 0x02, 0x02, 0x02, + 0x82, 0x07, 0x33, 0xf2, 0xd0, 0x7e, 0x00, 0x80, + 0x45, 0x00, 0xbd, 0x46, 0xc1, 0x37, 0x2b, 0x18, + 0x40, 0x00, 0x40, 0x80, 0x42, 0x20, 0xc0, 0x01, + 0x04, 0x00, 0xc8, 0x80, 0x00, 0x00, 0x85, 0xc0, + 0x01, 0x20, 0x00, 0x81, 0x04, 0x00, 0x48, 0x41, + 0xa2, 0xbb, 0xcc, 0x0a + }; + + uint8_t data_mcs6[] = { + 0x07, 0x00, 0x00, 0xc2, 0x62, 0x00, 0x70, 0x82, + 0xa2, 0xd0, 0x80, 0xc3, 0x88, 0xd8, 0x87, 0x5c, + 0xe6, 0xcf, 0x4f, 0xc4, 0xd0, 0xff, 0x3f, 0x00, + 0x00, 0x00, 0xc1, 0x8a, 0x41, 0x40, 0x08, 0x30, + 0x2a, 0x40, 0xc1, 0x89, 0x08, 0x20, 0x60, 0x08, + 0x84, 0x00, 0x00, 0x00, 0x44, 0xa0, 0x01, 0x02, + 0x02, 0x02, 0xc2, 0xa0, 0x01, 0x02, 0x02, 0x02, + 0x02, 0x40, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, + 0x40, 0x03, 0x01, 0x02, 0x02, 0x02, 0xc2, 0x07, + 0x33, 0xf2, 0xd0, 0x7e, 0x00, 0x00 + }; + + uint8_t data_mcs7[] = { + 0x0f, 0x00, 0x00, 0x02, 0xa0, 0x05, 0x00, 0x27, + 0x28, 0x0a, 0x0d, 0x38, 0x8c, 0x88, 0x7d, 0xc8, + 0x65, 0xfe, 0xfc, 0x44, 0x0c, 0xfd, 0xff, 0x03, + 0x00, 0x00, 0x10, 0xac, 0x18, 0x04, 0x84, 0x00, + 0xa3, 0x02, 0x14, 0x9c, 0x88, 0x00, 0x02, 0x86, + 0x40, 0x08, 0x00, 0x00, 0x40, 0x04, 0x1a, 0x20, + 0x20, 0x20, 0x20, 0x0c, 0x1a, 0x20, 0x20, 0x20, + 0x20, 0x00, 0x34, 0x10, 0x20, 0xa0, 0xe1, 0xf4, + 0x8f, 0x80, 0x80, 0x00, 0xd0, 0x40, 0x80, 0x80, + 0x80, 0x80, 0xf0, 0xc1, 0x8c, 0x3c, 0xb4, 0x1f, + 0x00, 0x60, 0x11, 0x40, 0xaf, 0x51, 0xf0, 0xcd, + 0x0a, 0x06, 0x10, 0x00, 0x10, 0xa0, 0x10, 0x08, + 0x70, 0x00, 0x01, 0x00, 0x32, 0x20, 0x00, 0x40, + 0x21, 0x70, 0x00, 0x08, 0x40, 0x20, 0x01, 0x00, + 0x52, 0x90, 0xe8, 0x2e, 0xb3, 0x02 + }; + + uint8_t data_mcs8[] = { + 0x07, 0x00, 0x00, 0x02, 0x58, 0x05, 0x00, 0x27, + 0x28, 0x0a, 0x0d, 0x38, 0x8c, 0x88, 0x7d, 0xc8, + 0x65, 0xfe, 0xfc, 0x44, 0x0c, 0xfd, 0xff, 0x03, + 0x00, 0x00, 0x10, 0xac, 0x18, 0x04, 0x84, 0x00, + 0xa3, 0x02, 0x14, 0x9c, 0x88, 0x00, 0x02, 0x86, + 0x40, 0x08, 0x00, 0x00, 0x40, 0x04, 0x1a, 0x20, + 0x20, 0x20, 0x20, 0x0c, 0x1a, 0x20, 0x20, 0x20, + 0x20, 0x00, 0x34, 0x10, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x34, 0x10, 0x20, 0x20, 0x20, 0x20, 0x7c, + 0x30, 0x23, 0xe0, 0xf4, 0x8f, 0x3c, 0xb4, 0x1f, + 0x00, 0x60, 0x11, 0x40, 0xaf, 0x51, 0xf0, 0xcd, + 0x0a, 0x06, 0x10, 0x00, 0x10, 0xa0, 0x10, 0x08, + 0x70, 0x00, 0x01, 0x00, 0x32, 0x20, 0x00, 0x40, + 0x21, 0x70, 0x00, 0x08, 0x40, 0x20, 0x01, 0x00, + 0x52, 0x90, 0xe8, 0x2e, 0xb3, 0xb2, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0x02 + }; + + uint8_t data_mcs9[] = { + 0x07, 0x00, 0x00, 0x02, 0x28, 0x2c, 0x06, 0x00, + 0x27, 0x28, 0x0a, 0x0d, 0x38, 0x8c, 0x88, 0x7d, + 0xc8, 0x65, 0xfe, 0xfc, 0x44, 0x0c, 0xfd, 0xff, + 0x03, 0x00, 0x00, 0x10, 0xac, 0x18, 0x04, 0x84, + 0x00, 0xa3, 0x02, 0x14, 0x9c, 0x88, 0x00, 0x02, + 0x86, 0x40, 0x08, 0x00, 0x00, 0x40, 0x04, 0x1a, + 0x20, 0x20, 0x20, 0x20, 0x0c, 0x1a, 0x20, 0x20, + 0x20, 0x20, 0x00, 0x34, 0x10, 0x20, 0x20, 0x20, + 0x20, 0x00, 0x34, 0x10, 0x20, 0x20, 0x20, 0x20, + 0x7c, 0x30, 0x23, 0x0f, 0xed, 0x07, 0x00, 0x60, + 0xf4, 0x6f, 0x11, 0x40, 0xaf, 0x51, 0xf0, 0xcd, + 0x0a, 0x06, 0x10, 0x00, 0x10, 0xa0, 0x10, 0x08, + 0x70, 0x00, 0x01, 0x00, 0x32, 0x20, 0x00, 0x40, + 0x21, 0x70, 0x00, 0x08, 0x40, 0x20, 0x01, 0x00, + 0x52, 0x90, 0xe8, 0x2e, 0xb3, 0xb2, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, + 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, + 0xb2, 0x02 + }; + + printf("\n==> %s (CS1)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_CS1; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_cs1, sizeof(data_cs1)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (CS2)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_CS2; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_cs2, sizeof(data_cs2)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (CS3)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_CS3; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_cs3, sizeof(data_cs3)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (CS4)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_CS4; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_cs4, sizeof(data_cs4)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS1)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR3; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs1, sizeof(data_mcs1)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS2)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR3; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs2, sizeof(data_mcs2)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS3)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR3; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs3, sizeof(data_mcs3)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS4)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR3; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs4, sizeof(data_mcs4)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS5)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR2; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs5, sizeof(data_mcs5)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS6)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR2; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs6, sizeof(data_mcs6)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS7)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR1; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs7, sizeof(data_mcs7)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS8)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR1; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs8, sizeof(data_mcs8)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + + printf("\n==> %s (MCS9)\n", __func__); + memset(&frame, 0, sizeof(frame)); + frame.u.pcu_data_ind.tav = 0; + frame.u.pcu_data_ind.ul_frame_err = false; + frame.u.pcu_data_ind.cs_hdr = CS_OR_HDR_HDR1; + frame.u.pcu_data_ind.ul_chan_mode = ER_UL_CHMOD_NB_GMSK; + frame.u.pcu_data_ind.atten_db = 0x0f; + frame.u.pcu_data_ind.timing_offset = 0x01; + frame.type = ER_GPRS_TRAU_FT_DATA; + memcpy(frame.u.pcu_data_ind.data, data_mcs9, sizeof(data_mcs9)); + rc = er_gprs_trau_frame_encode_64k(trau_frame, &frame); + OSMO_ASSERT(rc == 1280); + dump_frame(trau_frame, ER_GPRS_TRAU_FRAME_LEN_64K); + +} + +void er_gprs_trau_frame_decode_64k_FT_SYNC_test(void) +{ + int rc; + struct er_gprs_trau_frame frame; + + /* TRAU frame as received from BTS when no PCU-SYNC-IND was sent yet. + * The PSEQ value is not yet available */ + const ubit_t bits_1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 0, 1, 0, 0, + 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 1, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }; + + /* TRAU frame as received from BTS after a few PCU-SYNC-IND frames + * were sent. The PSEQ value is now known to the BTS. */ + const ubit_t bits_2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 1, 0, 0, 1, + 0, 0, 1, 0, 1, 0, 1, 1, + 1, 0, 1, 0, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 1, 0, 0, 1, + 0, 0, 1, 0, 1, 0, 1, 1, + 1, 0, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }; + + printf("\n==> %s (not yet synced)\n", __func__); + rc = er_gprs_trau_frame_decode_64k(&frame, bits_1); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_SYNC); + printf(" ccu_sync_ind.tav=%02x\n", frame.u.ccu_sync_ind.tav); + printf(" ccu_sync_ind.dfe=%02x\n", frame.u.ccu_sync_ind.dfe); + printf(" ccu_sync_ind.dbe=%02x\n", frame.u.ccu_sync_ind.dbe); + printf(" ccu_sync_ind.pseq=%u\n", frame.u.ccu_sync_ind.pseq); + printf(" ccu_sync_ind.afn_ul=%u\n", frame.u.ccu_sync_ind.afn_ul); + printf(" ccu_sync_ind.afn_dl=%u\n", frame.u.ccu_sync_ind.afn_dl); + + printf("\n==> %s (synced)\n", __func__); + rc = er_gprs_trau_frame_decode_64k(&frame, bits_2); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_SYNC); + printf(" ccu_sync_ind.tav=%02x\n", frame.u.ccu_sync_ind.tav); + printf(" ccu_sync_ind.dfe=%02x\n", frame.u.ccu_sync_ind.dfe); + printf(" ccu_sync_ind.dbe=%02x\n", frame.u.ccu_sync_ind.dbe); + printf(" ccu_sync_ind.pseq=%u\n", frame.u.ccu_sync_ind.pseq); + printf(" ccu_sync_ind.afn_ul=%u\n", frame.u.ccu_sync_ind.afn_ul); + printf(" ccu_sync_ind.afn_dl=%u\n", frame.u.ccu_sync_ind.afn_dl); +} + +void er_gprs_trau_frame_decode_64k_FT_DATA_test(void) +{ + int rc; + struct er_gprs_trau_frame frame; + + /* TRAU frame with CS1 block and correct CRC. CS1 one data itsself is + * noise. */ + const ubit_t bits_cs1[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 1, 0, 0, + 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 1, 1, 0, + 1, 1, 1, 0, 1, 1, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 1, 0, + 1, 0, 0, 1, 1, 0, 0, 1, + 1, 1, 1, 1, 0, 0, 0, 1, + 1, 0, 1, 0, 1, 1, 1, 0, + 0, 0, 1, 1, 0, 1, 0, 1, + 1, 0, 1, 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 1, 0, 1, + 1, 0, 0, 1, 1, 1, 0, 1, + 1, 1, 1, 0, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 0, 1, 0, + 1, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 0, 1, 0, 1, + 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }; + + const ubit_t bits_cs2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 1, 1, 0, + 1, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 1, 0, + 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 0, 1, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 0, 1, + 0, 1, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 0, + 1, 1, 0, 0, 1, 1, 1, 0, + 1, 0, 1, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 1, 1, 1, + 0, 1, 0, 0, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 1, 0, 0, 1, + 1, 0, 1, 1, 0, 1, 0, 1, + 0, 0, 1, 0, 0, 1, 1, 0, + 0, 0, 0, 1, 0, 1, 0, 1, + 0, 0, 1, 0, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 1, 0, + 0, 0, 0, 1, 1, 0, 1, 1, + 0, 0, 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 0, 1, 1, 1, 0, 1, + 1, 0, 0, 1, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 0, 1, 1, + 0, 1, 0, 0, 0, 1, 1, 1, + 0, 1, 0, 0, 1, 1, 1, 1, + 0, 1, 0, 1, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + /* [...] shortened since decode won't access filler bits after + * the TRAU frame. */ + }; + + /* TRAU frame with AB data (noise). */ + const ubit_t bits_ab[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 1, 0, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + /* [...] shortened since decode won't access filler bits after + * the TRAU frame. */ + }; + + printf("\n==> %s (CS1)\n", __func__); + rc = er_gprs_trau_frame_decode_64k(&frame, bits_cs1); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_DATA); + printf(" ccu_data_ind.tav=%02x\n", frame.u.ccu_data_ind.tav); + printf(" ccu_data_ind.dbe=%u\n", frame.u.ccu_data_ind.dbe); + printf(" ccu_data_ind.cs_hdr=%u\n", frame.u.ccu_data_ind.cs_hdr); + printf(" ccu_data_ind.gprs.rx_lev=%u\n", frame.u.ccu_data_ind.rx_lev); + printf(" ccu_data_ind.gprs.est_acc_del_dev=%d\n", frame.u.ccu_data_ind.est_acc_del_dev); + printf(" ccu_data_ind.u.gprs.block_qual=%u\n", frame.u.ccu_data_ind.u.gprs.block_qual); + printf(" ccu_data_ind.u.gprs.parity_ok=%u\n", frame.u.ccu_data_ind.u.gprs.parity_ok); + printf(" ccu_data_ind.u.data_len=%u\n", frame.u.ccu_data_ind.data_len); + printf(" ccu_data_ind.data=%s\n", osmo_hexdump_nospc(frame.u.ccu_data_ind.data, frame.u.ccu_data_ind.data_len)); + + printf("\n==> %s (CS2)\n", __func__); + rc = er_gprs_trau_frame_decode_64k(&frame, bits_cs2); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_DATA); + printf(" ccu_data_ind.tav=%02x\n", frame.u.ccu_data_ind.tav); + printf(" ccu_data_ind.dbe=%u\n", frame.u.ccu_data_ind.dbe); + printf(" ccu_data_ind.cs_hdr=%u\n", frame.u.ccu_data_ind.cs_hdr); + printf(" ccu_data_ind.gprs.rx_lev=%u\n", frame.u.ccu_data_ind.rx_lev); + printf(" ccu_data_ind.gprs.est_acc_del_dev=%d\n", frame.u.ccu_data_ind.est_acc_del_dev); + printf(" ccu_data_ind.u.gprs.block_qual=%u\n", frame.u.ccu_data_ind.u.gprs.block_qual); + printf(" ccu_data_ind.u.gprs.parity_ok=%u\n", frame.u.ccu_data_ind.u.gprs.parity_ok); + printf(" ccu_data_ind.u.data_len=%u\n", frame.u.ccu_data_ind.data_len); + printf(" ccu_data_ind.data=%s\n", osmo_hexdump_nospc(frame.u.ccu_data_ind.data, frame.u.ccu_data_ind.data_len)); + + printf("\n==> %s (AB)\n", __func__); + rc = er_gprs_trau_frame_decode_64k(&frame, bits_ab); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(frame.type == ER_GPRS_TRAU_FT_DATA); + printf(" ccu_data_ind.tav=%02x\n", frame.u.ccu_data_ind.tav); + printf(" ccu_data_ind.dbe=%u\n", frame.u.ccu_data_ind.dbe); + printf(" ccu_data_ind.cs_hdr=%u\n", frame.u.ccu_data_ind.cs_hdr); + printf(" ccu_data_ind.gprs.rx_lev=%u\n", frame.u.ccu_data_ind.rx_lev); + printf(" ccu_data_ind.gprs.est_acc_del_dev=%d\n", frame.u.ccu_data_ind.est_acc_del_dev); + printf(" ccu_data_ind.u.gprs.block_qual=%u\n", frame.u.ccu_data_ind.u.gprs.block_qual); + printf(" ccu_data_ind.u.gprs.parity_ok=%u\n", frame.u.ccu_data_ind.u.gprs.parity_ok); + printf(" ccu_data_ind.u.data_len=%u\n", frame.u.ccu_data_ind.data_len); + printf(" ccu_data_ind.data=%s\n", osmo_hexdump_nospc(frame.u.ccu_data_ind.data, frame.u.ccu_data_ind.data_len)); + printf(" ccu_data_ind.ab[0]=\n"); + dump_ab(&frame.u.ccu_data_ind.ab[0]); + printf(" ccu_data_ind.ab[1]=\n"); + dump_ab(&frame.u.ccu_data_ind.ab[1]); + printf(" ccu_data_ind.ab[2]=\n"); + dump_ab(&frame.u.ccu_data_ind.ab[2]); + printf(" ccu_data_ind.ab[3]=\n"); + dump_ab(&frame.u.ccu_data_ind.ab[3]); +} + +static void test_body(void) +{ + er_gprs_trau_frame_encode_16k_FT_SYNC_test(); + er_gprs_trau_frame_encode_16k_FT_DATA_test(); + er_gprs_trau_frame_decode_16k_FT_SYNC_test(); + er_gprs_trau_frame_decode_16k_FT_DATA_test(); + + er_gprs_trau_frame_encode_64k_FT_SYNC_test(); + er_gprs_trau_frame_encode_64k_FT_DATA_test(); + er_gprs_trau_frame_decode_64k_FT_SYNC_test(); + er_gprs_trau_frame_decode_64k_FT_DATA_test(); +} + +static const struct log_info_cat default_categories[] = { +}; + +const struct log_info log_info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + +int main(int argc, char **argv) +{ + osmo_init_logging2(NULL, NULL); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE); + log_set_print_category(osmo_stderr_target, 0); + log_set_print_category_hex(osmo_stderr_target, 0); + log_set_log_level(osmo_stderr_target, LOGL_INFO); + test_body(); +} diff --git a/tests/trau_pcu_ericsson/trau_pcu_ericsson_test.ok b/tests/trau_pcu_ericsson/trau_pcu_ericsson_test.ok new file mode 100644 index 0000000..6d93eed --- /dev/null +++ b/tests/trau_pcu_ericsson/trau_pcu_ericsson_test.ok @@ -0,0 +1,2579 @@ + +==> er_gprs_trau_frame_encode_16k_FT_SYNC_test + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 1 1 1 1 0 0 0 + 1 0 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 0 0 0 0 0 0 0 + 1 0 0 0 0 1 0 0 + 1 1 0 1 0 0 1 0 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 + +==> er_gprs_trau_frame_encode_16k_FT_DATA_test (CS1) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 1 1 1 1 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 1 0 1 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 1 1 1 0 1 0 0 + 0 0 0 0 0 0 1 0 + 0 0 0 0 1 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 1 0 1 0 + 1 0 0 0 0 1 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 1 0 0 0 1 + 1 1 1 0 0 0 0 1 + 0 0 0 1 1 0 0 0 + 1 0 0 0 1 1 1 0 + 1 1 0 0 0 0 0 0 + 0 0 0 1 1 1 0 1 + 0 0 0 0 1 1 0 1 + 0 0 0 0 0 0 1 1 + 0 0 0 1 0 1 0 0 + 0 0 0 0 0 1 0 1 + 1 1 1 1 0 1 0 1 + 1 1 1 0 1 1 0 0 + 1 0 1 0 1 1 1 0 + 0 0 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 + +==> er_gprs_trau_frame_encode_16k_FT_DATA_test (CS2) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 0 1 0 0 1 0 + 0 0 0 0 0 0 1 0 + 0 0 0 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 0 0 0 1 0 0 1 0 + 1 1 0 1 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 1 1 1 0 0 1 0 + 0 0 0 0 0 0 1 0 + 0 0 0 0 1 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 1 0 1 0 + 1 0 0 0 0 1 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 1 0 0 0 1 + 1 1 1 0 0 0 0 1 + 0 0 0 1 1 0 0 0 + 1 0 0 0 1 1 1 0 + 1 1 0 0 0 0 0 0 + 0 0 0 1 1 1 0 1 + 0 0 0 0 1 1 0 1 + 0 0 0 0 0 0 1 1 + 0 0 0 1 0 1 0 0 + 0 0 0 0 0 1 0 1 + 1 1 1 1 0 0 1 1 + 0 1 1 1 0 0 0 0 + 1 0 1 0 1 0 0 0 + 0 0 1 1 0 1 1 1 + 0 1 1 0 1 1 0 1 + 0 1 1 0 1 1 1 0 + 1 1 1 0 1 0 1 0 + 1 0 1 1 1 0 1 0 + 1 0 0 1 1 0 1 0 + 1 0 0 1 1 0 1 0 + 1 0 0 0 0 0 0 0 + 0 0 1 1 1 1 1 1 + 1 1 1 1 + +==> er_gprs_trau_frame_decode_16k_FT_SYNC_test (not yet synced) + ccu_sync_ind.tav=00 + ccu_sync_ind.dfe=00 + ccu_sync_ind.dbe=00 + ccu_sync_ind.pseq=4194303 + ccu_sync_ind.afn_ul=770937 + ccu_sync_ind.afn_dl=770930 + +==> er_gprs_trau_frame_decode_16k_FT_SYNC_test (synced) + ccu_sync_ind.tav=01 + ccu_sync_ind.dfe=01 + ccu_sync_ind.dbe=00 + ccu_sync_ind.pseq=489 + ccu_sync_ind.afn_ul=1507383 + ccu_sync_ind.afn_dl=1507376 + +==> er_gprs_trau_frame_decode_16k_FT_DATA_test (CS1) + ccu_data_ind.tav=00 + ccu_data_ind.dbe=0 + ccu_data_ind.cs_hdr=1 + ccu_data_ind.gprs.rx_lev=63 + ccu_data_ind.gprs.est_acc_del_dev=0 + ccu_data_ind.u.gprs.block_qual=0 + ccu_data_ind.u.gprs.parity_ok=1 + ccu_data_ind.u.data_len=23 + ccu_data_ind.data=110315e27819cd4552054000401117e8c0a80003080808 + +==> er_gprs_trau_frame_decode_16k_FT_DATA_test (CS2) + ccu_data_ind.tav=00 + ccu_data_ind.dbe=0 + ccu_data_ind.cs_hdr=2 + ccu_data_ind.gprs.rx_lev=63 + ccu_data_ind.gprs.est_acc_del_dev=0 + ccu_data_ind.u.gprs.block_qual=0 + ccu_data_ind.u.gprs.parity_ok=1 + ccu_data_ind.u.data_len=34 + ccu_data_ind.data=00010449eb20fe38676f6f676c6503636f6d00000100019ab9f92b2b2b2b2b2b2b00 + +==> er_gprs_trau_frame_decode_16k_FT_DATA_test (AB) + ccu_data_ind.tav=00 + ccu_data_ind.dbe=0 + ccu_data_ind.cs_hdr=0 + ccu_data_ind.gprs.rx_lev=63 + ccu_data_ind.gprs.est_acc_del_dev=0 + ccu_data_ind.u.gprs.block_qual=0 + ccu_data_ind.u.gprs.parity_ok=1 + ccu_data_ind.u.data_len=32 + ccu_data_ind.data=6000ff3f3fb81f006000ff3f3f181f006000ff3f3f981f006000ff3f3ff41f00 + ccu_data_ind.ab[0]= + ab->ab_type=2 + ab->rxlev=0 + ab->acc_delay=184 + ab->data=0000 + ab->u.type_2.abi=3 + ab->u.type_2.type=0 + ccu_data_ind.ab[1]= + ab->ab_type=2 + ab->rxlev=0 + ab->acc_delay=24 + ab->data=0000 + ab->u.type_2.abi=3 + ab->u.type_2.type=0 + ccu_data_ind.ab[2]= + ab->ab_type=2 + ab->rxlev=0 + ab->acc_delay=152 + ab->data=0000 + ab->u.type_2.abi=3 + ab->u.type_2.type=0 + ccu_data_ind.ab[3]= + ab->ab_type=2 + ab->rxlev=0 + ab->acc_delay=244 + ab->data=0000 + ab->u.type_2.abi=3 + ab->u.type_2.type=0 + +==> er_gprs_trau_frame_encode_64k_FT_SYNC_test + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 1 1 1 1 0 0 0 + 1 1 0 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 1 1 0 1 0 0 1 0 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (CS1) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 0 0 1 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 1 0 1 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 1 1 0 1 0 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 1 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 1 0 1 + 0 1 0 0 0 0 1 0 + 0 0 1 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 1 1 1 1 0 0 0 0 + 1 0 0 0 1 1 0 0 + 0 1 0 0 0 1 1 1 + 0 1 1 0 0 0 0 0 + 0 0 0 0 1 1 1 0 + 1 0 0 0 0 1 1 0 + 1 0 0 0 0 0 0 1 + 1 0 0 0 1 0 1 0 + 0 0 0 0 0 0 1 0 + 1 1 1 1 1 0 1 0 + 1 1 1 1 0 1 1 0 + 0 1 0 1 0 1 1 1 + 0 0 0 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (CS2) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 0 1 0 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 1 + 0 0 0 0 1 0 0 1 + 0 1 1 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 1 1 0 0 1 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 1 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 1 0 1 + 0 1 0 0 0 0 1 0 + 0 0 1 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 1 1 1 1 0 0 0 0 + 1 0 0 0 1 1 0 0 + 0 1 0 0 0 1 1 1 + 0 1 1 0 0 0 0 0 + 0 0 0 0 1 1 1 0 + 1 0 0 0 0 1 1 0 + 1 0 0 0 0 0 0 1 + 1 0 0 0 1 0 1 0 + 0 0 0 0 0 0 1 0 + 1 1 1 1 1 0 0 1 + 1 0 1 1 1 0 0 0 + 0 1 0 1 0 1 0 0 + 0 0 0 1 1 0 1 1 + 1 0 1 1 0 1 1 0 + 1 0 1 1 0 1 1 1 + 0 1 1 1 0 1 0 1 + 0 1 0 1 1 1 0 1 + 0 1 0 0 1 1 0 1 + 0 1 0 0 1 1 0 1 + 0 1 0 0 0 0 0 0 + 0 0 0 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (CS3) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 0 1 1 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 1 1 0 1 1 + 0 0 0 0 0 1 0 1 + 0 0 0 1 0 1 0 0 + 0 0 1 0 1 1 0 0 + 0 0 0 0 0 1 1 1 + 0 0 0 0 1 1 0 0 + 0 1 0 0 0 1 0 0 + 0 1 1 0 1 1 1 1 + 1 0 0 0 0 1 0 0 + 1 1 1 0 1 0 0 1 + 1 0 0 1 1 1 1 1 + 1 1 0 0 1 1 1 1 + 1 1 0 0 1 0 0 0 + 1 0 0 0 1 1 0 0 + 0 0 1 0 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 0 0 0 0 1 1 0 1 + 0 1 0 0 0 1 1 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 1 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 1 1 0 0 0 1 + 0 1 0 1 0 0 0 0 + 0 0 0 0 1 0 1 0 + 0 0 0 0 1 1 1 0 + 0 1 0 0 0 1 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 1 1 0 0 0 + 0 1 0 0 0 0 0 0 + 1 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (CS4) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 0 0 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 1 1 0 0 1 + 0 0 0 0 0 1 0 1 + 0 0 0 1 0 1 0 0 + 0 0 1 0 1 1 0 0 + 0 0 0 0 0 1 1 1 + 0 0 0 0 1 1 0 0 + 0 1 0 0 0 1 0 0 + 0 1 1 0 1 1 1 1 + 1 0 0 0 0 1 0 0 + 1 1 1 0 1 0 0 1 + 1 0 0 1 1 1 1 1 + 1 1 0 0 1 1 1 1 + 1 1 0 0 1 0 0 0 + 1 0 0 0 1 1 0 0 + 0 0 1 0 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 0 0 0 0 1 1 0 1 + 0 1 0 0 0 1 1 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 1 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 1 1 0 0 0 1 + 0 1 0 1 0 0 0 0 + 0 0 0 0 1 0 1 0 + 0 0 0 0 1 1 1 0 + 0 1 0 0 0 1 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 1 1 0 0 0 + 0 1 0 0 0 0 0 0 + 1 0 0 0 0 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 1 0 0 0 + 0 0 0 1 0 1 1 0 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 1 + 0 0 0 0 1 1 0 0 + 0 0 0 1 0 1 1 0 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 0 0 0 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS1) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 1 1 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 1 1 0 0 0 + 0 0 0 0 0 0 0 1 + 1 0 0 0 0 0 1 1 + 0 1 0 0 0 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 1 1 0 + 1 1 1 1 1 0 1 0 + 1 1 0 0 0 1 0 1 + 0 0 0 0 0 0 0 0 + 0 1 1 1 1 0 1 1 + 0 1 0 0 0 1 0 1 + 0 0 0 0 0 0 0 0 + 0 1 1 1 1 1 0 0 + 0 1 1 0 1 0 0 0 + 1 1 0 0 1 1 0 0 + 0 1 0 1 1 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS2) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 1 1 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 1 0 0 + 1 0 0 0 0 1 1 0 + 1 1 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 1 + 1 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 1 0 0 0 0 0 1 1 + 0 1 0 0 1 0 1 1 + 1 1 0 1 0 1 0 0 + 1 1 0 1 1 1 1 0 + 0 0 0 1 0 1 1 0 + 1 1 1 1 1 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 1 1 + 0 1 0 0 0 1 0 0 + 0 0 0 0 0 0 0 1 + 0 1 1 1 1 0 1 0 + 1 1 0 0 0 1 0 1 + 0 0 0 0 0 1 1 1 + 1 1 0 1 1 0 0 1 + 1 0 1 0 1 0 0 0 + 0 0 1 1 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS3) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 1 1 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 0 0 0 0 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 1 1 0 + 0 0 0 0 0 0 0 1 + 0 1 1 0 0 1 1 1 + 1 1 1 1 1 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 1 1 1 0 1 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 1 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 0 1 0 + 1 0 1 0 0 0 0 1 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 1 1 1 1 0 0 0 + 0 1 0 0 0 1 1 0 + 0 0 1 0 0 0 1 1 + 1 0 1 1 0 0 0 0 + 0 0 0 0 0 1 1 1 + 0 1 0 0 0 0 1 1 + 0 1 0 0 0 0 0 0 + 1 1 0 0 0 1 0 1 + 0 0 0 0 0 0 0 1 + 0 1 1 1 1 1 1 0 + 1 0 1 1 1 1 1 1 + 0 1 1 0 0 1 1 1 + 0 0 1 0 1 0 1 0 + 1 0 1 0 1 0 1 1 + 1 1 0 1 0 0 0 0 + 1 1 0 1 0 1 1 1 + 1 1 1 1 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS4) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 1 1 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 0 1 0 + 0 0 0 0 0 0 0 1 + 0 1 1 0 0 1 1 1 + 1 1 1 1 1 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 1 1 1 0 1 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 1 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 0 1 0 + 1 0 1 0 0 0 0 1 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 1 1 1 1 0 0 0 + 0 1 0 0 0 1 1 0 + 0 0 1 0 0 0 1 1 + 1 0 1 1 0 0 0 0 + 0 0 0 0 0 1 1 1 + 0 1 0 0 0 0 1 1 + 0 1 0 0 0 0 0 0 + 1 1 0 0 0 1 0 1 + 0 0 0 0 0 0 0 1 + 0 1 1 1 1 0 1 1 + 1 1 1 1 1 0 0 0 + 0 1 1 1 1 1 1 0 + 1 1 0 1 1 0 0 1 + 1 1 1 0 0 0 1 1 + 0 1 1 0 1 1 1 0 + 0 1 1 1 0 0 0 1 + 1 0 1 1 1 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 0 + 1 0 1 0 0 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS5) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 1 0 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 + 0 0 0 0 0 0 0 1 + 0 0 0 1 0 1 1 0 + 0 0 0 1 1 1 0 0 + 1 0 1 1 1 1 1 1 + 1 1 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 1 1 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 1 1 1 1 0 + 0 0 0 0 1 1 0 0 + 1 1 0 0 0 1 0 0 + 1 1 1 1 0 0 0 0 + 1 0 1 1 0 1 1 1 + 1 1 1 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 1 1 0 1 0 + 0 0 1 0 0 0 0 0 + 0 0 0 0 1 0 1 1 + 1 1 0 1 0 1 1 0 + 0 0 1 0 1 0 0 0 + 0 0 1 1 1 1 1 0 + 1 1 0 0 1 1 0 1 + 0 1 0 0 0 0 0 1 + 1 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 + 0 0 0 1 0 1 0 0 + 0 0 1 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 1 1 1 0 0 0 + 0 0 0 0 0 0 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 1 + 0 0 1 1 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 1 0 1 0 + 0 0 0 1 0 0 0 0 + 0 0 1 1 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 1 0 0 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 1 + 0 0 1 0 1 0 0 0 + 0 0 1 0 0 1 0 0 + 0 1 0 1 1 1 0 1 + 1 1 0 1 0 0 1 1 + 0 0 1 1 0 1 0 1 + 0 0 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS6) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 1 0 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 1 1 0 1 0 0 + 0 1 1 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 1 1 0 0 1 0 0 + 0 0 0 1 0 1 0 0 + 0 1 0 1 0 0 0 0 + 1 0 1 1 0 0 0 0 + 0 0 0 1 1 1 0 0 + 0 0 1 1 0 0 0 1 + 0 0 0 1 0 0 0 1 + 1 0 1 1 1 1 1 0 + 0 0 0 1 0 0 1 1 + 1 0 1 0 0 1 1 0 + 0 1 1 1 1 1 1 1 + 0 0 1 1 1 1 1 1 + 0 0 1 0 0 0 1 0 + 0 0 1 1 0 0 0 0 + 1 0 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 1 1 0 1 0 1 + 0 0 0 1 1 0 0 0 + 0 0 1 0 0 0 0 0 + 0 0 1 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 1 1 0 0 0 1 0 1 + 0 1 0 0 0 0 0 0 + 0 0 1 0 1 0 0 0 + 0 0 1 1 1 0 0 1 + 0 0 0 1 0 0 0 1 + 0 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 1 0 0 0 0 1 + 0 0 0 0 0 0 1 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 0 0 1 0 0 0 0 0 + 0 1 0 1 1 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 1 1 0 0 0 0 + 0 1 0 1 1 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 1 1 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 1 1 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 0 0 + 0 0 1 1 1 1 1 0 + 0 0 0 0 1 1 0 0 + 1 1 0 0 0 1 0 0 + 1 1 1 1 0 0 0 0 + 1 0 1 1 0 1 1 1 + 1 1 1 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS7) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 0 1 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 0 0 0 + 0 1 0 1 1 0 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 1 1 1 0 + 0 1 0 0 0 0 0 1 + 0 1 0 0 0 1 0 1 + 0 0 0 0 1 0 1 1 + 0 0 0 0 0 0 0 1 + 1 1 0 0 0 0 1 1 + 0 0 0 1 0 0 0 1 + 0 0 0 1 1 0 1 1 + 1 1 1 0 0 0 0 1 + 0 0 1 1 1 0 1 0 + 0 1 1 0 0 1 1 1 + 1 1 1 1 0 0 1 1 + 1 1 1 1 0 0 1 0 + 0 0 1 0 0 0 1 1 + 0 0 0 0 1 0 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 1 1 + 0 1 0 1 0 0 0 1 + 1 0 0 0 0 0 1 0 + 0 0 0 0 0 0 1 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 1 1 0 0 + 0 1 0 1 0 1 0 0 + 0 0 0 0 0 0 1 0 + 1 0 0 0 0 0 1 1 + 1 0 0 1 0 0 0 1 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 1 0 + 0 0 0 1 0 0 0 0 + 0 0 1 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 1 0 + 0 0 0 0 0 1 0 1 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 1 1 + 0 0 0 0 0 1 0 1 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 1 1 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 1 1 0 0 0 + 0 1 1 1 0 0 1 0 + 1 1 1 1 1 1 1 1 + 0 0 0 1 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 1 0 0 0 0 + 0 0 1 0 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 1 0 0 0 0 + 0 0 0 1 0 0 0 0 + 1 1 1 1 1 0 0 0 + 0 0 1 1 0 0 1 1 + 0 0 0 1 0 0 1 1 + 1 1 0 0 0 0 1 0 + 1 1 0 1 1 1 1 1 + 1 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 1 1 0 1 0 0 0 + 1 0 0 0 0 0 0 0 + 0 0 1 0 1 1 1 1 + 0 1 0 1 1 0 0 0 + 1 0 1 0 0 0 0 0 + 1 1 1 1 1 0 1 1 + 0 0 1 1 0 1 0 1 + 0 0 0 0 0 1 1 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 1 0 1 0 0 0 0 + 1 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 1 1 1 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 1 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 1 0 0 0 + 0 1 0 0 0 0 0 0 + 1 1 1 0 0 0 0 0 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 + 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 1 0 1 0 0 0 0 0 + 1 0 0 1 0 0 0 1 + 0 1 1 1 0 1 1 1 + 0 1 0 0 1 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS8) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 1 0 1 1 0 0 + 1 1 1 0 1 0 0 1 + 0 0 0 0 0 0 0 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 0 0 1 + 1 0 1 0 1 0 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 1 1 1 0 + 0 1 0 0 0 0 0 1 + 0 1 0 0 0 1 0 1 + 0 0 0 0 1 0 1 1 + 0 0 0 0 0 0 0 1 + 1 1 0 0 0 0 1 1 + 0 0 0 1 0 0 0 1 + 0 0 0 1 1 0 1 1 + 1 1 1 0 0 0 0 1 + 0 0 1 1 1 0 1 0 + 0 1 1 0 0 1 1 1 + 1 1 1 1 0 0 1 1 + 1 1 1 1 0 0 1 0 + 0 0 1 0 0 0 1 1 + 0 0 0 0 1 0 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 1 1 + 0 1 0 1 0 0 0 1 + 1 0 0 0 0 0 1 0 + 0 0 0 0 0 0 1 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 1 1 0 0 + 0 1 0 1 0 1 0 0 + 0 0 0 0 0 0 1 0 + 1 0 0 0 0 0 1 1 + 1 0 0 1 0 0 0 1 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 1 0 + 0 0 0 1 0 0 0 0 + 0 0 1 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 1 0 + 0 0 0 0 0 1 0 1 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 1 1 + 0 0 0 0 0 1 0 1 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 1 1 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 1 1 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 1 1 + 1 1 1 0 0 0 0 0 + 1 1 0 0 1 1 0 0 + 0 1 0 0 0 0 0 0 + 0 1 1 1 0 0 1 0 + 1 1 1 1 1 1 1 1 + 0 0 0 1 0 0 1 1 + 1 1 0 0 0 0 1 0 + 1 1 0 1 1 1 1 1 + 1 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 1 1 0 1 0 0 0 + 1 0 0 0 0 0 0 0 + 0 0 1 0 1 1 1 1 + 0 1 0 1 1 0 0 0 + 1 0 1 0 0 0 0 0 + 1 1 1 1 1 0 1 1 + 0 0 1 1 0 1 0 1 + 0 0 0 0 0 1 1 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 1 0 1 0 0 0 0 + 1 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 1 1 1 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 1 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 1 0 0 0 + 0 1 0 0 0 0 0 0 + 1 1 1 0 0 0 0 0 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 + 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 1 0 1 0 0 0 0 0 + 1 0 0 1 0 0 0 1 + 0 1 1 1 0 1 1 1 + 0 1 0 0 1 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_encode_64k_FT_DATA_test (MCS9) + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 1 1 1 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 + 0 0 0 0 1 0 1 0 + 0 0 0 1 1 0 1 0 + 0 0 0 1 0 0 0 0 + 1 1 0 0 1 1 1 1 + 1 1 1 0 0 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 1 1 1 0 + 0 1 0 0 0 0 0 1 + 0 1 0 0 0 1 0 1 + 0 0 0 0 1 0 1 1 + 0 0 0 0 0 0 0 1 + 1 1 0 0 0 0 1 1 + 0 0 0 1 0 0 0 1 + 0 0 0 1 1 0 1 1 + 1 1 1 0 0 0 0 1 + 0 0 1 1 1 0 1 0 + 0 1 1 0 0 1 1 1 + 1 1 1 1 0 0 1 1 + 1 1 1 1 0 0 1 0 + 0 0 1 0 0 0 1 1 + 0 0 0 0 1 0 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 1 1 + 0 1 0 1 0 0 0 1 + 1 0 0 0 0 0 1 0 + 0 0 0 0 0 0 1 0 + 0 0 0 1 0 0 0 0 + 0 0 0 0 1 1 0 0 + 0 1 0 1 0 1 0 0 + 0 0 0 0 0 0 1 0 + 1 0 0 0 0 0 1 1 + 1 0 0 1 0 0 0 1 + 0 0 0 1 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 0 0 0 0 1 1 0 + 0 0 0 1 0 0 0 0 + 0 0 1 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 1 0 + 0 0 0 0 0 1 0 1 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 1 1 + 0 0 0 0 0 1 0 1 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 1 1 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 + 1 1 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 1 0 0 0 0 1 1 + 1 1 1 0 0 0 0 0 + 1 1 0 0 1 1 0 0 + 0 1 0 0 1 1 1 1 + 0 0 0 0 1 0 1 1 + 0 1 1 1 1 1 1 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 1 1 0 0 0 1 0 + 1 1 1 1 1 1 1 1 + 0 1 1 0 1 0 0 0 + 1 0 0 0 0 0 0 0 + 0 0 1 0 1 1 1 1 + 0 1 0 1 1 0 0 0 + 1 0 1 0 0 0 0 0 + 1 1 1 1 1 0 1 1 + 0 0 1 1 0 1 0 1 + 0 0 0 0 0 1 1 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 1 0 0 0 0 0 0 0 + 0 1 0 1 0 0 0 0 + 1 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 1 1 1 0 0 0 0 0 + 0 0 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 1 1 0 0 0 0 0 0 + 0 1 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 1 0 1 0 0 0 + 0 1 0 0 0 0 0 0 + 1 1 1 0 0 0 0 0 + 0 0 0 0 0 0 0 1 + 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 + 0 1 0 0 1 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 1 0 1 0 0 0 0 0 + 1 0 0 1 0 0 0 1 + 0 1 1 1 0 1 1 1 + 0 1 0 0 1 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 0 1 0 1 0 0 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + +==> er_gprs_trau_frame_decode_64k_FT_SYNC_test (not yet synced) + ccu_sync_ind.tav=00 + ccu_sync_ind.dfe=00 + ccu_sync_ind.dbe=00 + ccu_sync_ind.pseq=4194303 + ccu_sync_ind.afn_ul=1372265 + ccu_sync_ind.afn_dl=1372258 + +==> er_gprs_trau_frame_decode_64k_FT_SYNC_test (synced) + ccu_sync_ind.tav=00 + ccu_sync_ind.dfe=01 + ccu_sync_ind.dbe=00 + ccu_sync_ind.pseq=388 + ccu_sync_ind.afn_ul=601006 + ccu_sync_ind.afn_dl=600998 + +==> er_gprs_trau_frame_decode_64k_FT_DATA_test (CS1) + ccu_data_ind.tav=00 + ccu_data_ind.dbe=0 + ccu_data_ind.cs_hdr=1 + ccu_data_ind.gprs.rx_lev=0 + ccu_data_ind.gprs.est_acc_del_dev=3 + ccu_data_ind.u.gprs.block_qual=7 + ccu_data_ind.u.gprs.parity_ok=0 + ccu_data_ind.u.data_len=23 + ccu_data_ind.data=dd9517653ed6b1367eb0e69e3b9df90356d9c6781c02e6 + +==> er_gprs_trau_frame_decode_64k_FT_DATA_test (CS2) + ccu_data_ind.tav=01 + ccu_data_ind.dbe=0 + ccu_data_ind.cs_hdr=2 + ccu_data_ind.gprs.rx_lev=0 + ccu_data_ind.gprs.est_acc_del_dev=0 + ccu_data_ind.u.gprs.block_qual=5 + ccu_data_ind.u.gprs.parity_ok=0 + ccu_data_ind.u.data_len=34 + ccu_data_ind.data=f3de176a2008cd15a8cb074cb692a1122461e3c470f8bff8e5a6638bcb2bb903653f + +==> er_gprs_trau_frame_decode_64k_FT_DATA_test (AB) + ccu_data_ind.tav=01 + ccu_data_ind.dbe=0 + ccu_data_ind.cs_hdr=0 + ccu_data_ind.gprs.rx_lev=63 + ccu_data_ind.gprs.est_acc_del_dev=0 + ccu_data_ind.u.gprs.block_qual=7 + ccu_data_ind.u.gprs.parity_ok=0 + ccu_data_ind.u.data_len=32 + ccu_data_ind.data=6000ff3f3f081f006000ff3f3f5c1f006000ff3f3fc81f006000ff3f3fdc1f00 + ccu_data_ind.ab[0]= + ab->ab_type=2 + ab->rxlev=0 + ab->acc_delay=8 + ab->data=0000 + ab->u.type_2.abi=3 + ab->u.type_2.type=0 + ccu_data_ind.ab[1]= + ab->ab_type=2 + ab->rxlev=0 + ab->acc_delay=92 + ab->data=0000 + ab->u.type_2.abi=3 + ab->u.type_2.type=0 + ccu_data_ind.ab[2]= + ab->ab_type=2 + ab->rxlev=0 + ab->acc_delay=200 + ab->data=0000 + ab->u.type_2.abi=3 + ab->u.type_2.type=0 + ccu_data_ind.ab[3]= + ab->ab_type=2 + ab->rxlev=0 + ab->acc_delay=220 + ab->data=0000 + ab->u.type_2.abi=3 + ab->u.type_2.type=0 |