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