source: trunk/FACT++/dim/src/dic.c@ 11279

Last change on this file since 11279 was 11121, checked in by tbretz, 13 years ago
Updated from v19r21 to v19r22
File size: 49.9 KB
Line 
1
2/*
3 * DIC (Delphi Information Client) Package implements a library of
4 * routines to be used by clients.
5 *
6 * Started on : 10-11-91
7 * Last modification : 10-08-94
8 * Written by : C. Gaspar
9 * Adjusted by : G.C. Ballintijn
10 *
11 */
12
13#ifdef VMS
14# include <cfortran.h>
15# include <assert.h>
16#endif
17
18#define DIMLIB
19#include <dim.h>
20#include <dic.h>
21
22/*
23#define DEBUG
24*/
25
26#ifdef VMS
27#define TMP_ENABLE_AST long int ast_enable = sys$setast(1);
28#define TMP_DISABLE_AST if (ast_enable != SS$_WASSET) sys$setast(0);
29#endif
30
31#define BAD_CONN_TIMEOUT 10
32
33
34typedef struct bad_conn {
35 struct bad_conn *next;
36 struct bad_conn *prev;
37 DIC_CONNECTION conn;
38 int n_retries;
39 int retrying;
40} DIC_BAD_CONNECTION;
41
42static DIC_SERVICE *Service_pend_head = 0;
43static DIC_SERVICE *Cmnd_head = 0;
44static DIC_SERVICE *Current_server = 0;
45static DIC_BAD_CONNECTION *Bad_connection_head = 0;
46static int Dic_timer_q = 0;
47static int Dns_dic_conn_id = 0;
48static TIMR_ENT *Dns_dic_timr = NULL;
49static int Tmout_max = 0;
50static int Tmout_min = 0;
51static int Threads_off = 0;
52
53static void (*Error_user_routine)() = 0;
54static int Error_conn_id = 0;
55static int Curr_conn_id = 0;
56
57#ifdef DEBUG
58static int Debug_on = 1;
59#else
60static int Debug_on = 0;
61#endif
62
63_DIM_PROTO( unsigned request_service, (char *service_name, int req_type,
64 int req_timeout, void *service_address,
65 int service_size, void (*usr_routine)(void*,void*,int*),
66 long tag, void *fill_addr, int fill_size, int stamped) );
67_DIM_PROTO( int request_command, (char *service_name, void *service_address,
68 int service_size, void (*usr_routine)(void*,int*),
69 long tag, int stamped) );
70_DIM_PROTO( DIC_SERVICE *insert_service, (int type, int timeout, char *name,
71 int *address, int size, void (*routine)(),
72 long tag, int *fill_addr, int fill_size,
73 int pending, int stamped ) );
74_DIM_PROTO( void modify_service, (DIC_SERVICE *servp, int timeout,
75 int *address, int size, void (*routine)(),
76 long tag, int *fill_addr, int fill_size, int stamped) );
77_DIM_PROTO( DIC_SERVICE *locate_command, (char *serv_name) );
78_DIM_PROTO( DIC_SERVICE *locate_pending, (char *serv_name) );
79_DIM_PROTO( DIC_BAD_CONNECTION *locate_bad, (char *node, char *task, int port) );
80_DIM_PROTO( void service_tmout, (int serv_id) );
81_DIM_PROTO( static void request_dns_info, (int retry) );
82_DIM_PROTO( static int handle_dns_info, (DNS_DIC_PACKET *) );
83_DIM_PROTO( void close_dns_conn, (void) );
84_DIM_PROTO( static void release_conn, (int conn_id) );
85_DIM_PROTO( static void get_format_data, (int format, FORMAT_STR *format_data,
86 char *def) );
87_DIM_PROTO( static void execute_service, (DIS_PACKET *packet,
88 DIC_SERVICE *servp, int size) );
89
90void print_packet(DIS_PACKET *packet)
91{
92 dim_print_date_time();
93 printf(" - Bad ID received from server -> Packet received:\n");
94 printf("\tpacket->size = %d\n",vtohl(packet->size));
95 printf("\tpacket->service_id = %d\n",vtohl(packet->service_id));
96}
97
98void dic_set_debug_on()
99{
100 Debug_on = 1;
101}
102
103void dic_set_debug_off()
104{
105 Debug_on = 0;
106}
107
108void dic_no_threads()
109{
110 Threads_off = 1;
111}
112
113void dic_add_error_handler( void (*user_routine)())
114{
115
116 DISABLE_AST
117 Error_user_routine = user_routine;
118 ENABLE_AST
119}
120
121static void error_handler(int conn_id, int severity, int errcode, char *reason)
122{
123 int last_conn_id;
124
125 if(Error_user_routine)
126 {
127 Error_conn_id = conn_id;
128 last_conn_id = Curr_conn_id;
129 (Error_user_routine)(severity, errcode, reason);
130 Error_conn_id = 0;
131 Curr_conn_id = last_conn_id;
132 }
133 else
134 {
135 dim_print_msg(reason, severity);
136 if(severity == 3)
137 {
138 printf("Exiting!\n");
139 exit(2);
140 }
141 }
142}
143
144static void recv_rout( int conn_id, DIS_PACKET *packet, int size, int status )
145{
146 register DIC_SERVICE *servp, *auxp;
147 register DIC_CONNECTION *dic_connp;
148 int service_id, once_only, found = 0;
149 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
150 void move_to_notok_service();
151 void do_cmnd_callback();
152 void dim_panic(char *);
153
154 dic_connp = &Dic_conns[conn_id] ;
155 switch( status )
156 {
157 case STA_DISC:
158 if(Debug_on)
159 {
160 dna_get_node_task(conn_id, node, task);
161 dim_print_date_time();
162 printf(" - Conn %d: Server %s on node %s Disconnected\n",
163 conn_id, task, node);
164 fflush(stdout);
165 }
166 if( !(servp = (DIC_SERVICE *) dic_connp->service_head) )
167 {
168 release_conn( conn_id );
169 break;
170 }
171 while( (servp = (DIC_SERVICE *) dll_get_next(
172 (DLL *) dic_connp->service_head,
173 (DLL *) servp)) )
174 {
175#ifdef DEBUG
176 printf("\t %s was in the service list\n",servp->serv_name);
177 fflush(stdout);
178#endif
179/*
180 Will be done later by the DNS answer
181 service_tmout( servp->serv_id );
182*/
183 if(!strcmp(dic_connp->task_name,"DIS_DNS"))
184 {
185 service_tmout( servp->serv_id );
186 }
187 else if(Dns_dic_conn_id <= 0)
188 {
189 service_tmout( servp->serv_id );
190 }
191 servp->pending = WAITING_DNS_UP;
192 servp->conn_id = 0;
193 auxp = servp->prev;
194 move_to_notok_service( servp );
195 servp = auxp;
196 }
197 if( (servp = (DIC_SERVICE *) Cmnd_head) )
198 {
199 while( (servp = (DIC_SERVICE *) dll_get_next(
200 (DLL *) Cmnd_head,
201 (DLL *) servp)) )
202 {
203 if( servp->conn_id == conn_id )
204 {
205#ifdef DEBUG
206 printf("\t%s was in the Command list\n", servp->serv_name);
207 printf("servp = %x, type = %d, pending = %d\n",servp, servp->type, servp->pending);
208 fflush(stdout);
209#endif
210 auxp = servp->prev;
211 if( (servp->type == ONCE_ONLY ) &&
212 (servp->pending == WAITING_SERVER_UP))
213 {
214 service_tmout( servp->serv_id );
215 }
216 else if( (servp->type == COMMAND ) &&
217 (servp->pending == WAITING_CMND_ANSWER))
218 {
219 service_tmout( servp->serv_id );
220 }
221 else
222 {
223 servp->pending = WAITING_DNS_UP;
224 dic_release_service( servp->serv_id );
225 }
226 servp = auxp;
227 }
228 }
229 }
230 release_conn( conn_id );
231 request_dns_info(0);
232 break;
233 case STA_DATA:
234 if( !(DIC_SERVICE *) dic_connp->service_head )
235 break;
236 service_id = vtohl(packet->service_id);
237 if(service_id & 0x80000000) /* Service removed by server */
238 {
239 service_id &= 0x7fffffff;
240 if( (servp = (DIC_SERVICE *) id_get_ptr(service_id, SRC_DIC)))
241 {
242 if( servp->type != COMMAND )
243 {
244 service_tmout( servp->serv_id );
245 servp->pending = WAITING_DNS_UP;
246 servp->conn_id = 0;
247 move_to_notok_service( servp );
248 }
249 else
250 {
251 service_tmout( servp->serv_id );
252 break;
253 }
254 }
255 else
256 {
257/*
258 print_packet(packet);
259*/
260 if( (servp = (DIC_SERVICE *) Cmnd_head) )
261 {
262 while( (servp = (DIC_SERVICE *) dll_get_next(
263 (DLL *) Cmnd_head,
264 (DLL *) servp)) )
265 {
266 if( servp->conn_id == conn_id )
267 {
268#ifdef DEBUG
269 printf("\t%s was in the Command list\n", servp->serv_name);
270 fflush(stdout);
271#endif
272 auxp = servp->prev;
273 if( (servp->type == ONCE_ONLY ) &&
274 (servp->pending == WAITING_SERVER_UP))
275 {
276 service_tmout( servp->serv_id );
277 }
278 else if( (servp->type == COMMAND ) &&
279 (servp->pending == WAITING_CMND_ANSWER))
280 {
281 service_tmout( servp->serv_id );
282 }
283 else
284 {
285 servp->pending = WAITING_DNS_UP;
286 dic_release_service( servp->serv_id );
287 }
288 servp = auxp;
289 }
290 }
291 }
292 }
293 if( dll_empty((DLL *)dic_connp->service_head) ) {
294 if( (servp = (DIC_SERVICE *) Cmnd_head) ) {
295 while( (servp = (DIC_SERVICE *) dll_get_next(
296 (DLL *) Cmnd_head,
297 (DLL *) servp)) )
298 {
299 if( servp->conn_id == conn_id)
300 found = 1;
301 }
302 }
303 if( !found)
304 {
305 release_conn( conn_id );
306 }
307 }
308 request_dns_info(0);
309 break;
310 }
311 if( (servp = (DIC_SERVICE *) id_get_ptr(service_id, SRC_DIC)))
312 {
313 if(servp->serv_id == service_id)
314 {
315 once_only = 0;
316 if(servp->type == ONCE_ONLY)
317 once_only = 1;
318 else
319 {
320 if( servp->timeout > 0 )
321 {
322 if(servp->timer_ent)
323 dtq_clear_entry( servp->timer_ent );
324 }
325 }
326 Curr_conn_id = conn_id;
327 execute_service(packet, servp, size);
328 Curr_conn_id = 0;
329 if( once_only )
330 {
331 auxp = locate_command(servp->serv_name);
332 if((auxp) && (auxp != servp))
333 {
334 servp->pending = WAITING_DNS_UP;
335 dic_release_service( servp->serv_id );
336 }
337 else
338 {
339 servp->pending = NOT_PENDING;
340 servp->tmout_done = 0;
341 if( servp->timer_ent )
342 {
343 dtq_rem_entry( Dic_timer_q, servp->timer_ent );
344 servp->timer_ent = 0;
345 }
346 }
347 }
348 }
349 }
350/*
351 else
352 {
353 print_packet(packet);
354 if(Error_user_routine)
355 (Error_user_routine)( packet->buffer );
356 }
357*/
358 break;
359 case STA_CONN:
360 if(Debug_on)
361 {
362 dna_get_node_task(conn_id, node, task);
363 dim_print_date_time();
364 printf(" - Conn %d: Server %s on node %s Connected\n",
365 conn_id, task, node);
366 fflush(stdout);
367 }
368 break;
369 default: dim_panic( "recv_rout(): Bad switch" );
370 }
371}
372
373static void execute_service(DIS_PACKET *packet, DIC_SERVICE *servp, int size)
374{
375 int format;
376 FORMAT_STR format_data_cp[MAX_NAME/4], *formatp;
377 static int *buffer;
378 static int buffer_size = 0;
379 int add_size;
380 int *pkt_buffer, header_size;
381
382 Current_server = servp;
383 format = servp->format;
384 memcpy(format_data_cp, servp->format_data, sizeof(format_data_cp));
385 if((format & 0xF) == ((MY_FORMAT) & 0xF))
386 {
387 for(formatp = format_data_cp; formatp->par_bytes; formatp++)
388 formatp->flags &= 0xFFF0; /* NOSWAP */
389 }
390 if( servp->stamped)
391 {
392 pkt_buffer = ((DIS_STAMPED_PACKET *)packet)->buffer;
393 header_size = DIS_STAMPED_HEADER;
394 servp->time_stamp[0] = vtohl(((DIS_STAMPED_PACKET *)packet)->time_stamp[0]);
395 if((servp->time_stamp[0] & 0xFFFF0000) == 0xc0de0000)
396 {
397/*
398 servp->time_stamp[0] &= 0x0000FFFF;
399*/
400 servp->time_stamp[1] = vtohl(((DIS_STAMPED_PACKET *)packet)->time_stamp[1]);
401 servp->quality = vtohl(((DIS_STAMPED_PACKET *)packet)->quality);
402 }
403 else if((vtohl(((DIS_STAMPED_PACKET *)packet)->reserved[0])) == (int)0xc0dec0de)
404 {
405/*
406 servp->time_stamp[0] &= 0x0000FFFF;
407*/
408 servp->time_stamp[1] = vtohl(((DIS_STAMPED_PACKET *)packet)->time_stamp[1]);
409 servp->quality = vtohl(((DIS_STAMPED_PACKET *)packet)->quality);
410 }
411 else
412 {
413 pkt_buffer = ((DIS_PACKET *)packet)->buffer;
414 header_size = DIS_HEADER;
415 }
416 }
417 else
418 {
419 pkt_buffer = ((DIS_PACKET *)packet)->buffer;
420 header_size = DIS_HEADER;
421 }
422 size -= header_size;
423 if( servp->serv_address )
424 {
425 if( size > servp->serv_size )
426 size = servp->serv_size;
427 add_size = copy_swap_buffer_in(format_data_cp,
428 servp->serv_address,
429 pkt_buffer, size);
430 if( servp->user_routine )
431 (servp->user_routine)(&servp->tag, servp->serv_address, &add_size );
432 }
433 else
434 {
435 if( servp->user_routine )
436 {
437 add_size = size + (size/2);
438 if(!buffer_size)
439 {
440 buffer = (int *)malloc(add_size);
441 buffer_size = add_size;
442 }
443 else
444 {
445 if( add_size > buffer_size )
446 {
447 free(buffer);
448 buffer = (int *)malloc(add_size);
449 buffer_size = add_size;
450 }
451 }
452 add_size = copy_swap_buffer_in(format_data_cp,
453 buffer,
454 pkt_buffer, size);
455 (servp->user_routine)( &servp->tag, buffer, &add_size );
456 }
457 }
458 Current_server = 0;
459}
460
461static void recv_dns_dic_rout( int conn_id, DNS_DIC_PACKET *packet, int size, int status )
462{
463 register DIC_SERVICE *servp, *auxp;
464 void dim_panic(char *);
465
466 if(size){}
467 switch( status )
468 {
469 case STA_DISC: /* connection broken */
470 servp = Service_pend_head;
471 while( (servp = (DIC_SERVICE *) dll_get_next(
472 (DLL *) Service_pend_head,
473 (DLL *) servp)) )
474 {
475 if( (servp->pending == WAITING_DNS_ANSWER) ||
476 (servp->pending == WAITING_SERVER_UP))
477 {
478 if(( servp->type == COMMAND )||( servp->type == ONCE_ONLY ))
479 {
480 auxp = servp->prev;
481 servp->pending = WAITING_DNS_UP;
482 service_tmout( servp->serv_id );
483 servp = auxp;
484 }
485 else
486 {
487 servp->pending = WAITING_DNS_UP;
488 }
489 }
490 }
491 dna_close( Dns_dic_conn_id );
492 Dns_dic_conn_id = 0;
493 request_dns_info(0);
494 break;
495 case STA_CONN: /* connection received */
496 if(Dns_dic_conn_id < 0)
497 {
498 Dns_dic_conn_id = conn_id;
499 request_dns_info(0);
500
501 }
502 break;
503 case STA_DATA: /* normal packet */
504 if( vtohl(packet->size) == DNS_DIC_HEADER )
505 {
506 handle_dns_info( packet );
507 }
508 break;
509 default: dim_panic( "recv_dns_dic_rout(): Bad switch" );
510 }
511}
512
513
514void service_tmout( int serv_id )
515{
516 int once_only, size = 0;
517 register DIC_SERVICE *servp;
518
519/*
520dim_print_date_time();
521printf("In service tmout\n");
522*/
523 servp=(DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
524 if(!servp)
525 return;
526 if(servp->tmout_done)
527 return;
528/*
529dim_print_date_time();
530printf("In service tmout %s\n", servp->serv_name);
531*/
532 servp->tmout_done = 1;
533 Curr_conn_id = servp->conn_id;
534/*
535 if( servp->type == UPDATE )
536 return;
537*/
538 if( servp->type == COMMAND )
539 {
540 if( servp->user_routine )
541 {
542 if(servp->pending == WAITING_CMND_ANSWER)
543 size = 1;
544 else
545 size = 0;
546 (servp->user_routine)( &servp->tag, &size );
547 }
548 dic_release_service( servp->serv_id );
549 Curr_conn_id = 0;
550 return;
551 }
552 once_only = 0;
553 if(servp->type == ONCE_ONLY)
554 once_only = 1;
555 if( servp->fill_address )
556 {
557 size = servp->fill_size;
558 if( servp->serv_address )
559 {
560 if( size > servp->serv_size )
561 size = servp->serv_size;
562 memcpy(servp->serv_address, servp->fill_address, size);
563 if( servp->user_routine )
564 (servp->user_routine)( &servp->tag, servp->serv_address, &size);
565 }
566 else
567 {
568 if( servp->user_routine )
569 (servp->user_routine)( &servp->tag, servp->fill_address, &size);
570 }
571 }
572 if( once_only )
573 {
574 dic_release_service( servp->serv_id );
575 }
576 Curr_conn_id = 0;
577}
578
579
580unsigned dic_info_service( char *serv_name, int req_type, int req_timeout, void *serv_address,
581 int serv_size, void (*usr_routine)(), long tag, void *fill_addr, int fill_size )
582{
583 unsigned ret;
584
585 ret = request_service( serv_name, req_type, req_timeout,
586 serv_address, serv_size, usr_routine, tag,
587 fill_addr, fill_size, 0 );
588
589 return(ret);
590}
591
592unsigned dic_info_service_stamped( char *serv_name, int req_type, int req_timeout, void *serv_address,
593 int serv_size, void (*usr_routine)(), long tag, void *fill_addr, int fill_size )
594{
595 unsigned ret;
596
597 ret = request_service( serv_name, req_type, req_timeout,
598 serv_address, serv_size, usr_routine, tag,
599 fill_addr, fill_size, 1 );
600
601 return(ret);
602}
603
604unsigned request_service( char *serv_name, int req_type, int req_timeout, void *serv_address,
605 int serv_size, void (*usr_routine)(), long tag, void *fill_addr, int fill_size, int stamped )
606{
607 register DIC_SERVICE *servp;
608 int conn_id;
609 int send_service();
610 int locate_service();
611 void dim_init_threads(void);
612
613 if(!Threads_off)
614 {
615 dim_init_threads();
616 }
617 {
618 DISABLE_AST
619 /* create a timer queue for timeouts if not yet done */
620 if( !Dic_timer_q ) {
621 conn_arr_create( SRC_DIC );
622 Dic_timer_q = dtq_create();
623 }
624
625 /* store_service */
626 if(req_timeout < 0)
627 req_timeout = 0;
628 if(req_type == ONCE_ONLY)
629 {
630 if( !Cmnd_head ) {
631 Cmnd_head = (DIC_SERVICE *) malloc(sizeof(DIC_SERVICE) );
632 dll_init( (DLL *) Cmnd_head );
633 Cmnd_head->serv_id = 0;
634 }
635 if( (servp = locate_command(serv_name)) )
636 {
637 if( (conn_id = servp->conn_id) )
638 {
639 if(servp->pending == NOT_PENDING)
640 {
641 modify_service( servp, req_timeout,
642 (int *)serv_address, serv_size, usr_routine, tag,
643 (int *)fill_addr, fill_size, stamped);
644 servp->pending = WAITING_SERVER_UP;
645 if(send_service(conn_id, servp))
646 {
647 ENABLE_AST
648 return(1);
649 }
650 }
651 }
652 }
653 }
654 servp = insert_service( req_type, req_timeout,
655 serv_name, (int *)serv_address, serv_size, usr_routine, tag,
656 (int *)fill_addr, fill_size, WAITING_DNS_UP, stamped );
657
658 /* get_address of server from name_server */
659
660 if( locate_service(servp) <= 0)
661 {
662/*
663 service_tmout( servp->serv_id );
664*/
665 dtq_start_timer( 0, service_tmout, servp->serv_id);
666 }
667 ENABLE_AST
668 }
669 return((unsigned) servp->serv_id);
670}
671
672
673int dic_cmnd_service( char *serv_name, void *serv_address, int serv_size )
674{
675 int ret;
676
677 ret = request_command( serv_name, serv_address, serv_size,
678 0, 0, 0 );
679
680 return(ret ? 1 : 0);
681
682}
683
684int dic_cmnd_service_stamped( char *serv_name, void *serv_address, int serv_size )
685{
686 int ret;
687
688 ret = request_command( serv_name, serv_address, serv_size,
689 0, 0, 1 );
690
691 return(ret ? 1 : 0);
692
693}
694
695int dic_cmnd_callback( char *serv_name, void *serv_address, int serv_size,
696 void (*usr_routine)(), long tag )
697{
698 int ret;
699
700 ret = request_command( serv_name, serv_address, serv_size,
701 usr_routine, tag, 0 );
702 return(ret ? 1 : 0);
703}
704
705int dic_cmnd_callback_stamped( char *serv_name, void *serv_address, int serv_size,
706 void (*usr_routine)(), long tag )
707{
708 int ret;
709
710 ret = request_command( serv_name, serv_address, serv_size,
711 usr_routine, tag, 1 );
712 return(ret ? 1 : 0);
713}
714
715int request_command(char *serv_name, void *serv_address, int serv_size,
716 void (*usr_routine)(), long tag, int stamped)
717{
718 int conn_id, ret;
719 register DIC_SERVICE *servp, *testp;
720 int *fillp;
721 int send_command();
722 int end_command();
723 void dim_init_threads(void);
724 int locate_service();
725
726 if(!Threads_off)
727 {
728 dim_init_threads();
729 }
730 {
731 DISABLE_AST
732 /* create a timer queue for timeouts if not yet done */
733 if( !Dic_timer_q ) {
734 conn_arr_create( SRC_DIC );
735 Dic_timer_q = dtq_create();
736 }
737
738 /* store_service */
739 if( !Cmnd_head ) {
740 Cmnd_head = (DIC_SERVICE *) malloc(sizeof(DIC_SERVICE) );
741 dll_init( (DLL *) Cmnd_head );
742 Cmnd_head->serv_id = 0;
743 }
744 if( (servp = locate_command(serv_name)) )
745 {
746 if(!(testp = locate_pending(serv_name)))
747 {
748 if( (conn_id = servp->conn_id) )
749 {
750 free( servp->fill_address );
751 fillp = (int *)malloc(serv_size);
752 memcpy( (char *)fillp, (char *)serv_address, serv_size );
753 servp->fill_address = fillp;
754 servp->fill_size = serv_size;
755/*
756 servp->fill_address = (int *)serv_address;
757 servp->fill_size = serv_size;
758*/
759 servp->user_routine = usr_routine;
760 servp->tag = tag;
761 ret = send_command(conn_id, servp);
762 end_command(servp, ret);
763 ENABLE_AST
764 return(1);
765 }
766 }
767 }
768 servp = insert_service( COMMAND, 0,
769 serv_name, 0, 0, usr_routine, tag,
770 (int *)serv_address, serv_size,
771 WAITING_DNS_UP, stamped );
772 if( locate_service(servp) <= 0)
773 {
774/*
775 service_tmout( servp->serv_id );
776*/
777 dtq_start_timer( 0, service_tmout, servp->serv_id);
778 }
779 ENABLE_AST
780 }
781 return(-1);
782}
783
784DIC_SERVICE *insert_service( int type, int timeout, char *name, int *address, int size,
785 void (*routine)(), long tag, int *fill_addr, int fill_size,
786 int pending, int stamped)
787{
788 register DIC_SERVICE *newp;
789 int *fillp;
790 int service_id;
791 int tout;
792 float ftout;
793
794 DISABLE_AST
795 newp = (DIC_SERVICE *) malloc(sizeof(DIC_SERVICE));
796 newp->pending = 0;
797 strncpy( newp->serv_name, name, MAX_NAME );
798 newp->type = type;
799 newp->timeout = timeout;
800 newp->serv_address = address;
801 newp->serv_size = size;
802 newp->user_routine = routine;
803 newp->tag = tag;
804 fillp = (int *)malloc(fill_size);
805 memcpy( (char *) fillp, (char *) fill_addr, fill_size );
806 newp->fill_address = fillp;
807 newp->fill_size = fill_size;
808 newp->conn_id = 0;
809 newp->format_data[0].par_bytes = 0;
810 newp->next = (DIC_SERVICE *)0;
811 service_id = id_get((void *)newp, SRC_DIC);
812 newp->serv_id = service_id;
813 if( !Service_pend_head )
814 {
815 Service_pend_head = (DIC_SERVICE *) malloc(sizeof(DIC_SERVICE));
816 dll_init( (DLL *) Service_pend_head );
817 Service_pend_head->serv_id = 0;
818 }
819 dll_insert_queue( (DLL *) Service_pend_head, (DLL *)newp );
820 newp->timer_ent = NULL;
821 if(type != MONIT_FIRST)
822 {
823 if( timeout )
824 {
825 tout = timeout;
826 if(type != ONCE_ONLY)
827 {
828 if(tout < 10)
829 tout = 10;
830 ftout = (float)tout * (float)1.5;
831 tout = (int)ftout;
832 }
833 newp->curr_timeout = tout;
834 newp->timer_ent = dtq_add_entry( Dic_timer_q,
835 newp->curr_timeout,
836 service_tmout, newp->serv_id );
837 }
838 }
839 newp->pending = pending;
840 newp->tmout_done = 0;
841 newp->stamped = stamped;
842 newp->time_stamp[0] = 0;
843 newp->time_stamp[1] = 0;
844 newp->quality = 0;
845 newp->def[0] = '\0';
846#ifdef VxWorks
847 newp->tid = taskIdSelf();
848#endif
849 ENABLE_AST
850 return(newp);
851}
852
853
854void modify_service( DIC_SERVICE *servp, int timeout, int *address, int size, void (*routine)(),
855 long tag, int *fill_addr, int fill_size, int stamped)
856{
857 int *fillp;
858
859 if( servp->timer_ent )
860 {
861 dtq_rem_entry( Dic_timer_q, servp->timer_ent );
862 servp->timer_ent = 0;
863 }
864 servp->timeout = timeout;
865 servp->serv_address = address;
866 servp->serv_size = size;
867 servp->user_routine = routine;
868 servp->tag = tag;
869 free( servp->fill_address );
870 fillp = (int *)malloc(fill_size);
871 memcpy( (char *) fillp, (char *) fill_addr, fill_size );
872 servp->fill_address = fillp;
873 servp->fill_size = fill_size;
874 servp->stamped = stamped;
875 if(timeout)
876 {
877 servp->curr_timeout = timeout;
878 servp->timer_ent = dtq_add_entry( Dic_timer_q,
879 servp->curr_timeout,
880 service_tmout, servp->serv_id );
881 }
882 else
883 servp->timer_ent = NULL;
884}
885
886void dic_change_address( unsigned serv_id, void *serv_address, int serv_size)
887{
888 register DIC_SERVICE *servp;
889
890 DISABLE_AST
891 if( serv_id == 0 )
892 {
893 ENABLE_AST
894 return;
895 }
896 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
897 servp->serv_address = (int *)serv_address;
898 servp->serv_size = serv_size;
899 ENABLE_AST
900}
901
902int dic_get_quality( unsigned serv_id )
903{
904 register DIC_SERVICE *servp;
905
906 DISABLE_AST
907 if( serv_id == 0 )
908 {
909 if(Current_server)
910 servp = Current_server;
911 else
912 {
913
914 ENABLE_AST
915 return(-1);
916 }
917 }
918 else
919 {
920 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
921 }
922 ENABLE_AST
923 return(servp->quality);
924}
925
926char *dic_get_format( unsigned serv_id )
927{
928 register DIC_SERVICE *servp;
929
930 DISABLE_AST
931 if( serv_id == 0 )
932 {
933 if(Current_server)
934 servp = Current_server;
935 else
936 {
937 ENABLE_AST
938 return((char *) 0);
939 }
940 }
941 else
942 {
943 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
944 }
945 ENABLE_AST
946 return(servp->def);
947}
948
949int dic_get_timestamp( unsigned serv_id, int *secs, int *milisecs )
950{
951 register DIC_SERVICE *servp;
952
953 DISABLE_AST
954 *secs = 0;
955 *milisecs = 0;
956 if( serv_id == 0 )
957 {
958 if(Current_server)
959 servp = Current_server;
960 else
961 {
962 ENABLE_AST
963 return(-1);
964 }
965 }
966 else
967 {
968 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
969 }
970 ENABLE_AST
971 if(servp->time_stamp[1])
972 {
973 *secs = servp->time_stamp[1];
974 if((servp->time_stamp[0] & 0xFFFF0000) == 0xc0de0000)
975 *milisecs = servp->time_stamp[0] & 0x0000FFFF;
976 else
977 *milisecs = servp->time_stamp[0];
978 return(1);
979 }
980 else
981 {
982/*
983 *secs = 0;
984 *milisecs = 0;
985*/
986 return(0);
987 }
988}
989
990void dic_release_service( unsigned service_id )
991{
992 register DIC_SERVICE *servp;
993 register int conn_id, pending;
994 static DIC_PACKET *dic_packet;
995 static int packet_size = 0;
996 DIC_DNS_PACKET dic_dns_packet;
997 register DIC_DNS_PACKET *dic_dns_p = &dic_dns_packet;
998 SERVICE_REQ *serv_reqp;
999 int release_service();
1000
1001 DISABLE_AST
1002 if( !packet_size ) {
1003 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER);
1004 packet_size = DIC_HEADER;
1005 }
1006 if( service_id == 0 )
1007 {
1008 ENABLE_AST
1009 return;
1010 }
1011 servp = (DIC_SERVICE *)id_get_ptr(service_id, SRC_DIC);
1012 if( servp == 0 )
1013 {
1014 ENABLE_AST
1015 return;
1016 }
1017 if(servp->serv_id != (int)service_id)
1018 {
1019 ENABLE_AST
1020 return;
1021 }
1022 pending = servp->pending;
1023 switch( pending )
1024 {
1025 case NOT_PENDING :
1026 conn_id = servp->conn_id;
1027 strncpy(dic_packet->service_name, servp->serv_name, MAX_NAME);
1028 dic_packet->type = htovl(DIM_DELETE);
1029 dic_packet->service_id = htovl(service_id);
1030 dic_packet->size = htovl(DIC_HEADER);
1031 dna_write( conn_id, dic_packet, DIC_HEADER );
1032 release_service( servp );
1033 break;
1034 case WAITING_SERVER_UP :
1035 if( ( servp->type == COMMAND )||( servp->type == ONCE_ONLY ) )
1036 {
1037 servp->pending = DELETED;
1038 break;
1039 }
1040 if( Dns_dic_conn_id > 0) {
1041 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1042 dic_dns_p->src_type = htovl(SRC_DIC);
1043 serv_reqp = &dic_dns_p->service;
1044 strcpy( serv_reqp->service_name, servp->serv_name );
1045 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1046 dna_write( Dns_dic_conn_id, dic_dns_p,
1047 sizeof(DIC_DNS_PACKET) );
1048 }
1049 release_service( servp );
1050 break;
1051 case WAITING_CMND_ANSWER :
1052 case WAITING_DNS_UP :
1053 release_service( servp );
1054 break;
1055 case WAITING_DNS_ANSWER :
1056 servp->pending = DELETED;
1057 break;
1058 }
1059 ENABLE_AST
1060}
1061
1062
1063int release_service( DIC_SERVICE *servicep )
1064{
1065 register DIC_SERVICE *servp;
1066 register int conn_id = 0;
1067 register int found = 0;
1068 register DIC_CONNECTION *dic_connp;
1069 char name[MAX_NAME], *ptr;
1070 int id;
1071
1072 id = servicep->serv_id;
1073 servicep->serv_id = 0;
1074 conn_id = servicep->conn_id;
1075 dic_connp = &Dic_conns[conn_id] ;
1076 dll_remove( (DLL *) servicep );
1077 if( servicep->timer_ent )
1078 {
1079 dtq_rem_entry( Dic_timer_q, servicep->timer_ent );
1080 }
1081/*
1082 if(servicep->type != COMMAND)
1083*/
1084 free( servicep->fill_address );
1085 if(strstr(servicep->serv_name,"/RpcOut"))
1086 {
1087 strcpy(name, servicep->serv_name);
1088 }
1089 else
1090 name[0] = '\0';
1091 free( servicep );
1092 if( conn_id && dic_connp->service_head )
1093 {
1094 if( dll_empty((DLL *)dic_connp->service_head) )
1095 {
1096 if( (servp = (DIC_SERVICE *) Cmnd_head) )
1097 {
1098 while( (servp = (DIC_SERVICE *) dll_get_next(
1099 (DLL *) Cmnd_head,
1100 (DLL *) servp)) )
1101 {
1102 if( servp->conn_id == conn_id)
1103 found = 1;
1104 }
1105 }
1106 if( !found)
1107 {
1108 if(Debug_on)
1109 {
1110 dim_print_date_time();
1111 printf("Conn %d, Server %s on node %s released\n",
1112 conn_id, dic_connp->task_name, dic_connp->node_name);
1113 fflush(stdout);
1114 }
1115 release_conn( conn_id );
1116 }
1117 }
1118 }
1119 if(name[0])
1120 {
1121 ptr = strstr(name,"/RpcOut");
1122 strcpy(ptr + 4, "In");
1123 if( (servp = locate_command(name)) )
1124 release_service(servp);
1125 }
1126 id_free(id, SRC_DIC);
1127 return(1);
1128}
1129
1130
1131int locate_service( DIC_SERVICE *servp )
1132{
1133 extern int open_dns(long, void (*)(), void (*)(), int, int, int);
1134
1135 if(!strcmp(servp->serv_name,"DIS_DNS/SERVER_INFO"))
1136 {
1137 Tmout_min = DID_DNS_TMOUT_MIN;
1138 Tmout_max = DID_DNS_TMOUT_MAX;
1139 }
1140 if(Tmout_min == 0)
1141 {
1142 Tmout_min = DIC_DNS_TMOUT_MIN;
1143 Tmout_max = DIC_DNS_TMOUT_MAX;
1144 }
1145 if( !Dns_dic_conn_id )
1146 {
1147 DISABLE_AST;
1148 Dns_dic_conn_id = open_dns( 0, recv_dns_dic_rout, error_handler,
1149 Tmout_min,
1150 Tmout_max,
1151 SRC_DIC);
1152 if(Dns_dic_conn_id == -2)
1153 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
1154 ENABLE_AST;
1155 }
1156 if( Dns_dic_conn_id > 0)
1157 {
1158 DISABLE_AST;
1159 request_dns_info(servp->prev->serv_id);
1160 ENABLE_AST;
1161 }
1162
1163 return(Dns_dic_conn_id);
1164}
1165
1166DIC_SERVICE *locate_command( char *serv_name )
1167{
1168 register DIC_SERVICE *servp;
1169
1170 if(!Cmnd_head)
1171 return((DIC_SERVICE *)0);
1172 if( (servp = (DIC_SERVICE *) dll_search( (DLL *) Cmnd_head, serv_name,
1173 strlen(serv_name)+1)) )
1174 return(servp);
1175 return((DIC_SERVICE *)0);
1176}
1177
1178DIC_SERVICE *locate_pending( char *serv_name )
1179{
1180 register DIC_SERVICE *servp;
1181
1182 if(!Service_pend_head)
1183 return((DIC_SERVICE *)0);
1184 if( (servp = (DIC_SERVICE *) dll_search( (DLL *) Service_pend_head, serv_name,
1185 strlen(serv_name)+1)) )
1186 return(servp);
1187 return((DIC_SERVICE *)0);
1188}
1189
1190DIC_BAD_CONNECTION *locate_bad(char *node, char *task, int port)
1191{
1192 DIC_BAD_CONNECTION *bad_connp;
1193
1194 if(!Bad_connection_head)
1195 return((DIC_BAD_CONNECTION *)0);
1196 bad_connp = Bad_connection_head;
1197 while( (bad_connp = (DIC_BAD_CONNECTION *) dll_get_next(
1198 (DLL *) Bad_connection_head,
1199 (DLL *) bad_connp)) )
1200 {
1201 if((!strcmp(bad_connp->conn.node_name, node)) &&
1202 (!strcmp(bad_connp->conn.task_name, task)) &&
1203 (bad_connp->conn.port == port) )
1204 return(bad_connp);
1205 }
1206 return((DIC_BAD_CONNECTION *)0);
1207}
1208
1209static void request_dns_info(int id)
1210{
1211 DIC_SERVICE *servp, *ptr;
1212 int n_pend = 0;
1213 int request_dns_single_info();
1214 extern int open_dns();
1215
1216 DISABLE_AST
1217 if( Dns_dic_conn_id <= 0)
1218 {
1219 Dns_dic_conn_id = open_dns( 0, recv_dns_dic_rout, error_handler,
1220 Tmout_min,
1221 Tmout_max,
1222 SRC_DIC);
1223 if(Dns_dic_conn_id == -2)
1224 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
1225 }
1226 if( Dns_dic_conn_id > 0)
1227 {
1228 servp = Service_pend_head;
1229 if(id > 0)
1230 {
1231 ptr = (DIC_SERVICE *)id_get_ptr(id, SRC_DIC);
1232 if(ptr)
1233 {
1234 if((ptr->serv_id == id) && (ptr->pending != NOT_PENDING))
1235 servp = ptr;
1236 }
1237 }
1238
1239 while( (servp = (DIC_SERVICE *) dll_get_next(
1240 (DLL *) Service_pend_head,
1241 (DLL *) servp)) )
1242 {
1243 if( servp->pending == WAITING_DNS_UP)
1244 {
1245 if(!request_dns_single_info( servp ))
1246 {
1247 ENABLE_AST
1248 return;
1249 }
1250 n_pend++;
1251 }
1252 if(n_pend == 1000)
1253 {
1254 dtq_start_timer( 0, request_dns_info, servp->serv_id);
1255 ENABLE_AST
1256 return;
1257 }
1258 }
1259 }
1260 else
1261 {
1262 servp = Service_pend_head;
1263 while( (servp = (DIC_SERVICE *) dll_get_next(
1264 (DLL *) Service_pend_head,
1265 (DLL *) servp)) )
1266 {
1267 if( servp->pending == WAITING_DNS_UP)
1268 {
1269 if(( servp->type != COMMAND )&&( servp->type != ONCE_ONLY ))
1270 service_tmout( servp->serv_id );
1271 }
1272 }
1273 }
1274 ENABLE_AST
1275}
1276
1277
1278int request_dns_single_info( DIC_SERVICE *servp )
1279{
1280 static DIC_DNS_PACKET Dic_dns_packet;
1281 static SERVICE_REQ *serv_reqp;
1282 int ret = 1;
1283
1284 if( Dns_dic_conn_id > 0)
1285 {
1286 if(Debug_on)
1287 {
1288 dim_print_date_time();
1289 printf("Requesting DNS Info for %s, id %d\n",
1290 servp->serv_name, servp->serv_id);
1291 }
1292
1293 Dic_dns_packet.src_type = htovl(SRC_DIC);
1294 serv_reqp = &Dic_dns_packet.service;
1295 strcpy( serv_reqp->service_name, servp->serv_name );
1296 serv_reqp->service_id = htovl(servp->serv_id);
1297 servp->pending = WAITING_DNS_ANSWER;
1298 Dic_dns_packet.size = htovl(sizeof(DIC_DNS_PACKET));
1299 if(!dna_write( Dns_dic_conn_id, &Dic_dns_packet,
1300 sizeof(DIC_DNS_PACKET) ) )
1301 {
1302 ret = 0;
1303 }
1304
1305 }
1306 return ret;
1307}
1308
1309
1310static int handle_dns_info( DNS_DIC_PACKET *packet )
1311{
1312 int conn_id, service_id;
1313 DIC_SERVICE *servp;
1314 char *node_name, *task_name;
1315 char node_info[MAX_NODE_NAME+4];
1316 int i, port, protocol, format, ret, pid;
1317 register DIC_CONNECTION *dic_connp ;
1318 DIC_DNS_PACKET dic_dns_packet;
1319 register DIC_DNS_PACKET *dic_dns_p = &dic_dns_packet;
1320 SERVICE_REQ *serv_reqp;
1321 DIC_BAD_CONNECTION *bad_connp;
1322 int retrying = 0;
1323 int tmout;
1324 int send_service_command();
1325 int find_connection();
1326 void move_to_bad_service();
1327 void retry_bad_connection();
1328
1329 service_id = vtohl(packet->service_id);
1330
1331 servp = (DIC_SERVICE *)id_get_ptr(service_id, SRC_DIC);
1332 if(!servp)
1333 return(0);
1334 if(servp->serv_id != service_id)
1335 return(0);
1336 if(Debug_on)
1337 {
1338 dim_print_date_time();
1339 printf("Receiving DNS Info for service %s, id %d\n",servp->serv_name,
1340 vtohl(packet->service_id));
1341 }
1342 node_name = packet->node_name;
1343 if(node_name[0] == -1)
1344 {
1345 error_handler(0, DIM_FATAL, DIMDNSREFUS, "DIM_DNS refuses connection");
1346 return(0);
1347 }
1348
1349 task_name = packet->task_name;
1350 strcpy(node_info,node_name);
1351 for(i = 0; i < 4; i ++)
1352 node_info[strlen(node_name)+i+1] = packet->node_addr[i];
1353 port = vtohl(packet->port);
1354 pid = vtohl(packet->pid);
1355 protocol = vtohl(packet->protocol);
1356 format = vtohl(packet->format);
1357
1358 if( Dns_dic_timr )
1359 dtq_clear_entry( Dns_dic_timr );
1360 if( servp->pending == DELETED ) {
1361 if( Dns_dic_conn_id > 0) {
1362 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1363 dic_dns_p->src_type = htovl(SRC_DIC);
1364 serv_reqp = &dic_dns_p->service;
1365 strcpy( serv_reqp->service_name, servp->serv_name );
1366 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1367 dna_write( Dns_dic_conn_id, dic_dns_p,
1368 sizeof(DIC_DNS_PACKET) );
1369 }
1370 release_service( servp );
1371 return(0);
1372 }
1373 if( !node_name[0] )
1374 {
1375 servp->pending = WAITING_SERVER_UP;
1376 service_tmout( servp->serv_id );
1377 if( servp->pending == DELETED )
1378 {
1379 if( Dns_dic_conn_id > 0)
1380 {
1381 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1382 dic_dns_p->src_type = htovl(SRC_DIC);
1383 serv_reqp = &dic_dns_p->service;
1384 strcpy( serv_reqp->service_name, servp->serv_name );
1385 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1386 dna_write( Dns_dic_conn_id, dic_dns_p,
1387 sizeof(DIC_DNS_PACKET) );
1388 }
1389 release_service( servp );
1390 }
1391 return(0);
1392 }
1393#ifdef OSK
1394 {
1395 register char *ptr;
1396
1397 if(strncmp(node_name,"fidel",5))
1398 {
1399 for(ptr = node_name; *ptr; ptr++)
1400 {
1401 if(*ptr == '.')
1402 {
1403 *ptr = '\0';
1404 break;
1405 }
1406 }
1407 }
1408 }
1409#endif
1410 if( !(conn_id = find_connection(node_name, task_name, port)) )
1411 {
1412 bad_connp = locate_bad(node_name, task_name, port);
1413 if(bad_connp)
1414 retrying = bad_connp->retrying;
1415 if((!bad_connp) || (retrying))
1416 {
1417 if( (conn_id = dna_open_client(node_info, task_name, port,
1418 protocol, recv_rout, error_handler, SRC_DIC)) )
1419 {
1420/*
1421#ifndef VxWorks
1422 if(format & MY_OS9)
1423 {
1424 dna_set_test_write(conn_id, TEST_TIME_OSK);
1425 format &= 0xfffff7ff;
1426 }
1427 else
1428 {
1429 dna_set_test_write(conn_id, TEST_TIME_VMS);
1430 }
1431#endif
1432*/
1433 dna_set_test_write(conn_id, TEST_TIME_OSK);
1434 dic_connp = &Dic_conns[conn_id];
1435 strncpy( dic_connp->node_name, node_name,
1436 MAX_NODE_NAME);
1437 strncpy( dic_connp->task_name, task_name,
1438 MAX_TASK_NAME);
1439 dic_connp->port = port;
1440 dic_connp->pid = pid;
1441 if(Debug_on)
1442 {
1443 dim_print_date_time();
1444 printf(" - Conn %d, Server %s on node %s Connecting\n",
1445 conn_id, dic_connp->task_name, dic_connp->node_name);
1446 fflush(stdout);
1447 }
1448
1449 dic_connp->service_head =
1450 malloc(sizeof(DIC_SERVICE));
1451 dll_init( (DLL *) dic_connp->service_head);
1452 ((DIC_SERVICE *)(dic_connp->service_head))->serv_id = 0;
1453 if(retrying)
1454 {
1455 dll_remove((DLL *)bad_connp->conn.service_head);
1456 free(bad_connp->conn.service_head);
1457 dll_remove((DLL *)bad_connp);
1458 free(bad_connp);
1459 }
1460 }
1461 else
1462 {
1463 if(!retrying)
1464 {
1465 if( !Bad_connection_head )
1466 {
1467 Bad_connection_head = (DIC_BAD_CONNECTION *) malloc(sizeof(DIC_BAD_CONNECTION));
1468 dll_init( (DLL *) Bad_connection_head );
1469 Bad_connection_head->conn.service_head = 0;
1470 }
1471 bad_connp = (DIC_BAD_CONNECTION *) malloc(sizeof(DIC_BAD_CONNECTION));
1472 bad_connp->n_retries = 0;
1473 bad_connp->conn.service_head = malloc(sizeof(DIC_SERVICE));
1474 dll_init( (DLL *) bad_connp->conn.service_head);
1475
1476 dll_insert_queue( (DLL *) Bad_connection_head, (DLL *) bad_connp );
1477 if(Debug_on)
1478 {
1479 dim_print_date_time();
1480 printf(" - Failed connecting to Server %s on node %s port %d\n",
1481 task_name, node_name, port);
1482 fflush(stdout);
1483 }
1484 service_tmout( servp->serv_id );
1485 }
1486 bad_connp->n_retries++;
1487 bad_connp->retrying = 0;
1488 strncpy( bad_connp->conn.node_name, node_name, MAX_NODE_NAME);
1489 strncpy( bad_connp->conn.task_name, task_name, MAX_TASK_NAME);
1490 bad_connp->conn.port = port;
1491 tmout = BAD_CONN_TIMEOUT * bad_connp->n_retries;
1492 if(tmout > 120)
1493 tmout = 120;
1494 dtq_start_timer(tmout, retry_bad_connection, (long)bad_connp);
1495 if(( servp->type == COMMAND )||( servp->type == ONCE_ONLY ))
1496 return(0);
1497 move_to_bad_service(servp, bad_connp);
1498/*
1499 ((DIC_SERVICE *)(dic_connp->service_head))->serv_id = 0;
1500
1501 servp = Service_pend_head;
1502 while( (servp = (DIC_SERVICE *) dll_get_next(
1503 (DLL *) Service_pend_head,
1504 (DLL *) servp)) )
1505 {
1506 if( (servp->pending == WAITING_DNS_ANSWER) ||
1507 (servp->pending == WAITING_SERVER_UP))
1508 servp->pending = WAITING_DNS_UP;
1509 }
1510 dna_close( Dns_dic_conn_id );
1511 Dns_dic_conn_id = 0;
1512 request_dns_info(0);
1513*/
1514 return(0);
1515 }
1516 }
1517 else
1518 {
1519 if(!retrying)
1520 service_tmout( servp->serv_id );
1521 if(( servp->type == COMMAND )||( servp->type == ONCE_ONLY ))
1522 return(0);
1523 move_to_bad_service(servp, bad_connp);
1524 return(0);
1525 }
1526 }
1527 strcpy(servp->def, packet->service_def);
1528 get_format_data(format, servp->format_data, servp->def);
1529 servp->format = format;
1530 servp->conn_id = conn_id;
1531
1532 ret = send_service_command( servp );
1533/*
1534 if( ret == 1)
1535 {
1536 if(servp->pending != WAITING_CMND_ANSWER)
1537 servp->pending = NOT_PENDING;
1538 servp->tmout_done = 0;
1539 }
1540*/
1541 return(1);
1542}
1543
1544void retry_bad_connection(DIC_BAD_CONNECTION *bad_connp)
1545{
1546DIC_SERVICE *servp, *auxp;
1547int found = 0;
1548void move_to_notok_service();
1549
1550 if(!bad_connp)
1551 return;
1552 servp = (DIC_SERVICE *)bad_connp->conn.service_head;
1553 while( (servp = (DIC_SERVICE *) dll_get_next(
1554 (DLL *) bad_connp->conn.service_head,
1555 (DLL *) servp)) )
1556 {
1557 servp->pending = WAITING_DNS_UP;
1558 servp->conn_id = 0;
1559 auxp = servp->prev;
1560 move_to_notok_service( servp );
1561 servp = auxp;
1562 found = 1;
1563 }
1564 bad_connp->retrying = 1;
1565 if(found)
1566 request_dns_info(0);
1567}
1568
1569void move_to_ok_service( DIC_SERVICE *servp, int conn_id )
1570{
1571 if(Dic_conns[conn_id].service_head)
1572 {
1573 servp->pending = NOT_PENDING;
1574 servp->tmout_done = 0;
1575 dll_remove( (DLL *) servp );
1576 dll_insert_queue( (DLL *) Dic_conns[conn_id].service_head,
1577 (DLL *) servp );
1578 }
1579}
1580
1581void move_to_bad_service( DIC_SERVICE *servp, DIC_BAD_CONNECTION *bad_connp)
1582{
1583 servp->pending = WAITING_DNS_UP;
1584 dll_remove( (DLL *) servp );
1585 dll_insert_queue( (DLL *) bad_connp->conn.service_head, (DLL *) servp );
1586}
1587
1588void move_to_cmnd_service( DIC_SERVICE *servp )
1589{
1590/*
1591 if(servp->pending != WAITING_CMND_ANSWER)
1592*/
1593 servp->pending = NOT_PENDING;
1594 servp->tmout_done = 0;
1595 dll_remove( (DLL *) servp );
1596 dll_insert_queue( (DLL *) Cmnd_head, (DLL *) servp );
1597}
1598
1599void move_to_notok_service(DIC_SERVICE *servp )
1600{
1601
1602 dll_remove( (DLL *) servp );
1603 dll_insert_queue( (DLL *) Service_pend_head, (DLL *) servp );
1604}
1605
1606static void get_format_data(int format, FORMAT_STR *format_data, char *def)
1607{
1608 register FORMAT_STR *formatp = format_data;
1609 register char code, last_code = 0;
1610 int num;
1611 char *ptr = def;
1612
1613 if(format){}
1614 while(*ptr)
1615 {
1616 switch(*ptr)
1617 {
1618 case 'i':
1619 case 'I':
1620 case 'l':
1621 case 'L':
1622 *ptr = 'I';
1623 break;
1624 case 'x':
1625 case 'X':
1626 *ptr = 'X';
1627 break;
1628 case 's':
1629 case 'S':
1630 *ptr = 'S';
1631 break;
1632 case 'f':
1633 case 'F':
1634 *ptr = 'F';
1635 break;
1636 case 'd':
1637 case 'D':
1638 *ptr = 'D';
1639 break;
1640 case 'c':
1641 case 'C':
1642 *ptr = 'C';
1643 break;
1644 }
1645 ptr++;
1646 }
1647 code = *def;
1648 while(*def)
1649 {
1650 if(code != last_code)
1651 {
1652 formatp->par_num = 0;
1653 formatp->flags = 0;
1654 switch(code)
1655 {
1656 case 'i':
1657 case 'I':
1658 case 'l':
1659 case 'L':
1660 formatp->par_bytes = SIZEOF_LONG;
1661 formatp->flags |= SWAPL;
1662 break;
1663 case 'x':
1664 case 'X':
1665 formatp->par_bytes = SIZEOF_DOUBLE;
1666 formatp->flags |= SWAPD;
1667 break;
1668 case 's':
1669 case 'S':
1670 formatp->par_bytes = SIZEOF_SHORT;
1671 formatp->flags |= SWAPS;
1672 break;
1673 case 'f':
1674 case 'F':
1675 formatp->par_bytes = SIZEOF_LONG;
1676 formatp->flags |= SWAPL;
1677#ifdef vms
1678/*
1679 if((format & 0xF0) != (MY_FORMAT & 0xF0))
1680*/
1681 formatp->flags |= (format & 0xF0);
1682 formatp->flags |= IT_IS_FLOAT;
1683#endif
1684 break;
1685 case 'd':
1686 case 'D':
1687 formatp->par_bytes = SIZEOF_DOUBLE;
1688 formatp->flags |= SWAPD;
1689#ifdef vms
1690/*
1691 if((format & 0xF0) != (MY_FORMAT & 0xF0))
1692*/
1693 formatp->flags |= (format & 0xF0);
1694 formatp->flags |= IT_IS_FLOAT;
1695#endif
1696 break;
1697 case 'c':
1698 case 'C':
1699 case 'b':
1700 case 'B':
1701 case 'v':
1702 case 'V':
1703 formatp->par_bytes = SIZEOF_CHAR;
1704 formatp->flags |= NOSWAP;
1705 break;
1706 }
1707 }
1708 def++;
1709 if(*def != ':')
1710 {
1711/* tested by the server
1712 if(*def)
1713 {
1714 printf("Bad service definition parsing\n");
1715 fflush(stdout);
1716 }
1717 else
1718*/
1719 formatp->par_num = 0;
1720 }
1721 else
1722 {
1723 def++;
1724 sscanf(def,"%d",&num);
1725 formatp->par_num += num;
1726 while((*def != ';') && (*def != '\0'))
1727 def++;
1728 if(*def)
1729 def++;
1730 }
1731 last_code = code;
1732 code = *def;
1733 if(code != last_code)
1734 formatp++;
1735 }
1736 formatp->par_bytes = 0;
1737/*
1738 if((format & 0xF) == (MY_FORMAT & 0xF))
1739 {
1740 for(i = 0, formatp = format_data; i<index;i++, formatp++)
1741 formatp->flags &= 0xF0;
1742 }
1743*/
1744}
1745
1746int end_command(DIC_SERVICE *servp, int ret)
1747{
1748 DIC_SERVICE *aux_servp;
1749 DIC_CONNECTION *dic_connp;
1750
1751 DISABLE_AST
1752 dic_connp = &Dic_conns[servp->conn_id];
1753 if(servp->pending != WAITING_CMND_ANSWER)
1754 {
1755 if((!ret) || (!dic_connp->service_head))
1756 {
1757 servp->pending = WAITING_DNS_UP;
1758 dic_release_service( servp->serv_id );
1759 }
1760 else
1761 {
1762 aux_servp = locate_command(servp->serv_name);
1763 if( !aux_servp )
1764 {
1765 move_to_cmnd_service( servp );
1766 }
1767 else
1768 {
1769 if(aux_servp != servp)
1770 {
1771 servp->pending = WAITING_DNS_UP;
1772 dic_release_service( servp->serv_id );
1773 }
1774 }
1775 }
1776 }
1777 ENABLE_AST
1778 return(ret);
1779}
1780
1781int send_service_command(DIC_SERVICE *servp)
1782{
1783 int ret = 1;
1784 int conn_id;
1785 int send_command();
1786 int send_service();
1787
1788 conn_id = servp->conn_id;
1789 if( servp->type == COMMAND )
1790 {
1791 ret = send_command(conn_id, servp);
1792 end_command(servp, ret);
1793 }
1794 else
1795 {
1796 if( send_service(conn_id, servp))
1797 {
1798 if( servp->type == ONCE_ONLY )
1799 {
1800 if( !locate_command(servp->serv_name) )
1801 {
1802 move_to_cmnd_service( servp );
1803 }
1804 }
1805 else
1806 move_to_ok_service( servp, conn_id );
1807 }
1808 }
1809 return(ret);
1810}
1811
1812int send_service(int conn_id, DIC_SERVICE *servp)
1813{
1814 static DIC_PACKET *dic_packet;
1815 static int serv_packet_size = 0;
1816 int type, ret;
1817
1818 if( !serv_packet_size ) {
1819 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER);
1820 serv_packet_size = DIC_HEADER;
1821 }
1822
1823 strncpy( dic_packet->service_name, servp->serv_name, MAX_NAME );
1824 type = servp->type;
1825 if(servp->stamped)
1826 type |= STAMPED;
1827 dic_packet->type = htovl(type);
1828 dic_packet->timeout = htovl(servp->timeout);
1829 dic_packet->service_id = htovl(servp->serv_id);
1830 dic_packet->format = htovl(MY_FORMAT);
1831 dic_packet->size = htovl(DIC_HEADER);
1832 ret = dna_write(conn_id, dic_packet, DIC_HEADER);
1833 return(ret);
1834}
1835
1836typedef struct
1837{
1838 int ret_code;
1839 int serv_id;
1840} CMNDCB_ITEM;
1841
1842void do_cmnd_callback(CMNDCB_ITEM *itemp)
1843{
1844
1845 DIC_SERVICE *servp;
1846 int ret, serv_id;
1847/*
1848 itemp = (CMNDCB_ITEM *)id_get_ptr(id, SRC_DIC);
1849*/
1850 serv_id = itemp->serv_id;
1851 ret = itemp->ret_code;
1852 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
1853 if(servp)
1854 {
1855 if(servp->serv_id == serv_id)
1856 {
1857 Curr_conn_id = servp->conn_id;
1858 (servp->user_routine)( &servp->tag, &ret );
1859 servp->pending = NOT_PENDING;
1860 end_command(servp, ret);
1861 Curr_conn_id = 0;
1862 }
1863 }
1864/*
1865 id_free(id, SRC_DIC);
1866*/
1867 free(itemp);
1868}
1869
1870int send_command(int conn_id, DIC_SERVICE *servp)
1871{
1872 static DIC_PACKET *dic_packet;
1873 static int cmnd_packet_size = 0;
1874 register int size;
1875 int ret;
1876 CMNDCB_ITEM *itemp;
1877
1878 size = servp->fill_size;
1879
1880 if( !cmnd_packet_size ) {
1881 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER + size);
1882 cmnd_packet_size = DIC_HEADER + size;
1883 }
1884 else
1885 {
1886 if( DIC_HEADER + size > cmnd_packet_size ) {
1887 free( dic_packet );
1888 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER + size);
1889 cmnd_packet_size = DIC_HEADER + size;
1890 }
1891 }
1892
1893 strncpy(dic_packet->service_name, servp->serv_name, MAX_NAME);
1894 dic_packet->type = htovl(COMMAND);
1895 dic_packet->timeout = htovl(0);
1896 dic_packet->format = htovl(MY_FORMAT);
1897
1898 dic_packet->service_id = /*id_get((void *)servp)*/servp->serv_id;
1899
1900 size = copy_swap_buffer_out(servp->format, servp->format_data,
1901 dic_packet->buffer, servp->fill_address,
1902 size);
1903 dic_packet->size = htovl( size + DIC_HEADER);
1904 if( servp->user_routine )
1905 {
1906 servp->pending = WAITING_CMND_ANSWER;
1907 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1908 itemp = (CMNDCB_ITEM *)malloc(sizeof(CMNDCB_ITEM));
1909 itemp->serv_id = servp->serv_id;
1910 itemp->ret_code = ret;
1911/*
1912 id = id_get((void *)itemp, SRC_DIC);
1913*/
1914 dtq_start_timer(0, do_cmnd_callback, (long)itemp);
1915/*
1916 (servp->user_routine)( &servp->tag, &ret );
1917*/
1918 }
1919 else
1920 {
1921 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1922 }
1923/*
1924 if(!ret)
1925 {
1926 servp->pending = WAITING_DNS_UP;
1927 dic_release_service( servp->serv_id );
1928 }
1929*/
1930 /*
1931 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1932 if(!ret)
1933 {
1934 servp->pending = WAITING_DNS_UP;
1935 dic_release_service( servp->serv_id );
1936 }
1937 else
1938 {
1939 dim_usleep(5000);
1940 if( servp->user_routine )
1941 (servp->user_routine)( &servp->tag, &ret );
1942 }
1943*/
1944 return(ret);
1945}
1946
1947int find_connection(char *node, char *task, int port)
1948{
1949 register int i;
1950 register DIC_CONNECTION *dic_connp;
1951
1952 if(task){}
1953 for( i=0, dic_connp = Dic_conns; i<Curr_N_Conns; i++, dic_connp++ )
1954 {
1955/*
1956 if((!strcmp(dic_connp->task_name, task))
1957 &&(!strcmp(dic_connp->node_name, node)))
1958*/
1959 if((!strcmp(dic_connp->node_name, node))
1960 && (dic_connp->port == port))
1961 return(i);
1962 }
1963 return(0);
1964}
1965
1966int dic_get_id(char *name)
1967{
1968 extern int get_proc_name(char *name);
1969
1970 get_proc_name(name);
1971 strcat(name,"@");
1972 get_node_name(&name[strlen(name)]);
1973 return(1);
1974}
1975
1976#ifdef VxWorks
1977void dic_destroy(int tid)
1978{
1979 register int i;
1980 register DIC_CONNECTION *dic_connp;
1981 register DIC_SERVICE *servp, *auxp;
1982 int found = 0;
1983
1984 if(!Dic_conns)
1985 return;
1986 for( i=0, dic_connp = Dic_conns; i<Curr_N_Conns; i++, dic_connp++ )
1987 {
1988 if(servp = (DIC_SERVICE *) dic_connp->service_head)
1989 {
1990 while( servp = (DIC_SERVICE *) dll_get_next(
1991 (DLL *) dic_connp->service_head,
1992 (DLL *) servp) )
1993 {
1994 if( servp->tid == tid )
1995 {
1996 auxp = servp->prev;
1997 dic_release_service( servp->serv_id );
1998 servp = auxp;
1999 if(!dic_connp->service_head)
2000 break;
2001 }
2002 else
2003 found = 1;
2004 }
2005 }
2006 }
2007 if(!found)
2008 {
2009 if(Dns_dic_conn_id > 0)
2010 {
2011 dna_close( Dns_dic_conn_id );
2012 Dns_dic_conn_id = 0;
2013 }
2014 }
2015}
2016
2017void DIMDestroy(int tid)
2018{
2019 dis_destroy(tid);
2020 dic_destroy(tid);
2021}
2022
2023#endif
2024
2025static void release_conn(int conn_id)
2026{
2027 register DIC_CONNECTION *dic_connp = &Dic_conns[conn_id];
2028
2029 if(Debug_on)
2030 {
2031 dim_print_date_time();
2032 printf("Conn %d, Server %s on node %s completely released\n",
2033 conn_id, dic_connp->task_name, dic_connp->node_name);
2034 fflush(stdout);
2035 }
2036 dic_connp->task_name[0] = '\0';
2037 dic_connp->port = 0;
2038 if(dic_connp->service_head)
2039 {
2040 free((DIC_SERVICE *)dic_connp->service_head);
2041 dic_connp->service_head = (char *)0;
2042 }
2043 dna_close(conn_id);
2044}
2045
2046void dic_close_dns()
2047{
2048 register DIC_SERVICE *servp, *auxp;
2049
2050 if(Dns_dic_conn_id > 0)
2051 {
2052 if( (servp = (DIC_SERVICE *) Cmnd_head) )
2053 {
2054 while( (servp = (DIC_SERVICE *) dll_get_next(
2055 (DLL *) Cmnd_head,
2056 (DLL *) servp)) )
2057 {
2058#ifdef DEBUG
2059 printf("\t%s was in the Command list\n", servp->serv_name);
2060 printf("type = %d, pending = %d\n",servp->type, servp->pending);
2061 fflush(stdout);
2062#endif
2063 auxp = servp->prev;
2064 if( (servp->type == ONCE_ONLY ) &&
2065 (servp->pending == WAITING_SERVER_UP))
2066 {
2067 service_tmout( servp->serv_id );
2068 }
2069 else if( (servp->type == COMMAND ) &&
2070 (servp->pending == WAITING_CMND_ANSWER))
2071 {
2072 service_tmout( servp->serv_id );
2073 }
2074 else
2075 {
2076 servp->pending = WAITING_DNS_UP;
2077 dic_release_service( servp->serv_id );
2078 }
2079 servp = auxp;
2080 }
2081 }
2082 dna_close( Dns_dic_conn_id );
2083 Dns_dic_conn_id = 0;
2084 }
2085}
2086/*
2087append_service(service_info_buffer, servp)
2088char *service_info_buffer;
2089SERVICE *servp;
2090{
2091 char name[MAX_NAME], *ptr;
2092
2093 if(strstr(servp->name,"/RpcIn"))
2094 {
2095 strcpy(name,servp->name);
2096 ptr = (char *)strstr(name,"/RpcIn");
2097 *ptr = 0;
2098 strcat(service_info_buffer, name);
2099 strcat(service_info_buffer, "|");
2100 if(servp->def[0])
2101 {
2102 strcat(service_info_buffer, servp->def);
2103 }
2104 strcat(name,"/RpcOut");
2105 if(servp = find_service(name))
2106 {
2107 strcat(service_info_buffer, ",");
2108 if(servp->def[0])
2109 {
2110 strcat(service_info_buffer, servp->def);
2111 }
2112 }
2113 strcat(service_info_buffer, "|RPC");
2114 strcat(service_info_buffer, "\n");
2115 }
2116 else if(strstr(servp->name,"/RpcOut"))
2117 {
2118 }
2119 else
2120 {
2121 strcat(service_info_buffer, servp->name);
2122 strcat(service_info_buffer, "|");
2123 if(servp->def[0])
2124 {
2125 strcat(service_info_buffer, servp->def);
2126 }
2127 strcat(service_info_buffer, "|");
2128 if(servp->type == COMMAND)
2129 {
2130 strcat(service_info_buffer, "CMD");
2131 }
2132 strcat(service_info_buffer, "\n");
2133 }
2134}
2135*/
2136
2137char *dic_get_error_services()
2138{
2139 return(dic_get_server_services(Error_conn_id));
2140}
2141
2142char *dic_get_server_services(int conn_id)
2143{
2144 DIC_SERVICE *servp;
2145 DIC_CONNECTION *dic_connp;
2146 int n_services = 0;
2147 int max_size;
2148 static int curr_allocated_size = 0;
2149 static char *service_info_buffer;
2150 char *buff_ptr;
2151
2152
2153 if(!conn_id)
2154 return((char *)0);
2155 dic_connp = &Dic_conns[conn_id];
2156 if( (servp = (DIC_SERVICE *) dic_connp->service_head) )
2157 {
2158 while( (servp = (DIC_SERVICE *) dll_get_next(
2159 (DLL *) dic_connp->service_head,
2160 (DLL *) servp)) )
2161 {
2162 n_services++;
2163 }
2164 if(!n_services)
2165 return((char *)0);
2166 max_size = n_services * MAX_NAME;
2167 if(!curr_allocated_size)
2168 {
2169 service_info_buffer = (char *)malloc(max_size);
2170 curr_allocated_size = max_size;
2171 }
2172 else if (max_size > curr_allocated_size)
2173 {
2174 free(service_info_buffer);
2175 service_info_buffer = (char *)malloc(max_size);
2176 curr_allocated_size = max_size;
2177 }
2178 service_info_buffer[0] = '\0';
2179 buff_ptr = service_info_buffer;
2180
2181 servp = (DIC_SERVICE *) dic_connp->service_head;
2182 while( (servp = (DIC_SERVICE *) dll_get_next(
2183 (DLL *) dic_connp->service_head,
2184 (DLL *) servp)) )
2185 {
2186 strcat(buff_ptr, servp->serv_name);
2187 strcat(buff_ptr, "\n");
2188 buff_ptr += strlen(buff_ptr);
2189 }
2190 }
2191 else
2192 {
2193 return((char *)0);
2194 }
2195/*
2196 dim_print_date_time();
2197 printf("Server %s@%s provides services:\n",
2198 dic_connp->task_name, dic_connp->node_name);
2199 printf("%s\n",service_info_buffer);
2200*/
2201 return(service_info_buffer);
2202}
2203
2204int dic_get_conn_id()
2205{
2206 return(Curr_conn_id);
2207}
2208
2209int dic_get_server(char *name)
2210{
2211 int ret = 0;
2212 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2213
2214 DISABLE_AST
2215
2216 if(Curr_conn_id)
2217 {
2218 dna_get_node_task(Curr_conn_id, node, task);
2219 strcpy(name,task);
2220 strcat(name,"@");
2221 strcat(name,node);
2222 ret = Curr_conn_id;
2223 }
2224 ENABLE_AST
2225 return(ret);
2226}
2227
2228int dic_get_server_pid(int *pid)
2229{
2230 int ret = 0;
2231
2232 DISABLE_AST
2233
2234 *pid = 0;
2235 if(Curr_conn_id)
2236 {
2237 *pid = Dic_conns[Curr_conn_id].pid;
2238 ret = Curr_conn_id;
2239 }
2240 ENABLE_AST
2241 return(ret);
2242}
2243
2244void dic_stop()
2245{
2246 dtq_delete(Dic_timer_q);
2247 dic_close_dns();
2248 dim_stop();
2249}
2250
2251#ifdef VMS
2252/* CFORTRAN WRAPPERS */
2253FCALLSCFUN9(INT, dic_info_service, DIC_INFO_SERVICE, dic_info_service,
2254 STRING, INT, INT, PVOID, INT, PVOID, INT, PVOID, INT)
2255FCALLSCFUN9(INT, dic_info_service_stamped, DIC_INFO_SERVICE_STAMPED,
2256 dic_info_service_stamped,
2257 STRING, INT, INT, PVOID, INT, PVOID, INT, PVOID, INT)
2258FCALLSCFUN3(INT, dic_cmnd_service, DIC_CMND_SERVICE, dic_cmnd_service,
2259 STRING, PVOID, INT)
2260FCALLSCFUN5(INT, dic_cmnd_callback, DIC_CMND_CALLBACK, dic_cmnd_callback,
2261 STRING, PVOID, INT, PVOID, INT)
2262FCALLSCFUN3(INT, dic_cmnd_service_stamped, DIC_CMND_SERVICE_STAMPED,
2263 dic_cmnd_service_stamped,
2264 STRING, PVOID, INT)
2265FCALLSCFUN5(INT, dic_cmnd_callback_stamped, DIC_CMND_CALLBACK_STAMPED,
2266 dic_cmnd_callback_stamped,
2267 STRING, PVOID, INT, PVOID, INT)
2268FCALLSCSUB3( dic_change_address, DIC_CHANGE_ADDRESS, dic_change_address,
2269 INT, PVOID, INT)
2270FCALLSCSUB1( dic_release_service, DIC_RELEASE_SERVICE, dic_release_service,
2271 INT)
2272FCALLSCFUN1(INT, dic_get_quality, DIC_GET_QUALITY, dic_get_quality,
2273 INT)
2274FCALLSCFUN3(INT, dic_get_timestamp, DIC_GET_TIMESTAMP, dic_get_timestamp,
2275 INT,PINT,PINT)
2276FCALLSCFUN1(INT, dic_get_id, DIC_GET_ID, dic_get_id,
2277 PSTRING)
2278FCALLSCFUN1(STRING, dic_get_format, DIC_GET_FORMAT, dic_get_format,
2279 INT)
2280#endif
Note: See TracBrowser for help on using the repository browser.