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