comparison L1/cfile/tch_feature.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 * This module is a FreeCalypso addition; it contains code implementing
3 * our custom voice TCH rerouting feature.
4 */
5
6 #include "config.h"
7 #include "l1_confg.h"
8 #include "l1_types.h"
9 #include "sys_types.h"
10 #include <string.h>
11 #include "l1_const.h"
12 #include "l1_defty.h"
13 #include "l1_varex.h"
14 #include "l1_trace.h"
15 #include "tch_feature.h"
16
17 T_RVT_USER_ID tch_reroute_rvt_id;
18 BOOL tch_reroute_downlink;
19
20 void tch_send_downlink_bits(API *dsp_buffer)
21 {
22 T_RVT_BUFFER buf;
23 T_RVT_RET rc;
24 UINT8 *dp;
25 UWORD16 apiword;
26 int i;
27
28 rc = rvt_mem_alloc(tch_reroute_rvt_id, 41, &buf);
29 if (rc != RVT_OK)
30 return;
31 dp = buf;
32 *dp++ = TCH_DLBITS_IND;
33 for (i = 0; i < 20; i++) {
34 apiword = dsp_buffer[i];
35 *dp++ = apiword >> 8;
36 *dp++ = apiword;
37 }
38 rvt_send_trace_no_cpy(buf, tch_reroute_rvt_id, 41, RVT_BINARY_FORMAT);
39 }
40
41 static void send_tch_ulbits_conf()
42 {
43 T_RVT_BUFFER buf;
44 T_RVT_RET rc;
45
46 rc = rvt_mem_alloc(tch_reroute_rvt_id, 1, &buf);
47 if (rc == RVT_OK) {
48 buf[0] = TCH_ULBITS_CONF;
49 rvt_send_trace_no_cpy(buf, tch_reroute_rvt_id, 1,
50 RVT_BINARY_FORMAT);
51 }
52 }
53
54 #define UPLINK_QUEUE_SIZE 5
55 #define WORDS_PER_ENTRY 17
56
57 static UWORD16 uplink_data[UPLINK_QUEUE_SIZE][WORDS_PER_ENTRY];
58 static volatile int ul_read_ptr, ul_write_ptr;
59
60 void tch_substitute_uplink(API *dsp_buffer)
61 {
62 int read_ptr;
63 int i;
64
65 read_ptr = ul_read_ptr;
66 if (read_ptr == ul_write_ptr) {
67 /* no uplink substitution */
68 l1s_dsp_com.dsp_ndb_ptr->d_tch_mode &= ~B_PLAY_UL;
69 return;
70 }
71 for (i = 0; i < WORDS_PER_ENTRY; i++)
72 dsp_buffer[i+3] = uplink_data[read_ptr][i];
73 // Fill data block Header...
74 dsp_buffer[0] = (1 << B_BLUD); // 1st word: Set B_BLU bit.
75 dsp_buffer[1] = 0; // 2nd word: cleared.
76 dsp_buffer[2] = 0; // 3rd word: cleared.
77 l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_PLAY_UL;
78 /* advance the read pointer and send TCH_ULBITS_CONF */
79 read_ptr++;
80 if (read_ptr >= UPLINK_QUEUE_SIZE)
81 read_ptr = 0;
82 ul_read_ptr = read_ptr;
83 send_tch_ulbits_conf();
84 }
85
86 static void handle_tch_ulbits_req(T_RVT_BUFFER pkt)
87 {
88 int write_ptr, write_next, i;
89 UINT8 *sp;
90
91 write_ptr = ul_write_ptr;
92 write_next = write_ptr + 1;
93 if (write_next >= UPLINK_QUEUE_SIZE)
94 write_next = 0;
95 if (write_next == ul_read_ptr) /* queue full */
96 return;
97 sp = pkt + 1;
98 for (i = 0; i < WORDS_PER_ENTRY; i++) {
99 uplink_data[write_ptr][i] = (sp[0] << 8) | sp[1];
100 sp += 2;
101 }
102 ul_write_ptr = write_next;
103 }
104
105 static void handle_tch_config_req(T_RVT_BUFFER pkt)
106 {
107 UWORD8 config;
108 T_RVT_BUFFER buf;
109 T_RVT_RET rc;
110
111 config = pkt[1] & 0x01;
112 tch_reroute_downlink = config;
113
114 /* send TCH_CONFIG_CONF response */
115 rc = rvt_mem_alloc(tch_reroute_rvt_id, 2, &buf);
116 if (rc == RVT_OK) {
117 buf[0] = TCH_CONFIG_CONF;
118 buf[1] = config;
119 rvt_send_trace_no_cpy(buf, tch_reroute_rvt_id, 2,
120 RVT_BINARY_FORMAT);
121 }
122 }
123
124 /*
125 * The following function is the callback registered with RVT; it gets
126 * called in RVT HISR context.
127 */
128 static void tch_rvt_input_callback(T_RVT_BUFFER pkt, UINT16 pktlen)
129 {
130 if (pktlen < 1)
131 return;
132 switch (pkt[0]) {
133 case TCH_CONFIG_REQ:
134 if (pktlen != 2)
135 return;
136 handle_tch_config_req(pkt);
137 break;
138 case TCH_ULBITS_REQ:
139 if (pktlen < 34)
140 return;
141 handle_tch_ulbits_req(pkt);
142 break;
143 }
144 }
145
146 void feature_tch_reroute_init()
147 {
148 rvt_register_id("TCH", &tch_reroute_rvt_id, tch_rvt_input_callback);
149 tch_reroute_downlink = FALSE;
150 ul_read_ptr = 0;
151 ul_write_ptr = 0;
152 }