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