# HG changeset patch # User Mychaela Falconia # Date 1724958122 0 # Node ID 26c9535df39eeea7bc0853b1c81e6f8dfc9a1fe9 # Parent e4a0b4a6164915356fdaf2af75e66a51b49c37c3 rm abis subdir: moved to e1-fake-trau repository The present code repository is meant to contain code for talking to a TRAU DUT, hence the name ice1-trau-tester. The different and separate function of talking to an E1 BTS (Abis instead of Ater, and in the opposite role) was never in scope for this project, but that code got added here in a haste when the InSite BTS arrived while the TRAU bring-up was still blocked. Now that we have our Nokia TCSM2 system working and are doing TRAU experiments, let's keep the code clean. diff -r e4a0b4a61649 -r 26c9535df39e Makefile --- a/Makefile Wed Aug 28 05:02:29 2024 +0000 +++ b/Makefile Thu Aug 29 19:02:02 2024 +0000 @@ -1,11 +1,10 @@ -PROGDIR=abis ater pcm pcm-br +PROGDIR=ater pcm pcm-br LIBDIR= libutil SUBDIR= ${PROGDIR} ${LIBDIR} DESTDIR= all: ${SUBDIR} -abis: libutil ater: libutil pcm: libutil pcm-br: libutil diff -r e4a0b4a61649 -r 26c9535df39e abis/Makefile --- a/abis/Makefile Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -PROG= itt-abis-16 -OBJS= dl_frames.o main.o read_ts.o record_ctrl.o subslot_rx.o tx_func.o \ - user_cmd.o -HDRS= dl_frames.h globals.h submux.h -LIBUTIL=../libutil/libutil.a - -include ../config.defs - -CPPFLAGS=${OSMO_INCLUDE} -OSMO_LINK=${OSMO_LPATH} ${OSMO_RPATH} ${OSMO_LIBS} - -all: ${PROG} - -${OBJS}: ${HDRS} - -${PROG}: ${OBJS} ${LIBUTIL} - ${CC} -o $@ ${OBJS} ${LIBUTIL} ${OSMO_LINK} - -install: - mkdir -p ${DESTDIR}${bindir} - install -c -m 755 ${PROG} ${DESTDIR}${bindir} - -clean: - rm -f *.o ${PROG} errs diff -r e4a0b4a61649 -r 26c9535df39e abis/dl_frames.c --- a/abis/dl_frames.c Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * In this module we generate canned TRAU-DL frames for FR and EFR, - * which will later be transmitted on Abis when individual subslots - * come alive. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "dl_frames.h" - -ubit_t dl_frame_fr[DL_OUTPUT_BUFLEN]; -ubit_t dl_frame_efr[DL_OUTPUT_BUFLEN]; - -static const uint8_t gsmfr_silence_frame[33] = { - 0xDA, 0xA7, 0xAA, 0xA5, 0x1A, - 0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B, - 0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B, - 0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B, - 0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B, -}; - -static const uint8_t efr_dhf_rtp[31] = { - 0xC0, 0x85, 0xEB, 0x49, 0x0F, 0xAA, 0xD6, 0x03, - 0xE3, 0xA1, 0x86, 0x07, 0xB0, 0xC4, 0x2C, 0x08, - 0x04, 0x80, 0x55, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static void gen_dl_fr(void) -{ - struct osmo_trau_frame tf; - struct osmo_trau2rtp_state st; - int rc; - - tf.dir = OSMO_TRAU_DIR_DL; - st.type = OSMO_TRAU16_FT_FR; - rc = osmo_rtp2trau(&tf, gsmfr_silence_frame, 33, &st); - OSMO_ASSERT(rc == 0); - tf.dl_ta_usec = 0; - rc = osmo_trau_frame_encode(dl_frame_fr, DL_OUTPUT_BUFLEN, &tf); - OSMO_ASSERT(rc == DL_OUTPUT_LEN); -} - -static void gen_dl_efr(void) -{ - struct osmo_trau_frame tf; - struct osmo_trau2rtp_state st; - int rc; - - tf.dir = OSMO_TRAU_DIR_DL; - st.type = OSMO_TRAU16_FT_EFR; - rc = osmo_rtp2trau(&tf, efr_dhf_rtp, 31, &st); - OSMO_ASSERT(rc == 0); - tf.dl_ta_usec = 0; - rc = osmo_trau_frame_encode(dl_frame_efr, DL_OUTPUT_BUFLEN, &tf); - OSMO_ASSERT(rc == DL_OUTPUT_LEN); -} - -void init_canned_dl_frames(void) -{ - gen_dl_fr(); - gen_dl_efr(); -} diff -r e4a0b4a61649 -r 26c9535df39e abis/dl_frames.h --- a/abis/dl_frames.h Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -/* - * This header file defines the interface to the module that provides - * canned TRAU-DL frames to be transmitted on Abis as needed. - */ - -#pragma once - -#include - -#define DL_OUTPUT_LEN 320 -#define DL_OUTPUT_BUFLEN 640 - -extern ubit_t dl_frame_fr[DL_OUTPUT_BUFLEN]; -extern ubit_t dl_frame_efr[DL_OUTPUT_BUFLEN]; - -void init_canned_dl_frames(void); diff -r e4a0b4a61649 -r 26c9535df39e abis/globals.h --- a/abis/globals.h Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -/* global vars and intermodule-linkage functions in itt-abis-16 */ - -#pragma once - -extern void *g_ctx; -extern struct osmo_e1dp_client *g_client; -extern int ts_fd; -extern struct osmo_i460_timeslot i460_ts; -extern uint8_t readbuf[160]; -extern FILE *record_file; - -int ts_fd_cb(struct osmo_fd *ofd, unsigned int what); -void transmit_e1_ts(void); - -void handle_user_cmd(int argc, char **argv); -void cmd_record_start(int argc, char **argv); -void cmd_record_stop(int argc, char **argv); -void cmd_print_rx(int argc, char **argv); diff -r e4a0b4a61649 -r 26c9535df39e abis/main.c --- a/abis/main.c Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * This C module is the main for itt-abis-16, a test program for collecting - * TRAU-UL captures from an E1 BTS. This program operates on a single E1 - * timeslot on Abis and treats it as consisting of four 16 kbit/s subslots. - * - * This code is based on osmo-e1d-pipe, - * (C) 2020-2022 by Harald Welte , - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../libutil/open_ts.h" -#include "../libutil/stdin_handler.h" -#include "globals.h" -#include "submux.h" -#include "dl_frames.h" - -void *g_ctx; -struct osmo_e1dp_client *g_client; -int ts_fd; -struct osmo_i460_timeslot i460_ts; -struct abis_subslot subslots[ABIS_SUBSLOTS]; - -static const char *e1d_socket_path = E1DP_DEFAULT_SOCKET; -static const char *timeslot_spec; -static struct osmo_fd ts_ofd, stdin_ofd; - -static void process_cmdline(int argc, char **argv) -{ - extern int optind; - extern char *optarg; - int c; - - while ((c = getopt(argc, argv, "p:")) != EOF) { - switch (c) { - case 'p': - e1d_socket_path = optarg; - continue; - default: - usage: - fprintf(stderr, "usage: %s [-p socket] intf:line:ts\n", - argv[0]); - exit(1); - } - } - if (argc != optind + 1) - goto usage; - timeslot_spec = argv[optind]; -} - -static void register_subslots(void) -{ - int nr; - struct osmo_i460_schan_desc chd; - - memset(&chd, 0, sizeof chd); - chd.rate = OSMO_I460_RATE_16k; - chd.demux.num_bits = 320; - chd.demux.out_cb_bits = i460_rx_func; - - for (nr = 0; nr < ABIS_SUBSLOTS; nr++) { - subslots[nr].nr = nr; - chd.demux.user_data = subslots + nr; - chd.mux.user_data = subslots + nr; - subslots[nr].schan = - osmo_i460_subchan_add(g_ctx, &i460_ts, &chd); - OSMO_ASSERT(subslots[nr].schan); - chd.bit_offset += 2; - } -} - -static void setup_rx_sync(void) -{ - int nr; - - for (nr = 0; nr < ABIS_SUBSLOTS; nr++) { - subslots[nr].sync = osmo_trau_sync_alloc(g_ctx, "TRAU-UL-sync", - sync_rx_func, OSMO_TRAU_SYNCP_16_FR_EFR, - subslots + nr); - OSMO_ASSERT(subslots[nr].sync); - } -} - -int main(int argc, char **argv) -{ - process_cmdline(argc, argv); - g_ctx = talloc_named_const(NULL, 0, "g_ctx"); - OSMO_ASSERT(g_ctx); - osmo_init_logging2(g_ctx, NULL); - - g_client = osmo_e1dp_client_create(g_ctx, e1d_socket_path); - if (!g_client) { - fprintf(stderr, "error: cannot connect to osmo-e1d at %s\n", - e1d_socket_path); - exit(1); - } - ts_fd = open_e1d_ts(g_client, timeslot_spec); - - osmo_i460_ts_init(&i460_ts); - register_subslots(); - setup_rx_sync(); - init_canned_dl_frames(); - - osmo_fd_setup(&ts_ofd, ts_fd, OSMO_FD_READ, ts_fd_cb, NULL, 0); - OSMO_ASSERT(osmo_fd_register(&ts_ofd) == 0); - - osmo_fd_setup(&stdin_ofd, 0, OSMO_FD_READ, stdin_select_cb, - handle_user_cmd, 0); - OSMO_ASSERT(osmo_fd_register(&stdin_ofd) == 0); - - while (1) { - osmo_select_main(0); - } -} diff -r e4a0b4a61649 -r 26c9535df39e abis/read_ts.c --- a/abis/read_ts.c Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * The function in this module gets called from Osmocom select loop - * whenever the data socket to osmo-e1d is ready for reading. - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "globals.h" - -uint8_t readbuf[160]; -FILE *record_file; - -int ts_fd_cb(struct osmo_fd *ofd, unsigned int what) -{ - int rc; - - rc = read(ts_fd, readbuf, 160); - if (rc != 160) { - fprintf(stderr, - "error: read from ts returned %d instead of 160\n", - rc); - exit(1); - } - if (record_file) - fwrite(readbuf, 1, 160, record_file); - osmo_i460_demux_in(&i460_ts, readbuf, 160); - transmit_e1_ts(); - return 0; -} diff -r e4a0b4a61649 -r 26c9535df39e abis/record_ctrl.c --- a/abis/record_ctrl.c Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Here we implement stdin commands that control recording of E1 timeslot - * read stream. - */ - -#include -#include -#include -#include - -#include - -#include "globals.h" - -void cmd_record_start(int argc, char **argv) -{ - if (argc != 2) { - printf("error: record command needs 1 argument\n"); - return; - } - if (record_file) { - printf("error: recording already in progress\n"); - return; - } - record_file = fopen(argv[1], "w"); - if (!record_file) - perror(argv[1]); -} - -void cmd_record_stop(int argc, char **argv) -{ - if (!record_file) { - printf("error: no recording in progress\n"); - return; - } - fclose(record_file); - record_file = NULL; -} - -void cmd_print_rx(int argc, char **argv) -{ - int i, j, off; - - off = 0; - for (i = 0; i < 10; i++) { - for (j = 0; j < 16; j++) - printf(" %02X", readbuf[off++]); - putchar('\n'); - } -} diff -r e4a0b4a61649 -r 26c9535df39e abis/submux.h --- a/abis/submux.h Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * The structures and functions defined in this header file deal with - * submultiplexing on the Abis interface. - */ - -#pragma once - -#include -#include - -#include -#include -#include - -#define ABIS_SUBSLOTS 4 - -struct abis_subslot { - struct osmo_i460_subchan *schan; - struct osmo_fsm_inst *sync; - int nr; - bool got_sync; - uint8_t frame_type; -}; - -extern struct abis_subslot subslots[ABIS_SUBSLOTS]; - -void i460_rx_func(struct osmo_i460_subchan *schan, void *user_data, - const ubit_t *bits, unsigned int num_bits); -void sync_rx_func(void *user_data, const ubit_t *bits, unsigned int num_bits); diff -r e4a0b4a61649 -r 26c9535df39e abis/subslot_rx.c --- a/abis/subslot_rx.c Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Here we are going to implement Abis subslot Rx. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "globals.h" -#include "submux.h" - -void i460_rx_func(struct osmo_i460_subchan *schan, void *user_data, - const ubit_t *bits, unsigned int num_bits) -{ - struct abis_subslot *ab = user_data; - - osmo_trau_sync_rx_ubits(ab->sync, bits, num_bits); -} - -static void sync_lost(struct abis_subslot *ab) -{ - if (!ab->got_sync) - return; - printf("Subslot %d lost frame sync\n", ab->nr); - ab->got_sync = false; -} - -/* function copied from libosmo-abis/src/trau/trau_frame.c */ -static uint32_t get_bits(const ubit_t *bitbuf, int offset, int num) -{ - int i; - uint32_t ret = 0; - - for (i = offset; i < offset + num; i++) { - ret = ret << 1; - if (bitbuf[i]) - ret |= 1; - } - return ret; -} - -void sync_rx_func(void *user_data, const ubit_t *bits, unsigned int num_bits) -{ - struct abis_subslot *ab = user_data; - uint8_t ft; - - if (!bits) { - sync_lost(ab); - return; - } - OSMO_ASSERT(num_bits == 320); - ft = get_bits(bits, 17, 5); - if (!ab->got_sync) { - printf("Subslot %d got frame sync with FT=0x%02X\n", - ab->nr, ft); - ab->got_sync = true; - ab->frame_type = ft; - return; - } - if (ft == ab->frame_type) - return; - printf("Subslot %d changed frame type from 0x%02X to 0x%02X\n", ab->nr, - ab->frame_type, ft); - ab->frame_type = ft; -} diff -r e4a0b4a61649 -r 26c9535df39e abis/tx_func.c --- a/abis/tx_func.c Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Here we are going to implement Tx on Abis toward the BTS. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "globals.h" -#include "submux.h" -#include "dl_frames.h" - -static void tx_service_subslot(int nr) -{ - struct abis_subslot *ab = &subslots[nr]; - const uint8_t *srcbuf; - struct msgb *msg; - uint8_t *outbuf; - - if (!ab->got_sync) - return; - switch (ab->frame_type) { - case TRAU_FT_FR_UP: - srcbuf = dl_frame_fr; - break; - case TRAU_FT_EFR: - srcbuf = dl_frame_efr; - break; - default: - return; - } - msg = msgb_alloc_c(g_ctx, DL_OUTPUT_LEN, "TRAU-DL-frame"); - if (!msg) - return; - outbuf = msgb_put(msg, DL_OUTPUT_LEN); - memcpy(outbuf, srcbuf, DL_OUTPUT_LEN); - osmo_i460_mux_enqueue(ab->schan, msg); -} - -void transmit_e1_ts(void) -{ - uint8_t buf[160]; - int nr; - - for (nr = 0; nr < ABIS_SUBSLOTS; nr++) - tx_service_subslot(nr); - osmo_i460_mux_out(&i460_ts, buf, 160); - write(ts_fd, buf, 160); -} diff -r e4a0b4a61649 -r 26c9535df39e abis/user_cmd.c --- a/abis/user_cmd.c Wed Aug 28 05:02:29 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * In this module we handle user-issued stdin commands during - * itt-abis-16 running session. - */ - -#include -#include -#include -#include -#include - -#include - -#include "globals.h" - -static struct cmdtab { - char *cmd; - void (*func)(int argc, char **argv); -} cmdtab[] = { - {"print-rx", cmd_print_rx}, - {"record", cmd_record_start}, - {"record-stop", cmd_record_stop}, - /* table search terminator */ - {NULL, NULL} -}; - -void handle_user_cmd(int argc, char **argv) -{ - struct cmdtab *tp; - - for (tp = cmdtab; tp->cmd; tp++) - if (!strcmp(tp->cmd, argv[0])) - break; - if (!tp->func) { - printf("error: unknown or unimplemented command\n"); - return; - } - tp->func(argc, argv); -}