comparison src/aci2/aci_dti_mng/dti_conn_mng.c @ 3:93999a60b835

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