FreeCalypso > hg > fc-tourmaline
view src/cs/layer1/cfile/l1_tch_tap.c @ 301:4bb5772a05a3
AT%SPVER: new command for setting custom speech version lists
The speech version list in the Bearer Capability IE tells the network
which speech codecs are supported by the MS, and in which order of
preference. The standard behaviour is to list all codecs that are
supported by the hw+fw platform, and the standard preference order
is newer over older, FR over HR. But sometimes it is desirable
(for network testing) to artificially restrict which codecs the test MS
will declare as supported, and/or to list them in some peculiar
non-standard order of preference. Add a new private AT command,
AT%SPVER, allowing the user to set and clear custom speech version
lists for the Bearer Capability IE composer in CC.
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Sun, 21 May 2023 21:43:10 +0000 |
| parents | edcb8364d45b |
| children |
line wrap: on
line source
/* * This module is a FreeCalypso addition; it contains code implementing * our TCH tap functional additions: TCH downlink capture and TCH uplink * play. */ #include "l1_macro.h" #include "l1_confg.h" #include "l1_types.h" #include "sys_types.h" #include <string.h> #include "l1_const.h" #if TESTMODE #include "l1tm_defty.h" #endif #if (AUDIO_TASK == 1) #include "l1audio_const.h" #include "l1audio_cust.h" #include "l1audio_defty.h" #endif #if (L1_GTT == 1) #include "l1gtt_const.h" #include "l1gtt_defty.h" #endif #if (L1_MIDI == 1) #include "l1midi_defty.h" #endif #include "l1_defty.h" #include "l1_varex.h" #include "l1_trace.h" #include "tch_tap_proto.h" T_RVT_USER_ID tch_tap_rvt_id; BOOL tch_dl_sniff_mode, tch_ul_play_mode; void tch_send_downlink_bits(API *dsp_buffer, UWORD8 nwords, UWORD8 chan_mode, UWORD8 fn_mod_104) { UWORD16 size; T_RVT_BUFFER buf; T_RVT_RET rc; UINT8 *dp; UWORD16 apiword; int i; size = nwords * 2 + 3; rc = rvt_mem_alloc(tch_tap_rvt_id, size, &buf); if (rc != RVT_OK) return; dp = buf; *dp++ = TCH_DLBITS_NEW_IND; *dp++ = chan_mode; *dp++ = fn_mod_104; for (i = 0; i < nwords; i++) { apiword = dsp_buffer[i]; *dp++ = apiword >> 8; *dp++ = apiword; } rvt_send_trace_no_cpy(buf, tch_tap_rvt_id, size, RVT_BINARY_FORMAT); } static void send_tch_ulbits_conf(void) { T_RVT_BUFFER buf; T_RVT_RET rc; rc = rvt_mem_alloc(tch_tap_rvt_id, 1, &buf); if (rc == RVT_OK) { buf[0] = TCH_ULBITS_CONF; rvt_send_trace_no_cpy(buf, tch_tap_rvt_id, 1, RVT_BINARY_FORMAT); } } #define UPLINK_QUEUE_SIZE 5 #define WORDS_PER_ENTRY 17 static UWORD16 uplink_data[UPLINK_QUEUE_SIZE][WORDS_PER_ENTRY]; static volatile int ul_read_ptr, ul_write_ptr; void tchf_substitute_uplink(API *dsp_buffer) { int read_ptr; int i; read_ptr = ul_read_ptr; if (read_ptr == ul_write_ptr) { /* no uplink substitution */ l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~B_PLAY_UL; tch_ul_play_mode = FALSE; return; } for (i = 0; i < WORDS_PER_ENTRY; i++) dsp_buffer[i+3] = uplink_data[read_ptr][i]; // Fill data block Header... dsp_buffer[0] = (1 << B_BLUD); // 1st word: Set B_BLU bit. dsp_buffer[1] = 0; // 2nd word: cleared. dsp_buffer[2] = 0; // 3rd word: cleared. l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_PLAY_UL; /* advance the read pointer and send TCH_ULBITS_CONF */ read_ptr++; if (read_ptr >= UPLINK_QUEUE_SIZE) read_ptr = 0; ul_read_ptr = read_ptr; send_tch_ulbits_conf(); } static void handle_tch_ulbits_req(T_RVT_BUFFER pkt) { int write_ptr, write_next, i; UINT8 *sp; write_ptr = ul_write_ptr; write_next = write_ptr + 1; if (write_next >= UPLINK_QUEUE_SIZE) write_next = 0; if (write_next == ul_read_ptr) /* queue full */ return; sp = pkt + 1; for (i = 0; i < WORDS_PER_ENTRY; i++) { uplink_data[write_ptr][i] = (sp[0] << 8) | sp[1]; sp += 2; } ul_write_ptr = write_next; tch_ul_play_mode = TRUE; } static void handle_tch_config_req(T_RVT_BUFFER pkt) { UWORD8 config; T_RVT_BUFFER buf; T_RVT_RET rc; config = pkt[1] & 0x01; tch_dl_sniff_mode = config; /* send TCH_CONFIG_CONF response */ rc = rvt_mem_alloc(tch_tap_rvt_id, 2, &buf); if (rc == RVT_OK) { buf[0] = TCH_CONFIG_CONF; buf[1] = config; rvt_send_trace_no_cpy(buf, tch_tap_rvt_id, 2, RVT_BINARY_FORMAT); } } /* * The following function is the callback registered with RVT; it gets * called in RVT HISR context. */ static void tch_rvt_input_callback(T_RVT_BUFFER pkt, UINT16 pktlen) { if (pktlen < 1) return; switch (pkt[0]) { case TCH_CONFIG_REQ: if (pktlen != 2) return; handle_tch_config_req(pkt); break; case TCH_ULBITS_REQ: if (pktlen < 34) return; handle_tch_ulbits_req(pkt); break; } } void tch_tap_init(void) { rvt_register_id("TCH", &tch_tap_rvt_id, tch_rvt_input_callback); tch_dl_sniff_mode = FALSE; tch_ul_play_mode = FALSE; ul_read_ptr = 0; ul_write_ptr = 0; }
