FreeCalypso > hg > ice1-trau-tester
view pcm/pcm_tx.c @ 37:26c9535df39e
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.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 29 Aug 2024 19:02:02 +0000 |
parents | fa341317c844 |
children |
line wrap: on
line source
/* * In this module we implement PCM Tx toward the TRAU. */ #include <sys/types.h> #include <sys/file.h> #include <sys/stat.h> #include <ctype.h> #include <stdint.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <osmocom/core/select.h> #include "globals.h" static const uint8_t dmw_alaw[8] = {0x34, 0x21, 0x21, 0x34, 0xB4, 0xA1, 0xA1, 0xB4}; static uint8_t pcm_fill_octet = 0x54; static bool dmw_active; static uint8_t *play_buffer; static unsigned play_buf_nframes, play_buf_ptr; static void fill_with_dmw(uint8_t *buf) { unsigned n; for (n = 0; n < 20; n++) { memcpy(buf, dmw_alaw, 8); buf += 8; } } static void fill_with_play(uint8_t *outbuf) { memcpy(outbuf, play_buffer + play_buf_ptr * 160, 160); play_buf_ptr++; if (play_buf_ptr < play_buf_nframes) return; free(play_buffer); play_buffer = NULL; printf("file play finished\n"); } void transmit_pcm_20ms(void) { uint8_t buf[160]; if (play_buffer) fill_with_play(buf); else if (dmw_active) fill_with_dmw(buf); else memset(buf, pcm_fill_octet, 160); write(ts_fd, buf, 160); } void cmd_pcm_fill(int argc, char **argv) { u_long val; char *cp; if (argc != 2) { printf("error: pcm-fill command needs 1 argument\n"); return; } if (!isxdigit(argv[1][0])) { inv_arg: printf("error: argument is not a valid hex octet\n"); return; } val = strtoul(argv[1], &cp, 16); if (*cp) goto inv_arg; if (val > 0xFF) goto inv_arg; pcm_fill_octet = val; } void cmd_dmw_on(int argc, char **argv) { dmw_active = true; } void cmd_dmw_off(int argc, char **argv) { dmw_active = false; } void cmd_play_file(int argc, char **argv) { int fd; struct stat st; if (argc != 2) { printf("error: play command needs 1 argument\n"); return; } if (play_buffer) { printf("error: file play already in progress\n"); return; } fd = open(argv[1], O_RDONLY); if (fd < 0) { perror(argv[1]); return; } fstat(fd, &st); if (!S_ISREG(st.st_mode)) { close(fd); fprintf(stderr, "error: %s is not a regular file\n", argv[1]); return; } if (!st.st_size) { close(fd); fprintf(stderr, "error: %s is an empty file\n", argv[1]); return; } if (st.st_size % 160) { close(fd); fprintf(stderr, "error: size of %s is not a multiple of 160 bytes\n", argv[1]); return; } play_buffer = malloc(st.st_size); if (!play_buffer) { close(fd); fprintf(stderr, "unable to malloc buffer for %s\n", argv[1]); return; } read(fd, play_buffer, st.st_size); close(fd); play_buf_nframes = st.st_size / 160; play_buf_ptr = 0; } void cmd_play_offset(int argc, char **argv) { int fd; struct stat st; unsigned offset, pre_offset; if (argc != 3) { printf("error: play-offset command needs 2 arguments\n"); return; } if (play_buffer) { printf("error: file play already in progress\n"); return; } offset = strtoul(argv[2], NULL, 0); if (offset < 1 || offset > 159) { printf("error: offset argument out of range\n"); return; } fd = open(argv[1], O_RDONLY); if (fd < 0) { perror(argv[1]); return; } fstat(fd, &st); if (!S_ISREG(st.st_mode)) { close(fd); fprintf(stderr, "error: %s is not a regular file\n", argv[1]); return; } if (!st.st_size) { close(fd); fprintf(stderr, "error: %s is an empty file\n", argv[1]); return; } if (st.st_size % 160) { close(fd); fprintf(stderr, "error: size of %s is not a multiple of 160 bytes\n", argv[1]); return; } play_buffer = malloc(st.st_size + 160); if (!play_buffer) { close(fd); fprintf(stderr, "unable to malloc buffer for %s\n", argv[1]); return; } pre_offset = 160 - offset; memset(play_buffer, pcm_fill_octet, pre_offset); read(fd, play_buffer + pre_offset, st.st_size); close(fd); memset(play_buffer + pre_offset + st.st_size, pcm_fill_octet, offset); play_buf_nframes = st.st_size / 160 + 1; play_buf_ptr = 0; } void cmd_play_stop(int argc, char **argv) { if (!play_buffer) { printf("error: no file play in progress\n"); return; } free(play_buffer); play_buffer = NULL; }