build: remove and ignore autogenerated files
[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 remote instance. 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                         /* interface must match the remote application */
628                         if (interface->remote && !strcmp(interface->remote_app, admin->remote_name)) {
629                                 /* interface must match the name, if given */
630                                 if (!msg->param.newref.interface[0] || !strcmp(msg->param.newref.interface, interface->name))
631                                         break;
632                         }
633                         interface = interface->next;
634                 }
635                 if (!interface) {
636                         union parameter param;
637                         unsigned int ref = new_remote++;
638
639                         start_trace(-1,
640                                 NULL,
641                                 NULL,
642                                 NULL,
643                                 DIRECTION_NONE,
644                                 0,
645                                 0,
646                                 "REMOTE APP illegal interface");
647                         add_trace("app", "name", "%s", admin->remote_name);
648                         add_trace("interface", "name", "%s", msg->param.newref.interface);
649                         end_trace();
650                         memset(&param, 0, sizeof(union parameter));
651                         param.newref.direction = 0;
652                         admin_message_from_lcr(admin->sock, ref, MESSAGE_NEWREF, &param);
653                         memset(&param, 0, sizeof(union parameter));
654                         param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
655                         param.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
656                         admin_message_from_lcr(admin->sock, ref, MESSAGE_RELEASE, &param);
657                         return 0;
658                 }
659                 /* creating port object, transparent until setup with hdlc */
660                 SPRINT(name, "%s-%s-in", interface->name, interface->remote_app);
661                 if (!(remote = new Premote(PORT_TYPE_REMOTE_IN, name, NULL, interface, admin->sock)))
662
663                         FATAL("Cannot create Port instance.\n");
664                 return(0);
665         }
666
667         /* check for ref */
668         if (!msg->ref) {
669                 PERROR("Remote application did not send us a valid ref with a message.\n");
670                 return(-1);
671         }
672
673         /* find port instance */
674         port = port_first;
675         while(port) {
676                 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_REMOTE) {
677                         remote = (class Premote *) port;
678                         if (remote->p_r_ref == msg->ref)
679                                 break;
680                 }
681                 port = port->next;
682         }
683         if (port) {
684                 if (admin->sock != remote->p_r_remote_id) {
685                         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);
686                         return(-1);
687                 }
688
689                 /* send message */
690                 remote->message_remote(msg->type, &msg->param);
691
692                 return(0);
693         }
694
695         PDEBUG(DEBUG_LOG, "No remote instance found with ref %d. (May have been already released.)\n", msg->ref);
696         return(0);
697
698 }
699
700
701 /*
702  * this function is called for every message to remote socket
703  */
704 int admin_message_from_lcr(int remote_id, unsigned int ref, int message_type, union parameter *param)
705 {
706         struct admin_list       *admin;
707         struct admin_queue      **responsep;    /* response pointer */
708
709         /* searching for admin id
710          * maybe there is no given remote application
711          */
712         admin = admin_first;
713         while(admin) {
714                 if (admin->remote_name[0] && admin->sock==remote_id)
715                         break;
716                 admin = admin->next;
717         }
718         /* no given remote application connected */
719         if (!admin)
720                 return(-1);
721
722         /* seek to end of response list */
723         responsep = &admin->response;
724         while(*responsep) {
725                 responsep = &(*responsep)->next;
726         }
727
728         /* create state response */
729         *responsep = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
730         memuse++;
731         (*responsep)->num = 1;
732
733         /* message */
734         (*responsep)->am[0].message = ADMIN_MESSAGE;
735         (*responsep)->am[0].u.msg.type = message_type;
736         (*responsep)->am[0].u.msg.ref = ref;
737         memcpy(&(*responsep)->am[0].u.msg.param, param, sizeof(union parameter));
738         admin->fd.when |= LCR_FD_WRITE;
739         return(0);
740 }
741
742
743 /*
744  * do state debugging
745  */
746 int admin_state(struct admin_queue **responsep)
747 {
748         class Port              *port;
749         class EndpointAppPBX    *apppbx;
750         class Join              *join;
751 #ifdef WITH_MISDN
752         class Pdss1             *pdss1;
753         struct mISDNport        *mISDNport;
754         struct select_channel   *selchannel;
755         int                     anybusy;
756 #endif
757         struct interface        *interface;
758         struct interface_port   *ifport;
759         int                     i;
760         int                     num;
761         struct admin_queue      *response;
762         struct admin_list       *admin;
763         struct tm               *now_tm;
764         time_t                  now;
765
766         /* create state response */
767         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
768         memuse++;
769         response->num = 1;
770         /* message */
771         response->am[0].message = ADMIN_RESPONSE_STATE;
772         /* version */
773         SCPY(response->am[0].u.s.version_string, VERSION_STRING);
774         /* time */
775         time(&now);
776         now_tm = localtime(&now);
777         memcpy(&response->am[0].u.s.tm, now_tm, sizeof(struct tm));
778         /* log file */
779         SCPY(response->am[0].u.s.logfile, options.log);
780         /* interface count */
781         i = 0;
782         interface = interface_first;
783         while(interface) {
784                 ifport = interface->ifport;
785                 if (!ifport)
786                         i++;
787                 while(ifport) {
788                         i++;
789                         ifport = ifport->next;
790                 }
791                 interface = interface->next;
792         }
793         response->am[0].u.s.interfaces = i;
794         /* remote connection count */
795         i = 0;
796         admin = admin_first;
797         while(admin) {
798                 if (admin->remote_name[0])
799                         i++;
800                 admin = admin->next;
801         }
802         response->am[0].u.s.remotes = i;
803         /* join count */
804         join = join_first;
805         i = 0;
806         while(join) {
807                 i++;
808                 join = join->next;
809         }
810         response->am[0].u.s.joins = i;
811         /* apppbx count */
812         apppbx = apppbx_first;
813         i = 0;
814         while(apppbx) {
815                 i++;
816                 apppbx = apppbx->next;
817         }
818         response->am[0].u.s.epoints = i;
819         /* port count */
820         i = 0;
821         port = port_first;
822         while(port) {
823                 i++;
824                 port = port->next;
825         }
826         response->am[0].u.s.ports = i;
827         /* attach to response chain */
828         *responsep = response;
829         responsep = &response->next;
830
831         /* create response for all instances */
832         num = (response->am[0].u.s.interfaces)
833             + (response->am[0].u.s.remotes)
834             + (response->am[0].u.s.joins)
835             + (response->am[0].u.s.epoints)
836             + (response->am[0].u.s.ports);
837         if (num == 0)
838                 return(0);
839         response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message)));
840         memuse++;
841         response->num = num;
842         *responsep = response;
843         responsep = &response->next;
844         interface = interface_first;
845         num = 0;
846         while(interface) {
847                 ifport = interface->ifport;
848                 if (!ifport) {
849                         /* message */
850                         response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
851                         /* interface */
852                         SCPY(response->am[num].u.i.interface_name, interface->name);
853                         /* portnum */
854                         response->am[num].u.i.portnum = -100; /* indicate: no ifport */
855                         /* iftype */
856                         response->am[num].u.i.extension = interface->extension;
857                         /* block */
858                         num++;
859                 }
860                 while(ifport) {
861                         /* message */
862                         response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
863                         /* interface */
864                         SCPY(response->am[num].u.i.interface_name, interface->name);
865                         /* portnum */
866                         response->am[num].u.i.portnum = ifport->portnum;
867                         /* portname */
868                         SCPY(response->am[num].u.i.portname, ifport->portname);
869                         /* iftype */
870                         response->am[num].u.i.extension = interface->extension;
871                         /* block */
872                         response->am[num].u.i.block = ifport->block;
873 #ifdef WITH_MISDN
874                         if (ifport->mISDNport) {
875                                 mISDNport = ifport->mISDNport;
876
877                                 /* ptp */
878                                 response->am[num].u.i.ptp = mISDNport->ptp;
879                                 /* l1hold */
880                                 response->am[num].u.i.l1hold = mISDNport->l1hold;
881                                 /* l2hold */
882                                 response->am[num].u.i.l2hold = mISDNport->l2hold;
883                                 /* ntmode */
884                                 response->am[num].u.i.ntmode = mISDNport->ntmode;
885                                 /* pri */
886                                 response->am[num].u.i.pri = mISDNport->pri;
887                                 /* use */
888                                 response->am[num].u.i.use = mISDNport->use;
889                                 /* l1link */
890                                 response->am[num].u.i.l1link = mISDNport->l1link;
891                                 /* l2link */
892                                 response->am[num].u.i.l2link = mISDNport->l2link;
893                                 memcpy(response->am[num].u.i.l2mask, mISDNport->l2mask, 16);
894                                 /* los */
895                                 response->am[num].u.i.los = mISDNport->los;
896                                 /* ais */
897                                 response->am[num].u.i.ais = mISDNport->ais;
898                                 /* rdi */
899                                 response->am[num].u.i.rdi = mISDNport->rdi;
900                                 /* slip */
901                                 response->am[num].u.i.slip_tx = mISDNport->slip_tx;
902                                 response->am[num].u.i.slip_rx = mISDNport->slip_rx;
903                                 /* channels */
904                                 response->am[num].u.i.channels = mISDNport->b_num;
905                                 /* channel selection */
906                                 selchannel = ifport->out_channel;
907                                 if (ifport->channel_force)
908                                         SCAT(response->am[num].u.i.out_channel, "force");
909                                 while (selchannel) {
910                                         if (response->am[num].u.i.out_channel[0])
911                                                 SCAT(response->am[num].u.i.out_channel, ",");
912                                         switch (selchannel->channel) {
913                                         case CHANNEL_NO:
914                                                 SCAT(response->am[num].u.i.out_channel, "no");
915                                                 break;
916                                         case CHANNEL_ANY:
917                                                 SCAT(response->am[num].u.i.out_channel, "any");
918                                                 break;
919                                         case CHANNEL_FREE:
920                                                 SCAT(response->am[num].u.i.out_channel, "free");
921                                                 break;
922                                         default:
923                                                 SPRINT(strchr(response->am[num].u.i.out_channel, '\0'), "%d", selchannel->channel);
924                                         }
925                                         selchannel = selchannel->next;
926                                 }
927                                 selchannel = ifport->in_channel;
928                                 while (selchannel) {
929                                         switch (selchannel->channel) {
930                                         case CHANNEL_FREE:
931                                                 SCAT(response->am[num].u.i.in_channel, "free");
932                                                 break;
933                                         default:
934                                                 SPRINT(strchr(response->am[num].u.i.in_channel, '\0'), "%d", selchannel->channel);
935                                         }
936                                         selchannel = selchannel->next;
937                                 }
938                                 /* channel state */
939                                 i = 0;
940                                 anybusy = 0;
941                                 while(i < mISDNport->b_num) {
942                                         response->am[num].u.i.busy[i] = mISDNport->b_state[i];
943                                         if (mISDNport->b_port[i])
944                                                 response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial;
945                                         response->am[num].u.i.mode[i] = mISDNport->b_mode[i];
946                                         i++;
947                                 }
948                         }
949 #endif
950                         num++;
951
952                         ifport = ifport->next;
953                 }
954                 interface = interface->next;
955         }
956
957         /* create response for all remotes */
958         admin = admin_first;
959         while(admin) {
960                 if (admin->remote_name[0]) {
961                         /* message */
962                         response->am[num].message = ADMIN_RESPONSE_S_REMOTE;
963                         /* name */
964                         SCPY(response->am[num].u.r.name, admin->remote_name);
965                         /* */
966                         num++;
967                 }
968                 admin = admin->next;
969         }
970
971         /* create response for all joins */
972         join = join_first;
973         while(join) {
974                 /* message */
975                 response->am[num].message = ADMIN_RESPONSE_S_JOIN;
976                 /* serial */
977                 response->am[num].u.j.serial = join->j_serial;
978                 /* partyline */
979                 if (join->j_type == JOIN_TYPE_PBX) {
980                         response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
981                         response->am[num].u.j.threepty = ((class JoinPBX *)join)->j_3pty;
982                 }
983                 /* */
984                 join = join->next;
985                 num++;
986         }
987
988         /* create response for all endpoint */
989         apppbx = apppbx_first;
990         while(apppbx) {
991                 /* message */
992                 response->am[num].message = ADMIN_RESPONSE_S_EPOINT;
993                 /* serial */
994                 response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial;
995                 /* join */
996                 response->am[num].u.e.join = apppbx->ea_endpoint->ep_join_id;
997                 /* rx notification */
998                 response->am[num].u.e.rx_state = apppbx->e_rx_state;
999                 /* tx notification */
1000                 response->am[num].u.e.tx_state = apppbx->e_tx_state;
1001                 /* state */
1002                 switch(apppbx->e_state) {
1003                         case EPOINT_STATE_IN_SETUP:
1004                         response->am[num].u.e.state = ADMIN_STATE_IN_SETUP;
1005                         break;
1006                         case EPOINT_STATE_OUT_SETUP:
1007                         response->am[num].u.e.state = ADMIN_STATE_OUT_SETUP;
1008                         break;
1009                         case EPOINT_STATE_IN_OVERLAP:
1010                         response->am[num].u.e.state = ADMIN_STATE_IN_OVERLAP;
1011                         break;
1012                         case EPOINT_STATE_OUT_OVERLAP:
1013                         response->am[num].u.e.state = ADMIN_STATE_OUT_OVERLAP;
1014                         break;
1015                         case EPOINT_STATE_IN_PROCEEDING:
1016                         response->am[num].u.e.state = ADMIN_STATE_IN_PROCEEDING;
1017                         break;
1018                         case EPOINT_STATE_OUT_PROCEEDING:
1019                         response->am[num].u.e.state = ADMIN_STATE_OUT_PROCEEDING;
1020                         break;
1021                         case EPOINT_STATE_IN_ALERTING:
1022                         response->am[num].u.e.state = ADMIN_STATE_IN_ALERTING;
1023                         break;
1024                         case EPOINT_STATE_OUT_ALERTING:
1025                         response->am[num].u.e.state = ADMIN_STATE_OUT_ALERTING;
1026                         break;
1027                         case EPOINT_STATE_CONNECT:
1028                         response->am[num].u.e.state = ADMIN_STATE_CONNECT;
1029                         break;
1030                         case EPOINT_STATE_IN_DISCONNECT:
1031                         response->am[num].u.e.state = ADMIN_STATE_IN_DISCONNECT;
1032                         break;
1033                         case EPOINT_STATE_OUT_DISCONNECT:
1034                         response->am[num].u.e.state = ADMIN_STATE_OUT_DISCONNECT;
1035                         break;
1036                         default:
1037                         response->am[num].u.e.state = ADMIN_STATE_IDLE;
1038                 }
1039                 /* terminal */
1040                 SCPY(response->am[num].u.e.terminal, apppbx->e_ext.number);
1041                 /* callerid */
1042                 SCPY(response->am[num].u.e.callerid, apppbx->e_callerinfo.id);
1043                 /* dialing */
1044                 SCPY(response->am[num].u.e.dialing, apppbx->e_dialinginfo.id);
1045                 /* action string */
1046                 if (apppbx->e_action)
1047                         SCPY(response->am[num].u.e.action, action_defs[apppbx->e_action->index].name);
1048 //              if (apppbx->e_action)
1049 //              printf("action=%s\n",action_defs[apppbx->e_action->index].name);
1050                 /* park */
1051                 response->am[num].u.e.park = apppbx->ea_endpoint->ep_park;
1052                 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))
1053                         memcpy(response->am[num].u.e.park_callid, apppbx->ea_endpoint->ep_park_callid, apppbx->ea_endpoint->ep_park_len);
1054                 response->am[num].u.e.park_len = apppbx->ea_endpoint->ep_park_len;
1055 #ifdef WITH_CRYPT
1056                 /* crypt */
1057                 if (apppbx->e_crypt == CRYPT_ON)
1058                         response->am[num].u.e.crypt = 1;
1059 #endif
1060                 /* */
1061                 apppbx = apppbx->next;
1062                 num++;
1063         }
1064
1065         /* create response for all ports */
1066         port = port_first;
1067         while(port) {
1068                 /* message */
1069                 response->am[num].message = ADMIN_RESPONSE_S_PORT;
1070                 /* serial */
1071                 response->am[num].u.p.serial = port->p_serial;
1072                 /* name */
1073                 SCPY(response->am[num].u.p.name, port->p_name);
1074                 /* epoint */
1075                 response->am[num].u.p.epoint = ACTIVE_EPOINT(port->p_epointlist);
1076                 /* state */
1077                 switch(port->p_state) {
1078                         case PORT_STATE_IN_SETUP:
1079                         response->am[num].u.p.state = ADMIN_STATE_IN_SETUP;
1080                         break;
1081                         case PORT_STATE_OUT_SETUP:
1082                         response->am[num].u.p.state = ADMIN_STATE_OUT_SETUP;
1083                         break;
1084                         case PORT_STATE_IN_OVERLAP:
1085                         response->am[num].u.p.state = ADMIN_STATE_IN_OVERLAP;
1086                         break;
1087                         case PORT_STATE_OUT_OVERLAP:
1088                         response->am[num].u.p.state = ADMIN_STATE_OUT_OVERLAP;
1089                         break;
1090                         case PORT_STATE_IN_PROCEEDING:
1091                         response->am[num].u.p.state = ADMIN_STATE_IN_PROCEEDING;
1092                         break;
1093                         case PORT_STATE_OUT_PROCEEDING:
1094                         response->am[num].u.p.state = ADMIN_STATE_OUT_PROCEEDING;
1095                         break;
1096                         case PORT_STATE_IN_ALERTING:
1097                         response->am[num].u.p.state = ADMIN_STATE_IN_ALERTING;
1098                         break;
1099                         case PORT_STATE_OUT_ALERTING:
1100                         response->am[num].u.p.state = ADMIN_STATE_OUT_ALERTING;
1101                         break;
1102                         case PORT_STATE_CONNECT:
1103                         response->am[num].u.p.state = ADMIN_STATE_CONNECT;
1104                         break;
1105                         case PORT_STATE_IN_DISCONNECT:
1106                         response->am[num].u.p.state = ADMIN_STATE_IN_DISCONNECT;
1107                         break;
1108                         case PORT_STATE_OUT_DISCONNECT:
1109                         response->am[num].u.p.state = ADMIN_STATE_OUT_DISCONNECT;
1110                         break;
1111                         case PORT_STATE_RELEASE:
1112                         response->am[num].u.p.state = ADMIN_STATE_RELEASE;
1113                         break;
1114                         default:
1115                         response->am[num].u.p.state = ADMIN_STATE_IDLE;
1116                 }
1117 #ifdef WITH_MISDN
1118                 /* isdn */
1119                 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
1120                         response->am[num].u.p.isdn = 1;
1121                         pdss1 = (class Pdss1 *)port;
1122                         response->am[num].u.p.isdn_chan = pdss1->p_m_b_channel;
1123                         response->am[num].u.p.isdn_hold = pdss1->p_m_hold;
1124                         response->am[num].u.p.isdn_ces = pdss1->p_m_d_ces;
1125                 }
1126 #endif
1127                 /* */
1128                 port = port->next;
1129                 num++;
1130         }
1131         return(0);
1132 }
1133
1134 int sockserial = 1; // must start with 1, because 0 is used if no serial is set
1135 /*
1136  * handle admin socket (non blocking)
1137  */
1138 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index);
1139
1140 int admin_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1141 {
1142         int                     new_sock;
1143         socklen_t               sock_len = sizeof(sock_address);
1144         struct admin_list       *admin;
1145
1146         /* check for new incoming connections */
1147         if ((new_sock = accept(sock, (struct sockaddr *)&sock_address, &sock_len)) >= 0) {
1148                 /* insert new socket */
1149                 admin = (struct admin_list *)MALLOC(sizeof(struct admin_list));
1150                 memuse++;
1151                 fhuse++;
1152                 admin->sockserial = sockserial++;
1153                 admin->next = admin_first;
1154                 admin_first = admin;
1155                 admin->sock = new_sock;
1156                 admin->fd.fd = new_sock;
1157                 register_fd(&admin->fd, LCR_FD_READ | LCR_FD_EXCEPT, admin_handle_con, admin, 0);
1158         } else {
1159                 if (errno != EWOULDBLOCK) {
1160                         PERROR("Failed to accept connection from socket \"%s\". (errno=%d) Closing socket.\n", sock_address.sun_path, errno);
1161                         admin_cleanup();
1162                         return 0;
1163                 }
1164         }
1165
1166         return 0;
1167 }
1168
1169 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1170 {
1171         struct admin_list *admin = (struct admin_list *)instance;
1172         void                    *temp;
1173         struct admin_message    msg;
1174         int                     len;
1175         struct Endpoint         *epoint;
1176
1177         if ((what & LCR_FD_READ)) {
1178                 /* read command */
1179                 len = read(admin->sock, &msg, sizeof(msg));
1180                 if (len < 0) {
1181                         brokenpipe:
1182                         PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
1183                         end:
1184                         /*release endpoint if exists */
1185                         if (admin->epointid) {
1186                                 epoint = find_epoint_id(admin->epointid);
1187                                 if (epoint && epoint->ep_app_type == EAPP_TYPE_PBX) {
1188                                         ((class EndpointAppPBX *)epoint->ep_app)->
1189                                                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
1190                                 }
1191                         }
1192
1193                         free_connection(admin);
1194                         return 0;
1195                 }
1196                 if (len == 0)
1197                         goto end;
1198                 if (len != sizeof(msg)) {
1199                         PERROR("Short/long read on socket %d. (len=%d != size=%d).\n", admin->sock, len, sizeof(msg));
1200                         goto end;
1201                 }
1202                 /* process socket command */
1203                 if (admin->response && msg.message != ADMIN_MESSAGE) {
1204                         PERROR("Data from socket %d while sending response.\n", admin->sock);
1205                         goto end;
1206                 }
1207                 switch (msg.message) {
1208                         case ADMIN_REQUEST_CMD_INTERFACE:
1209                         if (admin_interface(&admin->response) < 0) {
1210                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1211                                 goto response_error;
1212                         }
1213                         admin->fd.when |= LCR_FD_WRITE;
1214                         break;
1215
1216                         case ADMIN_REQUEST_CMD_ROUTE:
1217                         if (admin_route(&admin->response) < 0) {
1218                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1219                                 goto response_error;
1220                         }
1221                         admin->fd.when |= LCR_FD_WRITE;
1222                         break;
1223
1224                         case ADMIN_REQUEST_CMD_DIAL:
1225                         if (admin_dial(&admin->response, msg.u.x.message) < 0) {
1226                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1227                                 goto response_error;
1228                         }
1229                         admin->fd.when |= LCR_FD_WRITE;
1230                         break;
1231
1232                         case ADMIN_REQUEST_CMD_RELEASE:
1233                         if (admin_release(&admin->response, msg.u.x.message) < 0) {
1234                                 PERROR("Failed to create release response for socket %d.\n", admin->sock);
1235                                 goto response_error;
1236                         }
1237                         admin->fd.when |= LCR_FD_WRITE;
1238                         break;
1239
1240                         case ADMIN_REQUEST_STATE:
1241                         if (admin_state(&admin->response) < 0) {
1242                                 PERROR("Failed to create state response for socket %d.\n", admin->sock);
1243                                 goto response_error;
1244                         }
1245                         admin->fd.when |= LCR_FD_WRITE;
1246                         break;
1247
1248                         case ADMIN_TRACE_REQUEST:
1249                         if (admin_trace(admin, &msg.u.trace_req) < 0) {
1250                                 PERROR("Failed to create trace response for socket %d.\n", admin->sock);
1251                                 goto response_error;
1252                         }
1253                         admin->fd.when |= LCR_FD_WRITE;
1254                         break;
1255
1256                         case ADMIN_REQUEST_CMD_BLOCK:
1257                         if (admin_block(&admin->response, msg.u.x.portnum, msg.u.x.block) < 0) {
1258                                 PERROR("Failed to create block response for socket %d.\n", admin->sock);
1259                                 goto response_error;
1260                         }
1261                         admin->fd.when |= LCR_FD_WRITE;
1262                         break;
1263
1264                         case ADMIN_MESSAGE:
1265                         if (admin_message_to_lcr(&msg.u.msg, admin) < 0) {
1266                                 PERROR("Failed to deliver message for socket %d.\n", admin->sock);
1267                                 goto response_error;
1268                         }
1269                         break;
1270
1271                         case ADMIN_CALL_SETUP:
1272                         if (admin_call(admin, &msg) < 0) {
1273                                 PERROR("Failed to create call for socket %d.\n", admin->sock);
1274                                 response_error:
1275                                 goto end;
1276                         }
1277                         break;
1278
1279                         default:
1280                         PERROR("Invalid message %d from socket %d.\n", msg.message, admin->sock);
1281                         goto end;
1282                 }
1283         }
1284
1285         if ((what & LCR_FD_WRITE)) {
1286                 /* write queue */
1287                 if (admin->response) {
1288                         len = write(admin->sock, ((unsigned char *)(admin->response->am))+admin->response->offset, sizeof(struct admin_message)*(admin->response->num)-admin->response->offset);
1289                         if (len < 0) {
1290                                 goto brokenpipe;
1291                         }
1292                         if (len == 0)
1293                                 goto end;
1294                         if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset)) {
1295                                 admin->response->offset+=len;
1296                                 return 0;
1297                         } else {
1298                                 temp = admin->response;
1299                                 admin->response = admin->response->next;
1300                                 FREE(temp, 0);
1301                                 memuse--;
1302                         }
1303                 } else
1304                         admin->fd.when &= ~LCR_FD_WRITE;
1305         }
1306
1307         return 0;
1308 }
1309