From: Max msuraev@sysmocom.de
Signed-off-by: Max msuraev@sysmocom.de --- .gitignore | 1 + 1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore index 6cc9aa5..a22fd4f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ Makefile.in Makefile .deps +src/cscope*
aclocal.m4 autom4te.cache
From: Max msuraev@sysmocom.de
his option allows user to use custom IP address instead of default "localhost". Correspondingly gsmtap init moved from sysmoBTS-specific code up to "bts" struct level. This way it can be easier reused by other implementations.
Signed-off-by: Max msuraev@sysmocom.de --- src/bts.h | 2 ++ src/pcu_l1_if.cpp | 5 +++-- src/pcu_main.cpp | 20 ++++++++++++++++++-- src/sysmo_l1_if.c | 6 ++---- 4 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/bts.h b/src/bts.h index 45432ea..2b69023 100644 --- a/src/bts.h +++ b/src/bts.h @@ -27,6 +27,7 @@ extern "C" { #include <osmocom/core/rate_ctr.h> #include <osmocom/core/stat_item.h> #include <osmocom/core/timer.h> +#include <osmocom/core/gsmtap.h> }
#include "poll_controller.h" @@ -168,6 +169,7 @@ struct gprs_rlcmac_bts { uint8_t n3101; uint8_t n3103; uint8_t n3105; + struct gsmtap_inst *gsmtap; struct gprs_rlcmac_trx trx[8]; int (*alloc_algorithm)(struct gprs_rlcmac_bts *bts, struct GprsMs *ms, diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 9d7dbee..e816e6f 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -42,7 +42,7 @@ extern "C" {
// FIXME: move this, when changed from c++ to c. extern "C" { -void *l1if_open_pdch(void *priv, uint32_t hlayer1); +void *l1if_open_pdch(void *priv, uint32_t hlayer1, struct gsmtap_inst *gsmtap); int l1if_connect_pdch(void *obj, uint8_t ts); int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn, uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len); @@ -436,7 +436,8 @@ bssgp_failed: if (!bts->trx[trx].fl1h) bts->trx[trx].fl1h = l1if_open_pdch( (void *)trx, - info_ind->trx[trx].hlayer1); + info_ind->trx[trx].hlayer1, + bts->gsmtap); if (!bts->trx[trx].fl1h) { LOGP(DL1IF, LOGL_FATAL, "Failed to open direct " "DSP access for PDCH.\n"); diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index 96dc6d7..4065d71 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -33,6 +33,8 @@ extern "C" { #include <osmocom/vty/telnet_interface.h> #include <osmocom/vty/logging.h> #include <osmocom/core/stats.h> +#include <osmocom/core/gsmtap.h> +#include <osmocom/core/gsmtap_util.h> }
extern struct gprs_nsvc *nsvc; @@ -44,6 +46,7 @@ void *tall_pcu_ctx; extern void *bv_tall_ctx; static int quit = 0; static int rt_prio = -1; +static char *gsmtap_addr = "localhost"; // FIXME: use gengetopt's default value instead
static void print_help() { @@ -58,10 +61,11 @@ static void print_help() " -V --version print version\n" " -r --realtime PRIO Use SCHED_RR with the specified " "priority\n" + " -i --gsmtap-ip The destination IP used for GSMTAP.\n" ); }
-/* FIXME: finally get some option parsing code into libosmocore */ +/* FIXME: finally try using gengetopt */ static void handle_options(int argc, char **argv) { while (1) { @@ -74,10 +78,11 @@ static void handle_options(int argc, char **argv) { "version", 0, 0, 'V' }, { "realtime", 1, 0, 'r' }, { "exit", 0, 0, 'e' }, + { "gsmtap-ip", 1, 0, 'i' }, { 0, 0, 0, 0 } };
- c = getopt_long(argc, argv, "hc:m:n:Vr:e", + c = getopt_long(argc, argv, "hc:m:n:Vr:e:i:", long_options, &option_idx); if (c == -1) break; @@ -102,6 +107,9 @@ static void handle_options(int argc, char **argv) print_version(1); exit(0); break; + case 'i': + gsmtap_addr = optarg; + break; case 'r': rt_prio = atoi(optarg); break; @@ -212,6 +220,14 @@ int main(int argc, char *argv[]) exit(0); }
+ bts->gsmtap = gsmtap_source_init(gsmtap_addr, GSMTAP_UDP_PORT, 1); + + if (bts->gsmtap) { + gsmtap_source_add_sink(bts->gsmtap); + } else { + fprintf(stderr, "Failed to initialize GSMTAP for %s\n", gsmtap_addr); + } + rc = vty_read_config_file(config_file, NULL); if (rc < 0 && config_given) { fprintf(stderr, "Failed to parse the config file: '%s'\n", diff --git a/src/sysmo_l1_if.c b/src/sysmo_l1_if.c index 8572786..c7c54dd 100644 --- a/src/sysmo_l1_if.c +++ b/src/sysmo_l1_if.c @@ -357,7 +357,7 @@ int l1if_pdch_req(void *obj, uint8_t ts, int is_ptcch, uint32_t fn, return 0; }
-void *l1if_open_pdch(void *priv, uint32_t hlayer1) +void *l1if_open_pdch(void *priv, uint32_t hlayer1, struct gsmtap_inst *gsmtap) { struct femtol1_hdl *fl1h; int rc; @@ -378,9 +378,7 @@ void *l1if_open_pdch(void *priv, uint32_t hlayer1) return NULL; }
- fl1h->gsmtap = gsmtap_source_init("localhost", GSMTAP_UDP_PORT, 1); - if (fl1h->gsmtap) - gsmtap_source_add_sink(fl1h->gsmtap); + fl1h->gsmtap = gsmtap;
return fl1h; }
On 19 Feb 2016, at 19:20, msuraev@sysmocom.de wrote:
From: Max msuraev@sysmocom.de
his option allows user to use custom IP address instead of default "localhost". Correspondingly gsmtap init moved from sysmoBTS-specific code up to "bts" struct level. This way it can be easier reused by other implementations.
great. Have you checked that the osmo-pcu for the sysmoBTS behaves as before?
-/* FIXME: finally get some option parsing code into libosmocore */ +/* FIXME: finally try using gengetopt */
this is a different question. What I have seen in the OpenGGSN did not impress me. Now your patch is blocked by something that has nothing to do with gsmtap. ;)
static void handle_options(int argc, char **argv) { while (1) { @@ -74,10 +78,11 @@ static void handle_options(int argc, char **argv) { "version", 0, 0, 'V' }, { "realtime", 1, 0, 'r' }, { "exit", 0, 0, 'e' },
};{ "gsmtap-ip", 1, 0, 'i' }, { 0, 0, 0, 0 }
c = getopt_long(argc, argv, "hc:m:n:Vr:e",
if (c == -1) break;c = getopt_long(argc, argv, "hc:m:n:Vr:e:i:", long_options, &option_idx);@@ -102,6 +107,9 @@ static void handle_options(int argc, char **argv) print_version(1); exit(0); break;
case 'i':gsmtap_addr = optarg; case 'r': rt_prio = atoi(optarg); break;break;@@ -212,6 +220,14 @@ int main(int argc, char *argv[]) exit(0); }
- bts->gsmtap = gsmtap_source_init(gsmtap_addr, GSMTAP_UDP_PORT, 1);
- if (bts->gsmtap) {
gsmtap_source_add_sink(bts->gsmtap);- } else {
fprintf(stderr, "Failed to initialize GSMTAP for %s\n", gsmtap_addr);- }
coding style, please drop the curly braces. The rest does look fine.
From: Max msuraev@sysmocom.de
Instrument TX and RX functions dealing with regular BTS (without direct DSP access) to use GSMTAP. Previously only DSP-related functions were instrumented.
Signed-off-by: Max msuraev@sysmocom.de --- src/pcu_l1_if.cpp | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index e816e6f..1b727a5 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -30,6 +30,8 @@ extern "C" { #include <osmocom/core/talloc.h> #include <osmocom/core/select.h> #include <osmocom/core/msgb.h> +#include <osmocom/core/gsmtap_util.h> +#include <osmocom/core/gsmtap.h> }
#include <gprs_rlcmac.h> @@ -93,7 +95,7 @@ static int pcu_tx_act_req(uint8_t trx, uint8_t ts, uint8_t activate)
static int pcu_tx_data_req(uint8_t trx, uint8_t ts, uint8_t sapi, uint16_t arfcn, uint32_t fn, uint8_t block_nr, uint8_t *data, - uint8_t len) + uint8_t len, struct gsmtap_inst *gsmtap) { struct msgb *msg; struct gsm_pcu_if *pcu_prim; @@ -118,54 +120,58 @@ static int pcu_tx_data_req(uint8_t trx, uint8_t ts, uint8_t sapi, memcpy(data_req->data, data, len); data_req->len = len;
+ gsmtap_send(gsmtap, arfcn, ts, GSMTAP_CHANNEL_PACCH, 0, fn, 0, 0, data, len); + return pcu_sock_send(msg); }
void pcu_l1if_tx_pdtch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn, uint32_t fn, uint8_t block_nr) { -#ifdef ENABLE_SYSMODSP struct gprs_rlcmac_bts *bts = bts_main_data();
+#ifdef ENABLE_SYSMODSP if (bts->trx[trx].fl1h) l1if_pdch_req(bts->trx[trx].fl1h, ts, 0, fn, arfcn, block_nr, msg->data, msg->len); else #endif pcu_tx_data_req(trx, ts, PCU_IF_SAPI_PDTCH, arfcn, fn, block_nr, - msg->data, msg->len); + msg->data, msg->len, bts->gsmtap); msgb_free(msg); }
void pcu_l1if_tx_ptcch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn, uint32_t fn, uint8_t block_nr) { -#ifdef ENABLE_SYSMODSP struct gprs_rlcmac_bts *bts = bts_main_data();
+#ifdef ENABLE_SYSMODSP if (bts->trx[trx].fl1h) l1if_pdch_req(bts->trx[trx].fl1h, ts, 1, fn, arfcn, block_nr, msg->data, msg->len); else #endif pcu_tx_data_req(trx, ts, PCU_IF_SAPI_PTCCH, arfcn, fn, block_nr, - msg->data, msg->len); + msg->data, msg->len, bts->gsmtap); msgb_free(msg); }
void pcu_l1if_tx_agch(bitvec * block, int plen) { uint8_t data[23]; /* prefix PLEN */ - + struct gprs_rlcmac_bts *bts = bts_main_data(); + /* FIXME: why does OpenBTS has no PLEN and no fill in message? */ bitvec_pack(block, data + 1); data[0] = (plen << 2) | 0x01; - pcu_tx_data_req(0, 0, PCU_IF_SAPI_AGCH, 0, 0, 0, data, 23); + pcu_tx_data_req(0, 0, PCU_IF_SAPI_AGCH, 0, 0, 0, data, 23, bts->gsmtap); }
void pcu_l1if_tx_pch(bitvec * block, int plen, const char *imsi) { uint8_t data[23+3]; /* prefix PLEN */ + struct gprs_rlcmac_bts *bts = bts_main_data();
/* paging group */ if (!imsi || strlen(imsi) < 3) @@ -177,7 +183,7 @@ void pcu_l1if_tx_pch(bitvec * block, int plen, const char *imsi)
bitvec_pack(block, data + 3+1); data[3] = (plen << 2) | 0x01; - pcu_tx_data_req(0, 0, PCU_IF_SAPI_PCH, 0, 0, 0, data, 23+3); + pcu_tx_data_req(0, 0, PCU_IF_SAPI_PCH, 0, 0, 0, data, 23+3, bts->gsmtap); }
extern "C" void pcu_rx_block_time(uint16_t arfcn, uint32_t fn, uint8_t ts_no) @@ -200,7 +206,7 @@ extern "C" int pcu_rx_data_ind_pdtch(uint8_t trx_no, uint8_t ts_no, uint8_t *dat return pdch->rcv_block(data, len, fn, meas); }
-static int pcu_rx_data_ind(struct gsm_pcu_if_data *data_ind) +static int pcu_rx_data_ind(struct gsm_pcu_if_data *data_ind, struct gsmtap_inst *gsmtap) { int rc = 0; pcu_l1_meas meas; @@ -223,6 +229,15 @@ static int pcu_rx_data_ind(struct gsm_pcu_if_data *data_ind) rc = -EINVAL; }
+ if (rc < 0) + return rc; + + int r = gsmtap_send(gsmtap, data_ind->arfcn | GSMTAP_ARFCN_F_UPLINK, data_ind->ts_nr, + GSMTAP_CHANNEL_PACCH, 0, data_ind->fn, 0, 0, data_ind->data, data_ind->len); + if (r < 0) { + LOGP(DL1IF, LOGL_ERROR, "Sending RX data via GSMTAP failed: %d\n", r); + } + return rc; }
@@ -508,10 +523,11 @@ static int pcu_rx_pag_req(struct gsm_pcu_if_pag_req *pag_req) int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim) { int rc = 0; + struct gprs_rlcmac_bts *bts = bts_main_data();
switch (msg_type) { case PCU_IF_MSG_DATA_IND: - rc = pcu_rx_data_ind(&pcu_prim->u.data_ind); + rc = pcu_rx_data_ind(&pcu_prim->u.data_ind, bts->gsmtap); break; case PCU_IF_MSG_DATA_CNF: rc = pcu_rx_data_cnf(&pcu_prim->u.data_cnf);