FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/g23m-aci/bat/bat_l2p.c @ 775:eedbf248bac0
gsm-fw/g23m-aci subtree: initial import from LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 12 Oct 2014 01:45:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
774:40a721fd9854 | 775:eedbf248bac0 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : | |
4 | Modul : BAT | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2005 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : This Modul holds the functions | |
18 | for the L2P interface | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #define _BAT_L2P_C_ | |
23 | |
24 /*==== INCLUDES =============================================================*/ | |
25 #include "typedefs.h" | |
26 #include "gdd.h" | |
27 #include "gdd_sys.h" /* to get semaphore access */ | |
28 #include "l2p_types.h" | |
29 #include "l2p.h" | |
30 #include "bat.h" | |
31 #include "bat_ctrl.h" | |
32 #include "bat_intern.h" | |
33 | |
34 /*==== DEFINES ===========================================================*/ | |
35 #define ENTER_CRITICAL_SECTION(sem) if (bat_enter_critical_section(sem))return (NULL); | |
36 #define LEAVE_CRITICAL_SECTION(sem) if (bat_leave_critical_section(sem))return -1; | |
37 | |
38 /*==== LOCAL VARS ===========================================================*/ | |
39 | |
40 | |
41 /*==== LOCAL FUNCTIONS =====================================================*/ | |
42 | |
43 LOCAL void bat_semaphore_err (void) | |
44 { | |
45 static U8 out = 0; | |
46 if (!out) | |
47 { | |
48 out = 1; | |
49 BAT_TRACE_ERROR("semaphore error"); | |
50 } | |
51 } | |
52 | |
53 | |
54 LOCAL int bat_enter_critical_section (T_HANDLE sem) | |
55 { | |
56 if (gdd_sys_sem_down (sem) NEQ VSI_OK) | |
57 { | |
58 bat_semaphore_err(); | |
59 return -1; | |
60 } | |
61 else | |
62 { | |
63 return 0; | |
64 } | |
65 } | |
66 | |
67 | |
68 LOCAL int bat_leave_critical_section (T_HANDLE sem) | |
69 { | |
70 if (gdd_sys_sem_up(sem) NEQ VSI_OK) | |
71 { | |
72 bat_semaphore_err(); | |
73 return -1; | |
74 } | |
75 else | |
76 { | |
77 return 0; | |
78 } | |
79 } | |
80 | |
81 /* | |
82 * we have to maintain some stuff for L2P_Receive(). | |
83 */ | |
84 LOCAL void bat_update_l2p_mt (T_BAT_instance_maintain *inst_mt, T_GDD_SEGMENT *desc, U16 length, BOOL substract) | |
85 { | |
86 BAT_TRACE_EVENT_P1("bat_update_l2p_mt(): segment len is %d", length); | |
87 inst_mt->l2p_mt.desc = desc; | |
88 if (substract) | |
89 { | |
90 inst_mt->l2p_mt.length = inst_mt->l2p_mt.length - length; | |
91 } | |
92 else | |
93 { | |
94 inst_mt->l2p_mt.length = length; | |
95 } | |
96 } | |
97 | |
98 | |
99 LOCAL T_GDD_SEGMENT *bat_get_from_l2p_mt_desc (T_BAT_instance_maintain *inst_mt) | |
100 { | |
101 return (inst_mt->l2p_mt.desc); | |
102 } | |
103 | |
104 LOCAL U16 bat_get_from_l2p_mt_length (T_BAT_instance_maintain *inst_mt) | |
105 { | |
106 return (inst_mt->l2p_mt.length); | |
107 } | |
108 | |
109 | |
110 | |
111 /* | |
112 +----------------------------------------------------------------------------+ | |
113 | PROJECT : MODULE : BINARY AT COMMAND LIBRARY | | |
114 | STATE : code ROUTINE : bat_l2p_receive | | |
115 +----------------------------------------------------------------------------+ | |
116 PURPOSE : | |
117 This function is a wrapper around L2P_Receive to have all L2P related stuff | |
118 in one module. | |
119 */ | |
120 | |
121 BOOL bat_l2p_receive (U8 inst_hndl, T_GDD_BUF *buf) | |
122 { | |
123 T_BAT_instance_maintain *inst_mt = NULL; | |
124 T_GDD_SEGMENT *seg = NULL; | |
125 U16 length = 0; | |
126 T_L2P_STATUS l2p_status; | |
127 | |
128 if (bat_get_instance_from_instance_handle(inst_hndl, &inst_mt)) | |
129 { | |
130 BAT_TRACE_ERROR ("bat_l2p_receive(): inst_hndl is not correct!"); | |
131 return (FALSE); | |
132 } | |
133 | |
134 inst_mt->buffer.gdd_buf_rcv = buf; | |
135 BAT_TRACE_EVENT_P2 ("bat_l2p_receive(): data length: %d, has c_segment %d", buf->length, buf->c_segment); | |
136 | |
137 seg = buf->ptr_gdd_segment; | |
138 ++seg; /* Skip first segment which is the protocol ID and not needed */ | |
139 | |
140 length = buf->length; | |
141 | |
142 bat_update_l2p_mt (inst_mt, seg, length, FALSE); | |
143 | |
144 /* | |
145 * for the case that the BAT Module at ACI was not able to send BAT responses/indications, | |
146 * it builds up a linked list of responses/indications, | |
147 * which then is sent at once when BAT Module was able again. | |
148 * That is why we have here to iterate over the GDD list. | |
149 */ | |
150 do | |
151 { | |
152 /* | |
153 * within L2P_Receive() is called bat_l2p_get_next_buf_seg() if neccessary (fragmentation) | |
154 * and finally it is called bat_l2p_message_rxd(). | |
155 * Within bat_l2p_message_rxd() is called the application's callback. | |
156 */ | |
157 BAT_TRACE_EVENT("bat_l2p_receive() loop..."); | |
158 l2p_status = L2P_Receive(inst_hndl, seg->ptr_data, seg+1, length, seg->c_data); | |
159 switch (l2p_status) | |
160 { | |
161 case (L2P_STAT_SUCCESS): | |
162 { | |
163 /* for the next iteration get the updated parameter for L2P_Receive() */ | |
164 seg = bat_get_from_l2p_mt_desc(inst_mt); | |
165 length = bat_get_from_l2p_mt_length(inst_mt); | |
166 break; | |
167 } | |
168 default: /* any error */ | |
169 { | |
170 BAT_TRACE_EVENT_P1("bat_l2p_receive(): L2P status = %d", l2p_status); | |
171 return (FALSE); | |
172 } | |
173 } | |
174 } while(seg); | |
175 | |
176 return (TRUE); | |
177 } | |
178 | |
179 | |
180 /*==== functions exported to L2P ============================================*/ | |
181 | |
182 /* | |
183 * This function is called by L2P_Send() and L2P_Receive() | |
184 */ | |
185 void *bat_l2p_get_next_buf_seg (U8 inst_hndl, void *seg_hdr, void **seg_hdr_ptr, U16 *segSize) | |
186 { | |
187 T_BAT_instance_maintain *inst_mt = NULL; | |
188 T_GDD_SEGMENT *gdd_seg = (T_GDD_SEGMENT *)seg_hdr; | |
189 T_GDD_SEGMENT *seg = NULL; | |
190 | |
191 if (seg_hdr EQ NULL) | |
192 { | |
193 BAT_TRACE_EVENT ("bat_l2p_get_next_buf_seg(): GDD buffer is complete"); | |
194 return (NULL); | |
195 } | |
196 | |
197 if (bat_get_instance_from_instance_handle(inst_hndl, &inst_mt)) | |
198 { | |
199 BAT_TRACE_ERROR ("bat_l2p_get_next_buf_seg(): inst_hndl is not correct!"); | |
200 return (NULL); | |
201 } | |
202 | |
203 /* check whether we are in RX context (it is called for TX as well) */ | |
204 seg = bat_get_from_l2p_mt_desc(inst_mt); | |
205 | |
206 if (seg AND ((seg+1) EQ gdd_seg)) | |
207 { | |
208 bat_update_l2p_mt(inst_mt, gdd_seg+1, gdd_seg->c_data, TRUE); | |
209 } | |
210 | |
211 return (void*)(gdd_seg->ptr_data); | |
212 } | |
213 | |
214 | |
215 void *bat_l2p_get_tx_buffer(T_BAT_instance inst_hndl, U16 data_size, | |
216 void **seg_hdr_ptr, U16 *total_size, U16 *seg_size) | |
217 { | |
218 T_BAT_instance_maintain *inst_mt = NULL; | |
219 T_GDD_BUF *buf = NULL; | |
220 T_GDD_SEGMENT * seg = NULL; | |
221 | |
222 BAT_TRACE_FUNCTION ("bat_l2p_get_tx_buffer()"); | |
223 | |
224 if (bat_get_instance_from_instance_handle(inst_hndl, &inst_mt)) | |
225 { | |
226 BAT_TRACE_ERROR ("bat_l2p_get_tx_buffer(): inst_hndl is not correct!"); | |
227 return (NULL); | |
228 } | |
229 | |
230 if (data_size >= (int)(inst_mt->config->adapter.cap.dio_cap.mtu_size)) | |
231 { | |
232 BAT_TRACE_ERROR ("bat_l2p_get_tx_buffer(): requested buffer too big!"); | |
233 return (NULL); | |
234 } | |
235 | |
236 /* | |
237 * according to GR we have to make | |
238 * gdd_get_send_buffer() and gdd_send_data() "atomic", | |
239 * which means we release the semaphore in bat_l2p_send_frame() | |
240 */ | |
241 ENTER_CRITICAL_SECTION(inst_mt->sem_BAT); | |
242 | |
243 if (inst_mt->config->adapter.gdd_if.gdd_get_send_buffer | |
244 ((T_GDD_CON_HANDLE)(inst_mt->con_handle), &buf, data_size) NEQ GDD_OK) | |
245 { | |
246 BAT_TRACE_ERROR ("bat_l2p_get_tx_buffer(): call to get gdd buffer failed!"); | |
247 return (NULL); | |
248 } | |
249 /* To memorize the buffer address for later sending */ | |
250 inst_mt->buffer.gdd_buf = buf; | |
251 /* the first 2 bytes are not used */ | |
252 *total_size = (U16)(buf->length - 2); | |
253 /*store the pointer pointing to the next seg, ignore the first ptr bec it is for other purpose*/ | |
254 | |
255 seg = buf->ptr_gdd_segment; | |
256 ++seg; /* Skip first segment which is the protocol ID and not needed */ | |
257 *seg_hdr_ptr = (void*)(seg+1); | |
258 *seg_size = seg->c_data; | |
259 | |
260 return (void*)(seg->ptr_data); | |
261 } | |
262 | |
263 | |
264 int bat_l2p_send_frame(T_BAT_instance inst_hndl) | |
265 { | |
266 T_BAT_instance_maintain *inst_mt = NULL; | |
267 | |
268 BAT_TRACE_FUNCTION ("bat_l2p_send_frame()"); | |
269 | |
270 | |
271 if (bat_get_instance_from_instance_handle(inst_hndl, &inst_mt)) | |
272 { | |
273 BAT_TRACE_ERROR ("bat_l2p_send_frame(): inst_hndl is not correct!"); | |
274 return (0); | |
275 } | |
276 | |
277 if (inst_mt->config->adapter.gdd_if.gdd_send_data | |
278 ((T_GDD_CON_HANDLE)(inst_mt->con_handle), inst_mt->buffer.gdd_buf) NEQ GDD_OK) | |
279 { | |
280 BAT_TRACE_ERROR ("bat_l2p_send_frame(): call to send gdd buffer failed!"); | |
281 LEAVE_CRITICAL_SECTION(inst_mt->sem_BAT); | |
282 return (-1); | |
283 } | |
284 | |
285 LEAVE_CRITICAL_SECTION(inst_mt->sem_BAT); | |
286 /*return OK*/ | |
287 return (0); | |
288 } | |
289 | |
290 | |
291 void *bat_l2p_get_rx_buffer(U8 inst_hndl) | |
292 { | |
293 T_BAT_instance_maintain *inst_mt = NULL; | |
294 | |
295 BAT_TRACE_FUNCTION ("bat_l2p_get_rx_buffer()"); | |
296 | |
297 if (bat_get_instance_from_instance_handle(inst_hndl, &inst_mt)) | |
298 { | |
299 BAT_TRACE_ERROR ("bat_l2p_get_rx_buffer(): inst_hndl is not correct!"); | |
300 return (NULL); | |
301 } | |
302 /* set the state of the buffer */ | |
303 bat_change_buffer_state(inst_mt, BAT_BUF_FILLING); | |
304 | |
305 return (inst_mt->buffer.data); | |
306 } | |
307 | |
308 | |
309 void bat_l2p_message_rxd (U8 inst_hndl, U8 client_id, U32 data_tag, void *data_ptr, U16 data_size) | |
310 { | |
311 T_BAT_instance_maintain *inst_mt = NULL; | |
312 T_BATC_confirm cnf; | |
313 T_BAT_return ret = BAT_ERROR; | |
314 T_GDD_SEGMENT * seg = NULL; | |
315 | |
316 data_size = data_size; /* prevent compiler warnings */ | |
317 | |
318 BAT_TRACE_FUNCTION ("bat_l2p_message_rxd()"); | |
319 | |
320 if (bat_get_instance_from_instance_handle(inst_hndl, &inst_mt)) | |
321 { | |
322 BAT_TRACE_ERROR ("bat_l2p_message_rxd(): inst_hndl is not correct!"); | |
323 return; | |
324 } | |
325 | |
326 bat_change_buffer_state(inst_mt, BAT_BUF_FILLED); | |
327 | |
328 switch (client_id) | |
329 { | |
330 case (BAT_CONTROL_CHANNEL): | |
331 { | |
332 cnf.rsp.ptr_bat_open_client_cnf = data_ptr; | |
333 cnf.rsp_params = (T_BATC_rsp_param)data_tag; | |
334 ret = bat_control_confirm_rcv (inst_hndl, cnf); | |
335 break; | |
336 } | |
337 case (BAT_BROADCAST_CHANNEL): | |
338 { | |
339 inst_mt->buffer.rsp.ctrl_response = (T_BAT_ctrl_response)data_tag; | |
340 inst_mt->buffer.rsp.response.ptr_at_ok = data_ptr; | |
341 ret = bat_unsolicited_code_rcv (inst_hndl, &(inst_mt->buffer.rsp)); | |
342 break; | |
343 } | |
344 default: | |
345 { | |
346 inst_mt->buffer.rsp.ctrl_response = (T_BAT_ctrl_response)data_tag; | |
347 inst_mt->buffer.rsp.response.ptr_at_ok = data_ptr; | |
348 ret = bat_command_response_rcv (inst_hndl, client_id, &(inst_mt->buffer.rsp)); | |
349 break; | |
350 } | |
351 } | |
352 switch (ret) | |
353 { | |
354 case (BAT_OK): | |
355 case (BAT_BUSY_RESOURCE): | |
356 { | |
357 break; | |
358 } | |
359 case (BAT_ERROR): | |
360 { | |
361 BAT_TRACE_ERROR ("bat_l2p_message_rxd(): received data have not been processed!"); | |
362 break; | |
363 } | |
364 } | |
365 | |
366 seg = bat_get_from_l2p_mt_desc(inst_mt); | |
367 | |
368 if (seg) | |
369 { | |
370 /* Get next segment */ | |
371 int cur_idx = seg - inst_mt->buffer.gdd_buf_rcv->ptr_gdd_segment; | |
372 T_GDD_SEGMENT * next_seg; | |
373 | |
374 BAT_TRACE_EVENT_P1("buffer starts at 0x%08x", inst_mt->buffer.gdd_buf_rcv->ptr_gdd_segment); | |
375 BAT_TRACE_EVENT_P1("seg is 0x%08x", seg); | |
376 | |
377 BAT_TRACE_EVENT_P1("cur_idx is %d", cur_idx); | |
378 | |
379 if(cur_idx >= inst_mt->buffer.gdd_buf_rcv->c_segment-1) | |
380 next_seg = 0; | |
381 else | |
382 next_seg = ++seg; | |
383 | |
384 if (next_seg EQ NULL) | |
385 { | |
386 bat_update_l2p_mt(inst_mt, NULL, 0, FALSE); | |
387 } | |
388 else | |
389 { | |
390 /* | |
391 * update to the next GDD descriptor, which has a L2P header | |
392 * and reduce the overall L2P data length by the currently processed data length | |
393 */ | |
394 bat_update_l2p_mt(inst_mt, next_seg, seg->c_data, TRUE); | |
395 } | |
396 } | |
397 } | |
398 |