comparison gsm-fw/g23m-aci/aci_dti_mng/dti_conn_mng.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 c23e0dfa5154
comparison
equal deleted inserted replaced
774:40a721fd9854 775:eedbf248bac0
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 (void )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 (void) glob_params.mng_ent_cb(link_id, entity_list[i], entity_list[i+1], DTI_CONNECT);
223 (void)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 (void)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 (void)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 (void)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
584 TRACE_FUNCTION("dti_conn_close_dpath()");
585
586
587 dti_channel = dti_conn_find_dti_conn( dti_id );
588 if (dti_channel EQ NULL)
589 {
590 TRACE_EVENT_P1("[ERR] dti_conn_close_dpath: dti_channel dti_id=%x not found",
591 dti_id);
592 return FALSE;
593 }
594
595 if (dti_channel->state NEQ DTI_CONN_STATE_DISCONNECTED)
596 {
597 dti_channel->state = DTI_CONN_STATE_DISCONNECTING;
598
599 dti_conn_disconnect (dti_channel);
600 }
601 else
602 {
603 TRACE_EVENT("[ERR] dti_conn_close_dpath: try to close dpath which was DISCONNECTED");
604 return FALSE;
605 }
606
607 return TRUE;
608 }
609
610
611 /*
612 +-----------------------------------------------------------------------+
613 | PROJECT : MODULE : DTI_CONN |
614 | STATE : code ROUTINE : dti_conn_entity_connected |
615 +-----------------------------------------------------------------------+
616
617 PURPOSE : response after a DTI connect request. This function is called
618 to inform the DTI Connection Manager that a connection is
619 established.
620
621 */
622 GLOBAL void dti_conn_entity_connected( T_DTI_CONN_LINK_ID link_id,
623 T_DTI_ENTITY_ID ent_id,
624 T_DTI_CONN_RESULT result )
625 {
626 T_DTI_CONN_CHANNEL *dti_channel;
627 T_DTI_CONN_TUPLE *tuple;
628 UBYTE i;
629 UBYTE dti_id = EXTRACT_DTI_ID(link_id);
630 BOOL both_entities_connected = FALSE;
631 UBYTE count = 0;
632
633 TRACE_FUNCTION("dti_conn_entity_connected()");
634
635
636 dti_channel = dti_conn_find_dti_conn( dti_id );
637 if (dti_channel EQ NULL)
638 {
639 TRACE_EVENT_P1("[ERR] dti_conn_entity_connected: dti_channel link_id=%x not found",
640 link_id);
641 return;
642 }
643
644 if (result EQ DTI_ERROR)
645 {
646 /* mark entity as disconnected */
647 dti_conn_entity_disconnected( link_id, ent_id );
648
649 /* close the whole DTI channel */
650 dti_conn_close_dpath( dti_id );
651 return;
652 }
653
654 if (dti_channel->state EQ DTI_CONN_STATE_CONNECTED)
655 {
656 TRACE_EVENT_P1("dti channel with dti_id=%x already connected", dti_id);
657 return;
658 }
659
660 tuple = dti_conn_find_dti_tuple( dti_channel, EXTRACT_TUPLE_NO(link_id ) );
661
662 for (i=0; i<NUM_OF_PEERS; i++)
663 {
664 if (tuple->peers[i].state EQ DTI_CONN_STATE_CONNECTED)
665 {
666 count++;
667 }
668
669 if (tuple->peers[i].ent_id EQ ent_id)
670 {
671 if (tuple->peers[i].state EQ DTI_CONN_STATE_CONNECTING)
672 {
673 tuple->peers[i].state = DTI_CONN_STATE_CONNECTED;
674 count++;
675 }
676 }
677 if (count EQ NUM_OF_PEERS)
678 {
679 both_entities_connected = TRUE;
680 }
681 }
682
683 /* if both entities are CONNECTED */
684 if (both_entities_connected)
685 {
686 tuple->state = DTI_CONN_STATE_CONNECTED;
687
688 /* if all other tuples CONNECTED */
689 if (dti_conn_is_dti_channel_connected(ent_id, dti_id))
690 {
691 dti_channel->state = DTI_CONN_STATE_CONNECTED;
692
693 TRACE_EVENT_P1("DTI ID %d connected", dti_id);
694
695 /* call connect_cb here */
696 if (dti_channel->conn_cb)
697 {
698 (void)dti_channel->conn_cb(dti_id, DTI_CONN_STATE_CONNECTED);
699 }
700 else
701 {
702 TRACE_EVENT("conn_cb is NULL");
703 }
704 }
705 }
706 }
707
708
709 /*
710 +-----------------------------------------------------------------------+
711 | PROJECT : MODULE : DTI_CONN |
712 | STATE : code ROUTINE : dti_conn_entity_disconnected |
713 +-----------------------------------------------------------------------+
714
715 PURPOSE : response after a DTI connect request. This function is called
716 to inform the DTI Connection Manager that a connection is
717 closed.
718
719 */
720 GLOBAL void dti_conn_entity_disconnected( T_DTI_CONN_LINK_ID link_id, T_DTI_ENTITY_ID ent_id )
721 {
722 T_DTI_CONN_CHANNEL *dti_channel;
723 T_DTI_CONN_TUPLE *tuple;
724 UBYTE i;
725 UBYTE dti_id = EXTRACT_DTI_ID(link_id);
726 UBYTE count = 0;
727
728 TRACE_FUNCTION("dti_conn_entity_disconnected()");
729
730
731 dti_channel = dti_conn_find_dti_conn( dti_id );
732 if (dti_channel EQ NULL)
733 {
734 TRACE_EVENT_P1("[ERR] dti_conn_entity_disconnected: dti_channel link_id=%x not found",
735 link_id);
736 return;
737 }
738
739 if (dti_channel->state EQ DTI_CONN_STATE_DISCONNECTED)
740 {
741 TRACE_EVENT_P1("dti channel with dti_id=%x already diconnected", dti_id);
742 return;
743 }
744
745
746 tuple = dti_conn_find_dti_tuple( dti_channel, EXTRACT_TUPLE_NO(link_id) );
747
748 for (i=0; i<NUM_OF_PEERS; i++)
749 {
750 if (tuple->peers[i].state EQ DTI_CONN_STATE_DISCONNECTED)
751 {
752 count++;
753 }
754
755 /* find disconnected entity */
756 if (tuple->peers[i].ent_id EQ ent_id)
757 {
758 tuple->peers[i].state = DTI_CONN_STATE_DISCONNECTED;
759 tuple->peers[i].ent_id = DTI_ENTITY_INVALID;
760 count++;
761
762 tuple->state = DTI_CONN_STATE_DISCONNECTING;
763
764 if (dti_channel->state EQ DTI_CONN_STATE_CONNECTED)
765 {
766 /* set DTI channel state */
767 dti_channel->state = DTI_CONN_STATE_DISCONNECTING;
768 }
769 }
770 }
771
772 /* if both entities are DISCONNECTED */
773 if (count EQ NUM_OF_PEERS)
774 {
775 /* set tuple state */
776 tuple->state = DTI_CONN_STATE_DISCONNECTED;
777
778 /* if all other tuples DISCONNECTED */
779 if (dti_conn_is_dti_channel_disconnected(dti_id))
780 {
781 dti_channel->state = DTI_CONN_STATE_DISCONNECTED;
782
783 TRACE_EVENT_P1("DTI ID %d disconnected", dti_id);
784
785 /* reset number of conns */
786 dti_channel->num_of_conns = 0;
787
788 /* call disconnect_cb here */
789 if (dti_channel->conn_cb)
790 {
791 (void)dti_channel->conn_cb(dti_id, DTI_CONN_STATE_DISCONNECTED);
792 }
793 else
794 {
795 TRACE_EVENT("conn_cb is NULL");
796 }
797
798 if (glob_params.num_entities NEQ 0)
799 {
800 dti_channel->conn_cb = glob_params.conn_cb;
801 dti_conn_connect( dti_channel, glob_params.entity_list_buf, glob_params.num_entities, SPLIT );
802 glob_params.num_entities = 0;
803 }
804 else
805 {
806 if (dti_channel->erase_channel EQ TRUE)
807 {
808 /* erase entry in DTI Conn Mng */
809 dti_conn_erase_entry(dti_id);
810 }
811 }
812 }
813 }
814 }
815
816
817 /*
818 +-----------------------------------------------------------------------+
819 | PROJECT : MODULE : DTI_CONN |
820 | STATE : code ROUTINE : dti_conn_close_all_connections|
821 +-----------------------------------------------------------------------+
822
823 PURPOSE : This function is called to close all established DTI
824 connections.
825
826 */
827 GLOBAL void dti_conn_close_all_connections()
828 {
829 T_DTI_CONN_CHANNEL *dti_channel=NULL;
830
831 TRACE_FUNCTION("dti_conn_close_all_connections()");
832
833 while(TRUE)
834 {
835 dti_channel = get_next_element (dti_channel_list, dti_channel);
836 if (dti_channel EQ NULL)
837 {
838 return;
839 }
840
841 if (dti_channel->state EQ DTI_CONN_STATE_CONNECTED)
842 {
843 dti_conn_close_dpath(dti_channel->dti_id);
844 dti_channel->erase_channel = TRUE;
845 }
846 else
847 {
848 dti_conn_erase_entry(dti_channel->dti_id);
849 }
850 }
851 }