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