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 }