source: trunk/FACT++/dim_v19r19/src/dic.c@ 10480

Last change on this file since 10480 was 10480, checked in by tbretz, 14 years ago
New version V19r19 with some important bug fixes.
File size: 51.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 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 if( serv_id == 0 )
947 {
948 if(Current_server)
949 servp = Current_server;
950 else
951 {
952 ENABLE_AST
953 return(-1);
954 }
955 }
956 else
957 {
958 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
959 }
960 ENABLE_AST
961 if(servp->time_stamp[1])
962 {
963 *secs = servp->time_stamp[1];
964 if((servp->time_stamp[0] & 0xFFFF0000) == 0xc0de0000)
965 *milisecs = servp->time_stamp[0] & 0x0000FFFF;
966 else
967 *milisecs = servp->time_stamp[0];
968 return(1);
969 }
970 else
971 {
972 *secs = 0;
973 *milisecs = 0;
974 return(0);
975 }
976}
977
978void dic_release_service( unsigned service_id )
979{
980 register DIC_SERVICE *servp;
981 register int conn_id, pending;
982 static DIC_PACKET *dic_packet;
983 static int packet_size = 0;
984 DIC_DNS_PACKET dic_dns_packet;
985 register DIC_DNS_PACKET *dic_dns_p = &dic_dns_packet;
986 SERVICE_REQ *serv_reqp;
987 int release_service();
988
989 DISABLE_AST
990 if( !packet_size ) {
991 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER);
992 packet_size = DIC_HEADER;
993 }
994 if( service_id == 0 )
995 {
996 ENABLE_AST
997 return;
998 }
999 servp = (DIC_SERVICE *)id_get_ptr(service_id, SRC_DIC);
1000 if( servp == 0 )
1001 {
1002 ENABLE_AST
1003 return;
1004 }
1005 if(servp->serv_id != (int)service_id)
1006 {
1007 ENABLE_AST
1008 return;
1009 }
1010 pending = servp->pending;
1011 switch( pending )
1012 {
1013 case NOT_PENDING :
1014 conn_id = servp->conn_id;
1015 strncpy(dic_packet->service_name, servp->serv_name, MAX_NAME);
1016 dic_packet->type = htovl(DIM_DELETE);
1017 dic_packet->service_id = htovl(service_id);
1018 dic_packet->size = htovl(DIC_HEADER);
1019 dna_write( conn_id, dic_packet, DIC_HEADER );
1020 release_service( servp );
1021 break;
1022 case WAITING_SERVER_UP :
1023 if( ( servp->type == COMMAND )||( servp->type == ONCE_ONLY ) )
1024 {
1025 servp->pending = DELETED;
1026 break;
1027 }
1028 if( Dns_dic_conn_id > 0) {
1029 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1030 dic_dns_p->src_type = htovl(SRC_DIC);
1031 serv_reqp = &dic_dns_p->service;
1032 strcpy( serv_reqp->service_name, servp->serv_name );
1033 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1034 dna_write( Dns_dic_conn_id, dic_dns_p,
1035 sizeof(DIC_DNS_PACKET) );
1036 }
1037 release_service( servp );
1038 break;
1039 case WAITING_CMND_ANSWER :
1040 case WAITING_DNS_UP :
1041 release_service( servp );
1042 break;
1043 case WAITING_DNS_ANSWER :
1044 servp->pending = DELETED;
1045 break;
1046 }
1047 ENABLE_AST
1048}
1049
1050
1051int release_service( DIC_SERVICE *servicep )
1052{
1053 register DIC_SERVICE *servp;
1054 register int conn_id = 0;
1055 register int found = 0;
1056 register DIC_CONNECTION *dic_connp;
1057 char name[MAX_NAME], *ptr;
1058 int id;
1059
1060 id = servicep->serv_id;
1061 servicep->serv_id = 0;
1062 conn_id = servicep->conn_id;
1063 dic_connp = &Dic_conns[conn_id] ;
1064 dll_remove( (DLL *) servicep );
1065 if( servicep->timer_ent )
1066 {
1067 dtq_rem_entry( Dic_timer_q, servicep->timer_ent );
1068 }
1069/*
1070 if(servicep->type != COMMAND)
1071*/
1072 free( servicep->fill_address );
1073 if(strstr(servicep->serv_name,"/RpcOut"))
1074 {
1075 strcpy(name, servicep->serv_name);
1076 }
1077 else
1078 name[0] = '\0';
1079 free( servicep );
1080 if( conn_id && dic_connp->service_head )
1081 {
1082 if( dll_empty((DLL *)dic_connp->service_head) )
1083 {
1084 if( (servp = (DIC_SERVICE *) Cmnd_head) )
1085 {
1086 while( (servp = (DIC_SERVICE *) dll_get_next(
1087 (DLL *) Cmnd_head,
1088 (DLL *) servp)) )
1089 {
1090 if( servp->conn_id == conn_id)
1091 found = 1;
1092 }
1093 }
1094 if( !found)
1095 {
1096 if(Debug_on)
1097 {
1098 dim_print_date_time();
1099 printf("Conn %d, Server %s on node %s released\n",
1100 conn_id, dic_connp->task_name, dic_connp->node_name);
1101 fflush(stdout);
1102 }
1103 release_conn( conn_id );
1104 }
1105 }
1106 }
1107 if(name[0])
1108 {
1109 ptr = strstr(name,"/RpcOut");
1110 strcpy(ptr + 4, "In");
1111 if( (servp = locate_command(name)) )
1112 release_service(servp);
1113 }
1114 id_free(id, SRC_DIC);
1115 return(1);
1116}
1117
1118
1119int locate_service( DIC_SERVICE *servp )
1120{
1121 extern int open_dns(long, void (*)(), void (*)(), int, int, int);
1122
1123 if(!strcmp(servp->serv_name,"DIS_DNS/SERVER_INFO"))
1124 {
1125 Tmout_min = DID_DNS_TMOUT_MIN;
1126 Tmout_max = DID_DNS_TMOUT_MAX;
1127 }
1128 if(Tmout_min == 0)
1129 {
1130 Tmout_min = DIC_DNS_TMOUT_MIN;
1131 Tmout_max = DIC_DNS_TMOUT_MAX;
1132 }
1133 if( !Dns_dic_conn_id )
1134 {
1135 DISABLE_AST;
1136 Dns_dic_conn_id = open_dns( 0, recv_dns_dic_rout, error_handler,
1137 Tmout_min,
1138 Tmout_max,
1139 SRC_DIC);
1140 if(Dns_dic_conn_id == -2)
1141 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
1142 ENABLE_AST;
1143 }
1144 if( Dns_dic_conn_id > 0)
1145 {
1146 DISABLE_AST;
1147 request_dns_info(servp->prev->serv_id);
1148 ENABLE_AST;
1149 }
1150
1151 return(Dns_dic_conn_id);
1152}
1153
1154DIC_SERVICE *locate_command( char *serv_name )
1155{
1156 register DIC_SERVICE *servp;
1157
1158 if(!Cmnd_head)
1159 return((DIC_SERVICE *)0);
1160 if( (servp = (DIC_SERVICE *) dll_search( (DLL *) Cmnd_head, serv_name,
1161 strlen(serv_name)+1)) )
1162 return(servp);
1163 return((DIC_SERVICE *)0);
1164}
1165
1166DIC_SERVICE *locate_pending( char *serv_name )
1167{
1168 register DIC_SERVICE *servp;
1169
1170 if(!Service_pend_head)
1171 return((DIC_SERVICE *)0);
1172 if( (servp = (DIC_SERVICE *) dll_search( (DLL *) Service_pend_head, serv_name,
1173 strlen(serv_name)+1)) )
1174 return(servp);
1175 return((DIC_SERVICE *)0);
1176}
1177
1178DIC_BAD_CONNECTION *locate_bad(char *node, char *task, int port)
1179{
1180 DIC_BAD_CONNECTION *bad_connp;
1181
1182 if(!Bad_connection_head)
1183 return((DIC_BAD_CONNECTION *)0);
1184 bad_connp = Bad_connection_head;
1185 while( (bad_connp = (DIC_BAD_CONNECTION *) dll_get_next(
1186 (DLL *) Bad_connection_head,
1187 (DLL *) bad_connp)) )
1188 {
1189 if((!strcmp(bad_connp->conn.node_name, node)) &&
1190 (!strcmp(bad_connp->conn.task_name, task)) &&
1191 (bad_connp->conn.port == port) )
1192 return(bad_connp);
1193 }
1194 return((DIC_BAD_CONNECTION *)0);
1195}
1196
1197static void request_dns_info(int id)
1198{
1199 DIC_SERVICE *servp, *ptr;
1200 int n_pend = 0;
1201 int request_dns_single_info();
1202 extern int open_dns();
1203
1204 DISABLE_AST
1205 if( Dns_dic_conn_id <= 0)
1206 {
1207 Dns_dic_conn_id = open_dns( 0, recv_dns_dic_rout, error_handler,
1208 Tmout_min,
1209 Tmout_max,
1210 SRC_DIC);
1211 if(Dns_dic_conn_id == -2)
1212 error_handler(0, DIM_FATAL, DIMDNSUNDEF, "DIM_DNS_NODE undefined");
1213 }
1214 if( Dns_dic_conn_id > 0)
1215 {
1216 servp = Service_pend_head;
1217 if(id > 0)
1218 {
1219 ptr = (DIC_SERVICE *)id_get_ptr(id, SRC_DIC);
1220 if(ptr)
1221 {
1222 if((ptr->serv_id == id) && (ptr->pending != NOT_PENDING))
1223 servp = ptr;
1224 }
1225 }
1226
1227 while( (servp = (DIC_SERVICE *) dll_get_next(
1228 (DLL *) Service_pend_head,
1229 (DLL *) servp)) )
1230 {
1231 if( servp->pending == WAITING_DNS_UP)
1232 {
1233 if(!request_dns_single_info( servp ))
1234 {
1235 ENABLE_AST
1236 return;
1237 }
1238 n_pend++;
1239 }
1240 if(n_pend == 1000)
1241 {
1242 dtq_start_timer( 0, request_dns_info, servp->serv_id);
1243 ENABLE_AST
1244 return;
1245 }
1246 }
1247 }
1248 else
1249 {
1250 servp = Service_pend_head;
1251 while( (servp = (DIC_SERVICE *) dll_get_next(
1252 (DLL *) Service_pend_head,
1253 (DLL *) servp)) )
1254 {
1255 if( servp->pending == WAITING_DNS_UP)
1256 {
1257 if(( servp->type != COMMAND )&&( servp->type != ONCE_ONLY ))
1258 service_tmout( servp->serv_id );
1259 }
1260 }
1261 }
1262 ENABLE_AST
1263}
1264
1265
1266int request_dns_single_info( DIC_SERVICE *servp )
1267{
1268 static DIC_DNS_PACKET Dic_dns_packet;
1269 static SERVICE_REQ *serv_reqp;
1270 int ret = 1;
1271
1272 if( Dns_dic_conn_id > 0)
1273 {
1274 if(Debug_on)
1275 {
1276 dim_print_date_time();
1277 printf("Requesting DNS Info for %s, id %d\n",
1278 servp->serv_name, servp->serv_id);
1279 }
1280
1281 Dic_dns_packet.src_type = htovl(SRC_DIC);
1282 serv_reqp = &Dic_dns_packet.service;
1283 strcpy( serv_reqp->service_name, servp->serv_name );
1284 serv_reqp->service_id = htovl(servp->serv_id);
1285 servp->pending = WAITING_DNS_ANSWER;
1286 Dic_dns_packet.size = htovl(sizeof(DIC_DNS_PACKET));
1287 if(!dna_write( Dns_dic_conn_id, &Dic_dns_packet,
1288 sizeof(DIC_DNS_PACKET) ) )
1289 {
1290 ret = 0;
1291 }
1292
1293 }
1294 return ret;
1295}
1296
1297
1298static int handle_dns_info( DNS_DIC_PACKET *packet )
1299{
1300 int conn_id, service_id;
1301 DIC_SERVICE *servp;
1302 char *node_name, *task_name;
1303 char node_info[MAX_NODE_NAME+4];
1304 int i, port, protocol, format, ret, pid;
1305 register DIC_CONNECTION *dic_connp ;
1306 DIC_DNS_PACKET dic_dns_packet;
1307 register DIC_DNS_PACKET *dic_dns_p = &dic_dns_packet;
1308 SERVICE_REQ *serv_reqp;
1309 DIC_BAD_CONNECTION *bad_connp;
1310 int retrying = 0;
1311 int tmout;
1312 int send_service_command();
1313 int find_connection();
1314 void move_to_bad_service();
1315 void retry_bad_connection();
1316
1317 service_id = vtohl(packet->service_id);
1318
1319 servp = (DIC_SERVICE *)id_get_ptr(service_id, SRC_DIC);
1320 if(!servp)
1321 return(0);
1322 if(servp->serv_id != service_id)
1323 return(0);
1324 if(Debug_on)
1325 {
1326 dim_print_date_time();
1327 printf("Receiving DNS Info for service %s, id %d\n",servp->serv_name,
1328 vtohl(packet->service_id));
1329 }
1330 node_name = packet->node_name;
1331 if(node_name[0] == -1)
1332 {
1333 error_handler(0, DIM_FATAL, DIMDNSREFUS, "DIM_DNS refuses connection");
1334 return(0);
1335 }
1336
1337 task_name = packet->task_name;
1338 strcpy(node_info,node_name);
1339 for(i = 0; i < 4; i ++)
1340 node_info[strlen(node_name)+i+1] = packet->node_addr[i];
1341 port = vtohl(packet->port);
1342 pid = vtohl(packet->pid);
1343 protocol = vtohl(packet->protocol);
1344 format = vtohl(packet->format);
1345
1346 if( Dns_dic_timr )
1347 dtq_clear_entry( Dns_dic_timr );
1348 if( servp->pending == DELETED ) {
1349 if( Dns_dic_conn_id > 0) {
1350 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1351 dic_dns_p->src_type = htovl(SRC_DIC);
1352 serv_reqp = &dic_dns_p->service;
1353 strcpy( serv_reqp->service_name, servp->serv_name );
1354 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1355 dna_write( Dns_dic_conn_id, dic_dns_p,
1356 sizeof(DIC_DNS_PACKET) );
1357 }
1358 release_service( servp );
1359 return(0);
1360 }
1361 if( !node_name[0] )
1362 {
1363 servp->pending = WAITING_SERVER_UP;
1364 service_tmout( servp->serv_id );
1365 if( servp->pending == DELETED )
1366 {
1367 if( Dns_dic_conn_id > 0)
1368 {
1369 dic_dns_p->size = htovl(sizeof(DIC_DNS_PACKET));
1370 dic_dns_p->src_type = htovl(SRC_DIC);
1371 serv_reqp = &dic_dns_p->service;
1372 strcpy( serv_reqp->service_name, servp->serv_name );
1373 serv_reqp->service_id = htovl(servp->serv_id | 0x80000000);
1374 dna_write( Dns_dic_conn_id, dic_dns_p,
1375 sizeof(DIC_DNS_PACKET) );
1376 }
1377 release_service( servp );
1378 }
1379 return(0);
1380 }
1381#ifdef OSK
1382 {
1383 register char *ptr;
1384
1385 if(strncmp(node_name,"fidel",5))
1386 {
1387 for(ptr = node_name; *ptr; ptr++)
1388 {
1389 if(*ptr == '.')
1390 {
1391 *ptr = '\0';
1392 break;
1393 }
1394 }
1395 }
1396 }
1397#endif
1398 if( !(conn_id = find_connection(node_name, task_name, port)) )
1399 {
1400 bad_connp = locate_bad(node_name, task_name, port);
1401 if(bad_connp)
1402 retrying = bad_connp->retrying;
1403 if((!bad_connp) || (retrying))
1404 {
1405 if( (conn_id = dna_open_client(node_info, task_name, port,
1406 protocol, recv_rout, error_handler, SRC_DIC)) )
1407 {
1408/*
1409#ifndef VxWorks
1410 if(format & MY_OS9)
1411 {
1412 dna_set_test_write(conn_id, TEST_TIME_OSK);
1413 format &= 0xfffff7ff;
1414 }
1415 else
1416 {
1417 dna_set_test_write(conn_id, TEST_TIME_VMS);
1418 }
1419#endif
1420*/
1421 dna_set_test_write(conn_id, TEST_TIME_OSK);
1422 dic_connp = &Dic_conns[conn_id];
1423 strncpy( dic_connp->node_name, node_name,
1424 MAX_NODE_NAME);
1425 strncpy( dic_connp->task_name, task_name,
1426 MAX_TASK_NAME);
1427 dic_connp->port = port;
1428 dic_connp->pid = pid;
1429 if(Debug_on)
1430 {
1431 dim_print_date_time();
1432 printf(" - Conn %d, Server %s on node %s Connecting\n",
1433 conn_id, dic_connp->task_name, dic_connp->node_name);
1434 fflush(stdout);
1435 }
1436
1437 dic_connp->service_head =
1438 malloc(sizeof(DIC_SERVICE));
1439 dll_init( (DLL *) dic_connp->service_head);
1440 ((DIC_SERVICE *)(dic_connp->service_head))->serv_id = 0;
1441 if(retrying)
1442 {
1443 dll_remove((DLL *)bad_connp->conn.service_head);
1444 free(bad_connp->conn.service_head);
1445 dll_remove((DLL *)bad_connp);
1446 free(bad_connp);
1447 }
1448 }
1449 else
1450 {
1451 if(!retrying)
1452 {
1453 if( !Bad_connection_head )
1454 {
1455 Bad_connection_head = (DIC_BAD_CONNECTION *) malloc(sizeof(DIC_BAD_CONNECTION));
1456 dll_init( (DLL *) Bad_connection_head );
1457 Bad_connection_head->conn.service_head = 0;
1458 }
1459 bad_connp = (DIC_BAD_CONNECTION *) malloc(sizeof(DIC_BAD_CONNECTION));
1460 bad_connp->n_retries = 0;
1461 bad_connp->conn.service_head = malloc(sizeof(DIC_SERVICE));
1462 dll_init( (DLL *) bad_connp->conn.service_head);
1463
1464 dll_insert_queue( (DLL *) Bad_connection_head, (DLL *) bad_connp );
1465 if(Debug_on)
1466 {
1467 dim_print_date_time();
1468 printf(" - Failed connecting to Server %s on node %s port %d\n",
1469 task_name, node_name, port);
1470 fflush(stdout);
1471 }
1472 service_tmout( servp->serv_id );
1473 }
1474 bad_connp->n_retries++;
1475 bad_connp->retrying = 0;
1476 strncpy( bad_connp->conn.node_name, node_name, MAX_NODE_NAME);
1477 strncpy( bad_connp->conn.task_name, task_name, MAX_TASK_NAME);
1478 bad_connp->conn.port = port;
1479 tmout = BAD_CONN_TIMEOUT * bad_connp->n_retries;
1480 if(tmout > 120)
1481 tmout = 120;
1482 dtq_start_timer(tmout, retry_bad_connection, (long)bad_connp);
1483 if(( servp->type == COMMAND )||( servp->type == ONCE_ONLY ))
1484 return(0);
1485 move_to_bad_service(servp, bad_connp);
1486/*
1487 ((DIC_SERVICE *)(dic_connp->service_head))->serv_id = 0;
1488
1489 servp = Service_pend_head;
1490 while( (servp = (DIC_SERVICE *) dll_get_next(
1491 (DLL *) Service_pend_head,
1492 (DLL *) servp)) )
1493 {
1494 if( (servp->pending == WAITING_DNS_ANSWER) ||
1495 (servp->pending == WAITING_SERVER_UP))
1496 servp->pending = WAITING_DNS_UP;
1497 }
1498 dna_close( Dns_dic_conn_id );
1499 Dns_dic_conn_id = 0;
1500 request_dns_info(0);
1501*/
1502 return(0);
1503 }
1504 }
1505 else
1506 {
1507 if(!retrying)
1508 service_tmout( servp->serv_id );
1509 if(( servp->type == COMMAND )||( servp->type == ONCE_ONLY ))
1510 return(0);
1511 move_to_bad_service(servp, bad_connp);
1512 return(0);
1513 }
1514 }
1515 strcpy(servp->def, packet->service_def);
1516 get_format_data(format, servp->format_data, servp->def);
1517 servp->format = format;
1518 servp->conn_id = conn_id;
1519
1520 ret = send_service_command( servp );
1521/*
1522 if( ret == 1)
1523 {
1524 if(servp->pending != WAITING_CMND_ANSWER)
1525 servp->pending = NOT_PENDING;
1526 servp->tmout_done = 0;
1527 }
1528*/
1529 return(1);
1530}
1531
1532void retry_bad_connection(DIC_BAD_CONNECTION *bad_connp)
1533{
1534DIC_SERVICE *servp, *auxp;
1535int found = 0;
1536void move_to_notok_service();
1537
1538 if(!bad_connp)
1539 return;
1540 servp = (DIC_SERVICE *)bad_connp->conn.service_head;
1541 while( (servp = (DIC_SERVICE *) dll_get_next(
1542 (DLL *) bad_connp->conn.service_head,
1543 (DLL *) servp)) )
1544 {
1545 servp->pending = WAITING_DNS_UP;
1546 servp->conn_id = 0;
1547 auxp = servp->prev;
1548 move_to_notok_service( servp );
1549 servp = auxp;
1550 found = 1;
1551 }
1552 bad_connp->retrying = 1;
1553 if(found)
1554 request_dns_info(0);
1555}
1556
1557void move_to_ok_service( DIC_SERVICE *servp, int conn_id )
1558{
1559 if(Dic_conns[conn_id].service_head)
1560 {
1561 servp->pending = NOT_PENDING;
1562 servp->tmout_done = 0;
1563 dll_remove( (DLL *) servp );
1564 dll_insert_queue( (DLL *) Dic_conns[conn_id].service_head,
1565 (DLL *) servp );
1566 }
1567}
1568
1569void move_to_bad_service( DIC_SERVICE *servp, DIC_BAD_CONNECTION *bad_connp)
1570{
1571 servp->pending = WAITING_DNS_UP;
1572 dll_remove( (DLL *) servp );
1573 dll_insert_queue( (DLL *) bad_connp->conn.service_head, (DLL *) servp );
1574}
1575
1576void move_to_cmnd_service( DIC_SERVICE *servp )
1577{
1578/*
1579 if(servp->pending != WAITING_CMND_ANSWER)
1580*/
1581 servp->pending = NOT_PENDING;
1582 servp->tmout_done = 0;
1583 dll_remove( (DLL *) servp );
1584 dll_insert_queue( (DLL *) Cmnd_head, (DLL *) servp );
1585}
1586
1587void move_to_notok_service(DIC_SERVICE *servp )
1588{
1589
1590 dll_remove( (DLL *) servp );
1591 dll_insert_queue( (DLL *) Service_pend_head, (DLL *) servp );
1592}
1593
1594static void get_format_data(int format, FORMAT_STR *format_data, char *def)
1595{
1596 register FORMAT_STR *formatp = format_data;
1597 register char code, last_code = 0;
1598 int num;
1599 char *ptr = def;
1600
1601 if(format){}
1602 while(*ptr)
1603 {
1604 switch(*ptr)
1605 {
1606 case 'i':
1607 case 'I':
1608 case 'l':
1609 case 'L':
1610 *ptr = 'I';
1611 break;
1612 case 'x':
1613 case 'X':
1614 *ptr = 'X';
1615 break;
1616 case 's':
1617 case 'S':
1618 *ptr = 'S';
1619 break;
1620 case 'f':
1621 case 'F':
1622 *ptr = 'F';
1623 break;
1624 case 'd':
1625 case 'D':
1626 *ptr = 'D';
1627 break;
1628 case 'c':
1629 case 'C':
1630 *ptr = 'C';
1631 break;
1632 }
1633 ptr++;
1634 }
1635 code = *def;
1636 while(*def)
1637 {
1638 if(code != last_code)
1639 {
1640 formatp->par_num = 0;
1641 formatp->flags = 0;
1642 switch(code)
1643 {
1644 case 'i':
1645 case 'I':
1646 case 'l':
1647 case 'L':
1648 formatp->par_bytes = SIZEOF_LONG;
1649 formatp->flags |= SWAPL;
1650 break;
1651 case 'x':
1652 case 'X':
1653 formatp->par_bytes = SIZEOF_DOUBLE;
1654 formatp->flags |= SWAPD;
1655 break;
1656 case 's':
1657 case 'S':
1658 formatp->par_bytes = SIZEOF_SHORT;
1659 formatp->flags |= SWAPS;
1660 break;
1661 case 'f':
1662 case 'F':
1663 formatp->par_bytes = SIZEOF_LONG;
1664 formatp->flags |= SWAPL;
1665#ifdef vms
1666/*
1667 if((format & 0xF0) != (MY_FORMAT & 0xF0))
1668*/
1669 formatp->flags |= (format & 0xF0);
1670 formatp->flags |= IT_IS_FLOAT;
1671#endif
1672 break;
1673 case 'd':
1674 case 'D':
1675 formatp->par_bytes = SIZEOF_DOUBLE;
1676 formatp->flags |= SWAPD;
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 'c':
1686 case 'C':
1687 formatp->par_bytes = SIZEOF_CHAR;
1688 formatp->flags |= NOSWAP;
1689 break;
1690 }
1691 }
1692 def++;
1693 if(*def != ':')
1694 {
1695/* tested by the server
1696 if(*def)
1697 {
1698 printf("Bad service definition parsing\n");
1699 fflush(stdout);
1700 }
1701 else
1702*/
1703 formatp->par_num = 0;
1704 }
1705 else
1706 {
1707 def++;
1708 sscanf(def,"%d",&num);
1709 formatp->par_num += num;
1710 while((*def != ';') && (*def != '\0'))
1711 def++;
1712 if(*def)
1713 def++;
1714 }
1715 last_code = code;
1716 code = *def;
1717 if(code != last_code)
1718 formatp++;
1719 }
1720 formatp->par_bytes = 0;
1721/*
1722 if((format & 0xF) == (MY_FORMAT & 0xF))
1723 {
1724 for(i = 0, formatp = format_data; i<index;i++, formatp++)
1725 formatp->flags &= 0xF0;
1726 }
1727*/
1728}
1729
1730int end_command(DIC_SERVICE *servp, int ret)
1731{
1732 DIC_SERVICE *aux_servp;
1733 DIC_CONNECTION *dic_connp;
1734
1735 DISABLE_AST
1736 dic_connp = &Dic_conns[servp->conn_id];
1737 if(servp->pending != WAITING_CMND_ANSWER)
1738 {
1739 if((!ret) || (!dic_connp->service_head))
1740 {
1741 servp->pending = WAITING_DNS_UP;
1742 dic_release_service( servp->serv_id );
1743 }
1744 else
1745 {
1746 aux_servp = locate_command(servp->serv_name);
1747 if( !aux_servp )
1748 {
1749 move_to_cmnd_service( servp );
1750 }
1751 else
1752 {
1753 if(aux_servp != servp)
1754 {
1755 servp->pending = WAITING_DNS_UP;
1756 dic_release_service( servp->serv_id );
1757 }
1758 }
1759 }
1760 }
1761 ENABLE_AST
1762 return(ret);
1763}
1764
1765int send_service_command(DIC_SERVICE *servp)
1766{
1767 int ret = 1;
1768 int conn_id;
1769 int send_command();
1770 int send_service();
1771
1772 conn_id = servp->conn_id;
1773 if( servp->type == COMMAND )
1774 {
1775 ret = send_command(conn_id, servp);
1776 end_command(servp, ret);
1777 }
1778 else
1779 {
1780 if( send_service(conn_id, servp))
1781 {
1782 if( servp->type == ONCE_ONLY )
1783 {
1784 if( !locate_command(servp->serv_name) )
1785 {
1786 move_to_cmnd_service( servp );
1787 }
1788 }
1789 else
1790 move_to_ok_service( servp, conn_id );
1791 }
1792 }
1793 return(ret);
1794}
1795
1796int send_service(int conn_id, DIC_SERVICE *servp)
1797{
1798 static DIC_PACKET *dic_packet;
1799 static int serv_packet_size = 0;
1800 int type, ret;
1801
1802 if( !serv_packet_size ) {
1803 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER);
1804 serv_packet_size = DIC_HEADER;
1805 }
1806
1807 strncpy( dic_packet->service_name, servp->serv_name, MAX_NAME );
1808 type = servp->type;
1809 if(servp->stamped)
1810 type |= STAMPED;
1811 dic_packet->type = htovl(type);
1812 dic_packet->timeout = htovl(servp->timeout);
1813 dic_packet->service_id = htovl(servp->serv_id);
1814 dic_packet->format = htovl(MY_FORMAT);
1815 dic_packet->size = htovl(DIC_HEADER);
1816 ret = dna_write(conn_id, dic_packet, DIC_HEADER);
1817 return(ret);
1818}
1819
1820typedef struct
1821{
1822 int ret_code;
1823 int serv_id;
1824} CMNDCB_ITEM;
1825
1826void do_cmnd_callback(CMNDCB_ITEM *itemp)
1827{
1828
1829 DIC_SERVICE *servp;
1830 int ret, serv_id;
1831/*
1832 itemp = (CMNDCB_ITEM *)id_get_ptr(id, SRC_DIC);
1833*/
1834 serv_id = itemp->serv_id;
1835 ret = itemp->ret_code;
1836 servp = (DIC_SERVICE *)id_get_ptr(serv_id, SRC_DIC);
1837 if(servp)
1838 {
1839 if(servp->serv_id == serv_id)
1840 {
1841 Curr_conn_id = servp->conn_id;
1842 (servp->user_routine)( &servp->tag, &ret );
1843 servp->pending = NOT_PENDING;
1844 end_command(servp, ret);
1845 Curr_conn_id = 0;
1846 }
1847 }
1848/*
1849 id_free(id, SRC_DIC);
1850*/
1851 free(itemp);
1852}
1853
1854int send_command(int conn_id, DIC_SERVICE *servp)
1855{
1856 static DIC_PACKET *dic_packet;
1857 static int cmnd_packet_size = 0;
1858 register int size;
1859 int ret;
1860 CMNDCB_ITEM *itemp;
1861
1862 size = servp->fill_size;
1863
1864 if( !cmnd_packet_size ) {
1865 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER + size);
1866 cmnd_packet_size = DIC_HEADER + size;
1867 }
1868 else
1869 {
1870 if( DIC_HEADER + size > cmnd_packet_size ) {
1871 free( dic_packet );
1872 dic_packet = (DIC_PACKET *)malloc(DIC_HEADER + size);
1873 cmnd_packet_size = DIC_HEADER + size;
1874 }
1875 }
1876
1877 strncpy(dic_packet->service_name, servp->serv_name, MAX_NAME);
1878 dic_packet->type = htovl(COMMAND);
1879 dic_packet->timeout = htovl(0);
1880 dic_packet->format = htovl(MY_FORMAT);
1881
1882 dic_packet->service_id = /*id_get((void *)servp)*/servp->serv_id;
1883
1884 size = copy_swap_buffer_out(servp->format, servp->format_data,
1885 dic_packet->buffer, servp->fill_address,
1886 size);
1887 dic_packet->size = htovl( size + DIC_HEADER);
1888 if( servp->user_routine )
1889 {
1890 servp->pending = WAITING_CMND_ANSWER;
1891 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1892 itemp = (CMNDCB_ITEM *)malloc(sizeof(CMNDCB_ITEM));
1893 itemp->serv_id = servp->serv_id;
1894 itemp->ret_code = ret;
1895/*
1896 id = id_get((void *)itemp, SRC_DIC);
1897*/
1898 dtq_start_timer(0, do_cmnd_callback, (long)itemp);
1899/*
1900 (servp->user_routine)( &servp->tag, &ret );
1901*/
1902 }
1903 else
1904 {
1905 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1906 }
1907/*
1908 if(!ret)
1909 {
1910 servp->pending = WAITING_DNS_UP;
1911 dic_release_service( servp->serv_id );
1912 }
1913*/
1914 /*
1915 ret = dna_write_nowait(conn_id, dic_packet, DIC_HEADER + size);
1916 if(!ret)
1917 {
1918 servp->pending = WAITING_DNS_UP;
1919 dic_release_service( servp->serv_id );
1920 }
1921 else
1922 {
1923 dim_usleep(5000);
1924 if( servp->user_routine )
1925 (servp->user_routine)( &servp->tag, &ret );
1926 }
1927*/
1928 return(ret);
1929}
1930
1931int find_connection(char *node, char *task, int port)
1932{
1933 register int i;
1934 register DIC_CONNECTION *dic_connp;
1935
1936 if(task){}
1937 for( i=0, dic_connp = Dic_conns; i<Curr_N_Conns; i++, dic_connp++ )
1938 {
1939/*
1940 if((!strcmp(dic_connp->task_name, task))
1941 &&(!strcmp(dic_connp->node_name, node)))
1942*/
1943 if((!strcmp(dic_connp->node_name, node))
1944 && (dic_connp->port == port))
1945 return(i);
1946 }
1947 return(0);
1948}
1949
1950int dic_get_id(char *name)
1951{
1952 extern int get_proc_name(char *name);
1953
1954 get_proc_name(name);
1955 strcat(name,"@");
1956 get_node_name(&name[strlen(name)]);
1957 return(1);
1958}
1959
1960#ifdef VxWorks
1961void dic_destroy(int tid)
1962{
1963 register int i;
1964 register DIC_CONNECTION *dic_connp;
1965 register DIC_SERVICE *servp, *auxp;
1966 int found = 0;
1967
1968 if(!Dic_conns)
1969 return;
1970 for( i=0, dic_connp = Dic_conns; i<Curr_N_Conns; i++, dic_connp++ )
1971 {
1972 if(servp = (DIC_SERVICE *) dic_connp->service_head)
1973 {
1974 while( servp = (DIC_SERVICE *) dll_get_next(
1975 (DLL *) dic_connp->service_head,
1976 (DLL *) servp) )
1977 {
1978 if( servp->tid == tid )
1979 {
1980 auxp = servp->prev;
1981 dic_release_service( servp->serv_id );
1982 servp = auxp;
1983 if(!dic_connp->service_head)
1984 break;
1985 }
1986 else
1987 found = 1;
1988 }
1989 }
1990 }
1991 if(!found)
1992 {
1993 if(Dns_dic_conn_id > 0)
1994 {
1995 dna_close( Dns_dic_conn_id );
1996 Dns_dic_conn_id = 0;
1997 }
1998 }
1999}
2000
2001void DIMDestroy(int tid)
2002{
2003 dis_destroy(tid);
2004 dic_destroy(tid);
2005}
2006
2007#endif
2008
2009static void release_conn(int conn_id)
2010{
2011 register DIC_CONNECTION *dic_connp = &Dic_conns[conn_id];
2012
2013 if(Debug_on)
2014 {
2015 dim_print_date_time();
2016 printf("Conn %d, Server %s on node %s completely released\n",
2017 conn_id, dic_connp->task_name, dic_connp->node_name);
2018 fflush(stdout);
2019 }
2020 dic_connp->task_name[0] = '\0';
2021 dic_connp->port = 0;
2022 if(dic_connp->service_head)
2023 {
2024 free((DIC_SERVICE *)dic_connp->service_head);
2025 dic_connp->service_head = (char *)0;
2026 }
2027 dna_close(conn_id);
2028}
2029
2030void dic_close_dns()
2031{
2032 register DIC_SERVICE *servp, *auxp;
2033
2034 if(Dns_dic_conn_id > 0)
2035 {
2036 if( (servp = (DIC_SERVICE *) Cmnd_head) )
2037 {
2038 while( (servp = (DIC_SERVICE *) dll_get_next(
2039 (DLL *) Cmnd_head,
2040 (DLL *) servp)) )
2041 {
2042#ifdef DEBUG
2043 printf("\t%s was in the Command list\n", servp->serv_name);
2044 printf("type = %d, pending = %d\n",servp->type, servp->pending);
2045 fflush(stdout);
2046#endif
2047 auxp = servp->prev;
2048 if( (servp->type == ONCE_ONLY ) &&
2049 (servp->pending == WAITING_SERVER_UP))
2050 {
2051 service_tmout( servp->serv_id );
2052 }
2053 else if( (servp->type == COMMAND ) &&
2054 (servp->pending == WAITING_CMND_ANSWER))
2055 {
2056 service_tmout( servp->serv_id );
2057 }
2058 else
2059 {
2060 servp->pending = WAITING_DNS_UP;
2061 dic_release_service( servp->serv_id );
2062 }
2063 servp = auxp;
2064 }
2065 }
2066 dna_close( Dns_dic_conn_id );
2067 Dns_dic_conn_id = 0;
2068 }
2069}
2070/*
2071append_service(service_info_buffer, servp)
2072char *service_info_buffer;
2073SERVICE *servp;
2074{
2075 char name[MAX_NAME], *ptr;
2076
2077 if(strstr(servp->name,"/RpcIn"))
2078 {
2079 strcpy(name,servp->name);
2080 ptr = (char *)strstr(name,"/RpcIn");
2081 *ptr = 0;
2082 strcat(service_info_buffer, name);
2083 strcat(service_info_buffer, "|");
2084 if(servp->def[0])
2085 {
2086 strcat(service_info_buffer, servp->def);
2087 }
2088 strcat(name,"/RpcOut");
2089 if(servp = find_service(name))
2090 {
2091 strcat(service_info_buffer, ",");
2092 if(servp->def[0])
2093 {
2094 strcat(service_info_buffer, servp->def);
2095 }
2096 }
2097 strcat(service_info_buffer, "|RPC");
2098 strcat(service_info_buffer, "\n");
2099 }
2100 else if(strstr(servp->name,"/RpcOut"))
2101 {
2102 }
2103 else
2104 {
2105 strcat(service_info_buffer, servp->name);
2106 strcat(service_info_buffer, "|");
2107 if(servp->def[0])
2108 {
2109 strcat(service_info_buffer, servp->def);
2110 }
2111 strcat(service_info_buffer, "|");
2112 if(servp->type == COMMAND)
2113 {
2114 strcat(service_info_buffer, "CMD");
2115 }
2116 strcat(service_info_buffer, "\n");
2117 }
2118}
2119*/
2120
2121char *dic_get_error_services()
2122{
2123 return(dic_get_server_services(Error_conn_id));
2124}
2125
2126char *dic_get_server_services(int conn_id)
2127{
2128 DIC_SERVICE *servp;
2129 DIC_CONNECTION *dic_connp;
2130 int n_services = 0;
2131 int max_size;
2132 static int curr_allocated_size = 0;
2133 static char *service_info_buffer;
2134 char *buff_ptr;
2135
2136
2137 if(!conn_id)
2138 return((char *)0);
2139 dic_connp = &Dic_conns[conn_id];
2140 if( (servp = (DIC_SERVICE *) dic_connp->service_head) )
2141 {
2142 while( (servp = (DIC_SERVICE *) dll_get_next(
2143 (DLL *) dic_connp->service_head,
2144 (DLL *) servp)) )
2145 {
2146 n_services++;
2147 }
2148 if(!n_services)
2149 return((char *)0);
2150 max_size = n_services * MAX_NAME;
2151 if(!curr_allocated_size)
2152 {
2153 service_info_buffer = (char *)malloc(max_size);
2154 curr_allocated_size = max_size;
2155 }
2156 else if (max_size > curr_allocated_size)
2157 {
2158 free(service_info_buffer);
2159 service_info_buffer = (char *)malloc(max_size);
2160 curr_allocated_size = max_size;
2161 }
2162 service_info_buffer[0] = '\0';
2163 buff_ptr = service_info_buffer;
2164
2165 servp = (DIC_SERVICE *) dic_connp->service_head;
2166 while( (servp = (DIC_SERVICE *) dll_get_next(
2167 (DLL *) dic_connp->service_head,
2168 (DLL *) servp)) )
2169 {
2170 strcat(buff_ptr, servp->serv_name);
2171 strcat(buff_ptr, "\n");
2172 buff_ptr += strlen(buff_ptr);
2173 }
2174 }
2175 else
2176 {
2177 return((char *)0);
2178 }
2179/*
2180 dim_print_date_time();
2181 printf("Server %s@%s provides services:\n",
2182 dic_connp->task_name, dic_connp->node_name);
2183 printf("%s\n",service_info_buffer);
2184*/
2185 return(service_info_buffer);
2186}
2187
2188int dic_get_conn_id()
2189{
2190 return(Curr_conn_id);
2191}
2192
2193int dic_get_server(char *name)
2194{
2195 int ret = 0;
2196 char node[MAX_NODE_NAME], task[MAX_TASK_NAME];
2197
2198 DISABLE_AST
2199
2200 if(Curr_conn_id)
2201 {
2202 dna_get_node_task(Curr_conn_id, node, task);
2203 strcpy(name,task);
2204 strcat(name,"@");
2205 strcat(name,node);
2206 ret = Curr_conn_id;
2207 }
2208 ENABLE_AST
2209 return(ret);
2210}
2211
2212int dic_get_server_pid(int *pid)
2213{
2214 int ret = 0;
2215
2216 DISABLE_AST
2217
2218 *pid = 0;
2219 if(Curr_conn_id)
2220 {
2221 *pid = Dic_conns[Curr_conn_id].pid;
2222 ret = Curr_conn_id;
2223 }
2224 ENABLE_AST
2225 return(ret);
2226}
2227
2228void dic_stop()
2229{
2230 dtq_delete(Dic_timer_q);
2231 dic_close_dns();
2232 dim_stop();
2233}
2234
2235#ifdef VMS
2236/* CFORTRAN WRAPPERS */
2237FCALLSCFUN9(INT, dic_info_service, DIC_INFO_SERVICE, dic_info_service,
2238 STRING, INT, INT, PVOID, INT, PVOID, INT, PVOID, INT)
2239FCALLSCFUN9(INT, dic_info_service_stamped, DIC_INFO_SERVICE_STAMPED,
2240 dic_info_service_stamped,
2241 STRING, INT, INT, PVOID, INT, PVOID, INT, PVOID, INT)
2242FCALLSCFUN3(INT, dic_cmnd_service, DIC_CMND_SERVICE, dic_cmnd_service,
2243 STRING, PVOID, INT)
2244FCALLSCFUN5(INT, dic_cmnd_callback, DIC_CMND_CALLBACK, dic_cmnd_callback,
2245 STRING, PVOID, INT, PVOID, INT)
2246FCALLSCFUN3(INT, dic_cmnd_service_stamped, DIC_CMND_SERVICE_STAMPED,
2247 dic_cmnd_service_stamped,
2248 STRING, PVOID, INT)
2249FCALLSCFUN5(INT, dic_cmnd_callback_stamped, DIC_CMND_CALLBACK_STAMPED,
2250 dic_cmnd_callback_stamped,
2251 STRING, PVOID, INT, PVOID, INT)
2252FCALLSCSUB3( dic_change_address, DIC_CHANGE_ADDRESS, dic_change_address,
2253 INT, PVOID, INT)
2254FCALLSCSUB1( dic_release_service, DIC_RELEASE_SERVICE, dic_release_service,
2255 INT)
2256FCALLSCFUN1(INT, dic_get_quality, DIC_GET_QUALITY, dic_get_quality,
2257 INT)
2258FCALLSCFUN3(INT, dic_get_timestamp, DIC_GET_TIMESTAMP, dic_get_timestamp,
2259 INT,PINT,PINT)
2260FCALLSCFUN1(INT, dic_get_id, DIC_GET_ID, dic_get_id,
2261 PSTRING)
2262FCALLSCFUN1(STRING, dic_get_format, DIC_GET_FORMAT, dic_get_format,
2263 INT)
2264#endif
Note: See TracBrowser for help on using the repository browser.