FreeCalypso > hg > freecalypso-citrine
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 } |