FreeCalypso > hg > freecalypso-sw
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 } |