FreeCalypso > hg > freecalypso-citrine
comparison g23m-aci/aci_dti_mng/dti_conn_mng.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 +----------------------------------------------------------------------------- | |
3 | Project : ... | |
4 | Modul : dti_conn_mng.c | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 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 DTI Connection Manager | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 | |
22 #ifndef DTI_CONN_MNG_C | |
23 #define DTI_CONN_MNG_C | |
24 #endif | |
25 | |
26 | |
27 /*===== INCLUDES ===================================================*/ | |
28 | |
29 #include "config.h" | |
30 #include "fixedconf.h" | |
31 #include "condat-features.h" | |
32 #include "aci_conf.h" | |
33 | |
34 #include "aci_all.h" | |
35 | |
36 #include "pconst.cdg" | |
37 #include "mconst.cdg" | |
38 #include "cnf_aci.h" | |
39 #include "mon_aci.h" | |
40 #include "pei.h" | |
41 #include "aci_cmh.h" | |
42 #include "ati_cmd.h" | |
43 #include "aci_io.h" | |
44 | |
45 #include "aci_cmh.h" | |
46 #include "aci_lst.h" | |
47 #include "aci_mem.h" | |
48 | |
49 #include "dti.h" | |
50 #include "dti_conn_mng.h" | |
51 #include "dti_cntrl_mng.h" | |
52 | |
53 | |
54 | |
55 LOCAL ULONG used_dti_channels = 0; | |
56 LOCAL T_ACI_LIST *dti_channel_list = NULL; /* list_begin */ | |
57 | |
58 LOCAL T_DTI_CONN_PARAMS glob_params; | |
59 | |
60 | |
61 /********************** LOCAL FUNCTIONS *****************************/ | |
62 | |
63 | |
64 LOCAL UBYTE dti_conn_get_new_dti_id (void) | |
65 { | |
66 ULONG tst_id; | |
67 UBYTE i; | |
68 | |
69 TRACE_FUNCTION("dti_conn_get_new_dti_id()"); | |
70 | |
71 /* create a new DTI ID */ | |
72 for (i = 0; i <= MAX_DTI_CONN_CHANNELS; i++) | |
73 { | |
74 tst_id = (0x01 << i) & used_dti_channels; | |
75 if (!tst_id) | |
76 { | |
77 break; | |
78 } | |
79 } | |
80 if (tst_id) | |
81 { | |
82 TRACE_EVENT("No DTI ID available"); | |
83 return (DTI_DTI_ID_NOTPRESENT); | |
84 } | |
85 used_dti_channels |= (0x01 << i); | |
86 | |
87 TRACE_EVENT_P1("DTI ID %d created", i); | |
88 | |
89 return (i); | |
90 } | |
91 | |
92 | |
93 LOCAL void dti_conn_remove_dti_id (UBYTE dti_id) | |
94 { | |
95 ULONG tst_id; | |
96 | |
97 TRACE_FUNCTION("dti_conn_remove_id()"); | |
98 | |
99 if (dti_id >= MAX_DTI_CONN_CHANNELS) | |
100 return; | |
101 | |
102 tst_id = 0x01 << (dti_id); | |
103 used_dti_channels &= ~tst_id; | |
104 | |
105 TRACE_EVENT_P1("DTI ID %d removed", dti_id); | |
106 | |
107 } | |
108 | |
109 | |
110 LOCAL BOOL dti_conn_error_cb(UBYTE dti_id, T_DTI_CONN_STATE result_type) | |
111 { | |
112 /* theorically should not be called... Yet helpfull for testing */ | |
113 TRACE_FUNCTION("dti_conn_error_cb()"); | |
114 | |
115 TRACE_EVENT("ERROR: DTI connection callback has not been initialized !"); | |
116 | |
117 return FALSE; | |
118 } | |
119 | |
120 | |
121 LOCAL void dti_conn_reset_conn_parms( T_DTI_CONN_CHANNEL *dti_channel ) | |
122 { | |
123 | |
124 UBYTE i,j; | |
125 | |
126 TRACE_FUNCTION("dti_conn_reset_conn_parms()"); | |
127 | |
128 dti_channel->erase_channel = FALSE; | |
129 dti_channel->num_of_conns = 0; | |
130 dti_channel->conn_cb = dti_conn_error_cb; | |
131 dti_channel->state = DTI_CONN_STATE_DISCONNECTED; | |
132 | |
133 for (i=0; i<MAX_DTI_CONN_TUPLES; i++) | |
134 { | |
135 dti_channel->tuple_list[i].state = DTI_CONN_STATE_DISCONNECTED; | |
136 for (j=0; j<NUM_OF_PEERS; j++) | |
137 { | |
138 dti_channel->tuple_list[i].peers[j].state = DTI_CONN_STATE_DISCONNECTED; | |
139 dti_channel->tuple_list[i].peers[j].ent_id = DTI_ENTITY_INVALID; | |
140 } | |
141 } | |
142 } | |
143 | |
144 | |
145 LOCAL BOOL DTItest_dti_id( UBYTE dti_id, void *elem) | |
146 { | |
147 T_DTI_CONN_CHANNEL *dti_channel = (T_DTI_CONN_CHANNEL *)elem; | |
148 | |
149 if (dti_channel EQ NULL) | |
150 return FALSE; | |
151 if (dti_channel -> dti_id EQ dti_id ) | |
152 return TRUE; | |
153 else | |
154 return FALSE; | |
155 } | |
156 | |
157 LOCAL T_DTI_CONN_TUPLE *dti_conn_find_dti_tuple( T_DTI_CONN_CHANNEL *dti_channel, UBYTE tuple_no) | |
158 { | |
159 return &(dti_channel->tuple_list[tuple_no]); | |
160 } | |
161 | |
162 | |
163 LOCAL T_DTI_CONN_CHANNEL *dti_conn_find_dti_conn( UBYTE dti_id ) | |
164 { | |
165 T_DTI_CONN_CHANNEL *dti_channel; | |
166 | |
167 TRACE_FUNCTION("dti_conn_find_dti_conn()"); | |
168 | |
169 /*find channel in list */ | |
170 dti_channel = find_element (dti_channel_list, dti_id, DTItest_dti_id); | |
171 | |
172 return dti_channel; | |
173 } | |
174 | |
175 | |
176 LOCAL BOOL dti_conn_connect( T_DTI_CONN_CHANNEL* dti_channel, | |
177 T_DTI_ENTITY_ID* entity_list, | |
178 UBYTE num_entities, | |
179 T_DTI_CONN_MODE mode ) | |
180 { | |
181 ULONG link_id; | |
182 UBYTE tuple_no; | |
183 UBYTE i; | |
184 | |
185 TRACE_FUNCTION("dti_conn_connect()"); | |
186 | |
187 dti_channel->state = DTI_CONN_STATE_CONNECTING; | |
188 | |
189 if (dti_channel->conn_cb) | |
190 { | |
191 (void )dti_channel->conn_cb(dti_channel->dti_id, DTI_CONN_STATE_CONNECTING); | |
192 } | |
193 else | |
194 { | |
195 TRACE_EVENT("conn_cb is NULL"); | |
196 } | |
197 | |
198 | |
199 if (mode EQ APPEND) | |
200 { | |
201 tuple_no = dti_channel->num_of_conns; | |
202 } | |
203 else /* SPLIT */ | |
204 { | |
205 tuple_no = 0; | |
206 dti_channel->num_of_conns = 0; | |
207 } | |
208 | |
209 for (i=0; i<num_entities-1; i++) | |
210 { | |
211 dti_channel->tuple_list[tuple_no].peers[0].ent_id = entity_list[i]; | |
212 dti_channel->tuple_list[tuple_no].peers[1].ent_id = entity_list[i+1]; | |
213 | |
214 if ( (dti_channel->tuple_list[tuple_no].state NEQ DTI_CONN_STATE_DISCONNECTING) AND | |
215 (dti_channel->tuple_list[tuple_no].state NEQ DTI_CONN_STATE_CONNECTING) ) | |
216 { | |
217 dti_channel->tuple_list[tuple_no].state = DTI_CONN_STATE_CONNECTING; | |
218 dti_channel->tuple_list[tuple_no].tuple_no = tuple_no; | |
219 dti_channel->state = DTI_CONN_STATE_CONNECTING; | |
220 | |
221 link_id = dti_conn_compose_link_id(0, 0, dti_channel->dti_id, tuple_no); | |
222 | |
223 dti_channel->tuple_list[tuple_no].peers[0].state = DTI_CONN_STATE_CONNECTING; | |
224 dti_channel->tuple_list[tuple_no].peers[1].state = DTI_CONN_STATE_CONNECTING; | |
225 | |
226 /* connect a tuple */ | |
227 (void) glob_params.mng_ent_cb(link_id, entity_list[i], entity_list[i+1], DTI_CONNECT); | |
228 (void)glob_params.mng_ent_cb(link_id, entity_list[i+1], entity_list[i], DTI_CONNECT); | |
229 } | |
230 | |
231 tuple_no++; | |
232 } | |
233 | |
234 dti_channel->num_of_conns = tuple_no; | |
235 | |
236 return TRUE; | |
237 } | |
238 | |
239 | |
240 LOCAL BOOL dti_conn_disconnect( T_DTI_CONN_CHANNEL* dti_channel ) | |
241 { | |
242 ULONG link_id; | |
243 UBYTE i; | |
244 | |
245 TRACE_FUNCTION("dti_conn_disconnect()"); | |
246 | |
247 dti_channel->state = DTI_CONN_STATE_DISCONNECTING; | |
248 | |
249 if (dti_channel->conn_cb) | |
250 { | |
251 (void)dti_channel->conn_cb(dti_channel->dti_id, DTI_CONN_STATE_DISCONNECTING); | |
252 } | |
253 else | |
254 { | |
255 TRACE_EVENT("conn_cb is NULL"); | |
256 } | |
257 | |
258 for (i=0; i < dti_channel->num_of_conns; i++) | |
259 { | |
260 | |
261 /* set tuple state only if it is not already DISCONNECTED */ | |
262 if (dti_channel->tuple_list[i].state NEQ DTI_CONN_STATE_DISCONNECTED) | |
263 { | |
264 dti_channel->tuple_list[i].state = DTI_CONN_STATE_DISCONNECTING; | |
265 } | |
266 | |
267 link_id = dti_conn_compose_link_id(0, 0, dti_channel->dti_id, i); | |
268 | |
269 /* disconnect only a connected entity */ | |
270 if (dti_channel->tuple_list[i].peers[0].state EQ DTI_CONN_STATE_CONNECTED OR | |
271 dti_channel->tuple_list[i].peers[0].state EQ DTI_CONN_STATE_CONNECTING ) | |
272 { | |
273 dti_channel->tuple_list[i].peers[0].state = DTI_CONN_STATE_DISCONNECTING; | |
274 (void)glob_params.mng_ent_cb(link_id, dti_channel->tuple_list[i].peers[0].ent_id, | |
275 dti_channel->tuple_list[i].peers[1].ent_id, DTI_DISCONNECT); | |
276 } | |
277 | |
278 /* disconnect only a connected entity */ | |
279 if (dti_channel->tuple_list[i].peers[1].state EQ DTI_CONN_STATE_CONNECTED OR | |
280 dti_channel->tuple_list[i].peers[1].state EQ DTI_CONN_STATE_CONNECTING ) | |
281 { | |
282 dti_channel->tuple_list[i].peers[1].state = DTI_CONN_STATE_DISCONNECTING; | |
283 (void)glob_params.mng_ent_cb(link_id, dti_channel->tuple_list[i].peers[1].ent_id, | |
284 dti_channel->tuple_list[i].peers[0].ent_id, DTI_DISCONNECT); | |
285 } | |
286 } | |
287 | |
288 return TRUE; | |
289 } | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | |
296 | |
297 /********************** GLOBAL FUNCTIONS *****************************/ | |
298 | |
299 | |
300 GLOBAL T_DTI_CONN_LINK_ID dti_conn_compose_link_id(UBYTE dummy, UBYTE assoc, UBYTE dti_id, UBYTE tuple_no) | |
301 { | |
302 T_DTI_CONN_LINK_ID link_id = 0; | |
303 | |
304 link_id += dummy; | |
305 link_id <<= 8; | |
306 link_id += assoc; | |
307 link_id <<= 8; | |
308 link_id += dti_id; | |
309 link_id <<= 8; | |
310 link_id += tuple_no; | |
311 | |
312 return link_id; | |
313 } | |
314 | |
315 | |
316 /* | |
317 +--------------------------------------------------------------------+ | |
318 | PROJECT : MODULE : DTI_CONN | | |
319 | STATE : code ROUTINE : dti_conn_init | | |
320 +--------------------------------------------------------------------+ | |
321 | |
322 PURPOSE : initialise the DTI Connection Manager | |
323 | |
324 */ | |
325 GLOBAL void dti_conn_init( T_DTI_CONN_MNG_ENT_CB* mng_ent_cb ) | |
326 { | |
327 TRACE_FUNCTION("dti_conn_init()"); | |
328 | |
329 dti_channel_list = new_list (); | |
330 | |
331 glob_params.conn_cb = NULL; | |
332 glob_params.mng_ent_cb = mng_ent_cb; | |
333 glob_params.num_entities = 0; | |
334 | |
335 } | |
336 | |
337 | |
338 /* | |
339 +--------------------------------------------------------------------+ | |
340 | PROJECT : MODULE : DTI_CONN | | |
341 | STATE : code ROUTINE : dti_conn_new | | |
342 +--------------------------------------------------------------------+ | |
343 | |
344 PURPOSE : register new DTI channel | |
345 | |
346 */ | |
347 GLOBAL UBYTE dti_conn_new(UBYTE dti_id ) | |
348 { | |
349 T_DTI_CONN_CHANNEL *dti_channel; | |
350 | |
351 TRACE_FUNCTION("dti_conn_new()"); | |
352 | |
353 | |
354 if (dti_id EQ DTI_DTI_ID_NOTPRESENT) | |
355 { | |
356 dti_id = dti_conn_get_new_dti_id (); | |
357 } | |
358 | |
359 if (dti_id EQ DTI_DTI_ID_NOTPRESENT) | |
360 { | |
361 return (DTI_DTI_ID_NOTPRESENT); | |
362 } | |
363 | |
364 /* search for an existing entry with correspondant dti_id */ | |
365 dti_channel = dti_conn_find_dti_conn (dti_id); | |
366 | |
367 if( dti_channel ) | |
368 { | |
369 return (DTI_DTI_ID_NOTPRESENT); /* couldn't create a new entry */ | |
370 } | |
371 | |
372 ACI_MALLOC(dti_channel, sizeof(T_DTI_CONN_CHANNEL)); | |
373 | |
374 dti_conn_reset_conn_parms (dti_channel); | |
375 dti_channel->dti_id = dti_id; | |
376 insert_list(dti_channel_list, dti_channel); | |
377 | |
378 return (dti_channel->dti_id); | |
379 } | |
380 | |
381 | |
382 /* | |
383 +---------------------------------------------------------------------+ | |
384 | PROJECT : MODULE : DTI_CONN | | |
385 | STATE : code ROUTINE : dti_conn_erase_entry | | |
386 +---------------------------------------------------------------------+ | |
387 | |
388 PURPOSE : erase entry from DTI channel list | |
389 | |
390 */ | |
391 GLOBAL void dti_conn_erase_entry(UBYTE dti_id) | |
392 { | |
393 T_DTI_CONN_CHANNEL *dti_channel; | |
394 | |
395 TRACE_FUNCTION("dti_conn_erase_entry"); | |
396 | |
397 /* find element to be erased */ | |
398 dti_channel = remove_element (dti_channel_list, dti_id, DTItest_dti_id); | |
399 | |
400 if( dti_channel NEQ NULL ) /* entry not erased yet */ | |
401 ACI_MFREE (dti_channel); | |
402 | |
403 dti_conn_remove_dti_id(dti_id); | |
404 } | |
405 | |
406 | |
407 /* | |
408 +-----------------------------------------------------------------------+ | |
409 | PROJECT : MODULE : DTI_CONN | | |
410 | STATE : code ROUTINE : dti_conn_is_dti_channel_connected | | |
411 +-----------------------------------------------------------------------+ | |
412 | |
413 PURPOSE : returns TRUE if end-to-end DTI connection is connected and | |
414 the given entity is in this connection | |
415 | |
416 */ | |
417 GLOBAL BOOL dti_conn_is_dti_channel_connected( T_DTI_ENTITY_ID ent_id, UBYTE dti_id ) | |
418 { | |
419 UBYTE count = 0; | |
420 UBYTE i; | |
421 UBYTE entity_found = FALSE; | |
422 T_DTI_CONN_CHANNEL *dti_channel = dti_conn_find_dti_conn( dti_id ); | |
423 | |
424 TRACE_FUNCTION("dti_conn_is_dti_channel_connected()"); | |
425 | |
426 if (dti_channel EQ NULL) | |
427 { | |
428 TRACE_EVENT_P1("dti_channel for dti_id %d not found", dti_id); | |
429 return FALSE; | |
430 } | |
431 | |
432 for (i=0; i<dti_channel->num_of_conns; i++) | |
433 { | |
434 if ((dti_channel->tuple_list[i].peers[0].ent_id EQ ent_id) OR | |
435 (dti_channel->tuple_list[i].peers[1].ent_id EQ ent_id)) | |
436 { | |
437 entity_found = TRUE; | |
438 break; | |
439 } | |
440 } | |
441 | |
442 if (entity_found EQ FALSE) | |
443 return FALSE; | |
444 | |
445 if (dti_channel->state EQ DTI_CONN_STATE_CONNECTED) | |
446 { | |
447 return TRUE; | |
448 } | |
449 else | |
450 { | |
451 for (i=0; i<dti_channel->num_of_conns; i++) | |
452 { | |
453 if (dti_channel->tuple_list[i].state EQ DTI_CONN_STATE_CONNECTED) | |
454 { | |
455 count++; | |
456 } | |
457 } | |
458 | |
459 if (count EQ dti_channel->num_of_conns) | |
460 { | |
461 return TRUE; | |
462 } | |
463 } | |
464 | |
465 return FALSE; | |
466 } | |
467 | |
468 | |
469 /* | |
470 +--------------------------------------------------------------------------+ | |
471 | PROJECT : MODULE : DTI_CONN | | |
472 | STATE : code ROUTINE : dti_conn_is_dti_channel_disconnected | | |
473 +--------------------------------------------------------------------------+ | |
474 | |
475 PURPOSE : returns TRUE if end-to-end DTI connection is disconnected | |
476 | |
477 */ | |
478 GLOBAL BOOL dti_conn_is_dti_channel_disconnected( UBYTE dti_id ) | |
479 { | |
480 UBYTE count = 0; | |
481 UBYTE i; | |
482 T_DTI_CONN_CHANNEL *dti_channel = dti_conn_find_dti_conn( dti_id ); | |
483 | |
484 TRACE_FUNCTION("dti_conn_is_dti_channel_disconnected()"); | |
485 | |
486 | |
487 if (dti_channel EQ NULL) | |
488 { | |
489 return TRUE; | |
490 } | |
491 | |
492 if (dti_channel->state EQ DTI_CONN_STATE_DISCONNECTED) | |
493 { | |
494 return TRUE; | |
495 } | |
496 else | |
497 { | |
498 for (i=0; i<dti_channel->num_of_conns; i++) | |
499 { | |
500 if (dti_channel->tuple_list[i].state EQ DTI_CONN_STATE_DISCONNECTED) | |
501 { | |
502 count++; | |
503 } | |
504 } | |
505 | |
506 if (count EQ dti_channel->num_of_conns) | |
507 { | |
508 return TRUE; | |
509 } | |
510 } | |
511 | |
512 return FALSE; | |
513 } | |
514 | |
515 | |
516 /* | |
517 +---------------------------------------------------------------------+ | |
518 | PROJECT : MODULE : DTI_CONN | | |
519 | STATE : code ROUTINE : dti_conn_est_dpath | | |
520 +---------------------------------------------------------------------+ | |
521 | |
522 PURPOSE : establishes data path. | |
523 | |
524 */ | |
525 GLOBAL BOOL dti_conn_est_dpath( UBYTE dti_id, | |
526 T_DTI_ENTITY_ID* entity_list, | |
527 UBYTE num_entities, | |
528 T_DTI_CONN_MODE mode, | |
529 T_DTI_CONN_CB* cb) | |
530 { | |
531 T_DTI_CONN_CHANNEL *dti_channel; | |
532 | |
533 TRACE_FUNCTION("dti_conn_est_dpath()"); | |
534 | |
535 | |
536 /*find channel in list */ | |
537 dti_channel = dti_conn_find_dti_conn (dti_id); | |
538 | |
539 if (dti_channel EQ NULL) | |
540 { | |
541 TRACE_EVENT_P1("[ERR] dti_conn_est_dpath: dti_channel dti_id=%x not found", | |
542 dti_id); | |
543 /* DTI ID not found */ | |
544 return FALSE; | |
545 } | |
546 | |
547 if ( entity_list[0] EQ DTI_ENTITY_INVALID OR entity_list[1] EQ DTI_ENTITY_INVALID) | |
548 { | |
549 /* improper entity list */ | |
550 TRACE_EVENT("[ERR] improper entity list "); | |
551 return FALSE; | |
552 } | |
553 | |
554 /* if 'SPLIT' then the whole DTI channel must be disconnected before a | |
555 * new connection is established | |
556 */ | |
557 if ((mode EQ SPLIT) AND (dti_channel->state NEQ DTI_CONN_STATE_DISCONNECTED)) | |
558 { | |
559 dti_conn_disconnect (dti_channel); | |
560 | |
561 /* save new entity list to entity list buffer */ | |
562 memcpy(glob_params.entity_list_buf, entity_list, sizeof(T_DTI_ENTITY_ID)*num_entities); | |
563 glob_params.num_entities = num_entities; | |
564 glob_params.conn_cb = cb; | |
565 } | |
566 else | |
567 { | |
568 dti_channel->conn_cb = cb; | |
569 dti_conn_connect (dti_channel, entity_list, num_entities, mode); | |
570 } | |
571 | |
572 return TRUE; | |
573 } | |
574 | |
575 | |
576 /* | |
577 +---------------------------------------------------------------------+ | |
578 | PROJECT : MODULE : DTI_CONN | | |
579 | STATE : code ROUTINE : dti_conn_close_dpath | | |
580 +---------------------------------------------------------------------+ | |
581 | |
582 PURPOSE : closes a DTI connection | |
583 | |
584 */ | |
585 GLOBAL BOOL dti_conn_close_dpath( UBYTE dti_id ) | |
586 { | |
587 T_DTI_CONN_CHANNEL *dti_channel; | |
588 | |
589 TRACE_FUNCTION("dti_conn_close_dpath()"); | |
590 | |
591 | |
592 dti_channel = dti_conn_find_dti_conn( dti_id ); | |
593 if (dti_channel EQ NULL) | |
594 { | |
595 TRACE_EVENT_P1("[ERR] dti_conn_close_dpath: dti_channel dti_id=%x not found", | |
596 dti_id); | |
597 return FALSE; | |
598 } | |
599 | |
600 if (dti_channel->state NEQ DTI_CONN_STATE_DISCONNECTED) | |
601 { | |
602 dti_channel->state = DTI_CONN_STATE_DISCONNECTING; | |
603 | |
604 dti_conn_disconnect (dti_channel); | |
605 } | |
606 else | |
607 { | |
608 TRACE_EVENT("[ERR] dti_conn_close_dpath: try to close dpath which was DISCONNECTED"); | |
609 return FALSE; | |
610 } | |
611 | |
612 return TRUE; | |
613 } | |
614 | |
615 | |
616 /* | |
617 +-----------------------------------------------------------------------+ | |
618 | PROJECT : MODULE : DTI_CONN | | |
619 | STATE : code ROUTINE : dti_conn_entity_connected | | |
620 +-----------------------------------------------------------------------+ | |
621 | |
622 PURPOSE : response after a DTI connect request. This function is called | |
623 to inform the DTI Connection Manager that a connection is | |
624 established. | |
625 | |
626 */ | |
627 GLOBAL void dti_conn_entity_connected( T_DTI_CONN_LINK_ID link_id, | |
628 T_DTI_ENTITY_ID ent_id, | |
629 T_DTI_CONN_RESULT result ) | |
630 { | |
631 T_DTI_CONN_CHANNEL *dti_channel; | |
632 T_DTI_CONN_TUPLE *tuple; | |
633 UBYTE i; | |
634 UBYTE dti_id = EXTRACT_DTI_ID(link_id); | |
635 BOOL both_entities_connected = FALSE; | |
636 UBYTE count = 0; | |
637 | |
638 TRACE_FUNCTION("dti_conn_entity_connected()"); | |
639 | |
640 | |
641 dti_channel = dti_conn_find_dti_conn( dti_id ); | |
642 if (dti_channel EQ NULL) | |
643 { | |
644 TRACE_EVENT_P1("[ERR] dti_conn_entity_connected: dti_channel link_id=%x not found", | |
645 link_id); | |
646 return; | |
647 } | |
648 | |
649 if (result EQ DTI_ERROR) | |
650 { | |
651 /* mark entity as disconnected */ | |
652 dti_conn_entity_disconnected( link_id, ent_id ); | |
653 | |
654 /* close the whole DTI channel */ | |
655 dti_conn_close_dpath( dti_id ); | |
656 return; | |
657 } | |
658 | |
659 if (dti_channel->state EQ DTI_CONN_STATE_CONNECTED) | |
660 { | |
661 TRACE_EVENT_P1("dti channel with dti_id=%x already connected", dti_id); | |
662 return; | |
663 } | |
664 | |
665 tuple = dti_conn_find_dti_tuple( dti_channel, EXTRACT_TUPLE_NO(link_id ) ); | |
666 | |
667 for (i=0; i<NUM_OF_PEERS; i++) | |
668 { | |
669 if (tuple->peers[i].state EQ DTI_CONN_STATE_CONNECTED) | |
670 { | |
671 count++; | |
672 } | |
673 | |
674 if (tuple->peers[i].ent_id EQ ent_id) | |
675 { | |
676 if (tuple->peers[i].state EQ DTI_CONN_STATE_CONNECTING) | |
677 { | |
678 tuple->peers[i].state = DTI_CONN_STATE_CONNECTED; | |
679 count++; | |
680 } | |
681 } | |
682 if (count EQ NUM_OF_PEERS) | |
683 { | |
684 both_entities_connected = TRUE; | |
685 } | |
686 } | |
687 | |
688 /* if both entities are CONNECTED */ | |
689 if (both_entities_connected) | |
690 { | |
691 tuple->state = DTI_CONN_STATE_CONNECTED; | |
692 | |
693 /* if all other tuples CONNECTED */ | |
694 if (dti_conn_is_dti_channel_connected(ent_id, dti_id)) | |
695 { | |
696 dti_channel->state = DTI_CONN_STATE_CONNECTED; | |
697 | |
698 TRACE_EVENT_P1("DTI ID %d connected", dti_id); | |
699 | |
700 /* call connect_cb here */ | |
701 if (dti_channel->conn_cb) | |
702 { | |
703 (void)dti_channel->conn_cb(dti_id, DTI_CONN_STATE_CONNECTED); | |
704 } | |
705 else | |
706 { | |
707 TRACE_EVENT("conn_cb is NULL"); | |
708 } | |
709 } | |
710 } | |
711 } | |
712 | |
713 | |
714 /* | |
715 +-----------------------------------------------------------------------+ | |
716 | PROJECT : MODULE : DTI_CONN | | |
717 | STATE : code ROUTINE : dti_conn_entity_disconnected | | |
718 +-----------------------------------------------------------------------+ | |
719 | |
720 PURPOSE : response after a DTI connect request. This function is called | |
721 to inform the DTI Connection Manager that a connection is | |
722 closed. | |
723 | |
724 */ | |
725 GLOBAL void dti_conn_entity_disconnected( T_DTI_CONN_LINK_ID link_id, T_DTI_ENTITY_ID ent_id ) | |
726 { | |
727 T_DTI_CONN_CHANNEL *dti_channel; | |
728 T_DTI_CONN_TUPLE *tuple; | |
729 UBYTE i; | |
730 UBYTE dti_id = EXTRACT_DTI_ID(link_id); | |
731 UBYTE count = 0; | |
732 | |
733 TRACE_FUNCTION("dti_conn_entity_disconnected()"); | |
734 | |
735 | |
736 dti_channel = dti_conn_find_dti_conn( dti_id ); | |
737 if (dti_channel EQ NULL) | |
738 { | |
739 TRACE_EVENT_P1("[ERR] dti_conn_entity_disconnected: dti_channel link_id=%x not found", | |
740 link_id); | |
741 return; | |
742 } | |
743 | |
744 if (dti_channel->state EQ DTI_CONN_STATE_DISCONNECTED) | |
745 { | |
746 TRACE_EVENT_P1("dti channel with dti_id=%x already diconnected", dti_id); | |
747 return; | |
748 } | |
749 | |
750 | |
751 tuple = dti_conn_find_dti_tuple( dti_channel, EXTRACT_TUPLE_NO(link_id) ); | |
752 | |
753 for (i=0; i<NUM_OF_PEERS; i++) | |
754 { | |
755 if (tuple->peers[i].state EQ DTI_CONN_STATE_DISCONNECTED) | |
756 { | |
757 count++; | |
758 } | |
759 | |
760 /* find disconnected entity */ | |
761 if (tuple->peers[i].ent_id EQ ent_id) | |
762 { | |
763 tuple->peers[i].state = DTI_CONN_STATE_DISCONNECTED; | |
764 tuple->peers[i].ent_id = DTI_ENTITY_INVALID; | |
765 count++; | |
766 | |
767 tuple->state = DTI_CONN_STATE_DISCONNECTING; | |
768 | |
769 if (dti_channel->state EQ DTI_CONN_STATE_CONNECTED) | |
770 { | |
771 /* set DTI channel state */ | |
772 dti_channel->state = DTI_CONN_STATE_DISCONNECTING; | |
773 } | |
774 } | |
775 } | |
776 | |
777 /* if both entities are DISCONNECTED */ | |
778 if (count EQ NUM_OF_PEERS) | |
779 { | |
780 /* set tuple state */ | |
781 tuple->state = DTI_CONN_STATE_DISCONNECTED; | |
782 | |
783 /* if all other tuples DISCONNECTED */ | |
784 if (dti_conn_is_dti_channel_disconnected(dti_id)) | |
785 { | |
786 dti_channel->state = DTI_CONN_STATE_DISCONNECTED; | |
787 | |
788 TRACE_EVENT_P1("DTI ID %d disconnected", dti_id); | |
789 | |
790 /* reset number of conns */ | |
791 dti_channel->num_of_conns = 0; | |
792 | |
793 /* call disconnect_cb here */ | |
794 if (dti_channel->conn_cb) | |
795 { | |
796 (void)dti_channel->conn_cb(dti_id, DTI_CONN_STATE_DISCONNECTED); | |
797 } | |
798 else | |
799 { | |
800 TRACE_EVENT("conn_cb is NULL"); | |
801 } | |
802 | |
803 if (glob_params.num_entities NEQ 0) | |
804 { | |
805 dti_channel->conn_cb = glob_params.conn_cb; | |
806 dti_conn_connect( dti_channel, glob_params.entity_list_buf, glob_params.num_entities, SPLIT ); | |
807 glob_params.num_entities = 0; | |
808 } | |
809 else | |
810 { | |
811 if (dti_channel->erase_channel EQ TRUE) | |
812 { | |
813 /* erase entry in DTI Conn Mng */ | |
814 dti_conn_erase_entry(dti_id); | |
815 } | |
816 } | |
817 } | |
818 } | |
819 } | |
820 | |
821 | |
822 /* | |
823 +-----------------------------------------------------------------------+ | |
824 | PROJECT : MODULE : DTI_CONN | | |
825 | STATE : code ROUTINE : dti_conn_close_all_connections| | |
826 +-----------------------------------------------------------------------+ | |
827 | |
828 PURPOSE : This function is called to close all established DTI | |
829 connections. | |
830 | |
831 */ | |
832 GLOBAL void dti_conn_close_all_connections() | |
833 { | |
834 T_DTI_CONN_CHANNEL *dti_channel=NULL; | |
835 | |
836 TRACE_FUNCTION("dti_conn_close_all_connections()"); | |
837 | |
838 while(TRUE) | |
839 { | |
840 dti_channel = get_next_element (dti_channel_list, dti_channel); | |
841 if (dti_channel EQ NULL) | |
842 { | |
843 return; | |
844 } | |
845 | |
846 if (dti_channel->state EQ DTI_CONN_STATE_CONNECTED) | |
847 { | |
848 dti_conn_close_dpath(dti_channel->dti_id); | |
849 dti_channel->erase_channel = TRUE; | |
850 } | |
851 else | |
852 { | |
853 dti_conn_erase_entry(dti_channel->dti_id); | |
854 } | |
855 } | |
856 } |