source: trunk/FACT++/dim_v19r20/src/dic.c@ 11035

Last change on this file since 11035 was 10614, checked in by tbretz, 14 years ago
New release V19 r20
File size: 52.0 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 servp=(DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
520 if(!servp)
521 return;
522 if(servp->tmout_done)
523 return;
524 servp->tmout_done = 1;
525 Curr_conn_id = servp->conn_id;
526/*
527 if( servp->type == UPDATE )
528 return;
529*/
530 if( servp->type == COMMAND )
531 {
532 if( servp->user_routine )
533 {
534 if(servp->pending == WAITING_CMND_ANSWER)
535 size = 1;
536 else
537 size = 0;
538 (servp->user_routine)( &servp->tag, &size );
539 }
540 dic_release_service( servp->serv_id );
541 Curr_conn_id = 0;
542 return;
543 }
544 once_only = 0;
545 if(servp->type == ONCE_ONLY)
546 once_only = 1;
547 if( servp->fill_address )
548 {
549 size = servp->fill_size;
550 if( servp->serv_address )
551 {
552 if( size > servp->serv_size )
553 size = servp->serv_size;
554 memcpy(servp->serv_address, servp->fill_address, size);
555 if( servp->user_routine )
556 (servp->user_routine)( &servp->tag, servp->serv_address, &size);
557 }
558 else
559 {
560 if( servp->user_routine )
561 (servp->user_routine)( &servp->tag, servp->fill_address, &size);
562 }
563 }
564 if( once_only )
565 {
566 dic_release_service( servp->serv_id );
567 }
568 Curr_conn_id = 0;
569}
570
571
572unsigned dic_info_service( char *serv_name, int req_type, int req_timeout, void *serv_address,
573 int serv_size, void (*usr_routine)(), long tag, void *fill_addr, int fill_size )
574{
575 unsigned ret;
576
577 ret = request_service( serv_name, req_type, req_timeout,
578 serv_address, serv_size, usr_routine, tag,
579 fill_addr, fill_size, 0 );
580
581 return(ret);
582}
583
584unsigned dic_info_service_stamped( char *serv_name, int req_type, int req_timeout, void *serv_address,
585 int serv_size, void (*usr_routine)(), long tag, void *fill_addr, int fill_size )
586{
587 unsigned ret;
588
589 ret = request_service( serv_name, req_type, req_timeout,
590 serv_address, serv_size, usr_routine, tag,
591 fill_addr, fill_size, 1 );
592
593 return(ret);
594}
595
596unsigned request_service( char *serv_name, int req_type, int req_timeout, void *serv_address,
597 int serv_size, void (*usr_routine)(), long tag, void *fill_addr, int fill_size, int stamped )
598{
599 register DIC_SERVICE *servp;
600 int conn_id;
601 int send_service();
602 int locate_service();
603 void dim_init_threads(void);
604
605 if(!Threads_off)
606 {
607 dim_init_threads();
608 }
609 {
610 DISABLE_AST
611 /* create a timer queue for timeouts if not yet done */
612 if( !Dic_timer_q ) {
613 conn_arr_create( SRC_DIC );
614 Dic_timer_q = dtq_create();
615 }
616
617 /* store_service */
618 if(req_timeout < 0)
619 req_timeout = 0;
620 if(req_type == ONCE_ONLY)
621 {
622 if( !Cmnd_head ) {
623 Cmnd_head = (DIC_SERVICE *) malloc(sizeof(DIC_SERVICE) );
624 dll_init( (DLL *) Cmnd_head );
625 Cmnd_head->serv_id = 0;
626 }
627 if( (servp = locate_command(serv_name)) )
628 {
629 if( (conn_id = servp->conn_id) )
630 {
631 if(servp->pending == NOT_PENDING)
632 {
633 modify_service( servp, req_timeout,
634 (int *)serv_address, serv_size, usr_routine, tag,
635 (int *)fill_addr, fill_size, stamped);
636 servp->pending = WAITING_SERVER_UP;
637 if(send_service(conn_id, servp))
638 {
639 ENABLE_AST
640 return(1);
641 }
642 }
643 }
644 }
645 }
646 servp = insert_service( req_type, req_timeout,
647 serv_name, (int *)serv_address, serv_size, usr_routine, tag,
648 (int *)fill_addr, fill_size, WAITING_DNS_UP, stamped );
649
650 /* get_address of server from name_server */
651
652 if( locate_service(servp) <= 0)
653 {
654/*
655 service_tmout( servp->serv_id );
656*/
657 dtq_start_timer( 0, service_tmout, servp->serv_id);
658 }
659 ENABLE_AST
660 }
661 return((unsigned) servp->serv_id);
662}
663
664
665int dic_cmnd_service( char *serv_name, void *serv_address, int serv_size )
666{
667 int ret;
668
669 ret = request_command( serv_name, serv_address, serv_size,
670 0, 0, 0 );
671
672 return(ret ? 1 : 0);
673
674}
675
676int dic_cmnd_service_stamped( char *serv_name, void *serv_address, int serv_size )
677{
678 int ret;
679
680 ret = request_command( serv_name, serv_address, serv_size,
681 0, 0, 1 );
682
683 return(ret ? 1 : 0);
684
685}
686
687int dic_cmnd_callback( char *serv_name, void *serv_address, int serv_size,
688 void (*usr_routine)(), long tag )
689{
690 int ret;
691
692 ret = request_command( serv_name, serv_address, serv_size,
693 usr_routine, tag, 0 );
694 return(ret ? 1 : 0);
695}
696
697int dic_cmnd_callback_stamped( char *serv_name, void *serv_address, int serv_size,
698 void (*usr_routine)(), long tag )
699{
700 int ret;
701
702 ret = request_command( serv_name, serv_address, serv_size,
703 usr_routine, tag, 1 );
704 return(ret ? 1 : 0);
705}
706
707int request_command(char *serv_name, void *serv_address, int serv_size,
708 void (*usr_routine)(), long tag, int stamped)
709{
710 int conn_id, ret;
711 register DIC_SERVICE *servp, *testp;
712 int *fillp;
713 int send_command();
714 int end_command();
715 void dim_init_threads(void);
716 int locate_service();
717
718 if(!Threads_off)
719 {
720 dim_init_threads();
721 }
722 {
723 DISABLE_AST
724 /* create a timer queue for timeouts if not yet done */
725 if( !Dic_timer_q ) {
726 conn_arr_create( SRC_DIC );
727 Dic_timer_q = dtq_create();
728 }
729
730 /* store_service */
731 if( !Cmnd_head ) {
732 Cmnd_head = (DIC_SERVICE *) malloc(sizeof(DIC_SERVICE) );
733 dll_init( (DLL *) Cmnd_head );
734 Cmnd_head->serv_id = 0;
735 }
736 if( (servp = locate_command(serv_name)) )
737 {
738 if(!(testp = locate_pending(serv_name)))
739 {
740 if( (conn_id = servp->conn_id) )
741 {
742 free( servp->fill_address );
743 fillp = (int *)malloc(serv_size);
744 memcpy( (char *)fillp, (char *)serv_address, serv_size );
745 servp->fill_address = fillp;
746 servp->fill_size = serv_size;
747/*
748 servp->fill_address = (int *)serv_address;
749 servp->fill_size = serv_size;
750*/
751 servp->user_routine = usr_routine;
752 servp->tag = tag;
753 ret = send_command(conn_id, servp);
754 end_command(servp, ret);
755 ENABLE_AST
756 return(1);
757 }
758 }
759 }
760 servp = insert_service( COMMAND, 0,
761 serv_name, 0, 0, usr_routine, tag,
762 (int *)serv_address, serv_size,
763 WAITING_DNS_UP, stamped );
764 if( locate_service(servp) <= 0)
765 {
766/*
767 service_tmout( servp->serv_id );
768*/
769 dtq_start_timer( 0, service_tmout, servp->serv_id);
770 }
771 ENABLE_AST
772 }
773 return(-1);
774}
775
776DIC_SERVICE *insert_service( int type, int timeout, char *name, int *address, int size,
777 void (*routine)(), long tag, int *fill_addr, int fill_size,
778 int pending, int stamped)
779{
780 register DIC_SERVICE *newp;
781 int *fillp;
782 int service_id;
783 int tout;
784 float ftout;
785
786 DISABLE_AST
787 newp = (DIC_SERVICE *) malloc(sizeof(DIC_SERVICE));
788 newp->pending = 0;
789 strncpy( newp->serv_name, name, MAX_NAME );
790 newp->type = type;
791 newp->timeout = timeout;
792 newp->serv_address = address;
793 newp->serv_size = size;
794 newp->user_routine = routine;
795 newp->tag = tag;
796 fillp = (int *)malloc(fill_size);
797 memcpy( (char *) fillp, (char *) fill_addr, fill_size );
798 newp->fill_address = fillp;
799 newp->fill_size = fill_size;
800 newp->conn_id = 0;
801 newp->format_data[0].par_bytes = 0;
802 newp->next = (DIC_SERVICE *)0;
803 service_id = id_get((void *)newp, SRC_DIC);
804 newp->serv_id = service_id;
805 if( !Service_pend_head )
806 {
807 Service_pend_head = (DIC_SERVICE *) malloc(sizeof(DIC_SERVICE));
808 dll_init( (DLL *) Service_pend_head );
809 Service_pend_head->serv_id = 0;
810 }
811 dll_insert_queue( (DLL *) Service_pend_head, (DLL *)newp );
812 newp->timer_ent = NULL;
813 if(type != MONIT_FIRST)
814 {
815 if( timeout )
816 {
817 tout = timeout;
818 if(type != ONCE_ONLY)
819 {
820 if(tout < 10)
821 tout = 10;
822 ftout = (float)tout * (float)1.5;
823 tout = (int)ftout;
824 }
825 newp->curr_timeout = tout;
826 newp->timer_ent = dtq_add_entry( Dic_timer_q,
827 newp->curr_timeout,
828 service_tmout, newp->serv_id );
829 }
830 }
831 newp->pending = pending;
832 newp->tmout_done = 0;
833 newp->stamped = stamped;
834 newp->time_stamp[0] = 0;
835 newp->time_stamp[1] = 0;
836 newp->quality = 0;
837 newp->def[0] = '\0';
838#ifdef VxWorks
839 newp->tid = taskIdSelf();
840#endif
841 ENABLE_AST
842 return(newp);
843}
844
845
846void modify_service( DIC_SERVICE *servp, int timeout, int *address, int size, void (*routine)(),
847 long tag, int *fill_addr, int fill_size, int stamped)
848{
849 int *fillp;
850
851 if( servp->timer_ent )
852 {
853 dtq_rem_entry( Dic_timer_q, servp->timer_ent );
854 servp->timer_ent = 0;
855 }
856 servp->timeout = timeout;
857 servp->serv_address = address;
858 servp->serv_size = size;
859 servp->user_routine = routine;
860 servp->tag = tag;
861 free( servp->fill_address );
862 fillp = (int *)malloc(fill_size);
863 memcpy( (char *) fillp, (char *) fill_addr, fill_size );
864 servp->fill_address = fillp;
865 servp->fill_size = fill_size;
866 servp->stamped = stamped;
867 if(timeout)
868 {
869 servp->curr_timeout = timeout;
870 servp->timer_ent = dtq_add_entry( Dic_timer_q,
871 servp->curr_timeout,
872 service_tmout, servp->serv_id );
873 }
874 else
875 servp->timer_ent = NULL;
876}
877
878void dic_change_address( unsigned serv_id, void *serv_address, int serv_size)
879{
880 register DIC_SERVICE *servp;
881
882 DISABLE_AST
883 if( serv_id == 0 )
884 {
885 ENABLE_AST
886 return;
887 }
888 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
889 servp->serv_address = (int *)serv_address;
890 servp->serv_size = serv_size;
891 ENABLE_AST
892}
893
894int dic_get_quality( unsigned serv_id )
895{
896 register DIC_SERVICE *servp;
897
898 DISABLE_AST
899 if( serv_id == 0 )
900 {
901 if(Current_server)
902 servp = Current_server;
903 else
904 {
905
906 ENABLE_AST
907 return(-1);
908 }
909 }
910 else
911 {
912 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
913 }
914 ENABLE_AST
915 return(servp->quality);
916}
917
918char *dic_get_format( unsigned serv_id )
919{
920 register DIC_SERVICE *servp;
921
922 DISABLE_AST
923 if( serv_id == 0 )
924 {
925 if(Current_server)
926 servp = Current_server;
927 else
928 {
929 ENABLE_AST
930 return((char *) 0);
931 }
932 }
933 else
934 {
935 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
936 }
937 ENABLE_AST
938 return(servp->def);
939}
940
941int dic_get_timestamp( unsigned serv_id, int *secs, int *milisecs )
942{
943 register DIC_SERVICE *servp;
944
945 DISABLE_AST
946 *secs = 0;
947 *milisecs = 0;
948 if( serv_id == 0 )
949 {
950 if(Current_server)
951 servp = Current_server;
952 else
953 {
954 ENABLE_AST
955 return(-1);
956 }
957 }
958 else
959 {
960 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
961 }
962 ENABLE_AST
963 if(servp->time_stamp[1])
964 {
965 *secs = servp->time_stamp[1];
966 if((servp->time_stamp[0] & 0xFFFF0000) == 0xc0de0000)
967 *milisecs = servp->time_stamp[0] & 0x0000FFFF;
968 else
969 *milisecs = servp->time_stamp[0];
970 return(1);
971 }
972 else
973 {
974/*
975 *secs = 0;
976 *milisecs = 0;
977*/
978 return(0);
979 }
980}
981
982void dic_release_service( unsigned service_id )
983{
984 register DIC_SERVICE *servp;
985 register int conn_id, pending;
986 static DIC_PACKET *dic_packet;
987 static int packet_size = 0;
988 DIC_DNS_PACKET dic_dns_packet;
989 register DIC_DNS_PACKET *dic_dns_p = &dic_dns_packet;
990 SERVICE_REQ *serv_reqp;
991 int release_service();
992
993 DISABLE_AST
994 if( !packet_size ) {
995 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER);
996 packet_size = DIC_HEADER;
997 }
998 if( service_id == 0 )
999 {
1000 ENABLE_AST
1001 return;
1002 }
1003 servp = (DIC_SERVICE *)id_get_ptr(service_id, SRC_DIC);
1004 if( servp == 0 )
1005 {
1006 ENABLE_AST
1007 return;
1008 }
1009 if(servp->serv_id != (int)service_id)
1010 {
1011 ENABLE_AST
1012 return;
1013 }
1014 pending = servp->pending;
1015 switch( pending )
1016 {
1017 case NOT_PENDING :
1018 conn_id = servp->conn_id;
1019 strncpy(dic_packet->service_name, servp->serv_name, MAX_NAME);
1020 dic_packet->type = htovl(DIM_DELETE);
1021 dic_packet->service_id = htovl(service_id);
1022 dic_packet->size = htovl(DIC_HEADER);
1023 dna_write( conn_id, dic_packet, DIC_HEADER );
1024 release_service( servp );
1025 break;
1026 case WAITING_SERVER_UP :
1027 if( ( servp->type == COMMAND )||( servp->type == ONCE_ONLY ) )
1028 {
1029 servp->pending = DELETED;
1030 break;
1031 }
1032 if( Dns_dic_conn_id > 0) {
1033 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1034 dic_dns_p->src_type = htovl(SRC_DIC);
1035 serv_reqp = &dic_dns_p->service;
1036 strcpy( serv_reqp->service_name, servp->serv_name );
1037 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1038 dna_write( Dns_dic_conn_id, dic_dns_p,
1039 sizeof(DIC_DNS_PACKET) );
1040 }
1041 release_service( servp );
1042 break;
1043 case WAITING_CMND_ANSWER :
1044 case WAITING_DNS_UP :
1045 release_service( servp );
1046 break;
1047 case WAITING_DNS_ANSWER :
1048 servp->pending = DELETED;
1049 break;
1050 }
1051 ENABLE_AST
1052}
1053
1054
1055int release_service( DIC_SERVICE *servicep )
1056{
1057 register DIC_SERVICE *servp;
1058 register int conn_id = 0;
1059 register int found = 0;
1060 register DIC_CONNECTION *dic_connp;
1061 char name[MAX_NAME], *ptr;
1062 int id;
1063
1064 id = servicep->serv_id;
1065 servicep->serv_id = 0;
1066 conn_id = servicep->conn_id;
1067 dic_connp = &Dic_conns[conn_id] ;
1068 dll_remove( (DLL *) servicep );
1069 if( servicep->timer_ent )
1070 {
1071 dtq_rem_entry( Dic_timer_q, servicep->timer_ent );
1072 }
1073/*
1074 if(servicep->type != COMMAND)
1075*/
1076 free( servicep->fill_address );
1077 if(strstr(servicep->serv_name,"/RpcOut"))
1078 {
1079 strcpy(name, servicep->serv_name);
1080 }
1081 else
1082 name[0] = '\0';
1083 free( servicep );
1084 if( conn_id && dic_connp->service_head )
1085 {
1086 if( dll_empty((DLL *)dic_connp->service_head) )
1087 {
1088 if( (servp = (DIC_SERVICE *) Cmnd_head) )
1089 {
1090 while( (servp = (DIC_SERVICE *) dll_get_next(
1091 (DLL *) Cmnd_head,
1092 (DLL *) servp)) )
1093 {
1094 if( servp->conn_id == conn_id)
1095 found = 1;
1096 }
1097 }
1098 if( !found)
1099 {
1100 if(Debug_on)
1101 {
1102 dim_print_date_time();
1103 printf("Conn %d, Server %s on node %s released\n",
1104 conn_id, dic_connp->task_name, dic_connp->node_name);
1105 fflush(stdout);
1106 }
1107 release_conn( conn_id );
1108 }
1109 }
1110 }
1111 if(name[0])
1112 {
1113 ptr = strstr(name,"/RpcOut");
1114 strcpy(ptr + 4, "In");
1115 if( (servp = locate_command(name)) )
1116 release_service(servp);
1117 }
1118 id_free(id, SRC_DIC);
1119 return(1);
1120}
1121
1122
1123int locate_service( DIC_SERVICE *servp )
1124{
1125 extern int open_dns(long, void (*)(), void (*)(), int, int, int);
1126
1127 if(!strcmp(servp->serv_name,"DIS_DNS/SERVER_INFO"))
1128 {
1129 Tmout_min = DID_DNS_TMOUT_MIN;
1130 Tmout_max = DID_DNS_TMOUT_MAX;
1131 }
1132 if(Tmout_min == 0)
1133 {
1134 Tmout_min = DIC_DNS_TMOUT_MIN;
1135 Tmout_max = DIC_DNS_TMOUT_MAX;
1136 }
1137 if( !Dns_dic_conn_id )
1138 {
1139 DISABLE_AST;
1140 Dns_dic_conn_id = open_dns( 0, recv_dns_dic_rout, error_handler,
1141 Tmout_min,
1142 Tmout_max,
1143 SRC_DIC);
1144 if(Dns_dic_conn_id == -2)
1145 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
1146 ENABLE_AST;
1147 }
1148 if( Dns_dic_conn_id > 0)
1149 {
1150 DISABLE_AST;
1151 request_dns_info(servp->prev->serv_id);
1152 ENABLE_AST;
1153 }
1154
1155 return(Dns_dic_conn_id);
1156}
1157
1158DIC_SERVICE *locate_command( char *serv_name )
1159{
1160 register DIC_SERVICE *servp;
1161
1162 if(!Cmnd_head)
1163 return((DIC_SERVICE *)0);
1164 if( (servp = (DIC_SERVICE *) dll_search( (DLL *) Cmnd_head, serv_name,
1165 strlen(serv_name)+1)) )
1166 return(servp);
1167 return((DIC_SERVICE *)0);
1168}
1169
1170DIC_SERVICE *locate_pending( char *serv_name )
1171{
1172 register DIC_SERVICE *servp;
1173
1174 if(!Service_pend_head)
1175 return((DIC_SERVICE *)0);
1176 if( (servp = (DIC_SERVICE *) dll_search( (DLL *) Service_pend_head, serv_name,
1177 strlen(serv_name)+1)) )
1178 return(servp);
1179 return((DIC_SERVICE *)0);
1180}
1181
1182DIC_BAD_CONNECTION *locate_bad(char *node, char *task, int port)
1183{
1184 DIC_BAD_CONNECTION *bad_connp;
1185
1186 if(!Bad_connection_head)
1187 return((DIC_BAD_CONNECTION *)0);
1188 bad_connp = Bad_connection_head;
1189 while( (bad_connp = (DIC_BAD_CONNECTION *) dll_get_next(
1190 (DLL *) Bad_connection_head,
1191 (DLL *) bad_connp)) )
1192 {
1193 if((!strcmp(bad_connp->conn.node_name, node)) &&
1194 (!strcmp(bad_connp->conn.task_name, task)) &&
1195 (bad_connp->conn.port == port) )
1196 return(bad_connp);
1197 }
1198 return((DIC_BAD_CONNECTION *)0);
1199}
1200
1201static void request_dns_info(int id)
1202{
1203 DIC_SERVICE *servp, *ptr;
1204 int n_pend = 0;
1205 int request_dns_single_info();
1206 extern int open_dns();
1207
1208 DISABLE_AST
1209 if( Dns_dic_conn_id <= 0)
1210 {
1211 Dns_dic_conn_id = open_dns( 0, recv_dns_dic_rout, error_handler,
1212 Tmout_min,
1213 Tmout_max,
1214 SRC_DIC);
1215 if(Dns_dic_conn_id == -2)
1216 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
1217 }
1218 if( Dns_dic_conn_id > 0)
1219 {
1220 servp = Service_pend_head;
1221 if(id > 0)
1222 {
1223 ptr = (DIC_SERVICE *)id_get_ptr(id, SRC_DIC);
1224 if(ptr)
1225 {
1226 if((ptr->serv_id == id) && (ptr->pending != NOT_PENDING))
1227 servp = ptr;
1228 }
1229 }
1230
1231 while( (servp = (DIC_SERVICE *) dll_get_next(
1232 (DLL *) Service_pend_head,
1233 (DLL *) servp)) )
1234 {
1235 if( servp->pending == WAITING_DNS_UP)
1236 {
1237 if(!request_dns_single_info( servp ))
1238 {
1239 ENABLE_AST
1240 return;
1241 }
1242 n_pend++;
1243 }
1244 if(n_pend == 1000)
1245 {
1246 dtq_start_timer( 0, request_dns_info, servp->serv_id);
1247 ENABLE_AST
1248 return;
1249 }
1250 }
1251 }
1252 else
1253 {
1254 servp = Service_pend_head;
1255 while( (servp = (DIC_SERVICE *) dll_get_next(
1256 (DLL *) Service_pend_head,
1257 (DLL *) servp)) )
1258 {
1259 if( servp->pending == WAITING_DNS_UP)
1260 {
1261 if(( servp->type != COMMAND )&&( servp->type != ONCE_ONLY ))
1262 service_tmout( servp->serv_id );
1263 }
1264 }
1265 }
1266 ENABLE_AST
1267}
1268
1269
1270int request_dns_single_info( DIC_SERVICE *servp )
1271{
1272 static DIC_DNS_PACKET Dic_dns_packet;
1273 static SERVICE_REQ *serv_reqp;
1274 int ret = 1;
1275
1276 if( Dns_dic_conn_id > 0)
1277 {
1278 if(Debug_on)
1279 {
1280 dim_print_date_time();
1281 printf("Requesting DNS Info for %s, id %d\n",
1282 servp->serv_name, servp->serv_id);
1283 }
1284
1285 Dic_dns_packet.src_type = htovl(SRC_DIC);
1286 serv_reqp = &Dic_dns_packet.service;
1287 strcpy( serv_reqp->service_name, servp->serv_name );
1288 serv_reqp->service_id = htovl(servp->serv_id);
1289 servp->pending = WAITING_DNS_ANSWER;
1290 Dic_dns_packet.size = htovl(sizeof(DIC_DNS_PACKET));
1291 if(!dna_write( Dns_dic_conn_id, &Dic_dns_packet,
1292 sizeof(DIC_DNS_PACKET) ) )
1293 {
1294 ret = 0;
1295 }
1296
1297 }
1298 return ret;
1299}
1300
1301
1302static int handle_dns_info( DNS_DIC_PACKET *packet )
1303{
1304 int conn_id, service_id;
1305 DIC_SERVICE *servp;
1306 char *node_name, *task_name;
1307 char node_info[MAX_NODE_NAME+4];
1308 int i, port, protocol, format, ret, pid;
1309 register DIC_CONNECTION *dic_connp ;
1310 DIC_DNS_PACKET dic_dns_packet;
1311 register DIC_DNS_PACKET *dic_dns_p = &dic_dns_packet;
1312 SERVICE_REQ *serv_reqp;
1313 DIC_BAD_CONNECTION *bad_connp;
1314 int retrying = 0;
1315 int tmout;
1316 int send_service_command();
1317 int find_connection();
1318 void move_to_bad_service();
1319 void retry_bad_connection();
1320
1321 service_id = vtohl(packet->service_id);
1322
1323 servp = (DIC_SERVICE *)id_get_ptr(service_id, SRC_DIC);
1324 if(!servp)
1325 return(0);
1326 if(servp->serv_id != service_id)
1327 return(0);
1328 if(Debug_on)
1329 {
1330 dim_print_date_time();
1331 printf("Receiving DNS Info for service %s, id %d\n",servp->serv_name,
1332 vtohl(packet->service_id));
1333 }
1334 node_name = packet->node_name;
1335 if(node_name[0] == -1)
1336 {
1337 error_handler(0, DIM_FATAL, DIMDNSREFUS, "DIM_DNS refuses connection");
1338 return(0);
1339 }
1340
1341 task_name = packet->task_name;
1342 strcpy(node_info,node_name);
1343 for(i = 0; i < 4; i ++)
1344 node_info[strlen(node_name)+i+1] = packet->node_addr[i];
1345 port = vtohl(packet->port);
1346 pid = vtohl(packet->pid);
1347 protocol = vtohl(packet->protocol);
1348 format = vtohl(packet->format);
1349
1350 if( Dns_dic_timr )
1351 dtq_clear_entry( Dns_dic_timr );
1352 if( servp->pending == DELETED ) {
1353 if( Dns_dic_conn_id > 0) {
1354 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1355 dic_dns_p->src_type = htovl(SRC_DIC);
1356 serv_reqp = &dic_dns_p->service;
1357 strcpy( serv_reqp->service_name, servp->serv_name );
1358 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1359 dna_write( Dns_dic_conn_id, dic_dns_p,
1360 sizeof(DIC_DNS_PACKET) );
1361 }
1362 release_service( servp );
1363 return(0);
1364 }
1365 if( !node_name[0] )
1366 {
1367 servp->pending = WAITING_SERVER_UP;
1368 service_tmout( servp->serv_id );
1369 if( servp->pending == DELETED )
1370 {
1371 if( Dns_dic_conn_id > 0)
1372 {
1373 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1374 dic_dns_p->src_type = htovl(SRC_DIC);
1375 serv_reqp = &dic_dns_p->service;
1376 strcpy( serv_reqp->service_name, servp->serv_name );
1377 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1378 dna_write( Dns_dic_conn_id, dic_dns_p,
1379 sizeof(DIC_DNS_PACKET) );
1380 }
1381 release_service( servp );
1382 }
1383 return(0);
1384 }
1385#ifdef OSK
1386 {
1387 register char *ptr;
1388
1389 if(strncmp(node_name,"fidel",5))
1390 {
1391 for(ptr = node_name; *ptr; ptr++)
1392 {
1393 if(*ptr == '.')
1394 {
1395 *ptr = '\0';
1396 break;
1397 }
1398 }
1399 }
1400 }
1401#endif
1402 if( !(conn_id = find_connection(node_name, task_name, port)) )
1403 {
1404 bad_connp = locate_bad(node_name, task_name, port);
1405 if(bad_connp)
1406 retrying = bad_connp->retrying;
1407 if((!bad_connp) || (retrying))
1408 {
1409 if( (conn_id = dna_open_client(node_info, task_name, port,
1410 protocol, recv_rout, error_handler, SRC_DIC)) )
1411 {
1412/*
1413#ifndef VxWorks
1414 if(format & MY_OS9)
1415 {
1416 dna_set_test_write(conn_id, TEST_TIME_OSK);
1417 format &= 0xfffff7ff;
1418 }
1419 else
1420 {
1421 dna_set_test_write(conn_id, TEST_TIME_VMS);
1422 }
1423#endif
1424*/
1425 dna_set_test_write(conn_id, TEST_TIME_OSK);
1426 dic_connp = &Dic_conns[conn_id];
1427 strncpy( dic_connp->node_name, node_name,
1428 MAX_NODE_NAME);
1429 strncpy( dic_connp->task_name, task_name,
1430 MAX_TASK_NAME);
1431 dic_connp->port = port;
1432 dic_connp->pid = pid;
1433 if(Debug_on)
1434 {
1435 dim_print_date_time();
1436 printf(" - Conn %d, Server %s on node %s Connecting\n",
1437 conn_id, dic_connp->task_name, dic_connp->node_name);
1438 fflush(stdout);
1439 }
1440
1441 dic_connp->service_head =
1442 malloc(sizeof(DIC_SERVICE));
1443 dll_init( (DLL *) dic_connp->service_head);
1444 ((DIC_SERVICE *)(dic_connp->service_head))->serv_id = 0;
1445 if(retrying)
1446 {
1447 dll_remove((DLL *)bad_connp->conn.service_head);
1448 free(bad_connp->conn.service_head);
1449 dll_remove((DLL *)bad_connp);
1450 free(bad_connp);
1451 }
1452 }
1453 else
1454 {
1455 if(!retrying)
1456 {
1457 if( !Bad_connection_head )
1458 {
1459 Bad_connection_head = (DIC_BAD_CONNECTION *) malloc(sizeof(DIC_BAD_CONNECTION));
1460 dll_init( (DLL *) Bad_connection_head );
1461 Bad_connection_head->conn.service_head = 0;
1462 }
1463 bad_connp = (DIC_BAD_CONNECTION *) malloc(sizeof(DIC_BAD_CONNECTION));
1464 bad_connp->n_retries = 0;
1465 bad_connp->conn.service_head = malloc(sizeof(DIC_SERVICE));
1466 dll_init( (DLL *) bad_connp->conn.service_head);
1467
1468 dll_insert_queue( (DLL *) Bad_connection_head, (DLL *) bad_connp );
1469 if(Debug_on)
1470 {
1471 dim_print_date_time();
1472 printf(" - Failed connecting to Server %s on node %s port %d\n",
1473 task_name, node_name, port);
1474 fflush(stdout);
1475 }
1476 service_tmout( servp->serv_id );
1477 }
1478 bad_connp->n_retries++;
1479 bad_connp->retrying = 0;
1480 strncpy( bad_connp->conn.node_name, node_name, MAX_NODE_NAME);
1481 strncpy( bad_connp->conn.task_name, task_name, MAX_TASK_NAME);
1482 bad_connp->conn.port = port;
1483 tmout = BAD_CONN_TIMEOUT * bad_connp->n_retries;
1484 if(tmout > 120)
1485 tmout = 120;
1486 dtq_start_timer(tmout, retry_bad_connection, (long)bad_connp);
1487 if(( servp->type == COMMAND )||( servp->type == ONCE_ONLY ))
1488 return(0);
1489 move_to_bad_service(servp, bad_connp);
1490/*
1491 ((DIC_SERVICE *)(dic_connp->service_head))->serv_id = 0;
1492
1493 servp = Service_pend_head;
1494 while( (servp = (DIC_SERVICE *) dll_get_next(
1495 (DLL *) Service_pend_head,
1496 (DLL *) servp)) )
1497 {
1498 if( (servp->pending == WAITING_DNS_ANSWER) ||
1499 (servp->pending == WAITING_SERVER_UP))
1500 servp->pending = WAITING_DNS_UP;
1501 }
1502 dna_close( Dns_dic_conn_id );
1503 Dns_dic_conn_id = 0;
1504 request_dns_info(0);
1505*/
1506 return(0);
1507 }
1508 }
1509 else
1510 {
1511 if(!retrying)
1512 service_tmout( servp->serv_id );
1513 if(( servp->type == COMMAND )||( servp->type == ONCE_ONLY ))
1514 return(0);
1515 move_to_bad_service(servp, bad_connp);
1516 return(0);
1517 }
1518 }
1519 strcpy(servp->def, packet->service_def);
1520 get_format_data(format, servp->format_data, servp->def);
1521 servp->format = format;
1522 servp->conn_id = conn_id;
1523
1524 ret = send_service_command( servp );
1525/*
1526 if( ret == 1)
1527 {
1528 if(servp->pending != WAITING_CMND_ANSWER)
1529 servp->pending = NOT_PENDING;
1530 servp->tmout_done = 0;
1531 }
1532*/
1533 return(1);
1534}
1535
1536void retry_bad_connection(DIC_BAD_CONNECTION *bad_connp)
1537{
1538DIC_SERVICE *servp, *auxp;
1539int found = 0;
1540void move_to_notok_service();
1541
1542 if(!bad_connp)
1543 return;
1544 servp = (DIC_SERVICE *)bad_connp->conn.service_head;
1545 while( (servp = (DIC_SERVICE *) dll_get_next(
1546 (DLL *) bad_connp->conn.service_head,
1547 (DLL *) servp)) )
1548 {
1549 servp->pending = WAITING_DNS_UP;
1550 servp->conn_id = 0;
1551 auxp = servp->prev;
1552 move_to_notok_service( servp );
1553 servp = auxp;
1554 found = 1;
1555 }
1556 bad_connp->retrying = 1;
1557 if(found)
1558 request_dns_info(0);
1559}
1560
1561void move_to_ok_service( DIC_SERVICE *servp, int conn_id )
1562{
1563 if(Dic_conns[conn_id].service_head)
1564 {
1565 servp->pending = NOT_PENDING;
1566 servp->tmout_done = 0;
1567 dll_remove( (DLL *) servp );
1568 dll_insert_queue( (DLL *) Dic_conns[conn_id].service_head,
1569 (DLL *) servp );
1570 }
1571}
1572
1573void move_to_bad_service( DIC_SERVICE *servp, DIC_BAD_CONNECTION *bad_connp)
1574{
1575 servp->pending = WAITING_DNS_UP;
1576 dll_remove( (DLL *) servp );
1577 dll_insert_queue( (DLL *) bad_connp->conn.service_head, (DLL *) servp );
1578}
1579
1580void move_to_cmnd_service( DIC_SERVICE *servp )
1581{
1582/*
1583 if(servp->pending != WAITING_CMND_ANSWER)
1584*/
1585 servp->pending = NOT_PENDING;
1586 servp->tmout_done = 0;
1587 dll_remove( (DLL *) servp );
1588 dll_insert_queue( (DLL *) Cmnd_head, (DLL *) servp );
1589}
1590
1591void move_to_notok_service(DIC_SERVICE *servp )
1592{
1593
1594 dll_remove( (DLL *) servp );
1595 dll_insert_queue( (DLL *) Service_pend_head, (DLL *) servp );
1596}
1597
1598static void get_format_data(int format, FORMAT_STR *format_data, char *def)
1599{
1600 register FORMAT_STR *formatp = format_data;
1601 register char code, last_code = 0;
1602 int num;
1603 char *ptr = def;
1604
1605 if(format){}
1606 while(*ptr)
1607 {
1608 switch(*ptr)
1609 {
1610 case 'i':
1611 case 'I':
1612 case 'l':
1613 case 'L':
1614 *ptr = 'I';
1615 break;
1616 case 'x':
1617 case 'X':
1618 *ptr = 'X';
1619 break;
1620 case 's':
1621 case 'S':
1622 *ptr = 'S';
1623 break;
1624 case 'f':
1625 case 'F':
1626 *ptr = 'F';
1627 break;
1628 case 'd':
1629 case 'D':
1630 *ptr = 'D';
1631 break;
1632 case 'c':
1633 case 'C':
1634 *ptr = 'C';
1635 break;
1636 }
1637 ptr++;
1638 }
1639 code = *def;
1640 while(*def)
1641 {
1642 if(code != last_code)
1643 {
1644 formatp->par_num = 0;
1645 formatp->flags = 0;
1646 switch(code)
1647 {
1648 case 'i':
1649 case 'I':
1650 case 'l':
1651 case 'L':
1652 formatp->par_bytes = SIZEOF_LONG;
1653 formatp->flags |= SWAPL;
1654 break;
1655 case 'x':
1656 case 'X':
1657 formatp->par_bytes = SIZEOF_DOUBLE;
1658 formatp->flags |= SWAPD;
1659 break;
1660 case 's':
1661 case 'S':
1662 formatp->par_bytes = SIZEOF_SHORT;
1663 formatp->flags |= SWAPS;
1664 break;
1665 case 'f':
1666 case 'F':
1667 formatp->par_bytes = SIZEOF_LONG;
1668 formatp->flags |= SWAPL;
1669#ifdef vms
1670/*
1671 if((format & 0xF0) != (MY_FORMAT & 0xF0))
1672*/
1673 formatp->flags |= (format & 0xF0);
1674 formatp->flags |= IT_IS_FLOAT;
1675#endif
1676 break;
1677 case 'd':
1678 case 'D':
1679 formatp->par_bytes = SIZEOF_DOUBLE;
1680 formatp->flags |= SWAPD;
1681#ifdef vms
1682/*
1683 if((format & 0xF0) != (MY_FORMAT & 0xF0))
1684*/
1685 formatp->flags |= (format & 0xF0);
1686 formatp->flags |= IT_IS_FLOAT;
1687#endif
1688 break;
1689 case 'c':
1690 case 'C':
1691 formatp->par_bytes = SIZEOF_CHAR;
1692 formatp->flags |= NOSWAP;
1693 break;
1694 }
1695 }
1696 def++;
1697 if(*def != ':')
1698 {
1699/* tested by the server
1700 if(*def)
1701 {
1702 printf("Bad service definition parsing\n");
1703 fflush(stdout);
1704 }
1705 else
1706*/
1707 formatp->par_num = 0;
1708 }
1709 else
1710 {
1711 def++;
1712 sscanf(def,"%d",&num);
1713 formatp->par_num += num;
1714 while((*def != ';') && (*def != '\0'))
1715 def++;
1716 if(*def)
1717 def++;
1718 }
1719 last_code = code;
1720 code = *def;
1721 if(code != last_code)
1722 formatp++;
1723 }
1724 formatp->par_bytes = 0;
1725/*
1726 if((format & 0xF) == (MY_FORMAT & 0xF))
1727 {
1728 for(i = 0, formatp = format_data; i<index;i++, formatp++)
1729 formatp->flags &= 0xF0;
1730 }
1731*/
1732}
1733
1734int end_command(DIC_SERVICE *servp, int ret)
1735{
1736 DIC_SERVICE *aux_servp;
1737 DIC_CONNECTION *dic_connp;
1738
1739 DISABLE_AST
1740 dic_connp = &Dic_conns[servp->conn_id];
1741 if(servp->pending != WAITING_CMND_ANSWER)
1742 {
1743 if((!ret) || (!dic_connp->service_head))
1744 {
1745 servp->pending = WAITING_DNS_UP;
1746 dic_release_service( servp->serv_id );
1747 }
1748 else
1749 {
1750 aux_servp = locate_command(servp->serv_name);
1751 if( !aux_servp )
1752 {
1753 move_to_cmnd_service( servp );
1754 }
1755 else
1756 {
1757 if(aux_servp != servp)
1758 {
1759 servp->pending = WAITING_DNS_UP;
1760 dic_release_service( servp->serv_id );
1761 }
1762 }
1763 }
1764 }
1765 ENABLE_AST
1766 return(ret);
1767}
1768
1769int send_service_command(DIC_SERVICE *servp)
1770{
1771 int ret = 1;
1772 int conn_id;
1773 int send_command();
1774 int send_service();
1775
1776 conn_id = servp->conn_id;
1777 if( servp->type == COMMAND )
1778 {
1779 ret = send_command(conn_id, servp);
1780 end_command(servp, ret);
1781 }
1782 else
1783 {
1784 if( send_service(conn_id, servp))
1785 {
1786 if( servp->type == ONCE_ONLY )
1787 {
1788 if( !locate_command(servp->serv_name) )
1789 {
1790 move_to_cmnd_service( servp );
1791 }
1792 }
1793 else
1794 move_to_ok_service( servp, conn_id );
1795 }
1796 }
1797 return(ret);
1798}
1799
1800int send_service(int conn_id, DIC_SERVICE *servp)
1801{
1802 static DIC_PACKET *dic_packet;
1803 static int serv_packet_size = 0;
1804 int type, ret;
1805
1806 if( !serv_packet_size ) {
1807 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER);
1808 serv_packet_size = DIC_HEADER;
1809 }
1810
1811 strncpy( dic_packet->service_name, servp->serv_name, MAX_NAME );
1812 type = servp->type;
1813 if(servp->stamped)
1814 type |= STAMPED;
1815 dic_packet->type = htovl(type);
1816 dic_packet->timeout = htovl(servp->timeout);
1817 dic_packet->service_id = htovl(servp->serv_id);
1818 dic_packet->format = htovl(MY_FORMAT);
1819 dic_packet->size = htovl(DIC_HEADER);
1820 ret = dna_write(conn_id, dic_packet, DIC_HEADER);
1821 return(ret);
1822}
1823
1824typedef struct
1825{
1826 int ret_code;
1827 int serv_id;
1828} CMNDCB_ITEM;
1829
1830void do_cmnd_callback(CMNDCB_ITEM *itemp)
1831{
1832
1833 DIC_SERVICE *servp;
1834 int ret, serv_id;
1835/*
1836 itemp = (CMNDCB_ITEM *)id_get_ptr(id, SRC_DIC);
1837*/
1838 serv_id = itemp->serv_id;
1839 ret = itemp->ret_code;
1840 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
1841 if(servp)
1842 {
1843 if(servp->serv_id == serv_id)
1844 {
1845 Curr_conn_id = servp->conn_id;
1846 (servp->user_routine)( &servp->tag, &ret );
1847 servp->pending = NOT_PENDING;
1848 end_command(servp, ret);
1849 Curr_conn_id = 0;
1850 }
1851 }
1852/*
1853 id_free(id, SRC_DIC);
1854*/
1855 free(itemp);
1856}
1857
1858int send_command(int conn_id, DIC_SERVICE *servp)
1859{
1860 static DIC_PACKET *dic_packet;
1861 static int cmnd_packet_size = 0;
1862 register int size;
1863 int ret;
1864 CMNDCB_ITEM *itemp;
1865
1866 size = servp->fill_size;
1867
1868 if( !cmnd_packet_size ) {
1869 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER + size);
1870 cmnd_packet_size = DIC_HEADER + size;
1871 }
1872 else
1873 {
1874 if( DIC_HEADER + size > cmnd_packet_size ) {
1875 free( dic_packet );
1876 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER + size);
1877 cmnd_packet_size = DIC_HEADER + size;
1878 }
1879 }
1880
1881 strncpy(dic_packet->service_name, servp->serv_name, MAX_NAME);
1882 dic_packet->type = htovl(COMMAND);
1883 dic_packet->timeout = htovl(0);
1884 dic_packet->format = htovl(MY_FORMAT);
1885
1886 dic_packet->service_id = /*id_get((void *)servp)*/servp->serv_id;
1887
1888 size = copy_swap_buffer_out(servp->format, servp->format_data,
1889 dic_packet->buffer, servp->fill_address,
1890 size);
1891 dic_packet->size = htovl( size + DIC_HEADER);
1892 if( servp->user_routine )
1893 {
1894 servp->pending = WAITING_CMND_ANSWER;
1895 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1896 itemp = (CMNDCB_ITEM *)malloc(sizeof(CMNDCB_ITEM));
1897 itemp->serv_id = servp->serv_id;
1898 itemp->ret_code = ret;
1899/*
1900 id = id_get((void *)itemp, SRC_DIC);
1901*/
1902 dtq_start_timer(0, do_cmnd_callback, (long)itemp);
1903/*
1904 (servp->user_routine)( &servp->tag, &ret );
1905*/
1906 }
1907 else
1908 {
1909 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1910 }
1911/*
1912 if(!ret)
1913 {
1914 servp->pending = WAITING_DNS_UP;
1915 dic_release_service( servp->serv_id );
1916 }
1917*/
1918 /*
1919 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1920 if(!ret)
1921 {
1922 servp->pending = WAITING_DNS_UP;
1923 dic_release_service( servp->serv_id );
1924 }
1925 else
1926 {
1927 dim_usleep(5000);
1928 if( servp->user_routine )
1929 (servp->user_routine)( &servp->tag, &ret );
1930 }
1931*/
1932 return(ret);
1933}
1934
1935int find_connection(char *node, char *task, int port)
1936{
1937 register int i;
1938 register DIC_CONNECTION *dic_connp;
1939
1940 if(task){}
1941 for( i=0, dic_connp = Dic_conns; i<Curr_N_Conns; i++, dic_connp++ )
1942 {
1943/*
1944 if((!strcmp(dic_connp->task_name, task))
1945 &&(!strcmp(dic_connp->node_name, node)))
1946*/
1947 if((!strcmp(dic_connp->node_name, node))
1948 && (dic_connp->port == port))
1949 return(i);
1950 }
1951 return(0);
1952}
1953
1954int dic_get_id(char *name)
1955{
1956 extern int get_proc_name(char *name);
1957
1958 get_proc_name(name);
1959 strcat(name,"@");
1960 get_node_name(&name[strlen(name)]);
1961 return(1);
1962}
1963
1964#ifdef VxWorks
1965void dic_destroy(int tid)
1966{
1967 register int i;
1968 register DIC_CONNECTION *dic_connp;
1969 register DIC_SERVICE *servp, *auxp;
1970 int found = 0;
1971
1972 if(!Dic_conns)
1973 return;
1974 for( i=0, dic_connp = Dic_conns; i<Curr_N_Conns; i++, dic_connp++ )
1975 {
1976 if(servp = (DIC_SERVICE *) dic_connp->service_head)
1977 {
1978 while( servp = (DIC_SERVICE *) dll_get_next(
1979 (DLL *) dic_connp->service_head,
1980 (DLL *) servp) )
1981 {
1982 if( servp->tid == tid )
1983 {
1984 auxp = servp->prev;
1985 dic_release_service( servp->serv_id );
1986 servp = auxp;
1987 if(!dic_connp->service_head)
1988 break;
1989 }
1990 else
1991 found = 1;
1992 }
1993 }
1994 }
1995 if(!found)
1996 {
1997 if(Dns_dic_conn_id > 0)
1998 {
1999 dna_close( Dns_dic_conn_id );
2000 Dns_dic_conn_id = 0;
2001 }
2002 }
2003}
2004
2005void DIMDestroy(int tid)
2006{
2007 dis_destroy(tid);
2008 dic_destroy(tid);
2009}
2010
2011#endif
2012
2013static void release_conn(int conn_id)
2014{
2015 register DIC_CONNECTION *dic_connp = &Dic_conns[conn_id];
2016
2017 if(Debug_on)
2018 {
2019 dim_print_date_time();
2020 printf("Conn %d, Server %s on node %s completely released\n",
2021 conn_id, dic_connp->task_name, dic_connp->node_name);
2022 fflush(stdout);
2023 }
2024 dic_connp->task_name[0] = '\0';
2025 dic_connp->port = 0;
2026 if(dic_connp->service_head)
2027 {
2028 free((DIC_SERVICE *)dic_connp->service_head);
2029 dic_connp->service_head = (char *)0;
2030 }
2031 dna_close(conn_id);
2032}
2033
2034void dic_close_dns()
2035{
2036 register DIC_SERVICE *servp, *auxp;
2037
2038 if(Dns_dic_conn_id > 0)
2039 {
2040 if( (servp = (DIC_SERVICE *) Cmnd_head) )
2041 {
2042 while( (servp = (DIC_SERVICE *) dll_get_next(
2043 (DLL *) Cmnd_head,
2044 (DLL *) servp)) )
2045 {
2046#ifdef DEBUG
2047 printf("\t%s was in the Command list\n", servp->serv_name);
2048 printf("type = %d, pending = %d\n",servp->type, servp->pending);
2049 fflush(stdout);
2050#endif
2051 auxp = servp->prev;
2052 if( (servp->type == ONCE_ONLY ) &&
2053 (servp->pending == WAITING_SERVER_UP))
2054 {
2055 service_tmout( servp->serv_id );
2056 }
2057 else if( (servp->type == COMMAND ) &&
2058 (servp->pending == WAITING_CMND_ANSWER))
2059 {
2060 service_tmout( servp->serv_id );
2061 }
2062 else
2063 {
2064 servp->pending = WAITING_DNS_UP;
2065 dic_release_service( servp->serv_id );
2066 }
2067 servp = auxp;
2068 }
2069 }
2070 dna_close( Dns_dic_conn_id );
2071 Dns_dic_conn_id = 0;
2072 }
2073}
2074/*
2075append_service(service_info_buffer, servp)
2076char *service_info_buffer;
2077SERVICE *servp;
2078{
2079 char name[MAX_NAME], *ptr;
2080
2081 if(strstr(servp->name,"/RpcIn"))
2082 {
2083 strcpy(name,servp->name);
2084 ptr = (char *)strstr(name,"/RpcIn");
2085 *ptr = 0;
2086 strcat(service_info_buffer, name);
2087 strcat(service_info_buffer, "|");
2088 if(servp->def[0])
2089 {
2090 strcat(service_info_buffer, servp->def);
2091 }
2092 strcat(name,"/RpcOut");
2093 if(servp = find_service(name))
2094 {
2095 strcat(service_info_buffer, ",");
2096 if(servp->def[0])
2097 {
2098 strcat(service_info_buffer, servp->def);
2099 }
2100 }
2101 strcat(service_info_buffer, "|RPC");
2102 strcat(service_info_buffer, "\n");
2103 }
2104 else if(strstr(servp->name,"/RpcOut"))
2105 {
2106 }
2107 else
2108 {
2109 strcat(service_info_buffer, servp->name);
2110 strcat(service_info_buffer, "|");
2111 if(servp->def[0])
2112 {
2113 strcat(service_info_buffer, servp->def);
2114 }
2115 strcat(service_info_buffer, "|");
2116 if(servp->type == COMMAND)
2117 {
2118 strcat(service_info_buffer, "CMD");
2119 }
2120 strcat(service_info_buffer, "\n");
2121 }
2122}
2123*/
2124
2125char *dic_get_error_services()
2126{
2127 return(dic_get_server_services(Error_conn_id));
2128}
2129
2130char *dic_get_server_services(int conn_id)
2131{
2132 DIC_SERVICE *servp;
2133 DIC_CONNECTION *dic_connp;
2134 int n_services = 0;
2135 int max_size;
2136 static int curr_allocated_size = 0;
2137 static char *service_info_buffer;
2138 char *buff_ptr;
2139
2140
2141 if(!conn_id)
2142 return((char *)0);
2143 dic_connp = &Dic_conns[conn_id];
2144 if( (servp = (DIC_SERVICE *) dic_connp->service_head) )
2145 {
2146 while( (servp = (DIC_SERVICE *) dll_get_next(
2147 (DLL *) dic_connp->service_head,
2148 (DLL *) servp)) )
2149 {
2150 n_services++;
2151 }
2152 if(!n_services)
2153 return((char *)0);
2154 max_size = n_services * MAX_NAME;
2155 if(!curr_allocated_size)
2156 {
2157 service_info_buffer = (char *)malloc(max_size);
2158 curr_allocated_size = max_size;
2159 }
2160 else if (max_size > curr_allocated_size)
2161 {
2162 free(service_info_buffer);
2163 service_info_buffer = (char *)malloc(max_size);
2164 curr_allocated_size = max_size;
2165 }
2166 service_info_buffer[0] = '\0';
2167 buff_ptr = service_info_buffer;
2168
2169 servp = (DIC_SERVICE *) dic_connp->service_head;
2170 while( (servp = (DIC_SERVICE *) dll_get_next(
2171 (DLL *) dic_connp->service_head,
2172 (DLL *) servp)) )
2173 {
2174 strcat(buff_ptr, servp->serv_name);
2175 strcat(buff_ptr, "\n");
2176 buff_ptr += strlen(buff_ptr);
2177 }
2178 }
2179 else
2180 {
2181 return((char *)0);
2182 }
2183/*
2184 dim_print_date_time();
2185 printf("Server %s@%s provides services:\n",
2186 dic_connp->task_name, dic_connp->node_name);
2187 printf("%s\n",service_info_buffer);
2188*/
2189 return(service_info_buffer);
2190}
2191
2192int dic_get_conn_id()
2193{
2194 return(Curr_conn_id);
2195}
2196
2197int dic_get_server(char *name)
2198{
2199 int ret = 0;
2200 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2201
2202 DISABLE_AST
2203
2204 if(Curr_conn_id)
2205 {
2206 dna_get_node_task(Curr_conn_id, node, task);
2207 strcpy(name,task);
2208 strcat(name,"@");
2209 strcat(name,node);
2210 ret = Curr_conn_id;
2211 }
2212 ENABLE_AST
2213 return(ret);
2214}
2215
2216int dic_get_server_pid(int *pid)
2217{
2218 int ret = 0;
2219
2220 DISABLE_AST
2221
2222 *pid = 0;
2223 if(Curr_conn_id)
2224 {
2225 *pid = Dic_conns[Curr_conn_id].pid;
2226 ret = Curr_conn_id;
2227 }
2228 ENABLE_AST
2229 return(ret);
2230}
2231
2232void dic_stop()
2233{
2234 dtq_delete(Dic_timer_q);
2235 dic_close_dns();
2236 dim_stop();
2237}
2238
2239#ifdef VMS
2240/* CFORTRAN WRAPPERS */
2241FCALLSCFUN9(INT, dic_info_service, DIC_INFO_SERVICE, dic_info_service,
2242 STRING, INT, INT, PVOID, INT, PVOID, INT, PVOID, INT)
2243FCALLSCFUN9(INT, dic_info_service_stamped, DIC_INFO_SERVICE_STAMPED,
2244 dic_info_service_stamped,
2245 STRING, INT, INT, PVOID, INT, PVOID, INT, PVOID, INT)
2246FCALLSCFUN3(INT, dic_cmnd_service, DIC_CMND_SERVICE, dic_cmnd_service,
2247 STRING, PVOID, INT)
2248FCALLSCFUN5(INT, dic_cmnd_callback, DIC_CMND_CALLBACK, dic_cmnd_callback,
2249 STRING, PVOID, INT, PVOID, INT)
2250FCALLSCFUN3(INT, dic_cmnd_service_stamped, DIC_CMND_SERVICE_STAMPED,
2251 dic_cmnd_service_stamped,
2252 STRING, PVOID, INT)
2253FCALLSCFUN5(INT, dic_cmnd_callback_stamped, DIC_CMND_CALLBACK_STAMPED,
2254 dic_cmnd_callback_stamped,
2255 STRING, PVOID, INT, PVOID, INT)
2256FCALLSCSUB3( dic_change_address, DIC_CHANGE_ADDRESS, dic_change_address,
2257 INT, PVOID, INT)
2258FCALLSCSUB1( dic_release_service, DIC_RELEASE_SERVICE, dic_release_service,
2259 INT)
2260FCALLSCFUN1(INT, dic_get_quality, DIC_GET_QUALITY, dic_get_quality,
2261 INT)
2262FCALLSCFUN3(INT, dic_get_timestamp, DIC_GET_TIMESTAMP, dic_get_timestamp,
2263 INT,PINT,PINT)
2264FCALLSCFUN1(INT, dic_get_id, DIC_GET_ID, dic_get_id,
2265 PSTRING)
2266FCALLSCFUN1(STRING, dic_get_format, DIC_GET_FORMAT, dic_get_format,
2267 INT)
2268#endif
Note: See TracBrowser for help on using the repository browser.