From 9731f0d3222f9583b74e8c9713f3e127f5935032 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Wed, 18 Sep 2019 21:38:03 +0700 Subject: host/trxcon: add optional GSMTAP frame logging support This feature may be useful for our TTCN-3 testing infrastructure. By default it's disabled, and can be enabled using command line arguments of the main binary: ./trxcon -g 127.0.0.1 ... Change-Id: Iab4128fee5f18d816830fdca6c5ebebaf7451902 --- src/host/trxcon/sched_lchan_common.c | 41 +++++++++++++++++++-- src/host/trxcon/sched_lchan_desc.c | 69 ++++++++++++++++++++++++++++++++++++ src/host/trxcon/sched_lchan_rach.c | 8 ++++- src/host/trxcon/sched_lchan_xcch.c | 6 ++-- src/host/trxcon/sched_trx.h | 7 ++++ src/host/trxcon/trxcon.c | 27 ++++++++++++-- src/host/trxcon/trxcon.h | 1 + 7 files changed, 150 insertions(+), 9 deletions(-) (limited to 'src/host/trxcon') diff --git a/src/host/trxcon/sched_lchan_common.c b/src/host/trxcon/sched_lchan_common.c index 615d81c9..d8d9ee13 100644 --- a/src/host/trxcon/sched_lchan_common.c +++ b/src/host/trxcon/sched_lchan_common.c @@ -2,7 +2,7 @@ * OsmocomBB <-> SDR connection bridge * TDMA scheduler: common routines for lchan handlers * - * (C) 2017 by Vadim Yanitskiy + * (C) 2017-2019 by Vadim Yanitskiy * * All Rights Reserved * @@ -32,15 +32,19 @@ #include #include +#include +#include #include #include +#include #include "l1ctl_proto.h" #include "scheduler.h" #include "sched_trx.h" #include "logging.h" +#include "trxcon.h" #include "trx_if.h" #include "l1ctl.h" @@ -80,13 +84,32 @@ const uint8_t sched_nb_training_bits[8][26] = { }, }; +int sched_gsmtap_send(enum trx_lchan_type lchan_type, uint32_t fn, uint8_t tn, + uint16_t band_arfcn, int8_t signal_dbm, uint8_t snr, + const uint8_t *data, size_t data_len) +{ + const struct trx_lchan_desc *lchan_desc = &trx_lchan_desc[lchan_type]; + + /* GSMTAP logging may not be enabled */ + if (gsmtap == NULL) + return 0; + + /* Omit frames with unknown channel type */ + if (lchan_desc->gsmtap_chan_type == GSMTAP_CHANNEL_UNKNOWN) + return 0; + + /* TODO: distinguish GSMTAP_CHANNEL_PCH and GSMTAP_CHANNEL_AGCH */ + return gsmtap_send(gsmtap, band_arfcn, tn, lchan_desc->gsmtap_chan_type, + lchan_desc->ss_nr, fn, signal_dbm, snr, data, data_len); +} + int sched_send_dt_ind(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint8_t *l2, size_t l2_len, int bit_error_count, bool dec_failed, bool traffic) { const struct trx_lchan_desc *lchan_desc; struct l1ctl_info_dl dl_hdr; - int dbm_avg; + int dbm_avg = 0; /* Set up pointers */ lchan_desc = &trx_lchan_desc[lchan->type]; @@ -117,6 +140,12 @@ int sched_send_dt_ind(struct trx_instance *trx, struct trx_ts *ts, /* Put a packet to higher layers */ l1ctl_tx_dt_ind(trx->l1l, &dl_hdr, l2, l2_len, traffic); + /* Optional GSMTAP logging */ + if (l2_len > 0 && (!traffic || lchan_desc->chan_nr == RSL_CHAN_OSMO_PDCH)) { + sched_gsmtap_send(lchan->type, lchan->rx_first_fn, ts->index, + trx->band_arfcn, dbm_avg, 0, l2, l2_len); + } + return 0; } @@ -140,6 +169,14 @@ int sched_send_dt_conf(struct trx_instance *trx, struct trx_ts *ts, l1ctl_tx_dt_conf(trx->l1l, &dl_hdr, traffic); + /* Optional GSMTAP logging */ + if (!traffic || lchan_desc->chan_nr == RSL_CHAN_OSMO_PDCH) { + sched_gsmtap_send(lchan->type, fn, ts->index, + trx->band_arfcn | ARFCN_UPLINK, + 0, 0, lchan->prim->payload, + lchan->prim->payload_len); + } + return 0; } diff --git a/src/host/trxcon/sched_lchan_desc.c b/src/host/trxcon/sched_lchan_desc.c index 67f770c5..fde4d4ee 100644 --- a/src/host/trxcon/sched_lchan_desc.c +++ b/src/host/trxcon/sched_lchan_desc.c @@ -24,6 +24,8 @@ */ #include +#include + #include "sched_trx.h" /* Forward declaration of handlers */ @@ -86,6 +88,7 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_BCCH] = { .name = "BCCH", /* 3GPP TS 05.02, section 3.3.2.3 */ .desc = "Broadcast control channel", + .gsmtap_chan_type = GSMTAP_CHANNEL_BCCH, .chan_nr = RSL_CHAN_BCCH, /* Rx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4), @@ -98,6 +101,7 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_RACH] = { .name = "RACH", /* 3GPP TS 05.02, section 3.3.3.1 */ .desc = "Random access channel", + .gsmtap_chan_type = GSMTAP_CHANNEL_RACH, .chan_nr = RSL_CHAN_RACH, /* Tx only, RACH convolutional coding (3GPP TS 05.03, section 4.6). */ @@ -107,6 +111,7 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_CCCH] = { .name = "CCCH", /* 3GPP TS 05.02, section 3.3.3.1 */ .desc = "Common control channel", + .gsmtap_chan_type = GSMTAP_CHANNEL_CCCH, .chan_nr = RSL_CHAN_PCH_AGCH, /* Rx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4), @@ -119,6 +124,7 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_TCHF] = { .name = "TCH/F", /* 3GPP TS 05.02, section 3.2 */ .desc = "Full Rate traffic channel", + .gsmtap_chan_type = GSMTAP_CHANNEL_TCH_F, .chan_nr = RSL_CHAN_Bm_ACCHs, .link_id = TRX_CH_LID_DEDIC, @@ -141,8 +147,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_TCHH_0] = { .name = "TCH/H(0)", /* 3GPP TS 05.02, section 3.2 */ .desc = "Half Rate traffic channel (sub-channel 0)", + .gsmtap_chan_type = GSMTAP_CHANNEL_TCH_H, .chan_nr = RSL_CHAN_Lm_ACCHs + (0 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 0, /* Rx and Tx, multiple convolutional coding types (3GPP TS 05.03, * chapter 3), block diagonal interleaving (3GPP TS 05.02, clause 7): @@ -165,8 +173,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_TCHH_1] = { .name = "TCH/H(1)", /* 3GPP TS 05.02, section 3.2 */ .desc = "Half Rate traffic channel (sub-channel 1)", + .gsmtap_chan_type = GSMTAP_CHANNEL_TCH_H, .chan_nr = RSL_CHAN_Lm_ACCHs + (1 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 1, /* Same as for TRXC_TCHH_0, see above. */ .burst_buf_size = 6 * GSM_BURST_PL_LEN, @@ -177,8 +187,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH4_0] = { .name = "SDCCH/4(0)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 0)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH4, .chan_nr = RSL_CHAN_SDCCH4_ACCH + (0 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 0, /* Same as for TRXC_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -189,8 +201,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH4_1] = { .name = "SDCCH/4(1)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 1)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH4, .chan_nr = RSL_CHAN_SDCCH4_ACCH + (1 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 1, /* Same as for TRXC_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -201,8 +215,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH4_2] = { .name = "SDCCH/4(2)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 2)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH4, .chan_nr = RSL_CHAN_SDCCH4_ACCH + (2 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 2, /* Same as for TRXC_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -213,8 +229,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH4_3] = { .name = "SDCCH/4(3)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 3)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH4, .chan_nr = RSL_CHAN_SDCCH4_ACCH + (3 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 3, /* Same as for TRXC_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -225,8 +243,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_0] = { .name = "SDCCH/8(0)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 0)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (0 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 0, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -237,8 +257,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_1] = { .name = "SDCCH/8(1)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 1)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (1 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 1, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -249,8 +271,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_2] = { .name = "SDCCH/8(2)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 2)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (2 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 2, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -261,8 +285,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_3] = { .name = "SDCCH/8(3)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 3)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (3 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 3, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -273,8 +299,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_4] = { .name = "SDCCH/8(4)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 4)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (4 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 4, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -285,8 +313,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_5] = { .name = "SDCCH/8(5)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 5)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (5 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 5, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -297,8 +327,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_6] = { .name = "SDCCH/8(6)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 6)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (6 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 6, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -309,8 +341,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_7] = { .name = "SDCCH/8(7)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Stand-alone dedicated control channel (sub-channel 7)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (7 << 3), .link_id = TRX_CH_LID_DEDIC, + .ss_nr = 7, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -321,6 +355,7 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCHTF] = { .name = "SACCH/TF", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow TCH/F associated control channel", + .gsmtap_chan_type = GSMTAP_CHANNEL_TCH_F | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_Bm_ACCHs, .link_id = TRX_CH_LID_SACCH, @@ -333,8 +368,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCHTH_0] = { .name = "SACCH/TH(0)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow TCH/H associated control channel (sub-channel 0)", + .gsmtap_chan_type = GSMTAP_CHANNEL_TCH_H | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_Lm_ACCHs + (0 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 0, /* Same as for TRXC_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -345,8 +382,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCHTH_1] = { .name = "SACCH/TH(1)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow TCH/H associated control channel (sub-channel 1)", + .gsmtap_chan_type = GSMTAP_CHANNEL_TCH_H | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_Lm_ACCHs + (1 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 1, /* Same as for TRXC_BCCH (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -357,8 +396,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH4_0] = { .name = "SACCH/4(0)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/4 associated control channel (sub-channel 0)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH4 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH4_ACCH + (0 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 0, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -369,8 +410,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH4_1] = { .name = "SACCH/4(1)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/4 associated control channel (sub-channel 1)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH4 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH4_ACCH + (1 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 1, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -381,8 +424,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH4_2] = { .name = "SACCH/4(2)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/4 associated control channel (sub-channel 2)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH4 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH4_ACCH + (2 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 2, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -393,8 +438,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH4_3] = { .name = "SACCH/4(3)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/4 associated control channel (sub-channel 3)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH4 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH4_ACCH + (3 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 3, /* Same as for TRXC_BCCH and TRXC_SDCCH4_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -405,8 +452,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH8_0] = { .name = "SACCH/8(0)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/8 associated control channel (sub-channel 0)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (0 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 0, /* Same as for TRXC_BCCH and TRXC_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -417,8 +466,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH8_1] = { .name = "SACCH/8(1)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/8 associated control channel (sub-channel 1)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (1 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 1, /* Same as for TRXC_BCCH and TRXC_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -429,8 +480,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH8_2] = { .name = "SACCH/8(2)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/8 associated control channel (sub-channel 2)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (2 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 2, /* Same as for TRXC_BCCH and TRXC_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -441,8 +494,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH8_3] = { .name = "SACCH/8(3)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/8 associated control channel (sub-channel 3)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (3 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 3, /* Same as for TRXC_BCCH and TRXC_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -453,8 +508,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH8_4] = { .name = "SACCH/8(4)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/8 associated control channel (sub-channel 4)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (4 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 4, /* Same as for TRXC_BCCH and TRXC_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -465,8 +522,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH8_5] = { .name = "SACCH/8(5)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/8 associated control channel (sub-channel 5)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (5 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 5, /* Same as for TRXC_BCCH and TRXC_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -477,8 +536,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH8_6] = { .name = "SACCH/8(6)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/8 associated control channel (sub-channel 6)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (6 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 6, /* Same as for TRXC_BCCH and TRXC_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -489,8 +550,10 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SACCH8_7] = { .name = "SACCH/8(7)", /* 3GPP TS 05.02, section 3.3.4.1 */ .desc = "Slow SDCCH/8 associated control channel (sub-channel 7)", + .gsmtap_chan_type = GSMTAP_CHANNEL_SDCCH8 | GSMTAP_CHANNEL_ACCH, .chan_nr = RSL_CHAN_SDCCH8_ACCH + (7 << 3), .link_id = TRX_CH_LID_SACCH, + .ss_nr = 7, /* Same as for TRXC_BCCH and TRXC_SDCCH8_* (xCCH), see above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -501,6 +564,7 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_PDTCH] = { .name = "PDTCH", /* 3GPP TS 05.02, sections 3.2.4, 3.3.2.4 */ .desc = "Packet data traffic & control channel", + .gsmtap_chan_type = GSMTAP_CHANNEL_PDTCH, .chan_nr = RSL_CHAN_OSMO_PDCH, /* Rx and Tx, multiple coding schemes: CS-1..4 and MCS-1..9 (3GPP TS @@ -515,6 +579,7 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_PTCCH] = { .name = "PTCCH", /* 3GPP TS 05.02, section 3.3.4.2 */ .desc = "Packet Timing advance control channel", + .gsmtap_chan_type = GSMTAP_CHANNEL_PTCCH, .chan_nr = RSL_CHAN_OSMO_PDCH, .link_id = TRX_CH_LID_PTCCH, @@ -531,7 +596,9 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH4_CBCH] = { .name = "SDCCH/4(CBCH)", /* 3GPP TS 05.02, section 3.3.5 */ .desc = "Cell Broadcast channel on SDCCH/4", + .gsmtap_chan_type = GSMTAP_CHANNEL_CBCH51, .chan_nr = RSL_CHAN_OSMO_CBCH4, + .ss_nr = 2, /* Same as for TRXC_BCCH (xCCH), but Rx only. See above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, @@ -541,7 +608,9 @@ const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { [TRXC_SDCCH8_CBCH] = { .name = "SDCCH/8(CBCH)", /* 3GPP TS 05.02, section 3.3.5 */ .desc = "Cell Broadcast channel on SDCCH/8", + .gsmtap_chan_type = GSMTAP_CHANNEL_CBCH52, .chan_nr = RSL_CHAN_OSMO_CBCH8, + .ss_nr = 2, /* Same as for TRXC_BCCH (xCCH), but Rx only. See above. */ .burst_buf_size = 4 * GSM_BURST_PL_LEN, diff --git a/src/host/trxcon/sched_lchan_rach.c b/src/host/trxcon/sched_lchan_rach.c index 5d1f3ab9..fe5821ba 100644 --- a/src/host/trxcon/sched_lchan_rach.c +++ b/src/host/trxcon/sched_lchan_rach.c @@ -2,7 +2,7 @@ * OsmocomBB <-> SDR connection bridge * TDMA scheduler: handlers for DL / UL bursts on logical channels * - * (C) 2017 by Vadim Yanitskiy + * (C) 2017-2019 by Vadim Yanitskiy * * All Rights Reserved * @@ -174,6 +174,12 @@ int tx_rach_fn(struct trx_instance *trx, struct trx_ts *ts, /* Confirm RACH request */ l1ctl_tx_rach_conf(trx->l1l, trx->band_arfcn, fn); + /* Optional GSMTAP logging */ + sched_gsmtap_send(lchan->type, fn, ts->index, + trx->band_arfcn | ARFCN_UPLINK, 0, 0, + PRIM_IS_RACH11(lchan->prim) ? (uint8_t *) &ext_req->ra11 : &req->ra, + PRIM_IS_RACH11(lchan->prim) ? 2 : 1); + /* Forget processed primitive */ sched_prim_drop(lchan); diff --git a/src/host/trxcon/sched_lchan_xcch.c b/src/host/trxcon/sched_lchan_xcch.c index 196f949c..d3416465 100644 --- a/src/host/trxcon/sched_lchan_xcch.c +++ b/src/host/trxcon/sched_lchan_xcch.c @@ -199,14 +199,14 @@ send_burst: /* If we have sent the last (4/4) burst */ if ((*mask & 0x0f) == 0x0f) { + /* Confirm data sending */ + sched_send_dt_conf(trx, ts, lchan, fn, false); + /* Forget processed primitive */ sched_prim_drop(lchan); /* Reset mask */ *mask = 0x00; - - /* Confirm data sending */ - sched_send_dt_conf(trx, ts, lchan, fn, false); } return 0; diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h index 0d424999..ab3883e9 100644 --- a/src/host/trxcon/sched_trx.h +++ b/src/host/trxcon/sched_trx.h @@ -114,6 +114,10 @@ struct trx_lchan_desc { uint8_t chan_nr; /*! \brief Link ID (like in RSL) */ uint8_t link_id; + /*! \brief Sub-slot number (for SDCCH and TCH/H) */ + uint8_t ss_nr; + /*! \brief GSMTAP channel type (see GSMTAP_CHANNEL_*) */ + uint8_t gsmtap_chan_type; /*! \brief How much memory do we need to store bursts */ size_t burst_buf_size; @@ -351,6 +355,9 @@ int sched_send_dt_ind(struct trx_instance *trx, struct trx_ts *ts, int bit_error_count, bool dec_failed, bool traffic); int sched_send_dt_conf(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, bool traffic); +int sched_gsmtap_send(enum trx_lchan_type lchan_type, uint32_t fn, uint8_t tn, + uint16_t band_arfcn, int8_t signal_dbm, uint8_t snr, + const uint8_t *data, size_t data_len); /* Interleaved TCH/H block TDMA frame mapping */ uint32_t sched_tchh_block_dl_first_fn(enum trx_lchan_type chan, diff --git a/src/host/trxcon/trxcon.c b/src/host/trxcon/trxcon.c index 8e371df1..d49b71fa 100644 --- a/src/host/trxcon/trxcon.c +++ b/src/host/trxcon/trxcon.c @@ -1,7 +1,7 @@ /* * OsmocomBB <-> SDR connection bridge * - * (C) 2016-2017 by Vadim Yanitskiy + * (C) 2016-2019 by Vadim Yanitskiy * * All Rights Reserved * @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include @@ -51,7 +53,7 @@ #include "sched_trx.h" #define COPYRIGHT \ - "Copyright (C) 2016-2017 by Vadim Yanitskiy \n" \ + "Copyright (C) 2016-2019 by Vadim Yanitskiy \n" \ "License GPLv2+: GNU GPL version 2 or later " \ "\n" \ "This is free software: you are free to change and redistribute it.\n" \ @@ -72,9 +74,11 @@ static struct { const char *trx_remote_ip; uint16_t trx_base_port; uint32_t trx_fn_advance; + const char *gsmtap_ip; } app_data; static void *tall_trxcon_ctx = NULL; +struct gsmtap_inst *gsmtap = NULL; struct osmo_fsm_inst *trxcon_fsm; static void trxcon_fsm_idle_action(struct osmo_fsm_inst *fi, @@ -158,6 +162,7 @@ static void print_help(void) printf(" -p --trx-port Base port of TRX instance (default 6700)\n"); printf(" -f --trx-advance Scheduler clock advance (default 20)\n"); printf(" -s --socket Listening socket for layer23 (default /tmp/osmocom_l2)\n"); + printf(" -g --gsmtap-ip The destination IP used for GSMTAP (disabled by default)\n"); printf(" -D --daemonize Run as daemon\n"); } @@ -176,11 +181,12 @@ static void handle_options(int argc, char **argv) {"trx-remote", 1, 0, 'i'}, {"trx-port", 1, 0, 'p'}, {"trx-advance", 1, 0, 'f'}, + {"gsmtap-ip", 1, 0, 'g'}, {"daemonize", 0, 0, 'D'}, {0, 0, 0, 0} }; - c = getopt_long(argc, argv, "d:b:i:p:f:s:Dh", + c = getopt_long(argc, argv, "d:b:i:p:f:s:g:Dh", long_options, &option_index); if (c == -1) break; @@ -209,6 +215,9 @@ static void handle_options(int argc, char **argv) case 's': app_data.bind_socket = optarg; break; + case 'g': + app_data.gsmtap_ip = optarg; + break; case 'D': app_data.daemonize = 1; break; @@ -227,6 +236,7 @@ static void init_defaults(void) app_data.trx_fn_advance = 20; app_data.debug_mask = NULL; + app_data.gsmtap_ip = NULL; app_data.daemonize = 0; app_data.quit = 0; } @@ -273,6 +283,17 @@ int main(int argc, char **argv) /* Init logging system */ trx_log_init(tall_trxcon_ctx, app_data.debug_mask); + /* Optional GSMTAP */ + if (app_data.gsmtap_ip != NULL) { + gsmtap = gsmtap_source_init(app_data.gsmtap_ip, GSMTAP_UDP_PORT, 1); + if (!gsmtap) { + LOGP(DAPP, LOGL_ERROR, "Failed to init GSMTAP\n"); + goto exit; + } + /* Suppress ICMP "destination unreachable" errors */ + gsmtap_source_add_sink(gsmtap); + } + /* Allocate the application state machine */ osmo_fsm_register(&trxcon_fsm_def); trxcon_fsm = osmo_fsm_inst_alloc(&trxcon_fsm_def, tall_trxcon_ctx, diff --git a/src/host/trxcon/trxcon.h b/src/host/trxcon/trxcon.h index f66a6285..9a0792bf 100644 --- a/src/host/trxcon/trxcon.h +++ b/src/host/trxcon/trxcon.h @@ -3,6 +3,7 @@ #define GEN_MASK(state) (0x01 << state) extern struct osmo_fsm_inst *trxcon_fsm; +extern struct gsmtap_inst *gsmtap; enum trxcon_fsm_states { TRXCON_STATE_IDLE = 0, -- cgit v1.2.3