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