From b8d33d90f73a1890287ab8c6947114acc3459235 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Sun, 2 Oct 2016 18:54:46 +0200 Subject: Control channels decoding with libosmocore --- lib/decoding/cch.c | 558 -------------------------- lib/decoding/cch.h | 63 --- lib/decoding/control_channels_decoder_impl.cc | 28 +- lib/decoding/control_channels_decoder_impl.h | 3 - lib/decoding/fire_crc.c | 163 -------- lib/decoding/fire_crc.h | 30 -- lib/decoding/interleave.c | 75 ---- lib/decoding/interleave.h | 32 -- 8 files changed, 14 insertions(+), 938 deletions(-) delete mode 100644 lib/decoding/cch.c delete mode 100644 lib/decoding/cch.h delete mode 100644 lib/decoding/fire_crc.c delete mode 100644 lib/decoding/fire_crc.h delete mode 100644 lib/decoding/interleave.c delete mode 100644 lib/decoding/interleave.h (limited to 'lib/decoding') diff --git a/lib/decoding/cch.c b/lib/decoding/cch.c deleted file mode 100644 index df83d3e..0000000 --- a/lib/decoding/cch.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - The Hacker's Choice - http://www.thc.org - Part of THC's GSM SCANNER PROJECT -*/ - -//#include "system.h" -#include -#include -#include -#include -#include - -//#include -//#include -#include -//#include "burst_types.h" -#include "cch.h" -#include "fire_crc.h" - - -/* - * GSM SACCH -- Slow Associated Control Channel - * - * These messages are encoded exactly the same as on the BCCH. - * (Broadcast Control Channel.) - * - * Input: 184 bits - * - * 1. Add parity and flushing bits. (Output 184 + 40 + 4 = 228 bit) - * 2. Convolutional encode. (Output 228 * 2 = 456 bit) - * 3. Interleave. (Output 456 bit) - * 4. Map on bursts. (4 x 156 bit bursts with each 2x57 bit content data) - */ - - -/* - * Parity (FIRE) for the GSM SACCH channel. - * - * g(x) = (x^23 + 1)(x^17 + x^3 + 1) - * = x^40 + x^26 + x^23 + x^17 + x^3 + 1 - */ - -static const unsigned char parity_polynomial[PARITY_SIZE + 1] = { - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, - 1 -}; - -// remainder after dividing data polynomial by g(x) -static const unsigned char parity_remainder[PARITY_SIZE] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 -}; - - -/* -static void parity_encode(unsigned char *d, unsigned char *p) { - - int i; - unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q; - - memcpy(buf, d, DATA_BLOCK_SIZE); - memset(buf + DATA_BLOCK_SIZE, 0, PARITY_SIZE); - - for(q = buf; q < buf + DATA_BLOCK_SIZE; q++) - if(*q) - for(i = 0; i < PARITY_SIZE + 1; i++) - q[i] ^= parity_polynomial[i]; - for(i = 0; i < PARITY_SIZE; i++) - p[i] = !buf[DATA_BLOCK_SIZE + i]; -} - */ - - -int parity_check(unsigned char *d) { - - unsigned int i; - unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q; - - memcpy(buf, d, DATA_BLOCK_SIZE + PARITY_SIZE); - - for(q = buf; q < buf + DATA_BLOCK_SIZE; q++) - if(*q) - for(i = 0; i < PARITY_SIZE + 1; i++) - q[i] ^= parity_polynomial[i]; - return memcmp(buf + DATA_BLOCK_SIZE, parity_remainder, PARITY_SIZE); -} - - -/* - * Convolutional encoding and Viterbi decoding for the GSM SACCH channel. - */ - -/* - * Convolutional encoding: - * - * G_0 = 1 + x^3 + x^4 - * G_1 = 1 + x + x^3 + x^4 - * - * i.e., - * - * c_{2k} = u_k + u_{k - 3} + u_{k - 4} - * c_{2k + 1} = u_k + u_{k - 1} + u_{k - 3} + u_{k - 4} - */ -#define K 5 -#define MAX_ERROR (2 * CONV_INPUT_SIZE + 1) - - -/* - * Given the current state and input bit, what are the output bits? - * - * encode[current_state][input_bit] - */ -static const unsigned int encode[1 << (K - 1)][2] = { - {0, 3}, {3, 0}, {3, 0}, {0, 3}, - {0, 3}, {3, 0}, {3, 0}, {0, 3}, - {1, 2}, {2, 1}, {2, 1}, {1, 2}, - {1, 2}, {2, 1}, {2, 1}, {1, 2} -}; - - -/* - * Given the current state and input bit, what is the next state? - * - * next_state[current_state][input_bit] - */ -static const unsigned int next_state[1 << (K - 1)][2] = { - {0, 8}, {0, 8}, {1, 9}, {1, 9}, - {2, 10}, {2, 10}, {3, 11}, {3, 11}, - {4, 12}, {4, 12}, {5, 13}, {5, 13}, - {6, 14}, {6, 14}, {7, 15}, {7, 15} -}; - - -/* - * Given the previous state and the current state, what input bit caused - * the transition? If it is impossible to transition between the two - * states, the value is 2. - * - * prev_next_state[previous_state][current_state] - */ -static const unsigned int prev_next_state[1 << (K - 1)][1 << (K - 1)] = { - { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2}, - { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2}, - { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2}, - { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2}, - { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2}, - { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2}, - { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2}, - { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2}, - { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2}, - { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2}, - { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2}, - { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2}, - { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2}, - { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2}, - { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1}, - { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1} -}; - - -static inline unsigned int hamming_distance2(unsigned int w) { - - return (w & 1) + !!(w & 2); -} - - -/* -static void conv_encode(unsigned char *data, unsigned char *output) { - - unsigned int i, state = 0, o; - - // encode data - for(i = 0; i < CONV_INPUT_SIZE; i++) { - o = encode[state][data[i]]; - state = next_state[state][data[i]]; - *output++ = !!(o & 2); - *output++ = o & 1; - } -} - */ - - -int conv_decode(unsigned char *output, unsigned char *data) { - - int i, t; - unsigned int rdata, state, nstate, b, o, distance, accumulated_error, - min_state, min_error, cur_state; - - unsigned int ae[1 << (K - 1)]; // accumulated error - unsigned int nae[1 << (K - 1)]; // next accumulated error - unsigned int state_history[1 << (K - 1)][CONV_INPUT_SIZE + 1]; - - // initialize accumulated error, assume starting state is 0 - for(i = 0; i < (1 << (K - 1)); i++){ - ae[i] = nae[i] = MAX_ERROR; - } - - ae[0] = 0; - - // build trellis - for(t = 0; t < CONV_INPUT_SIZE; t++) { - - // get received data symbol - rdata = (data[2 * t] << 1) | data[2 * t + 1]; - - // for each state - for(state = 0; state < (1 << (K - 1)); state++) { - - // make sure this state is possible - if(ae[state] >= MAX_ERROR) - continue; - - // find all states we lead to - for(b = 0; b < 2; b++) { - - // get next state given input bit b - nstate = next_state[state][b]; - - // find output for this transition - o = encode[state][b]; - - // calculate distance from received data - distance = hamming_distance2(rdata ^ o); - - // choose surviving path - accumulated_error = ae[state] + distance; - if(accumulated_error < nae[nstate]) { - - // save error for surviving state - nae[nstate] = accumulated_error; - - // update state history - state_history[nstate][t + 1] = state; - } - } - } - - // get accumulated error ready for next time slice - for(i = 0; i < (1 << (K - 1)); i++) { - ae[i] = nae[i]; - nae[i] = MAX_ERROR; - } - } - - // the final state is the state with the fewest errors - min_state = (unsigned int)-1; - min_error = MAX_ERROR; - for(i = 0; i < (1 << (K - 1)); i++) { - if(ae[i] < min_error) { - min_state = i; - min_error = ae[i]; - } - } - - // trace the path - cur_state = min_state; - for(t = CONV_INPUT_SIZE; t >= 1; t--) { - min_state = cur_state; - cur_state = state_history[cur_state][t]; // get previous - output[t - 1] = prev_next_state[cur_state][min_state]; - } - - // return the number of errors detected (hard-decision) - return min_error; -} - - -/* - * GSM SACCH interleaving and burst mapping - * - * Interleaving: - * - * Given 456 coded input bits, form 4 blocks of 114 bits: - * - * i(B, j) = c(n, k) k = 0, ..., 455 - * n = 0, ..., N, N + 1, ... - * B = B_0 + 4n + (k mod 4) - * j = 2(49k mod 57) + ((k mod 8) div 4) - * - * Mapping on Burst: - * - * e(B, j) = i(B, j) - * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56 - * e(B, 57) = h_l(B) - * e(B, 58) = h_n(B) - * - * Where h_l(B) and h_n(B) are bits in burst B indicating flags. - */ - -/* -static void interleave(unsigned char *data, unsigned char *iBLOCK) { - - int j, k, B; - - // for each bit in input data - for(k = 0; k < CONV_SIZE; k++) { - B = k % 4; - j = 2 * ((49 * k) % 57) + ((k % 8) / 4); - iBLOCK[B * iBLOCK_SIZE + j] = data[k]; - } -} - */ - - -#if 0 -static void decode_interleave(unsigned char *data, unsigned char *iBLOCK) { - - int j, k, B; - - for(k = 0; k < CONV_SIZE; k++) { - B = k % 4; - j = 2 * ((49 * k) % 57) + ((k % 8) / 4); - data[k] = iBLOCK[B * iBLOCK_SIZE + j]; - } -} - -#endif - -/* -static void burstmap(unsigned char *iBLOCK, unsigned char *eBLOCK, - unsigned char hl, unsigned char hn) { - - int j; - - for(j = 0; j < 57; j++) { - eBLOCK[j] = iBLOCK[j]; - eBLOCK[j + 59] = iBLOCK[j + 57]; - } - eBLOCK[57] = hl; - eBLOCK[58] = hn; -} - */ - - -static void decode_burstmap(unsigned char *iBLOCK, unsigned char *eBLOCK, - unsigned char *hl, unsigned char *hn) { - - int j; - - for(j = 0; j < 57; j++) { - iBLOCK[j] = eBLOCK[j]; - iBLOCK[j + 57] = eBLOCK[j + 59]; - } - *hl = eBLOCK[57]; - *hn = eBLOCK[58]; -} - - -/* - * Transmitted bits are sent least-significant first. - */ -static int compress_bits(unsigned char *dbuf, unsigned int dbuf_len, - unsigned char *sbuf, unsigned int sbuf_len) { - - unsigned int i, j, c, pos = 0; - - if(dbuf_len < ((sbuf_len + 7) >> 3)) - return -1; - - for(i = 0; i < sbuf_len; i += 8) { - for(j = 0, c = 0; (j < 8) && (i + j < sbuf_len); j++) - c |= (!!sbuf[i + j]) << j; - dbuf[pos++] = c & 0xff; - } - return pos; -} - - -#if 0 -int get_ns_l3_len(unsigned char *data, unsigned int datalen) { - - if((data[0] & 3) != 1) { - fprintf(stderr, "error: get_ns_l3_len: pseudo-length reserved " - "bits bad (%2.2x)\n", data[0] & 3); - return -1; - } - return (data[0] >> 2); -} - -#endif - - -/*static unsigned char *decode_sacch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen) {*/ - -/* int errors, len, data_size;*/ -/* unsigned char conv_data[CONV_SIZE], iBLOCK[BLOCKS][iBLOCK_SIZE],*/ -/* hl, hn, decoded_data[PARITY_OUTPUT_SIZE];*/ -/* FC_CTX fc_ctx;*/ - -/* data_size = sizeof ctx->msg;*/ -/* if(datalen)*/ -/* *datalen = 0;*/ - -/* // unmap the bursts*/ -/* decode_burstmap(iBLOCK[0], burst, &hl, &hn); // XXX ignore stealing bits*/ -/* decode_burstmap(iBLOCK[1], burst + 116, &hl, &hn);*/ -/* decode_burstmap(iBLOCK[2], burst + 116 * 2, &hl, &hn);*/ -/* decode_burstmap(iBLOCK[3], burst + 116 * 3, &hl, &hn);*/ - -/* // remove interleave*/ -/* interleave_decode(&ctx->interleave_ctx, conv_data, (unsigned char *)iBLOCK);*/ -/* //decode_interleave(conv_data, (unsigned char *)iBLOCK);*/ - -/* // Viterbi decode*/ -/* errors = conv_decode(decoded_data, conv_data);*/ -/* //DEBUGF("conv_decode: %d\n", errors);*/ - -/* // check parity*/ -/* // If parity check error detected try to fix it.*/ -/* if (parity_check(decoded_data))*/ -/* {*/ -/* unsigned char crc_result[224];*/ -/* if (FC_check_crc(&fc_ctx, decoded_data, crc_result) == 0)*/ -/* {*/ -/* errors = -1;*/ -/* //DEBUGF("error: sacch: parity error (%d fn=%d)\n",*/ -/* // errors, ctx->fn);*/ -/* return NULL;*/ -/* } else {*/ -/* //DEBUGF("Successfully corrected parity bits! (errors=%d fn=%d)\n",*/ -/* // errors, ctx->fn);*/ -/* memcpy(decoded_data, crc_result, sizeof crc_result);*/ -/* errors = 0;*/ -/* }*/ -/* }*/ - -/* if (errors)*/ -/* printf("WRN: errors=%d fn=%d\n", errors, ctx->fn);*/ - -/* if((len = compress_bits(ctx->msg, data_size, decoded_data,*/ -/* DATA_BLOCK_SIZE)) < 0) {*/ -/* fprintf(stderr, "error: compress_bits\n");*/ -/* return NULL;*/ -/* }*/ -/* if(len < data_size) {*/ -/* fprintf(stderr, "error: buf too small (%d < %d)\n",*/ -/* sizeof(ctx->msg), len);*/ -/* return NULL;*/ -/* }*/ - -/* if(datalen)*/ -/* *datalen = (unsigned int)len;*/ -/* return ctx->msg;*/ -/*}*/ - - -/* - * decode_cch - * - * Decode a "common" control channel. Most control channels use - * the same burst, interleave, Viterbi and parity configuration. - * The documentation for the control channels defines SACCH first - * and then just keeps referring to that. - * - * The current (investigated) list is as follows: - * - * BCCH Norm - * BCCH Ext - * PCH - * AGCH - * CBCH (SDCCH/4) - * CBCH (SDCCH/8) - * SDCCH/4 - * SACCH/C4 - * SDCCH/8 - * SACCH/C8 - * - * We provide two functions, one for where all four bursts are - * contiguous, and one where they aren't. - */ -/*unsigned char *decode_cch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen) {*/ - -/* return decode_sacch(ctx, burst, datalen);*/ -/*}*/ - - -#if 0 -unsigned char *decode_cch(GS_CTX *ctx, unsigned char *e, unsigned int *datalen) { - - return decode_sacch(ctx, e, e + eBLOCK_SIZE, e + 2 * eBLOCK_SIZE, - e + 3 * eBLOCK_SIZE, datalen); -} -#endif - -/*unsigned char *decode_facch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen, int offset) {*/ - -/* int errors, len, data_size;*/ -/* unsigned char conv_data[CONV_SIZE], iBLOCK[BLOCKS * 2][iBLOCK_SIZE],*/ -/* hl, hn, decoded_data[PARITY_OUTPUT_SIZE];*/ -/* FC_CTX fc_ctx;*/ - -/* data_size = sizeof ctx->msg;*/ -/* if(datalen)*/ -/* *datalen = 0;*/ - -/* // unmap the bursts*/ -/* decode_burstmap(iBLOCK[0], burst, &hl, &hn); // XXX ignore stealing bits*/ -/* decode_burstmap(iBLOCK[1], burst + 116, &hl, &hn);*/ -/* decode_burstmap(iBLOCK[2], burst + 116 * 2, &hl, &hn);*/ -/* decode_burstmap(iBLOCK[3], burst + 116 * 3, &hl, &hn);*/ -/* decode_burstmap(iBLOCK[4], burst + 116 * 4, &hl, &hn);*/ -/* decode_burstmap(iBLOCK[5], burst + 116 * 5, &hl, &hn);*/ -/* decode_burstmap(iBLOCK[6], burst + 116 * 6, &hl, &hn);*/ -/* decode_burstmap(iBLOCK[7], burst + 116 * 7, &hl, &hn);*/ - -/* // remove interleave*/ -/* if (offset == 0)*/ -/* interleave_decode(&ctx->interleave_facch_f1_ctx, conv_data, (unsigned char *)iBLOCK);*/ -/* else*/ -/* interleave_decode(&ctx->interleave_facch_f2_ctx, conv_data, (unsigned char *)iBLOCK);*/ -/* //decode_interleave(conv_data, (unsigned char *)iBLOCK);*/ - -/* // Viterbi decode*/ -/* errors = conv_decode(decoded_data, conv_data);*/ -/* //DEBUGF("conv_decode: %d\n", errors);*/ - -/* // check parity*/ -/* // If parity check error detected try to fix it.*/ -/* if (parity_check(decoded_data)) {*/ -/* FC_init(&fc_ctx, 40, 184);*/ -/* unsigned char crc_result[224];*/ -/* if (FC_check_crc(&fc_ctx, decoded_data, crc_result) == 0)*/ -/* {*/ -/* //DEBUGF("error: sacch: parity error (errors=%d fn=%d)\n", errors, ctx->fn);*/ -/* errors = -1;*/ -/* return NULL;*/ -/* } else {*/ -/* //DEBUGF("Successfully corrected parity bits! (errors=%d fn=%d)\n", errors, ctx->fn);*/ -/* memcpy(decoded_data, crc_result, sizeof crc_result);*/ -/* errors = 0;*/ -/* }*/ -/* }*/ - -/* if (errors)*/ -/* fprintf(stderr, "WRN: errors=%d fn=%d\n", errors, ctx->fn);*/ - -/* if ((len = compress_bits(ctx->msg, data_size, decoded_data,*/ -/* DATA_BLOCK_SIZE)) < 0) {*/ -/* fprintf(stderr, "error: compress_bits\n");*/ -/* return NULL;*/ -/* }*/ -/* if (len < data_size) {*/ -/* fprintf(stderr, "error: buf too small (%d < %d)\n",*/ -/* sizeof(ctx->msg), len);*/ -/* return NULL;*/ -/* }*/ - -/* if (datalen)*/ -/* *datalen = (unsigned int)len;*/ -/* return ctx->msg;*/ -/*}*/ diff --git a/lib/decoding/cch.h b/lib/decoding/cch.h deleted file mode 100644 index e371213..0000000 --- a/lib/decoding/cch.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - The Hacker's Choice - http://www.thc.org - Part of THC's GSM SCANNER PROJECT -*/ - -#ifndef __GSMSTACK_CCH_H__ -#define __GSMSTACK_CCH_H__ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -//#include "gsmstack.h" - -/* - * decode_cch - * - * Decode a "common" control channel. Most control channels use - * the same burst, interleave, Viterbi and parity configuration. - * The documentation for the control channels defines SACCH first - * and then just keeps referring to that. - * - * The current (investigated) list is as follows: - * - * BCCH Norm - * BCCH Ext - * PCH - * AGCH - * CBCH (SDCCH/4) - * CBCH (SDCCH/8) - * SDCCH/4 - * SACCH/C4 - * SDCCH/8 - * SACCH/C8 - * - * We provide two functions, one for where all four bursts are - * contiguous, and one where they aren't. - */ - -#define DATA_BLOCK_SIZE 184 -#define PARITY_SIZE 40 -#define FLUSH_BITS_SIZE 4 -#define PARITY_OUTPUT_SIZE (DATA_BLOCK_SIZE + PARITY_SIZE + FLUSH_BITS_SIZE) - -#define CONV_INPUT_SIZE PARITY_OUTPUT_SIZE -#define CONV_SIZE (2 * CONV_INPUT_SIZE) - -#define BLOCKS 4 -#define iBLOCK_SIZE (CONV_SIZE / BLOCKS) -#define eBLOCK_SIZE (iBLOCK_SIZE + 2) - -int conv_decode(unsigned char *output, unsigned char *data); -int parity_check(unsigned char *d); -//unsigned char *decode_cch(GS_CTX *ctx, unsigned char *burst, unsigned int *len); -//unsigned char *decode_facch(GS_CTX *ctx, unsigned char *burst, unsigned int *len, int offset); -//unsigned char *decode_cch(GS_CTX *ctx, unsigned char *, unsigned char *, unsigned char *, unsigned char *, unsigned int *len); -//unsigned char *decode_cch(GS_CTX *ctx, unsigned char *, unsigned int *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/decoding/control_channels_decoder_impl.cc b/lib/decoding/control_channels_decoder_impl.cc index ddea256..71695e2 100644 --- a/lib/decoding/control_channels_decoder_impl.cc +++ b/lib/decoding/control_channels_decoder_impl.cc @@ -82,42 +82,42 @@ namespace gr { { ubit_t bursts_u[116 * 4]; sbit_t bursts_s[116 * 4]; - uint8_t result[23]; - int n_errors, n_bits_total; - + uint8_t result[23]; + int n_errors, n_bits_total; + int8_t header_plus_data[sizeof(gsmtap_hdr)+DATA_BYTES]; + d_bursts[d_collected_bursts_num] = msg; d_collected_bursts_num++; + //get convecutive bursts - if(d_collected_bursts_num==4) { d_collected_bursts_num=0; - //reorganize data + //reorganize data from input bursts for(int ii = 0; ii < 4; ii++) { pmt::pmt_t header_plus_burst = pmt::cdr(d_bursts[ii]); int8_t * burst_bits = (int8_t *)(pmt::blob_data(header_plus_burst))+sizeof(gsmtap_hdr); - + memcpy(&bursts_u[ii*116], &burst_bits[3],58); - memcpy(&bursts_u[ii*116+58], &burst_bits[3+57+1+26],58); + memcpy(&bursts_u[ii*116+58], &burst_bits[3+57+1+26],58); } //convert to soft bits ubits2sbits(bursts_u, bursts_s, 116 * 4); //decode gsm0503_xcch_decode(result, bursts_s, &n_errors, &n_bits_total); - //send to the output + //extract header of the first burst of the four bursts pmt::pmt_t first_header_plus_burst = pmt::cdr(d_bursts[0]); gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(first_header_plus_burst); - int8_t header_plus_data[sizeof(gsmtap_hdr)+DATA_BYTES]; + //copy header and data memcpy(header_plus_data, header, sizeof(gsmtap_hdr)); - memcpy(header_plus_data+sizeof(gsmtap_hdr), result, DATA_BYTES); + //set data type in the header ((gsmtap_hdr*)header_plus_data)->type = GSMTAP_TYPE_UM; - - pmt::pmt_t msg_binary_blob = pmt::make_blob(header_plus_data,DATA_BYTES+sizeof(gsmtap_hdr)); - pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, msg_binary_blob); - + //prepare message + pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, pmt::make_blob(header_plus_data,DATA_BYTES+sizeof(gsmtap_hdr))); + //send message to the output message_port_pub(pmt::mp("msgs"), msg_out); } return; diff --git a/lib/decoding/control_channels_decoder_impl.h b/lib/decoding/control_channels_decoder_impl.h index 542335b..f2261a2 100644 --- a/lib/decoding/control_channels_decoder_impl.h +++ b/lib/decoding/control_channels_decoder_impl.h @@ -24,11 +24,8 @@ #define INCLUDED_GSM_CONTROL_CHANNELS_DECODER_IMPL_H #include -#include "fire_crc.h" -#include "cch.h" extern "C" { #include - #include } namespace gr { diff --git a/lib/decoding/fire_crc.c b/lib/decoding/fire_crc.c deleted file mode 100644 index 5800517..0000000 --- a/lib/decoding/fire_crc.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - The Hacker's Choice - http://www.thc.org - Part of THC's GSM SCANNER PROJECT -*/ - - -#include "fire_crc.h" -#include -#include - -#define REM(x, y) (x) % (y) - -static int FC_syndrome_shift(FC_CTX *ctx, unsigned int bit); - -static int -outit(int *data, int len) -{ - int i; - - for (i = 0; i < len; i++) - printf("%d ", data[i]); - printf("\n"); - return 0; -} - -int -FC_init(FC_CTX *ctx, unsigned int crc_size, unsigned int data_size) -{ - ctx->crc_size = crc_size; - ctx->data_size = data_size; - ctx->syn_start = 0; - - return 0; -} - -int -FC_check_crc(FC_CTX *ctx, unsigned char *input_bits, unsigned char *control_data) -{ - int j,error_count = 0, error_index = 0, success_flag = 0, syn_index = 0; - unsigned int i; - - ctx->syn_start = 0; - // reset the syndrome register - memset(ctx->syndrome_reg, 0, sizeof ctx->syndrome_reg); - - // shift in the data bits - for (i=0; i < ctx->data_size; i++) { - error_count = FC_syndrome_shift(ctx, input_bits[i]); - control_data[i] = input_bits[i]; - } - - // shift in the crc bits - for (i=0; i < ctx->crc_size; i++) { - error_count = FC_syndrome_shift(ctx, 1-input_bits[i+ctx->data_size]); - } - - // Find position of error burst - if (error_count == 0) { - error_index = 0; - } - else { - error_index = 1; - error_count = FC_syndrome_shift(ctx, 0); - error_index += 1; - while (error_index < (ctx->data_size + ctx->crc_size) ) { - error_count = FC_syndrome_shift(ctx, 0); - error_index += 1; - if ( error_count == 0 ) break; - } - } - - // Test for correctable errors - //printf("error_index %d\n",error_index); - if (error_index == 224) success_flag = 0; - else { - - // correct index depending on the position of the error - if (error_index == 0) syn_index = error_index; - else syn_index = error_index - 1; - - // error burst lies within data bits - if (error_index < 184) { - //printf("error < bit 184,%d\n",error_index); - j = error_index; - while ( j < (error_index+12) ) { - if (j < 184) { - control_data[j] = control_data[j] ^ - ctx->syndrome_reg[REM(ctx->syn_start+39-j+syn_index,40)]; - } - else break; - j = j + 1; - } - } - else if ( error_index > 212 ) { - //printf("error > bit 212,%d\n",error_index); - j = 0; - while ( j < (error_index - 212) ) { - control_data[j] = control_data[j] ^ - ctx->syndrome_reg[REM(ctx->syn_start+39-j-224+syn_index,40)]; - j = j + 1; - } - } - // for 183 < error_index < 213 error in parity alone so ignore - success_flag = 1; - } - return success_flag; -} - -static int -FC_syndrome_shift(FC_CTX *ctx, unsigned int bit) -{ - int error_count = 0; - unsigned int i; - - if (ctx->syn_start == 0) - ctx->syn_start = 39; - else ctx->syn_start -= 1; - - int temp_syndrome_reg[sizeof ctx->syndrome_reg]; - - memcpy(temp_syndrome_reg, ctx->syndrome_reg, sizeof temp_syndrome_reg); - - temp_syndrome_reg[REM(ctx->syn_start+3,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+3,40)] ^ - ctx->syndrome_reg[ctx->syn_start]; - temp_syndrome_reg[REM(ctx->syn_start+17,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+17,40)] ^ - ctx->syndrome_reg[ctx->syn_start]; - temp_syndrome_reg[REM(ctx->syn_start+23,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+23,40)] ^ - ctx->syndrome_reg[ctx->syn_start]; - temp_syndrome_reg[REM(ctx->syn_start+26,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+26,40)] ^ - ctx->syndrome_reg[ctx->syn_start]; - - temp_syndrome_reg[REM(ctx->syn_start+4,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+4,40)] ^ bit; - temp_syndrome_reg[REM(ctx->syn_start+6,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+6,40)] ^ bit; - temp_syndrome_reg[REM(ctx->syn_start+10,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+10,40)] ^ bit; - temp_syndrome_reg[REM(ctx->syn_start+16,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+16,40)] ^ bit; - temp_syndrome_reg[REM(ctx->syn_start+27,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+27,40)] ^ bit; - temp_syndrome_reg[REM(ctx->syn_start+29,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+29,40)] ^ bit; - temp_syndrome_reg[REM(ctx->syn_start+33,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+33,40)] ^ bit; - temp_syndrome_reg[REM(ctx->syn_start+39,40)] = - ctx->syndrome_reg[REM(ctx->syn_start+39,40)] ^ bit; - - temp_syndrome_reg[ctx->syn_start] = ctx->syndrome_reg[ctx->syn_start] ^ bit; - - memcpy(ctx->syndrome_reg, temp_syndrome_reg, sizeof ctx->syndrome_reg); - - for (i = 0; i < 28; i++) { - error_count = error_count + ctx->syndrome_reg[REM(ctx->syn_start+i,40)]; - } - return error_count; -} - - diff --git a/lib/decoding/fire_crc.h b/lib/decoding/fire_crc.h deleted file mode 100644 index d02021e..0000000 --- a/lib/decoding/fire_crc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - The Hacker's Choice - http://www.thc.org - Part of THC's GSM SCANNER PROJECT -*/ - - - -#ifndef INCLUDED_FIRE_CRC_H -#define INCLUDED_FIRE_CRC_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - unsigned int crc_size; - unsigned int data_size; - unsigned int syn_start; - int syndrome_reg[40]; -} FC_CTX; - -int FC_init(FC_CTX *ctx, unsigned int crc_size, unsigned int data_size); -int FC_check_crc(FC_CTX *ctx, unsigned char *input_bits, unsigned char *control_data); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/decoding/interleave.c b/lib/decoding/interleave.c deleted file mode 100644 index c6304db..0000000 --- a/lib/decoding/interleave.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - The Hacker's Choice - http://www.thc.org - Part of THC's GSM SCANNER PROJECT -*/ - -#include -#include -#include "interleave.h" - -int -interleave_init(INTERLEAVE_CTX *ictx, int size, int block_size) -{ - ictx->trans_size = size; - ictx->trans = (unsigned short *)malloc(size * sizeof *ictx->trans); - -// DEBUGF("size: %d\n", size); -// DEBUGF("Block size: %d\n", block_size); - int j, k, B; - for (k = 0; k < size; k++) - { - B = k % 4; - j = 2 * ((49 * k) % 57) + ((k % 8) / 4); - ictx->trans[k] = B * block_size + j; - /* Mapping: pos1 goes to pos2: pos1 -> pos2 */ - //printf("%d -> %d\n", ictx->trans[k], k); - } -// exit(0); - return 0; -} - -int -interleave_init_facch_f(INTERLEAVE_CTX *ictx, int size, int block_size, int block_offset) -{ - ictx->trans_size = size; - ictx->trans = (unsigned short *)malloc(size * sizeof *ictx->trans); - -// DEBUGF("size: %d\n", size); -// DEBUGF("Block size: %d\n", block_size); - int j, k, B; - for (k = 0; k < size; k++) - { - B = (k + block_offset) % 8; - j = 2 * ((49 * k) % 57) + ((k % 8) / 4); - ictx->trans[k] = B * block_size + j; - /* Mapping: pos1 goes to pos2: pos1 -> pos2 */ -// DEBUGF("%d -> %d\n", ictx->trans[k], k); - } -// exit(0); - return 0; -} - -int -interleave_deinit(INTERLEAVE_CTX *ictx) -{ - if (ictx->trans != NULL) - { - free(ictx->trans); - ictx->trans = NULL; - } - - return 0; -} - -void -interleave_decode(INTERLEAVE_CTX *ictx, unsigned char *dst, unsigned char *src) -{ - printf("Lol\n"); - int k; - for (k = 0; k < ictx->trans_size; k++) - { - printf("k=%d, ictx->trans[k]=%d\n", k, ictx->trans[k]); - dst[k] = src[ictx->trans[k]]; - } -} - diff --git a/lib/decoding/interleave.h b/lib/decoding/interleave.h deleted file mode 100644 index aba1dfd..0000000 --- a/lib/decoding/interleave.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - The Hacker's Choice - http://www.thc.org - Part of THC's GSM SCANNER PROJECT -*/ - -/* - * $Id:$ - */ - -#ifndef __GSMSP_INTERLEAVE_H__ -#define __GSMSP_INTERLEAVE_H__ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _interleave_ctx -{ - unsigned short *trans; - int trans_size; -} INTERLEAVE_CTX; - -int interleave_init(INTERLEAVE_CTX *ictx, int size, int block_size); -int interleave_init_facch_f(INTERLEAVE_CTX *ictx, int size, int block_size, int block_offset); -int interleave_deinit(INTERLEAVE_CTX *ictx); -void interleave_decode(INTERLEAVE_CTX *ictx, unsigned char *dst, unsigned char *src); - -#ifdef __cplusplus -} -#endif - -#endif -- cgit v1.2.3