struct msgb *parse_rawmsg(uint8_t *data, uint16_t len_msg, uint8_t **searchmsg_p) { struct msgb *msg = NULL; uint8_t *frame_p; if(*searchmsg_p && (frame_p = memmem(data, len_msg, *searchmsg_p, SEARCHLEN))) { *searchmsg_p = NULL; msg = gsmtap_makemsg(0, 0, GSMTAP_CHANNEL_SDCCH, 0, 0, 0, 0, frame_p - 3, 23); } else if((frame_p = memmem(data, len_msg, "\x25\x06\x06", 3))) { msg = gsmtap_makemsg(0, 0, guess_chantype(frame_p + 0x0d), 0, 0, 0, 0, frame_p + 0x0d, 23); } return msg; }
/* receive a message from L1/L2 and put it in GSMTAP */ int gsmtap_sendmsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type, uint8_t ss, uint32_t fn, int8_t signal_dbm, uint8_t snr, const uint8_t *data, unsigned int len) { struct msgb *msg; /* gsmtap was never initialized, so don't try to send anything */ if (gsmtap_bfd.fd == -1) return 0; msg = gsmtap_makemsg(arfcn, ts, chan_type, ss, fn, signal_dbm, snr, data, len); if (!msg) return -ENOMEM; msgb_enqueue(&gsmtap_txqueue, msg); gsmtap_bfd.when |= BSC_FD_WRITE; return 0; }
/* * 142 bit */ int GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn, int first_burst) { int bsic; int ret; unsigned char *data; int len; struct gs_ts_ctx *ts_ctx = &ctx->ts_ctx[ts]; memset(ctx->msg, 0, sizeof(ctx->msg)); if (ts_ctx->type == TST_TCHF && type == NORMAL && (fn % 26) != 12 && (fn % 26) != 25) { /* Dieter: we came here because the burst might contain FACCH bits */ ctx->fn = fn; /* get burst index to TCH bursts only */ ts_ctx->burst_count2 = fn % 26; if (ts_ctx->burst_count2 >= 12) ts_ctx->burst_count2--; ts_ctx->burst_count2 = ts_ctx->burst_count2 % 8; /* copy data bits and stealing flags to buffer */ memcpy(ts_ctx->burst2 + (116 * ts_ctx->burst_count2), src, 58); memcpy(ts_ctx->burst2 + (116 * ts_ctx->burst_count2) + 58, src + 58 + 26, 58); /* Return if not enough bursts for a full gsm message */ if ((ts_ctx->burst_count2 % 4) != 3) return 0; data = decode_facch(ctx, ts_ctx->burst2, &len, (ts_ctx->burst_count2 == 3) ? 1 : 0); if (data == NULL) { DEBUGF("cannot decode FACCH fnr=%d ts=%d\n", ctx->fn, ts); return -1; } out_gsmdecode(0, 0, ts, ctx->fn, data, len); if (ctx->gsmtap_fd >= 0) { struct msgb *msg; uint8_t chan_type = GSMTAP_CHANNEL_TCH_F; uint8_t ss = 0; int fn = (ctx->fn - 3); /* "- 3" for start of frame */ msg = gsmtap_makemsg(0, ts, chan_type, ss, ctx->fn, 0, 0, data, len); if (msg) write(ctx->gsmtap_fd, msg->data, msg->len); } return 0; } /* normal burst processing */ if (first_burst) /* Dieter: it is important to start with the correct burst */ ts_ctx->burst_count = 0; ctx->fn = fn; if (type == NORMAL) { /* Interested in these frame numbers (cch) * 2-5, 12-15, 22-25, 23-35, 42-45 * 6-9, 16-19, 26-29, 36-39, 46-49 */ /* Copy content data into new array */ //DEBUGF("burst count %d\n", ctx->burst_count); memcpy(ts_ctx->burst + (116 * ts_ctx->burst_count), src, 58); memcpy(ts_ctx->burst + (116 * ts_ctx->burst_count) + 58, src + 58 + 26, 58); ts_ctx->burst_count++; /* Return if not enough bursts for a full gsm message */ if (ts_ctx->burst_count < 4) return 0; ts_ctx->burst_count = 0; data = decode_cch(ctx, ts_ctx->burst, &len); if (data == NULL) { DEBUGF("cannot decode fnr=0x%06x (%6d) ts=%d\n", ctx->fn, ctx->fn, ts); return -1; } //DEBUGF("OK TS %d, len %d\n", ts, len); out_gsmdecode(0, 0, ts, ctx->fn, data, len); if (ctx->gsmtap_fd >= 0) { /* Dieter: set channel type according to configuration */ struct msgb *msg; uint8_t chan_type = GSMTAP_CHANNEL_BCCH; uint8_t ss = 0; int fn = (ctx->fn - 3); /* "- 3" for start of frame */ chan_type = get_chan_type(ts_ctx->type, fn, &ss); /* arfcn, ts, chan_type, ss, fn, signal, snr, data, len */ msg = gsmtap_makemsg(0, ts, chan_type, ss, ctx->fn, 0, 0, data, len); if (msg) write(ctx->gsmtap_fd, msg->data, msg->len); } #if 0 if (ctx->fn % 51 != 0) && ( (((ctx->fn % 51 + 5) % 10 == 0) || (((ctx->fn % 51) + 1) % 10 ==0) ) ) ready = 1; #endif return 0; }
struct msgb *make_gsml2_msg(uint8_t gsmtap_chan, uint8_t *msg_start, uint16_t msg_len, uint8_t **dummy) { return gsmtap_makemsg(0, 0, gsmtap_chan, 0, 0, 0, 0, msg_start, msg_len); }