FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/g23m-aci/gdd_dio/gdd_dio_con_mgr.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 | File : gdd_dio_con_mgr.c | |
4 +----------------------------------------------------------------------------- | |
5 | Copyright 2002 Texas Instruments Berlin, AG | |
6 | All rights reserved. | |
7 | | |
8 | This file is confidential and a trade secret of Texas | |
9 | Instruments Berlin, AG | |
10 | The receipt of or possession of this file does not convey | |
11 | any rights to reproduce or disclose its contents or to | |
12 | manufacture, use, or sell anything it may describe, in | |
13 | whole, or in part, without the specific written consent of | |
14 | Texas Instruments Berlin, AG. | |
15 +----------------------------------------------------------------------------- | |
16 | Purpose : Implements connection management functions | |
17 +----------------------------------------------------------------------------- | |
18 */ | |
19 | |
20 | |
21 #define ENTITY_GDD_DIO | |
22 | |
23 /*==== INCLUDES =============================================================*/ | |
24 | |
25 #include "typedefs.h" /* to get Condat data types */ | |
26 #include "vsi.h" /* to get a lot of macros */ | |
27 #include "prim.h" /* to get the definitions of used SAP and directions */ | |
28 #include "dti.h" | |
29 | |
30 #include "gdd_dio.h" /* to get the global entity definitions */ | |
31 #include "gdd_dio_queue.h" | |
32 #include "gdd_dio_con_mgr.h" | |
33 | |
34 #include <string.h> | |
35 | |
36 | |
37 /*==== DEFINITIONS ==========================================================*/ | |
38 | |
39 #define ENTER_CRITICAL_SECTION(sem) if (gdd_enter_critical_section(sem))return -1; | |
40 #define LEAVE_CRITICAL_SECTION(sem) if (gdd_leave_critical_section(sem))return -1; | |
41 | |
42 | |
43 /*==== CONST ================================================================*/ | |
44 | |
45 /*==== LOCAL VARS ===========================================================*/ | |
46 | |
47 static T_HANDLE sem_GDD_DIO_CON; | |
48 | |
49 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
50 | |
51 LOCAL int get_free_connection_slot(T_GDD_DIO_DATA * gdd_dio_data, | |
52 T_GDD_DIO_CON_DATA ** con_data /*output*/); | |
53 static void gdd_semaphore_err (void); | |
54 static int gdd_enter_critical_section (T_HANDLE sem); | |
55 static int gdd_leave_critical_section (T_HANDLE sem); | |
56 | |
57 | |
58 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
59 | |
60 | |
61 /* Initializes the connection manager */ | |
62 | |
63 GLOBAL void gdd_dio_con_mgr_init (T_GDD_DIO_DATA * gdd_dio_data) | |
64 { | |
65 int i; | |
66 T_GDD_DIO_CON_DATA * con_data = gdd_dio_data->con_arr; | |
67 | |
68 TRACE_FUNCTION( "[GDD] conn_init()" ); | |
69 | |
70 for(i = 0; i < gdd_dio_data->max_con; ++i, ++con_data) | |
71 { | |
72 con_data->con_state = GDD_DIO_CON_DEAD; | |
73 } | |
74 | |
75 sem_GDD_DIO_CON = vsi_s_open (VSI_CALLER "SEM_GDD_CON",1); | |
76 if (sem_GDD_DIO_CON EQ VSI_ERROR) | |
77 vsi_o_ttrace(VSI_CALLER TC_EVENT, "canīt open semaphore \"SEM_GDD_CON\""); | |
78 } | |
79 | |
80 | |
81 /* Setup a new DIO connection */ | |
82 | |
83 GLOBAL GDD_RESULT gdd_dio_con_mgr_new | |
84 ( T_GDD_DIO_DATA * gdd_dio_data, | |
85 T_GDD_CON_HANDLE * con_handle, | |
86 const T_GDD_CAP * cap, | |
87 T_GDD_RECEIVE_DATA_CB rcv_cb, | |
88 T_GDD_SIGNAL_CB sig_cb ) | |
89 { | |
90 T_GDD_DIO_CON_DATA * con_data = 0; | |
91 | |
92 TRACE_FUNCTION("[GDD] conn_new()"); | |
93 | |
94 if(get_free_connection_slot(gdd_dio_data, &con_data) NEQ 0) | |
95 { | |
96 TRACE_ERROR("Failed to get new connection slot"); | |
97 return GDD_NO_CONNECTION_SLOT; | |
98 } | |
99 | |
100 gdd_dio_queue_clear(&con_data->rx_queue); | |
101 gdd_dio_queue_clear(&con_data->tx_queue); | |
102 | |
103 con_data->wait_send_buf = FALSE; | |
104 | |
105 con_data->rcv_cb = rcv_cb; | |
106 con_data->sig_cb = sig_cb; | |
107 | |
108 con_data->dio_cap.device_type = DIO_TYPE_PKT; | |
109 con_data->dio_cap.device_flags = 0; | |
110 con_data->dio_cap.mtu_control = 0; | |
111 con_data->dio_cap.mtu_data = (U16)((T_GDD_DIO_CAP *)cap)->mtu_size; | |
112 con_data->dio_cap.driver_name = "GDD"; | |
113 | |
114 (*con_handle) = con_data->dio_device; | |
115 | |
116 | |
117 gdd_dio_send_signal_to_dio(con_data, DRV_SIGTYPE_CONNECT); | |
118 | |
119 return GDD_OK; | |
120 } | |
121 | |
122 | |
123 /* Close a connection */ | |
124 | |
125 GLOBAL GDD_RESULT gdd_dio_con_mgr_close | |
126 ( T_GDD_CON_HANDLE con_handle ) | |
127 { | |
128 T_GDD_INST_ID inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle); | |
129 T_GDD_DIO_CON_DATA * con_data; | |
130 | |
131 TRACE_FUNCTION( "[GDD] gdd_dio_con_mgr_close()" ); | |
132 | |
133 con_data = get_con_data(&(gdd_dio_data_base[inst]), con_handle); | |
134 if(con_data EQ NULL) | |
135 { | |
136 TRACE_ERROR("Failed to get connection data"); | |
137 return GDD_INTERNAL_ERROR; | |
138 } | |
139 | |
140 con_data->con_state = GDD_DIO_CON_CLOSE; | |
141 | |
142 gdd_dio_send_signal_to_dio(con_data, DRV_SIGTYPE_DISCONNECT); | |
143 | |
144 return GDD_OK; | |
145 } | |
146 | |
147 | |
148 /* Mark a connection as dead */ | |
149 | |
150 GDD_RESULT gdd_dio_con_mgr_mark_dead( T_GDD_CON_HANDLE con_handle ) | |
151 { | |
152 T_GDD_INST_ID inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle); | |
153 T_GDD_DIO_CON_DATA * con_data; | |
154 | |
155 TRACE_FUNCTION( "[GDD] gdd_dio_con_mgr_mark_dead()" ); | |
156 | |
157 con_data = get_con_data(&(gdd_dio_data_base[inst]), con_handle); | |
158 if(con_data EQ NULL) | |
159 { | |
160 TRACE_ERROR("Failed to get connection data"); | |
161 return GDD_INTERNAL_ERROR; | |
162 } | |
163 | |
164 /* Clear the connection slot | |
165 - it's sufficient to set state and nullify handle */ | |
166 con_data->con_state = GDD_DIO_CON_DEAD; | |
167 | |
168 return GDD_OK; | |
169 } | |
170 | |
171 | |
172 /* Check if any of the connections is (still) open or in connecting state. */ | |
173 | |
174 BOOL gdd_dio_con_mgr_has_open_connection | |
175 ( const T_GDD_DIO_DATA * gdd_dio_data ) | |
176 { | |
177 int i; | |
178 T_GDD_DIO_CON_DATA * con_data = gdd_dio_data->con_arr; | |
179 | |
180 TRACE_FUNCTION( "[GDD] gdd_dio_con_mgr_has_open_connection()" ); | |
181 | |
182 for(i = 0; i < gdd_dio_data->max_con; ++i, ++con_data) | |
183 { | |
184 if(con_data->con_state EQ GDD_DIO_CON_READY || | |
185 con_data->con_state EQ GDD_DIO_CON_SENDING || | |
186 con_data->con_state EQ GDD_DIO_CON_CONNECT) | |
187 { | |
188 return TRUE; | |
189 } | |
190 } | |
191 return FALSE; | |
192 } | |
193 | |
194 | |
195 /* Get the connection data for a given instance & handle */ | |
196 | |
197 GLOBAL T_GDD_DIO_CON_DATA * get_con_data(const T_GDD_DIO_DATA * gdd_dio_data, | |
198 T_GDD_CON_HANDLE con_handle) | |
199 { | |
200 int i; | |
201 | |
202 /* Deliberately NO tracing */ | |
203 | |
204 for(i=0; i<gdd_dio_data->max_con; ++i) | |
205 { | |
206 if(gdd_dio_data->con_arr[i].dio_device EQ con_handle) | |
207 return &gdd_dio_data->con_arr[i]; | |
208 } | |
209 return NULL; | |
210 } | |
211 | |
212 | |
213 | |
214 /* Get the connection data for a given handle only */ | |
215 | |
216 GLOBAL T_GDD_DIO_CON_DATA * get_con_data_from_handle(T_GDD_CON_HANDLE con_handle) | |
217 { | |
218 T_GDD_INST_ID inst; | |
219 | |
220 /* Deliberately NO tracing */ | |
221 | |
222 inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle); | |
223 | |
224 if(inst < 0 || inst >= GDD_NUM_INSTS) | |
225 { | |
226 return 0; | |
227 } | |
228 | |
229 return get_con_data(&(gdd_dio_data_base[inst]), con_handle); | |
230 } | |
231 | |
232 | |
233 /* Send a DIO signal via the specificed connection */ | |
234 | |
235 void gdd_dio_send_signal_to_dio | |
236 (T_GDD_DIO_CON_DATA * con_data, U16 sig_type) | |
237 { | |
238 T_DRV_SIGNAL drv_signal; | |
239 T_GDD_DIO_DATA * inst_data; | |
240 char * sig_type_str; | |
241 | |
242 TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_dio_send_signal_to_dio()"); | |
243 | |
244 inst_data = &gdd_dio_data_base[inst_num_from_dev_id(con_data->dio_device)]; | |
245 | |
246 switch (sig_type) | |
247 { | |
248 case DRV_SIGTYPE_WRITE: sig_type_str = "DRV_SIGTYPE_WRITE"; break; | |
249 case DRV_SIGTYPE_READ: sig_type_str = "DRV_SIGTYPE_READ"; break; | |
250 case DRV_SIGTYPE_CONNECT: sig_type_str = "DRV_SIGTYPE_CONNECT"; break; | |
251 case DRV_SIGTYPE_DISCONNECT: sig_type_str = "DRV_SIGTYPE_DISCONNECT"; break; | |
252 default: sig_type_str = "ununsed signal type"; break; | |
253 } | |
254 | |
255 TRACE_USER_CLASS_P2(TC_SIGNALS, "[GDD] Sending signal %s to DIO IL (con_handle=0x%4x)", sig_type_str, con_data->dio_device); | |
256 | |
257 drv_signal.SignalType = sig_type; | |
258 drv_signal.DrvHandle = inst_data->drv_handle; | |
259 drv_signal.DataLength = sizeof(U32); | |
260 drv_signal.UserData = &(con_data->dio_device); | |
261 (*(inst_data->signal_callback))(&drv_signal); | |
262 } | |
263 | |
264 | |
265 /*==== PRIVATE FUNCTIONS =====================================================*/ | |
266 | |
267 /* | |
268 +------------------------------------------------------------------------------ | |
269 | Function : get_free_connection_slot | |
270 +------------------------------------------------------------------------------ | |
271 | Description : Find the next free connection slot for given instance. | |
272 | | |
273 | Parameters : gdd_dio_data - pointer to instance data | |
274 | con_data - pointer to pointer to connection data (output) | |
275 | | |
276 | Returns : 0 - Success (con_data has been set) | |
277 | -1 - Failed (no slot found) | |
278 +------------------------------------------------------------------------------ | |
279 */ | |
280 LOCAL int get_free_connection_slot(T_GDD_DIO_DATA * gdd_dio_data, | |
281 T_GDD_DIO_CON_DATA ** con_data /*output*/) | |
282 { | |
283 int i; | |
284 | |
285 TRACE_FUNCTION( "[GDD] get_free_connection_slot()" ); | |
286 | |
287 ENTER_CRITICAL_SECTION(sem_GDD_DIO_CON); | |
288 | |
289 for(i = 0; i < gdd_dio_data->max_con; ++i) | |
290 { | |
291 if(gdd_dio_data->device_range_start+i <= gdd_dio_data->device_range_end) | |
292 { | |
293 if(gdd_dio_data->con_arr[i].con_state EQ GDD_DIO_CON_DEAD) | |
294 { | |
295 gdd_dio_data->con_arr[i].dio_device = gdd_dio_data->device_range_start+i; | |
296 *con_data = &(gdd_dio_data->con_arr[i]); | |
297 (*con_data)->con_state = GDD_DIO_CON_CONNECT; | |
298 | |
299 LEAVE_CRITICAL_SECTION(sem_GDD_DIO_CON); | |
300 return 0; | |
301 } | |
302 } | |
303 } | |
304 | |
305 LEAVE_CRITICAL_SECTION(sem_GDD_DIO_CON); | |
306 | |
307 return -1; | |
308 } | |
309 | |
310 | |
311 /* | |
312 +------------------------------------------------------------------------------ | |
313 | Function : gdd_semaphore_err | |
314 +------------------------------------------------------------------------------ | |
315 | Description : Handle a semaphore error | |
316 +------------------------------------------------------------------------------ | |
317 */ | |
318 static void gdd_semaphore_err (void) | |
319 { | |
320 static UCHAR out = 0; | |
321 if (!out) | |
322 { | |
323 out = 1; | |
324 vsi_o_ttrace(VSI_CALLER TC_EVENT, "semaphore error"); | |
325 } | |
326 } | |
327 | |
328 | |
329 /* | |
330 +------------------------------------------------------------------------------ | |
331 | Function : gdd_enter_critical_section | |
332 +------------------------------------------------------------------------------ | |
333 | Description : Enters a critical section. | |
334 | | |
335 | Parameters : sem - Semaphore handle | |
336 | | |
337 | Returns : 0 - Success | |
338 | -1 - Failure | |
339 +------------------------------------------------------------------------------ | |
340 */ | |
341 static int gdd_enter_critical_section (T_HANDLE sem) | |
342 { | |
343 if (vsi_s_get (VSI_CALLER sem) NEQ VSI_OK) | |
344 { | |
345 gdd_semaphore_err(); | |
346 return -1; | |
347 } | |
348 else | |
349 { | |
350 return 0; | |
351 } | |
352 } | |
353 | |
354 | |
355 /* | |
356 +------------------------------------------------------------------------------ | |
357 | Function : gdd_leave_critical_section | |
358 +------------------------------------------------------------------------------ | |
359 | Description : Leaves a critical section. | |
360 | | |
361 | Parameters : sem - Semaphore handle | |
362 | | |
363 | Returns : 0 - Success | |
364 | -1 - Failure | |
365 +------------------------------------------------------------------------------ | |
366 */ | |
367 static int gdd_leave_critical_section (T_HANDLE sem) | |
368 { | |
369 if (vsi_s_release (VSI_CALLER sem) NEQ VSI_OK) | |
370 { | |
371 gdd_semaphore_err(); | |
372 return -1; | |
373 } | |
374 else | |
375 { | |
376 return 0; | |
377 } | |
378 } |