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