changed long to int (64 bit system's compatibilty)
[lcr.git] / socket_server.c
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** Socket link server                                                        **
9 **                                                                           **
10 \*****************************************************************************/
11
12 #include "main.h"
13 #include <sys/socket.h>
14 #include <sys/un.h>
15 #include <curses.h>
16
17
18 char *socket_name = SOCKET_NAME;
19 int sock = -1;
20 struct sockaddr_un sock_address;
21
22 struct admin_list *admin_first = NULL;
23
24 /*
25  * initialize admin socket 
26  */
27 int admin_init(void)
28 {
29         unsigned int on = 1;
30
31         /* open and bind socket */
32         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
33         {
34                 PERROR("Failed to create admin socket. (errno=%d)\n", errno);
35                 return(-1);
36         }
37         fhuse++;
38         memset(&sock_address, 0, sizeof(sock_address));
39         sock_address.sun_family = AF_UNIX;
40         UCPY(sock_address.sun_path, socket_name);
41         unlink(socket_name);
42         if (bind(sock, (struct sockaddr *)(&sock_address), SUN_LEN(&sock_address)) < 0)
43         {
44                 close(sock);
45                 unlink(socket_name);
46                 fhuse--;
47                 sock = -1;
48                 PERROR("Failed to bind admin socket to \"%s\". (errno=%d)\n", sock_address.sun_path, errno);
49                 return(-1);
50         }
51         if (listen(sock, 5) < 0)
52         {
53                 close(sock);
54                 unlink(socket_name);
55                 fhuse--;
56                 sock = -1;
57                 PERROR("Failed to listen to socket \"%s\". (errno=%d)\n", sock_address.sun_path, errno);
58                 return(-1);
59         }
60         if (ioctl(sock, FIONBIO, (unsigned char *)(&on)) < 0)
61         {
62                 close(sock);
63                 unlink(socket_name);
64                 fhuse--;
65                 sock = -1;
66                 PERROR("Failed to set socket \"%s\" into non-blocking mode. (errno=%d)\n", sock_address.sun_path, errno);
67                 return(-1);
68         }
69         return(0);
70 }
71
72
73 /*
74  * free connection
75  * also releases all remote joins
76  */
77 void free_connection(struct admin_list *admin)
78 {
79         struct admin_queue *response;
80         void *temp;
81         union parameter param;
82         class Join *join, *joinnext;
83         struct mISDNport *mISDNport;
84         int i, ii;
85
86         /* free remote joins */
87         if (admin->remote_name[0])
88         {
89                 start_trace(0,
90                         NULL,
91                         NULL,
92                         NULL,
93                         DIRECTION_NONE,
94                         0,
95                         0,
96                         "REMOTE APP release");
97                 add_trace("app", "name", "%s", admin->remote_name);
98                 end_trace();
99                 /* release all exported channels */
100                 mISDNport = mISDNport_first;
101                 while(mISDNport)
102                 {
103                         i = 0;
104                         ii = mISDNport->b_num;
105                         while(i < ii)
106                         {
107                                 if (mISDNport->b_remote_id[i] == admin->sock)
108                                 {
109                                         mISDNport->b_state[i] = B_STATE_IDLE;
110                                         mISDNport->b_timer[i] = 0;
111                                         mISDNport->b_remote_id[i] = 0;
112                                         mISDNport->b_remote_ref[i] = 0;
113                                 }
114                                 i++;
115                         }
116                         mISDNport = mISDNport->next;
117                 }
118                 /* release join */
119                 join = join_first;
120                 while(join)
121                 {
122                         joinnext = join->next;
123                         if (join->j_type==JOIN_TYPE_REMOTE) if (((class JoinRemote *)join)->j_remote_id == admin->sock)
124                         {
125                                 memset(&param, 0, sizeof(param));
126                                 param.disconnectinfo.cause = CAUSE_OUTOFORDER;
127                                 param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
128                                 ((class JoinRemote *)join)->message_remote(MESSAGE_RELEASE, &param);
129                                 /* join is now destroyed, so we go to next join */
130                         }
131                         join = joinnext;
132                 }
133         }
134
135         if (admin->sock >= 0)
136         {
137                 close(admin->sock);
138                 fhuse--;
139         }
140 //      printf("new\n", response);
141         response = admin->response;
142         while (response)
143         {
144 //#warning
145 //      printf("%x\n", response);
146                 temp = response->next;
147                 FREE(response, 0);
148                 memuse--;
149                 response = (struct admin_queue *)temp;
150         }
151 //      printf("new2\n", response);
152         FREE(admin, 0);
153 //      printf("new3\n", response);
154         memuse--;
155 }
156
157
158 /*
159  * cleanup admin socket 
160  */
161 void admin_cleanup(void)
162 {
163         struct admin_list *admin, *next;;
164
165         admin = admin_first;
166         while(admin)
167         {
168 //printf("clean\n");
169                 next = admin->next;
170                 free_connection(admin);
171                 admin = next;
172         }
173
174         if (sock >= 0)
175         {
176                 close(sock);
177                 fhuse--;
178         }
179 }
180
181
182 /*
183  * do interface reload
184  */
185 int admin_interface(struct admin_queue **responsep)
186 {
187         struct admin_queue      *response;      /* response pointer */
188         char                    *err_txt = "";
189         int                     err = 0;
190
191         if (read_interfaces())
192         {
193                 relink_interfaces();
194                 free_interfaces(interface_first);
195                 interface_first = interface_newlist;
196                 interface_newlist = NULL;
197         } else
198         {
199                 err_txt = interface_error;
200                 err = -1;
201         }
202         /* create state response */
203         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
204         memuse++;
205         response->num = 1;
206         /* message */
207         response->am[0].message = ADMIN_RESPONSE_CMD_INTERFACE;
208         /* error */
209         response->am[0].u.x.error = err;
210         /* message */
211         SCPY(response->am[0].u.x.message, err_txt);
212         /* attach to response chain */
213         *responsep = response;
214         responsep = &response->next;
215
216         return(0);
217 }
218
219
220 /*
221  * do route reload
222  */
223 int admin_route(struct admin_queue **responsep)
224 {
225         struct route_ruleset    *ruleset_new;
226         struct admin_queue      *response;      /* response pointer */
227         char                    err_txt[256] = "";
228         int                     err = 0;
229 #if 0
230         int                     n;
231 #endif
232         class EndpointAppPBX    *apppbx;
233
234 #if 0
235         n = 0;
236         apppbx = apppbx_first;
237         while(apppbx)
238         {
239                 n++;
240                 apppbx = apppbx->next;
241         }
242         if (apppbx_first)
243         {
244                 SPRINT(err_txt, "Cannot reload routing, because %d endpoints active\n", n);
245                 err = -1;
246                 goto response;
247         }
248 #endif
249         if (!(ruleset_new = ruleset_parse()))
250         {
251                 SPRINT(err_txt, ruleset_error);
252                 err = -1;
253                 goto response;
254         }
255         ruleset_free(ruleset_first);
256         ruleset_first = ruleset_new;
257         ruleset_main = getrulesetbyname("main");
258         if (!ruleset_main)
259         {
260                 SPRINT(err_txt, "Ruleset reloaded, but rule 'main' not found.\n");
261                 err = -1;
262         }
263         apppbx = apppbx_first;
264         while(apppbx)
265         {
266                 if (apppbx->e_action)
267                 {
268                         switch(apppbx->e_action->index)
269                         {
270                                 case ACTION_INTERNAL:
271                                 apppbx->e_action = &action_internal;
272                                 break;
273                                 case ACTION_EXTERNAL:
274                                 apppbx->e_action = &action_external;
275                                 break;
276                                 case ACTION_REMOTE:
277                                 apppbx->e_action = &action_remote;
278                                 break;
279                                 case ACTION_VBOX_RECORD:
280                                 apppbx->e_action = &action_vbox;
281                                 break;
282                                 case ACTION_PARTYLINE:
283                                 apppbx->e_action = &action_partyline;
284                                 break;
285                                 default:
286                                 goto release;
287                         }
288                 } else if (apppbx->e_state != EPOINT_STATE_CONNECT)
289                 {
290                         release:
291                         apppbx->e_callback = 0;
292                         apppbx->e_action = NULL;
293                         apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
294                         start_trace(0,
295                                 NULL,
296                                 numberrize_callerinfo(apppbx->e_callerinfo.id, apppbx->e_callerinfo.ntype, options.national, options.international),
297                                 apppbx->e_dialinginfo.id,
298                                 DIRECTION_NONE,
299                                 CATEGORY_EP,
300                                 apppbx->ea_endpoint->ep_serial,
301                                 "KICK (reload routing)");
302                         end_trace();
303                 }
304
305                 apppbx->e_action_timeout = 0;
306                 apppbx->e_rule = NULL;
307                 apppbx->e_ruleset = NULL;
308
309                 apppbx = apppbx->next;
310         }
311
312         response:
313         /* create state response */
314         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
315         memuse++;
316         response->num = 1;
317         /* message */
318         response->am[0].message = ADMIN_RESPONSE_CMD_ROUTE;
319         /* error */
320         response->am[0].u.x.error = err;
321         /* message */
322         SCPY(response->am[0].u.x.message, err_txt);
323         /* attach to response chain */
324         *responsep = response;
325         responsep = &response->next;
326
327         return(0);
328 }
329
330
331 /*
332  * do dialing
333  */
334 int admin_dial(struct admin_queue **responsep, char *message)
335 {
336         struct extension        ext;            /* temporary extension's settings */
337         struct admin_queue      *response;      /* response pointer */
338         char                    *p;             /* pointer to dialing digits */
339
340         /* create state response */
341         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
342         memuse++;
343         response->num = 1;
344         /* message */
345         response->am[0].message = ADMIN_RESPONSE_CMD_DIAL;
346
347         /* process request */
348         if (!(p = strchr(message,':')))
349         {
350                 response->am[0].u.x.error = -EINVAL;
351                 SPRINT(response->am[0].u.x.message, "no seperator ':' in message to seperate number from extension");
352                 goto out;
353         }
354         *p++ = 0;
355
356         /* modify extension */
357         if (!read_extension(&ext, message))
358         {
359                 response->am[0].u.x.error = -EINVAL;
360                 SPRINT(response->am[0].u.x.message, "extension doesn't exist");
361                 goto out;
362         }
363         SCPY(ext.next, p);
364         write_extension(&ext, message);
365
366         out:
367         /* attach to response chain */
368         *responsep = response;
369         responsep = &response->next;
370         return(0);
371 }
372
373
374 /*
375  * do tracing
376  */
377 int admin_trace(struct admin_list *admin, struct admin_trace_req *trace)
378 {
379         memcpy(&admin->trace, trace, sizeof(struct admin_trace_req));
380         return(0);
381 }
382
383
384 /*
385  * do blocking
386  * 
387  * 0 = make port available
388  * 1 = make port administratively blocked
389  * 2 = unload port
390  * the result is returned:
391  * 0 = port is now available
392  * 1 = port is now blocked
393  * 2 = port cannot be loaded or has been unloaded
394  * -1 = port doesn't exist
395  */
396 int admin_block(struct admin_queue **responsep, int portnum, int block)
397 {
398         struct admin_queue      *response;      /* response pointer */
399         struct interface        *interface;
400         struct interface_port   *ifport;
401
402         /* create block response */
403         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
404         memuse++;
405         response->num = 1;
406         /* message */
407         response->am[0].message = ADMIN_RESPONSE_CMD_BLOCK;
408         response->am[0].u.x.portnum = portnum;
409
410         /* search for port */
411         interface = interface_first;
412         while(interface)
413         {
414                 ifport = interface->ifport;
415                 while(ifport)
416                 {
417                         if (ifport->portnum == portnum)
418                                 break;
419                         ifport = ifport->next;
420                 }
421                 if (ifport)
422                         break;
423                 interface = interface->next;
424         }
425         /* not found, we return -1 */
426         if (!ifport)
427         {
428                 response->am[0].u.x.block = -1;
429                 response->am[0].u.x.error = 1;
430                 SPRINT(response->am[0].u.x.message, "Port %d does not exist.", portnum);
431                 goto out;
432         }
433
434         /* no interface */
435         if (!ifport->mISDNport)
436         {
437                 /* not loaded anyway */
438                 if (block >= 2)
439                 {
440                         response->am[0].u.x.block = 2;
441                         goto out;
442                 }
443
444                 /* try loading interface */
445                 ifport->block = block;
446                 load_port(ifport);
447
448                 /* port cannot load */
449                 if (ifport->block >= 2)
450                 {
451                         response->am[0].u.x.block = 2;
452                         response->am[0].u.x.error = 1;
453                         SPRINT(response->am[0].u.x.message, "Port %d will not load.", portnum);
454                         goto out;
455                 }
456
457                 /* port loaded */
458                 response->am[0].u.x.block = ifport->block;
459                 goto out;
460         }
461
462         /* if we shall unload interface */
463         if (block >= 2)
464         {
465                 mISDNport_close(ifport->mISDNport);
466                 ifport->mISDNport = 0;
467                 ifport->block = 2;
468                 goto out;
469         }
470         
471         /* port new blocking state */
472         ifport->block = response->am[0].u.x.block = block;
473
474         out:
475         /* attach to response chain */
476         *responsep = response;
477         responsep = &response->next;
478         return(0);
479 }
480
481
482 /*
483  * do release
484  */
485 int admin_release(struct admin_queue **responsep, char *message)
486 {
487         unsigned int            id;
488         struct admin_queue      *response;      /* response pointer */
489         class EndpointAppPBX    *apppbx;
490
491         /* create state response */
492         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
493         memuse++;
494         response->num = 1;
495         /* message */
496         response->am[0].message = ADMIN_RESPONSE_CMD_RELEASE;
497
498         id = atoi(message);
499         apppbx = apppbx_first;
500         while(apppbx)
501         {
502                 if (apppbx->ea_endpoint->ep_serial == id)
503                         break;
504                 apppbx = apppbx->next;
505         }
506         if (!apppbx)
507         {
508                 response->am[0].u.x.error = -EINVAL;
509                 SPRINT(response->am[0].u.x.message, "Given endpoint %d doesn't exist.", id);
510                 goto out;
511         }
512
513         apppbx->e_callback = 0;
514         apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
515
516         out:
517         /* attach to response chain */
518         *responsep = response;
519         responsep = &response->next;
520         return(0);
521 }
522
523
524 /*
525  * do call
526  */
527 int admin_call(struct admin_list *admin, struct admin_message *msg)
528 {
529         class Endpoint          *epoint;
530         class EndpointAppPBX    *apppbx;
531
532         if (!(epoint = new Endpoint(0, 0)))
533                 FATAL("No memory for Endpoint instance\n");
534         if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing
535                 FATAL("No memory for Endpoint Application instance\n");
536         apppbx->e_adminid = admin->sockserial;
537         admin->epointid = epoint->ep_serial;
538         SCPY(apppbx->e_callerinfo.id, nationalize_callerinfo(msg->u.call.callerid, &apppbx->e_callerinfo.ntype, options.national, options.international));
539         if (msg->u.call.present)
540                 apppbx->e_callerinfo.present = INFO_PRESENT_ALLOWED;
541         else
542                 apppbx->e_callerinfo.present = INFO_PRESENT_RESTRICTED;
543         apppbx->e_callerinfo.screen = INFO_SCREEN_NETWORK;
544
545 //printf("hh=%d\n", apppbx->e_capainfo.hlc);
546
547         apppbx->e_capainfo.bearer_capa = msg->u.call.bc_capa;
548         apppbx->e_capainfo.bearer_mode = msg->u.call.bc_mode;
549         apppbx->e_capainfo.bearer_info1 = msg->u.call.bc_info1;
550         apppbx->e_capainfo.hlc = msg->u.call.hlc;
551         apppbx->e_capainfo.exthlc = msg->u.call.exthlc;
552         SCPY(apppbx->e_dialinginfo.id, msg->u.call.dialing);
553         SCPY(apppbx->e_dialinginfo.interfaces, msg->u.call.interface);
554         apppbx->e_dialinginfo.sending_complete = 1;
555
556         apppbx->new_state(PORT_STATE_OUT_SETUP);
557         apppbx->out_setup();
558         return(0);
559 }
560
561
562 /*
563  * this function is called for response whenever a call state changes.
564  */
565 void admin_call_response(int adminid, int message, char *connected, int cause, int location, int notify)
566 {
567         struct admin_list       *admin;
568         struct admin_queue      *response, **responsep; /* response pointer */
569
570         /* searching for admin id
571          * maybe there is no admin instance, because the calling port was not
572          * initiated by admin_call */
573         admin = admin_first;
574         while(admin)
575         {
576                 if (adminid == admin->sockserial)
577                         break;
578                 admin = admin->next;
579         }
580         if (!admin)
581                 return;
582
583         /* seek to end of response list */
584         response = admin->response;
585         responsep = &admin->response;
586         while(response)
587         {
588                 responsep = &response->next;
589                 response = response->next;
590         }
591
592         /* create state response */
593         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
594         memuse++;
595         response->num = 1;
596         /* message */
597         response->am[0].message = message;
598 //      printf("MESSAGE: %d\n", message);
599
600         SCPY(response->am[0].u.call.callerid, connected);
601         response->am[0].u.call.cause = cause;
602         response->am[0].u.call.location = location;
603         response->am[0].u.call.notify = notify;
604
605         /* attach to response chain */
606         *responsep = response;
607         responsep = &response->next;
608 }
609
610
611 /*
612  * send data to the remote socket join instance
613  */
614 int admin_message_to_join(struct admin_msg *msg, struct admin_list *admin)
615 {
616         class Join                      *join;
617         struct admin_list               *temp;
618
619         /* hello message */
620         if (msg->type == MESSAGE_HELLO)
621         {
622                 if (admin->remote_name[0])
623                 {
624                         PERROR("Remote application repeats hello message.\n");
625                         return(-1);
626                 }
627                 /* look for second application */
628                 temp = admin_first;
629                 while(temp)
630                 {
631                         if (!strcmp(temp->remote_name, msg->param.hello.application))
632                                 break;
633                         temp = temp->next;
634                 }
635                 if (temp)
636                 {
637                         PERROR("Remote application connects twice??? (ignoring)\n");
638                         return(-1);
639                 }
640                 /* set remote socket instance */
641                 SCPY(admin->remote_name, msg->param.hello.application);
642                 start_trace(0,
643                         NULL,
644                         NULL,
645                         NULL,
646                         DIRECTION_NONE,
647                         0,
648                         0,
649                         "REMOTE APP registers");
650                 add_trace("app", "name", "%s", admin->remote_name);
651                 end_trace();
652                 return(0);
653         }
654
655         /* check we have no application name */
656         if (!admin->remote_name[0])
657         {
658                 PERROR("Remote application did not send us a hello message.\n");
659                 return(-1);
660         }
661
662         /* new join */
663         if (msg->type == MESSAGE_NEWREF)
664         {
665                 /* create new join instance */
666                 join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
667                 if (!join)
668                 {
669                         FATAL("No memory for remote join instance\n");
670                         return(-1);
671                 }
672                 return(0);
673         }
674
675         /* bchannel message
676          * no ref given for *_ack */
677         if (msg->type == MESSAGE_BCHANNEL)
678         if (msg->param.bchannel.type == BCHANNEL_ASSIGN_ACK
679          || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK
680          || msg->param.bchannel.type == BCHANNEL_RELEASE)
681         {
682                 /* no ref, but address */
683                 message_bchannel_from_remote(NULL, msg->param.bchannel.type, msg->param.bchannel.handle);
684                 return(0);
685         }
686         
687         /* check for ref */
688         if (!msg->ref)
689         {
690                 PERROR("Remote application did not send us a valid ref with a message.\n");
691                 return(-1);
692         }
693
694         /* find join instance */
695         join = join_first;
696         while(join)
697         {
698                 if (join->j_serial == msg->ref)
699                         break;
700                 join = join->next;
701         }
702         if (!join)
703         {
704                 PERROR("No join found with serial %d.\n", msg->ref);
705                 return(-1);
706         }
707
708         /* check application */
709         if (join->j_type != JOIN_TYPE_REMOTE)
710         {
711                 PERROR("Ref %d does not belong to a remote join instance.\n", msg->ref);
712                 return(-1);
713         }
714         if (admin->sock != ((class JoinRemote *)join)->j_remote_id)
715         {
716                 PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote_name, admin->remote_name);
717                 return(-1);
718         }
719
720         /* send message */
721         ((class JoinRemote *)join)->message_remote(msg->type, &msg->param);
722
723         return(0);
724 }
725
726
727 /*
728  * this function is called for every message to remote socket
729  */
730 int admin_message_from_join(int remote_id, unsigned int ref, int message_type, union parameter *param)
731 {
732         struct admin_list       *admin;
733         struct admin_queue      **responsep;    /* response pointer */
734
735         /* searching for admin id
736          * maybe there is no given remote application
737          */
738         admin = admin_first;
739         while(admin)
740         {
741                 if (admin->remote_name[0] && admin->sock==remote_id)
742                         break;
743                 admin = admin->next;
744         }
745         /* no given remote application connected */
746         if (!admin)
747                 return(-1);
748
749         /* seek to end of response list */
750         responsep = &admin->response;
751         while(*responsep)
752         {
753                 responsep = &(*responsep)->next;
754         }
755
756         /* create state response */
757         *responsep = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
758         memuse++;
759         (*responsep)->num = 1;
760
761         /* message */
762         (*responsep)->am[0].message = ADMIN_MESSAGE;
763         (*responsep)->am[0].u.msg.type = message_type;
764         (*responsep)->am[0].u.msg.ref = ref;
765         memcpy(&(*responsep)->am[0].u.msg.param, param, sizeof(union parameter));
766
767         return(0);
768 }
769
770
771 /*
772  * do state debugging
773  */
774 int admin_state(struct admin_queue **responsep)
775 {
776
777         class Port              *port;
778         class EndpointAppPBX    *apppbx;
779         class Join              *join;
780         class Pdss1             *pdss1;
781         struct interface        *interface;
782         struct interface_port   *ifport;
783         struct mISDNport        *mISDNport;
784         int                     i;
785         int                     num;
786         int                     anybusy;
787         struct admin_queue      *response;
788         struct admin_list       *admin;
789
790         /* create state response */
791         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
792         memuse++;
793         response->num = 1;
794         /* message */
795         response->am[0].message = ADMIN_RESPONSE_STATE;
796         /* version */
797         SCPY(response->am[0].u.s.version_string, VERSION_STRING);
798         /* time */
799         memcpy(&response->am[0].u.s.tm, now_tm, sizeof(struct tm));
800         /* log file */
801         SCPY(response->am[0].u.s.logfile, options.log);
802         /* interface count */
803         i = 0;
804         interface = interface_first;
805         while(interface)
806         {
807                 ifport = interface->ifport;
808                 while(ifport)
809                 {
810                         i++;
811                         ifport = ifport->next;
812                 }
813                 interface = interface->next;
814         }
815         response->am[0].u.s.interfaces = i;
816         /* remote connection count */
817         i = 0;
818         admin = admin_first;
819         while(admin)
820         {
821                 if (admin->remote_name[0])
822                         i++;
823                 admin = admin->next;
824         }
825         response->am[0].u.s.remotes = i;
826         /* join count */
827         join = join_first;
828         i = 0;
829         while(join)
830         {
831                 i++;
832                 join = join->next;
833         }
834         response->am[0].u.s.joins = i;
835         /* apppbx count */
836         apppbx = apppbx_first;
837         i = 0;
838         while(apppbx)
839         {
840                 i++;
841                 apppbx = apppbx->next;
842         }
843         response->am[0].u.s.epoints = i;
844         /* port count */
845         i = 0;
846         port = port_first;
847         while(port)
848         {
849                 i++;
850                 port = port->next;
851         }
852         response->am[0].u.s.ports = i;
853         /* attach to response chain */
854         *responsep = response;
855         responsep = &response->next;
856
857         /* create response for all instances */
858         num = (response->am[0].u.s.interfaces)
859             + (response->am[0].u.s.remotes)
860             + (response->am[0].u.s.joins)
861             + (response->am[0].u.s.epoints)
862             + (response->am[0].u.s.ports);
863         if (num == 0)
864                 return(0);
865         response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message)));
866         memuse++;
867         response->num = num;
868         *responsep = response;
869         responsep = &response->next;
870         interface = interface_first;
871         num = 0;
872         while(interface)
873         {
874                 ifport = interface->ifport;
875                 while(ifport)
876                 {
877                         /* message */
878                         response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
879                         /* interface */
880                         SCPY(response->am[num].u.i.interface_name, interface->name);
881                         /* portnum */
882                         response->am[num].u.i.portnum = ifport->portnum;
883                         /* iftype */
884                         response->am[num].u.i.extension = interface->extension;
885                         /* block */
886                         response->am[num].u.i.block = ifport->block;
887                         if (ifport->mISDNport)
888                         {
889                                 mISDNport = ifport->mISDNport;
890
891                                 /* ptp */
892                                 response->am[num].u.i.ptp = mISDNport->ptp;
893                                 /* ntmode */
894                                 response->am[num].u.i.ntmode = mISDNport->ntmode;
895                                 /* pri */
896                                 response->am[num].u.i.pri = mISDNport->pri;
897                                 /* use */
898                                 response->am[num].u.i.use = mISDNport->use;
899                                 /* l1link */
900                                 response->am[num].u.i.l1link = mISDNport->l1link;
901                                 /* l2link */
902                                 response->am[num].u.i.l2link = mISDNport->l2link;
903                                 /* los */
904                                 response->am[num].u.i.los = mISDNport->los;
905                                 /* ais */
906                                 response->am[num].u.i.ais = mISDNport->ais;
907                                 /* rdi */
908                                 response->am[num].u.i.rdi = mISDNport->rdi;
909                                 /* slip */
910                                 response->am[num].u.i.slip_tx = mISDNport->slip_tx;
911                                 response->am[num].u.i.slip_rx = mISDNport->slip_rx;
912                                 /* channels */
913                                 response->am[num].u.i.channels = mISDNport->b_num;
914                                 /* channel info */
915                                 i = 0;
916                                 anybusy = 0;
917                                 while(i < mISDNport->b_num)
918                                 {
919                                         response->am[num].u.i.busy[i] = mISDNport->b_state[i];
920                                         if (mISDNport->b_port[i])
921                                                 response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial;
922                                         i++;
923                                 }
924                         }
925                         num++;
926
927                         ifport = ifport->next;
928                 }
929                 interface = interface->next;
930         }
931
932         /* create response for all remotes */
933         admin = admin_first;
934         while(admin)
935         {
936                 if (admin->remote_name[0])
937                 {
938                         /* message */
939                         response->am[num].message = ADMIN_RESPONSE_S_REMOTE;
940                         /* name */
941                         SCPY(response->am[num].u.r.name, admin->remote_name);
942                         /* */
943                         num++;
944                 }
945                 admin = admin->next;
946         }
947
948         /* create response for all joins */
949         join = join_first;
950         while(join)
951         {
952                 /* message */
953                 response->am[num].message = ADMIN_RESPONSE_S_JOIN;
954                 /* serial */
955                 response->am[num].u.j.serial = join->j_serial;
956                 /* partyline */
957                 if (join->j_type == JOIN_TYPE_PBX)
958                         response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
959                 /* remote application */
960                 if (join->j_type == JOIN_TYPE_REMOTE)
961                         SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote_name);
962                 /* */
963                 join = join->next;
964                 num++;
965         }
966
967         /* create response for all endpoint */
968         apppbx = apppbx_first;
969         while(apppbx)
970         {
971                 /* message */
972                 response->am[num].message = ADMIN_RESPONSE_S_EPOINT;
973                 /* serial */
974                 response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial;
975                 /* join */
976                 response->am[num].u.e.join = apppbx->ea_endpoint->ep_join_id;
977                 /* rx notification */
978                 response->am[num].u.e.rx_state = apppbx->e_rx_state;
979                 /* tx notification */
980                 response->am[num].u.e.tx_state = apppbx->e_tx_state;
981                 /* state */
982                 switch(apppbx->e_state)
983                 {
984                         case EPOINT_STATE_IN_SETUP:
985                         response->am[num].u.e.state = ADMIN_STATE_IN_SETUP;
986                         break;
987                         case EPOINT_STATE_OUT_SETUP:
988                         response->am[num].u.e.state = ADMIN_STATE_OUT_SETUP;
989                         break;
990                         case EPOINT_STATE_IN_OVERLAP:
991                         response->am[num].u.e.state = ADMIN_STATE_IN_OVERLAP;
992                         break;
993                         case EPOINT_STATE_OUT_OVERLAP:
994                         response->am[num].u.e.state = ADMIN_STATE_OUT_OVERLAP;
995                         break;
996                         case EPOINT_STATE_IN_PROCEEDING:
997                         response->am[num].u.e.state = ADMIN_STATE_IN_PROCEEDING;
998                         break;
999                         case EPOINT_STATE_OUT_PROCEEDING:
1000                         response->am[num].u.e.state = ADMIN_STATE_OUT_PROCEEDING;
1001                         break;
1002                         case EPOINT_STATE_IN_ALERTING:
1003                         response->am[num].u.e.state = ADMIN_STATE_IN_ALERTING;
1004                         break;
1005                         case EPOINT_STATE_OUT_ALERTING:
1006                         response->am[num].u.e.state = ADMIN_STATE_OUT_ALERTING;
1007                         break;
1008                         case EPOINT_STATE_CONNECT:
1009                         response->am[num].u.e.state = ADMIN_STATE_CONNECT;
1010                         break;
1011                         case EPOINT_STATE_IN_DISCONNECT:
1012                         response->am[num].u.e.state = ADMIN_STATE_IN_DISCONNECT;
1013                         break;
1014                         case EPOINT_STATE_OUT_DISCONNECT:
1015                         response->am[num].u.e.state = ADMIN_STATE_OUT_DISCONNECT;
1016                         break;
1017                         default:
1018                         response->am[num].u.e.state = ADMIN_STATE_IDLE;
1019                 }
1020                 /* terminal */
1021                 SCPY(response->am[num].u.e.terminal, apppbx->e_ext.number);
1022                 /* callerid */
1023                 SCPY(response->am[num].u.e.callerid, apppbx->e_callerinfo.id);
1024                 /* dialing */
1025                 SCPY(response->am[num].u.e.dialing, apppbx->e_dialinginfo.id);
1026                 /* action string */
1027                 if (apppbx->e_action)
1028                         SCPY(response->am[num].u.e.action, action_defs[apppbx->e_action->index].name);
1029 //              if (apppbx->e_action)
1030 //              printf("action=%s\n",action_defs[apppbx->e_action->index].name);
1031                 /* park */
1032                 response->am[num].u.e.park = apppbx->ea_endpoint->ep_park;
1033                 if (apppbx->ea_endpoint->ep_park && apppbx->ea_endpoint->ep_park_len && apppbx->ea_endpoint->ep_park_len<=(int)sizeof(response->am[num].u.e.park_callid))
1034                         memcpy(response->am[num].u.e.park_callid, apppbx->ea_endpoint->ep_park_callid, apppbx->ea_endpoint->ep_park_len);
1035                 response->am[num].u.e.park_len = apppbx->ea_endpoint->ep_park_len;
1036                 /* crypt */
1037                 if (apppbx->e_crypt == CRYPT_ON)
1038                         response->am[num].u.e.crypt = 1;
1039                 /* */
1040                 apppbx = apppbx->next;
1041                 num++;
1042         }
1043
1044         /* create response for all ports */
1045         port = port_first;
1046         while(port)
1047         {
1048                 /* message */
1049                 response->am[num].message = ADMIN_RESPONSE_S_PORT;
1050                 /* serial */
1051                 response->am[num].u.p.serial = port->p_serial;
1052                 /* name */
1053                 SCPY(response->am[num].u.p.name, port->p_name);
1054                 /* epoint */
1055                 response->am[num].u.p.epoint = ACTIVE_EPOINT(port->p_epointlist);
1056                 /* state */
1057                 switch(port->p_state)
1058                 {
1059                         case PORT_STATE_IN_SETUP:
1060                         response->am[num].u.p.state = ADMIN_STATE_IN_SETUP;
1061                         break;
1062                         case PORT_STATE_OUT_SETUP:
1063                         response->am[num].u.p.state = ADMIN_STATE_OUT_SETUP;
1064                         break;
1065                         case PORT_STATE_IN_OVERLAP:
1066                         response->am[num].u.p.state = ADMIN_STATE_IN_OVERLAP;
1067                         break;
1068                         case PORT_STATE_OUT_OVERLAP:
1069                         response->am[num].u.p.state = ADMIN_STATE_OUT_OVERLAP;
1070                         break;
1071                         case PORT_STATE_IN_PROCEEDING:
1072                         response->am[num].u.p.state = ADMIN_STATE_IN_PROCEEDING;
1073                         break;
1074                         case PORT_STATE_OUT_PROCEEDING:
1075                         response->am[num].u.p.state = ADMIN_STATE_OUT_PROCEEDING;
1076                         break;
1077                         case PORT_STATE_IN_ALERTING:
1078                         response->am[num].u.p.state = ADMIN_STATE_IN_ALERTING;
1079                         break;
1080                         case PORT_STATE_OUT_ALERTING:
1081                         response->am[num].u.p.state = ADMIN_STATE_OUT_ALERTING;
1082                         break;
1083                         case PORT_STATE_CONNECT:
1084                         response->am[num].u.p.state = ADMIN_STATE_CONNECT;
1085                         break;
1086                         case PORT_STATE_IN_DISCONNECT:
1087                         response->am[num].u.p.state = ADMIN_STATE_IN_DISCONNECT;
1088                         break;
1089                         case PORT_STATE_OUT_DISCONNECT:
1090                         response->am[num].u.p.state = ADMIN_STATE_OUT_DISCONNECT;
1091                         break;
1092                         default:
1093                         response->am[num].u.p.state = ADMIN_STATE_IDLE;
1094                 }
1095                 /* isdn */
1096                 if ((port->p_type&PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1)
1097                 {
1098                         response->am[num].u.p.isdn = 1;
1099                         pdss1 = (class Pdss1 *)port;
1100                         response->am[num].u.p.isdn_chan = pdss1->p_m_b_channel;
1101                         response->am[num].u.p.isdn_hold = pdss1->p_m_hold;
1102                         response->am[num].u.p.isdn_ces = pdss1->p_m_d_ces;
1103                 }
1104                 /* */
1105                 port = port->next;
1106                 num++;
1107         }
1108         return(0);
1109 }
1110
1111 int sockserial = 1; // must start with 1, because 0 is used if no serial is set
1112 /*
1113  * handle admin socket (non blocking)
1114  */
1115 int admin_handle(void)
1116 {
1117         struct admin_list       *admin, **adminp;
1118         void                    *temp;
1119         struct admin_message    msg;
1120         int                     len;
1121         int                     new_sock;
1122         socklen_t               sock_len = sizeof(sock_address);
1123         unsigned int            on = 1;
1124         int                     work = 0; /* if work was done */
1125         struct Endpoint         *epoint;
1126
1127         if (sock < 0)
1128                 return(0);
1129
1130         /* check for new incoming connections */
1131         if ((new_sock = accept(sock, (struct sockaddr *)&sock_address, &sock_len)) >= 0)
1132         {
1133                 work = 1;
1134                 /* insert new socket */
1135                 admin = (struct admin_list *)MALLOC(sizeof(struct admin_list));
1136                 if (ioctl(new_sock, FIONBIO, (unsigned char *)(&on)) >= 0)
1137                 {
1138 //#warning
1139 //      PERROR("DEBUG incoming socket %d, serial=%d\n", new_sock, sockserial);
1140                         memuse++;
1141                         fhuse++;
1142                         admin->sockserial = sockserial++;
1143                         admin->next = admin_first;
1144                         admin_first = admin;
1145                         admin->sock = new_sock;
1146                 } else {
1147                         close(new_sock);
1148                         FREE(admin, sizeof(struct admin_list));
1149                 }
1150         } else
1151         {
1152                 if (errno != EWOULDBLOCK)
1153                 {
1154                         PERROR("Failed to accept connection from socket \"%s\". (errno=%d) Closing socket.\n", sock_address.sun_path, errno);
1155                         admin_cleanup();
1156                         return(1);
1157                 }
1158         }
1159
1160         /* loop all current socket connections */
1161         admin = admin_first;
1162         adminp = &admin_first;
1163         while(admin)
1164         {
1165                 /* read command */
1166                 len = read(admin->sock, &msg, sizeof(msg));
1167                 if (len < 0)
1168                 {
1169                         if (errno != EWOULDBLOCK)
1170                         {
1171                                 work = 1;
1172                                 brokenpipe:
1173                                 printf("Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
1174                                 PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
1175                                 *adminp = admin->next;
1176                                 free_connection(admin);
1177                                 admin = *adminp;
1178                                 continue;
1179                         }
1180                         goto send_data;
1181                 }
1182                 work = 1;
1183 //#warning
1184 //PERROR("DEBUG socket %d got data. serial=%d\n", admin->sock, admin->sockserial);
1185                 if (len == 0)
1186                 {
1187                         end:
1188
1189                         /*release endpoint if exists */
1190                         if (admin->epointid)
1191                         {
1192                                 epoint = find_epoint_id(admin->epointid);
1193                                 if (epoint)
1194                                 {
1195                                         ((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)->
1196                                                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
1197                                 }
1198                         }
1199
1200 //#warning
1201 //PERROR("DEBUG socket %d closed by remote.\n", admin->sock);
1202                         *adminp = admin->next;
1203                         free_connection(admin);
1204                         admin = *adminp;
1205 //PERROR("DEBUG (admin_first=%x)\n", admin_first);
1206                         continue;
1207                 }
1208                 if (len != sizeof(msg))
1209                 {
1210                         PERROR("Short/long read on socket %d. (len=%d != size=%d).\n", admin->sock, len, sizeof(msg));
1211                         *adminp = admin->next;
1212                         free_connection(admin);
1213                         admin = *adminp;
1214                         continue;
1215                 }
1216                 /* process socket command */
1217                 if (admin->response && msg.message != ADMIN_MESSAGE)
1218                 {
1219                         PERROR("Data from socket %d while sending response.\n", admin->sock);
1220                         *adminp = admin->next;
1221                         free_connection(admin);
1222                         admin = *adminp;
1223                         continue;
1224                 }
1225                 switch (msg.message)
1226                 {
1227                         case ADMIN_REQUEST_CMD_INTERFACE:
1228                         if (admin_interface(&admin->response) < 0)
1229                         {
1230                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1231                                 goto response_error;
1232                         }
1233                         break;
1234
1235                         case ADMIN_REQUEST_CMD_ROUTE:
1236                         if (admin_route(&admin->response) < 0)
1237                         {
1238                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1239                                 goto response_error;
1240                         }
1241                         break;
1242
1243                         case ADMIN_REQUEST_CMD_DIAL:
1244                         if (admin_dial(&admin->response, msg.u.x.message) < 0)
1245                         {
1246                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1247                                 goto response_error;
1248                         }
1249                         break;
1250
1251                         case ADMIN_REQUEST_CMD_RELEASE:
1252                         if (admin_release(&admin->response, msg.u.x.message) < 0)
1253                         {
1254                                 PERROR("Failed to create release response for socket %d.\n", admin->sock);
1255                                 goto response_error;
1256                         }
1257                         break;
1258
1259                         case ADMIN_REQUEST_STATE:
1260                         if (admin_state(&admin->response) < 0)
1261                         {
1262                                 PERROR("Failed to create state response for socket %d.\n", admin->sock);
1263                                 goto response_error;
1264                         }
1265                         break;
1266
1267                         case ADMIN_TRACE_REQUEST:
1268                         if (admin_trace(admin, &msg.u.trace_req) < 0)
1269                         {
1270                                 PERROR("Failed to create trace response for socket %d.\n", admin->sock);
1271                                 goto response_error;
1272                         }
1273                         break;
1274
1275                         case ADMIN_REQUEST_CMD_BLOCK:
1276                         if (admin_block(&admin->response, msg.u.x.portnum, msg.u.x.block) < 0)
1277                         {
1278                                 PERROR("Failed to create block response for socket %d.\n", admin->sock);
1279                                 goto response_error;
1280                         }
1281                         break;
1282
1283                         case ADMIN_MESSAGE:
1284                         if (admin_message_to_join(&msg.u.msg, admin) < 0)
1285                         {
1286                                 PERROR("Failed to deliver message for socket %d.\n", admin->sock);
1287                                 goto response_error;
1288                         }
1289 #if 0
1290 #warning DEBUGGING
1291 {
1292         struct admin_queue      *response;
1293         printf("Chain: ");
1294         response = admin->response;
1295         while(response)
1296         {
1297                 printf("%c", '0'+response->am[0].message);
1298                 response=response->next;
1299         }
1300         printf("\n");
1301 }
1302 #endif
1303                         break;
1304
1305                         case ADMIN_CALL_SETUP:
1306                         if (admin_call(admin, &msg) < 0)
1307                         {
1308                                 PERROR("Failed to create call for socket %d.\n", admin->sock);
1309                                 response_error:
1310                                 *adminp = admin->next;
1311                                 free_connection(admin);
1312                                 admin = *adminp;
1313                                 continue;
1314                         }
1315                         break;
1316
1317                         default:
1318                         PERROR("Invalid message %d from socket %d.\n", msg.message, admin->sock);
1319                         *adminp = admin->next;
1320                         free_connection(admin);
1321                         admin = *adminp;
1322                         continue;
1323                 }
1324                 /* write queue */
1325                 send_data:
1326                 if (admin->response)
1327                 {
1328 //#warning
1329 //PERROR("DEBUG socket %d sending data.\n", admin->sock);
1330                         len = write(admin->sock, ((unsigned char *)(admin->response->am))+admin->response->offset, sizeof(struct admin_message)*(admin->response->num)-admin->response->offset);
1331                         if (len < 0)
1332                         {
1333                                 if (errno != EWOULDBLOCK)
1334                                 {
1335                                         work = 1;
1336                                         goto brokenpipe;
1337                                 }
1338                                 goto next;
1339                         }
1340                         work = 1;
1341                         if (len == 0)
1342                                 goto end;
1343                         if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset))
1344                         {
1345                                 admin->response->offset+=len;
1346                                 goto next;
1347                         } else
1348                         {
1349                                 temp = admin->response;
1350                                 admin->response = admin->response->next;
1351                                 FREE(temp, 0);
1352                                 memuse--;
1353                         }
1354                 }
1355                 /* done with socket instance */
1356                 next:
1357                 adminp = &admin->next;
1358                 admin = admin->next;
1359         }
1360
1361         return(work);
1362 }
1363