FreeCalypso > hg > ice1-trau-tester
changeset 51:db39e8855f3d
ater: implement play-d144
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 25 Sep 2024 05:53:38 +0000 |
parents | 6ba4de500532 |
children | 626180a15857 |
files | ater/globals.h ater/play_cmd.c ater/read_file.c ater/read_file.h ater/tx_func.c ater/user_cmd.c |
diffstat | 6 files changed, 138 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/ater/globals.h Tue Sep 24 06:15:40 2024 +0000 +++ b/ater/globals.h Wed Sep 25 05:53:38 2024 +0000 @@ -20,6 +20,7 @@ void cmd_activate_csd(int argc, char **argv); void cmd_deact(int argc, char **argv); void cmd_play_file(int argc, char **argv); +void cmd_play_d144(int argc, char **argv); void cmd_play_stop(int argc, char **argv); void cmd_set_dbits(int argc, char **argv); void cmd_set_edata(int argc, char **argv);
--- a/ater/play_cmd.c Tue Sep 24 06:15:40 2024 +0000 +++ b/ater/play_cmd.c Wed Sep 25 05:53:38 2024 +0000 @@ -47,6 +47,38 @@ at->play_wait_align = true; } +void cmd_play_d144(int argc, char **argv) +{ + int nr, rc; + struct ater_subslot *at; + + if (argc != 3) { +usage: fprintf(stderr, "usage: %s 0|1|2|3 play-file.bin\n", argv[0]); + return; + } + if (argv[1][0] < '0' || argv[1][0] > '3' || argv[1][1]) + goto usage; + nr = argv[1][0] - '0'; + at = &subslots[nr]; + if (!at->is_active) { + fprintf(stderr, "error: subslot %d is not active\n", nr); + return; + } + if (!at->is_data_144) { + fprintf(stderr, "error: subslot %d is not in D144 mode\n", nr); + return; + } + if (at->play_buffer) { + fprintf(stderr, "error: file play already in progress\n"); + return; + } + rc = read_binary_file_d144(argv[2], &at->play_buffer, + &at->play_buf_total); + if (rc < 0) + return; /* error msg already printed */ + at->play_buf_ptr = 0; +} + void cmd_play_stop(int argc, char **argv) { int nr;
--- a/ater/read_file.c Tue Sep 24 06:15:40 2024 +0000 +++ b/ater/read_file.c Wed Sep 25 05:53:38 2024 +0000 @@ -96,3 +96,68 @@ *size_ret = nframes; return 0; } + +static int check_magic_d144(const uint8_t *buf, unsigned nframes) +{ + unsigned n; + + for (n = 0; n < nframes; n++) { + if (*buf != 0xD4) + return -1; + buf += 38; + } + return 0; +} + +int read_binary_file_d144(const char *filename, uint8_t **bufret, + unsigned *size_ret) +{ + int fd, rc; + struct stat st; + uint8_t *buf; + unsigned nframes; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + perror(filename); + return -1; + } + fstat(fd, &st); + if (!S_ISREG(st.st_mode)) { + close(fd); + fprintf(stderr, "error: %s is not a regular file\n", filename); + return -1; + } + if (!st.st_size) { + close(fd); + fprintf(stderr, "error: %s is an empty file\n", filename); + return -1; + } + if (st.st_size % 38) { + close(fd); + fprintf(stderr, + "error: size of %s is not a multiple of 38 bytes\n", + filename); + return -1; + } + buf = malloc(st.st_size); + if (!buf) { + close(fd); + fprintf(stderr, "unable to malloc buffer for %s\n", filename); + return -1; + } + read(fd, buf, st.st_size); + close(fd); + nframes = st.st_size / 38; + + rc = check_magic_d144(buf, nframes); + if (rc < 0) { + free(buf); + fprintf(stderr, "error: %s is not a valid D144 test file\n", + filename); + return -1; + } + *bufret = buf; + *size_ret = nframes; + return 0; +}
--- a/ater/read_file.h Tue Sep 24 06:15:40 2024 +0000 +++ b/ater/read_file.h Wed Sep 25 05:53:38 2024 +0000 @@ -10,3 +10,6 @@ int read_binary_file(const char *filename, bool is_efr, uint8_t **bufret, unsigned *size_ret); + +int read_binary_file_d144(const char *filename, uint8_t **bufret, + unsigned *size_ret);
--- a/ater/tx_func.c Tue Sep 24 06:15:40 2024 +0000 +++ b/ater/tx_func.c Wed Sep 25 05:53:38 2024 +0000 @@ -9,6 +9,7 @@ #include <string.h> #include <unistd.h> +#include <osmocom/core/bits.h> #include <osmocom/core/msgb.h> #include <osmocom/core/select.h> #include <osmocom/isdn/i460_mux.h> @@ -136,11 +137,46 @@ memset(fr->d_bits, 1, 63 * 4); } +static void d144_play_frame(struct ater_subslot *at, const uint8_t *filerec) +{ + struct osmo_trau_frame *fr = &at->ul_frame; + struct msgb *msg; + int len; + + msg = msgb_alloc_c(g_ctx, 320, "TRAU-UL-frame"); + if (!msg) + return; + fr->type = OSMO_TRAU16_FT_EDATA; + fr->dir = OSMO_TRAU_DIR_UL; + fr->c_bits[5] = 0; + memset(fr->c_bits + 6, 1, 7); + fr->m_bits[0] = (filerec[1] & 2) >> 1; + fr->m_bits[1] = filerec[1] & 1; + osmo_pbit2ubit(fr->d_bits, filerec + 2, 288); + len = osmo_trau_frame_encode(msg->tail, msgb_tailroom(msg), fr); + if (len <= 0) { + msgb_free(msg); + return; + } + msgb_put(msg, len); + osmo_i460_mux_enqueue(at->schan, msg); +} + static void handle_d144(int nr) { struct ater_subslot *at = &subslots[nr]; struct msgb *msg; + if (at->play_buffer) { + d144_play_frame(at, at->play_buffer + at->play_buf_ptr * 38); + at->play_buf_ptr++; + if (at->play_buf_ptr < at->play_buf_total) + return; + free(at->play_buffer); + at->play_buffer = NULL; + printf("file play finished\n"); + return; + } msg = msgb_alloc_c(g_ctx, 320, "TRAU-UL-frame"); if (!msg) return;
--- a/ater/user_cmd.c Tue Sep 24 06:15:40 2024 +0000 +++ b/ater/user_cmd.c Wed Sep 25 05:53:38 2024 +0000 @@ -23,6 +23,7 @@ {"dset", cmd_set_dbits}, {"edata", cmd_set_edata}, {"play", cmd_play_file}, + {"play-d144", cmd_play_d144}, {"play-stop", cmd_play_stop}, {"print-rx", cmd_print_rx}, {"record", cmd_record_start},