comparison gsm-fw/g23m-aci/gdd_dio/gdd_dio_if.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 :
5 +-----------------------------------------------------------------------------
6 | Copyright 2004 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 : Implementation of the GDD interface with DIOv4
18 +-----------------------------------------------------------------------------
19 */
20
21 #define GDD_DIO_IF_C
22
23 /*==== INCLUDES =============================================================*/
24
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stddef.h>
28 #include "typedefs.h"
29 #include "pcm.h"
30 #include "vsi.h"
31 #include "custom.h"
32 #include "gsm.h"
33 #include "pei.h"
34
35 #include "gdd.h"
36 #include "gdd_dio_data.h"
37 #include "gdd_dio.h"
38
39 #include "gdd_dio_con_mgr.h"
40 #include "gdd_dio_queue.h"
41
42 #include "gdd_dio_dtxf.h"
43 #include "gdd_dio_drxf.h"
44
45
46 /*==== CONSTANTS ============================================================*/
47
48 /*==== TYPES ================================================================*/
49
50 /*==== PROTOTYPES ===========================================================*/
51
52 /*==== GLOBAL VARS ==========================================================*/
53
54 /*==== LOCAL VARS ===========================================================*/
55
56 /*==== LOCAL FUNCTIONS=======================================================*/
57
58 /*==== EXPORTED FUNCTIONS====================================================*/
59
60 /** gdd_init_dio - see header "gdd.h" for comment and description */
61
62 GDD_RESULT gdd_init_dio
63 (
64 T_GDD_INST_ID inst,
65 void * mem,
66 U16 num_con
67 )
68 {
69 T_GDD_DIO_DATA * gdd_dio_data;
70
71 TRACE_FUNCTION("[GDD] gdd_init_dio()");
72
73 /* Check params */
74 if(inst < GDD_INST_BAT || inst >= GDD_NUM_INSTS)
75 {
76 TRACE_ERROR("[GDD] Instance id out of bounds");
77 return GDD_INVALID_PARAMS;
78 }
79
80 gdd_dio_data = &gdd_dio_data_base[inst];
81
82 if(gdd_dio_init_flag[inst])
83 {
84 TRACE_ERROR("[GDD] Attempted to call gdd_init_dio() twice for same instance");
85 return GDD_ALREADY_INITIALIZED;
86 }
87
88 if(num_con < 1 || num_con > gdd_dio_data->max_con)
89 {
90 TRACE_ERROR("[GDD] Number of connections out of bounds");
91 return GDD_INVALID_PARAMS;
92 }
93
94 if(mem)
95 {
96 gdd_dio_data->con_arr = mem;
97 gdd_dio_data->con_arr_mem_allocated = FALSE;
98 }
99 else
100 {
101 gdd_dio_data->con_arr = 0;
102 MALLOC(gdd_dio_data->con_arr, GDD_DIO_SIZEOF_CONDATA * num_con);
103 if(gdd_dio_data->con_arr EQ 0)
104 {
105 TRACE_ERROR("[GDD] memory allocation failed");
106 return GDD_NO_MEMORY;
107 }
108
109 gdd_dio_data->con_arr_mem_allocated = TRUE;
110 }
111
112 gdd_dio_data->max_con = num_con;
113
114 /* Initialize the connection manager */
115 gdd_dio_con_mgr_init(gdd_dio_data);
116
117 gdd_dio_init_flag[inst] = TRUE;
118
119 return GDD_OK;
120 }
121
122
123 /** gdd_deinit - see header "gdd.h" for comment and description*/
124 GDD_RESULT gdd_deinit_dio
125 (
126 T_GDD_INST_ID inst
127 )
128 {
129 T_GDD_DIO_DATA * gdd_dio_data = 0;
130
131 TRACE_FUNCTION("[GDD] gdd_deinit_dio()");
132
133 if(inst < GDD_INST_BAT || inst >= GDD_NUM_INSTS)
134 {
135 TRACE_ERROR("[GDD] instance id out of bounds");
136 return GDD_INVALID_PARAMS;
137 }
138
139 gdd_dio_data = &gdd_dio_data_base[inst];
140
141
142 /* If we allocated our own memory, free it. */
143 if(gdd_dio_data->con_arr_mem_allocated EQ FALSE)
144 {
145 MFREE(gdd_dio_data->con_arr);
146 gdd_dio_data->con_arr = 0;
147 gdd_dio_data->con_arr_mem_allocated = FALSE;
148 }
149
150 gdd_dio_init_flag[inst] = FALSE;
151
152 return GDD_OK;
153 }
154
155
156 /** gdd_connect - see header "gdd.h" for comment and description */
157 GDD_RESULT gdd_connect_dio
158 (
159 T_GDD_INST_ID inst,
160 T_GDD_CON_HANDLE * con_handle,
161 const T_GDD_CAP * cap,
162 T_GDD_RECEIVE_DATA_CB rcv_cb,
163 T_GDD_SIGNAL_CB sig_cb
164 )
165 {
166 T_GDD_DIO_DATA * gdd_dio_data;
167
168 TRACE_FUNCTION("[GDD] gdd_connect_dio()");
169
170 /**
171 * Do the necessary checks.
172 */
173
174 if(inst < GDD_INST_BAT || inst >= GDD_NUM_INSTS)
175 {
176 TRACE_ERROR("[GDD] instance id out of bounds");
177 return GDD_INVALID_PARAMS;
178 }
179
180 gdd_dio_data = &gdd_dio_data_base[inst];
181
182 if (gdd_dio_data->ker.state NEQ GDD_DIO_KER_READY)
183 {
184 TRACE_ERROR("[GDD] DIO driver not initialized");
185 return DRV_INTERNAL_ERROR;
186 }
187
188 /* Check if we are already initialized. If we not, we do it ourselfs! */
189 /* This is specific to the DIO implementation of GDD */
190 if(gdd_dio_init_flag[inst] EQ FALSE)
191 {
192 gdd_init_dio(inst, 0, gdd_dio_data->max_con);
193 }
194
195 if(con_handle EQ 0)
196 {
197 TRACE_ERROR("[GDD] Connection handle pointer cannot be 0");
198 return GDD_INVALID_PARAMS;
199 }
200
201 if(cap EQ 0)
202 {
203 TRACE_ERROR("[GDD] Capabilities pointer cannot be 0");
204 return GDD_INVALID_PARAMS;
205 }
206
207 if(rcv_cb EQ 0 || sig_cb EQ 0)
208 {
209 TRACE_ERROR("[GDD] Callback function pointer cannot be 0");
210 return GDD_INVALID_PARAMS;
211 }
212
213 /**
214 * We are ready to create the DIO connection
215 */
216 return gdd_dio_con_mgr_new(gdd_dio_data, con_handle, cap, rcv_cb, sig_cb);
217 }
218
219 /** gdd_disconnect - see header "gdd.h" for comment and description */
220 GDD_RESULT gdd_disconnect_dio
221 (
222 T_GDD_CON_HANDLE con_handle
223 )
224 {
225 if(con_handle EQ 0)
226 {
227 TRACE_ERROR("[GDD] Connection handle cannot be 0");
228 return GDD_INVALID_PARAMS;
229 }
230
231 /*
232 * Inform the connection manager
233 */
234 return gdd_dio_con_mgr_close(con_handle);
235 }
236
237
238 /** gdd_get_send_buffer - see header "gdd.h" for comment and description */
239 GDD_RESULT gdd_get_send_buffer_dio
240 (
241 T_GDD_CON_HANDLE con_handle,
242 T_GDD_BUF ** buf,
243 U16 data_size
244 )
245 {
246 TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_get_send_buffer_dio()");
247
248 if(con_handle EQ 0)
249 {
250 TRACE_ERROR("[GDD] Connection handle cannot be 0");
251 return GDD_INVALID_PARAMS;
252 }
253 if(buf EQ NULL)
254 {
255 TRACE_ERROR("[GDD] buf cannot be NULL");
256 return GDD_INVALID_PARAMS;
257 }
258
259 return gdd_dio_dtx_get_send_buffer(con_handle, buf, data_size);
260 }
261
262
263 /** gdd_send_data - see header "gdd.h" for comment and description */
264 GDD_RESULT gdd_send_data_dio
265 (
266 T_GDD_CON_HANDLE con_handle,
267 T_GDD_BUF * buf
268 )
269 {
270 TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_send_data_dio()");
271
272 if(con_handle EQ 0)
273 {
274 TRACE_ERROR("[GDD] Connection handle cannot be 0");
275 return GDD_INVALID_PARAMS;
276 }
277 if(buf EQ NULL)
278 {
279 TRACE_ERROR("[GDD] buf cannot be NULL");
280 return GDD_INVALID_PARAMS;
281 }
282
283 return gdd_dio_dtx_send_buffer(con_handle, buf);
284 }
285
286
287 /** gdd_signal_ready_rcv - see header "gdd.h" for comment and description */
288 void gdd_signal_ready_rcv_dio( T_GDD_CON_HANDLE con_handle )
289 {
290 TRACE_FUNCTION("[GDD] gdd_signal_ready_rcv_dio()");
291
292 if(con_handle NEQ 0)
293 {
294 return;
295 }
296
297 gdd_dio_drx_ready_to_rcv(con_handle);
298 }
299
300
301 /** Exported function table for DIO implementation of GDD */
302 T_GDD_FUNC gdd_func_dio =
303 {
304 gdd_init_dio,
305 gdd_deinit_dio,
306 gdd_connect_dio,
307 gdd_disconnect_dio,
308 gdd_get_send_buffer_dio,
309 gdd_send_data_dio,
310 gdd_signal_ready_rcv_dio
311 };
312
313
314 /*==== EXPORTED HELPER FUNCTIONS=============================================*/
315
316 S32 gdd_write_buf_with_pid(const U8 * src_buf,
317 U16 src_size,
318 T_GDD_BUF * dest_buf,
319 U8 protocol_id)
320 {
321 int idx_seg;
322 int remaining;
323
324 /* Check that we have more than one segment and that the first one
325 is the PID segment which. */
326 TRACE_ASSERT(dest_buf->c_segment > 1);
327 TRACE_ASSERT(dest_buf->ptr_gdd_segment[0].c_data EQ GDD_DIO_PID_SEG_SIZE);
328
329 if( dest_buf->c_segment < 2 ||
330 dest_buf->ptr_gdd_segment[0].c_data NEQ GDD_DIO_PID_SEG_SIZE )
331 {
332 return -1;
333 }
334
335 /* Set the protocol ID, which is carried in the first buffer segment */
336 /* Note: the DTI2 interface in the stack uses only 8 bits for the p_id. */
337 dest_buf->ptr_gdd_segment[0].ptr_data[0] = 0x0;/* not used, see note above */
338 dest_buf->ptr_gdd_segment[0].ptr_data[1] = protocol_id;
339
340
341 remaining = src_size;
342
343 for(idx_seg=1; idx_seg<dest_buf->c_segment; ++idx_seg)
344 {
345 T_GDD_SEGMENT * seg = &(dest_buf->ptr_gdd_segment[idx_seg]);
346 int bytes_to_copy = remaining < seg->c_data ? remaining : seg->c_data;
347
348 memcpy(seg->ptr_data, src_buf + src_size - remaining, bytes_to_copy);
349 remaining -= bytes_to_copy;
350 if(remaining EQ 0)
351 break;
352 }
353
354 dest_buf->length = src_size - remaining + GDD_DIO_PID_SEG_SIZE;
355 return remaining;
356 }
357
358 #define DTI_PID_IP (0x21) /* simple ip packet (IPv4) */
359
360 S32 gdd_write_buf(const U8 * src_buf, U16 src_size, T_GDD_BUF * dest_buf)
361 {
362 return gdd_write_buf_with_pid(src_buf, src_size, dest_buf, DTI_PID_IP);
363 }
364
365 S32 gdd_read_buf(const T_GDD_BUF * src_buf, U8 * dest_buf, U16 dest_size)
366 {
367 int idx_seg;
368 int remaining;
369
370 /* Check that we have more than one segment and that the first one
371 is the PID segment which. */
372
373 TRACE_ASSERT(src_buf->c_segment > 1);
374 TRACE_ASSERT(src_buf->ptr_gdd_segment[0].c_data EQ GDD_DIO_PID_SEG_SIZE);
375 if( src_buf->c_segment < 2 ||
376 src_buf->ptr_gdd_segment[0].c_data NEQ GDD_DIO_PID_SEG_SIZE )
377 {
378 return -1;
379 }
380
381 remaining = src_buf->length - GDD_DIO_PID_SEG_SIZE;
382 if(remaining > dest_size)
383 {
384 remaining = dest_size;
385 }
386
387 for(idx_seg=1; idx_seg<src_buf->c_segment; ++idx_seg)
388 {
389 T_GDD_SEGMENT * seg = &(src_buf->ptr_gdd_segment[idx_seg]);
390 int bytes_to_copy = remaining < seg->c_data ? remaining : seg->c_data;
391
392 memcpy(dest_buf + dest_size - remaining, seg->ptr_data, bytes_to_copy);
393 remaining -= bytes_to_copy;
394 if(remaining EQ 0)
395 break;
396 }
397
398 return remaining;
399 }