1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
15 #include <sys/types.h>
16 //#include <sys/stat.h>
21 #include <sys/ioctl.h>
22 //#include <sys/file.h>
24 //#include <sys/mman.h>
25 //#include <sys/resource.h>
26 #include <sys/socket.h>
32 char *socket_name = SOCKET_NAME;
34 struct sockaddr_un sock_address;
36 struct admin_list *admin_list = NULL;
39 * initialize admin socket
45 /* open and bind socket */
46 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
48 PERROR("Failed to create admin socket. (errno=%d)\n", errno);
52 memset(&sock_address, 0, sizeof(sock_address));
53 sock_address.sun_family = AF_UNIX;
54 UCPY(sock_address.sun_path, socket_name);
56 if (bind(sock, (struct sockaddr *)(&sock_address), SUN_LEN(&sock_address)) < 0)
62 PERROR("Failed to bind admin socket to \"%s\". (errno=%d)\n", sock_address.sun_path, errno);
65 if (listen(sock, 5) < 0)
71 PERROR("Failed to listen to socket \"%s\". (errno=%d)\n", sock_address.sun_path, errno);
74 if (ioctl(sock, FIONBIO, (unsigned char *)(&on)) < 0)
80 PERROR("Failed to set socket \"%s\" into non-blocking mode. (errno=%d)\n", sock_address.sun_path, errno);
90 void free_connection(struct admin_list *admin)
92 struct admin_queue *response;
100 // printf("new\n", response);
101 response = admin->response;
105 // printf("%x\n", response);
106 temp = response->next;
109 response = (struct admin_queue *)temp;
111 // printf("new2\n", response);
113 // printf("new3\n", response);
119 * cleanup admin socket
121 void admin_cleanup(void)
123 struct admin_list *admin, *next;;
130 free_connection(admin);
143 * do interface reload
145 int admin_interface(struct admin_queue **responsep)
147 struct admin_queue *response; /* response pointer */
151 if (read_interfaces())
154 free_interfaces(interface_first);
155 interface_first = interface_newlist;
156 interface_newlist = NULL;
159 err_txt = interface_error;
162 /* create state response */
163 response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message));
167 memset(response, 0, sizeof(admin_queue));
170 response->am[0].message = ADMIN_RESPONSE_CMD_INTERFACE;
172 response->am[0].u.x.error = err;
174 SCPY(response->am[0].u.x.message, err_txt);
175 /* attach to response chain */
176 *responsep = response;
177 responsep = &response->next;
186 int admin_route(struct admin_queue **responsep)
188 struct route_ruleset *ruleset_new;
189 struct admin_queue *response; /* response pointer */
190 char err_txt[256] = "";
195 class EndpointAppPBX *apppbx;
199 apppbx = apppbx_first;
203 apppbx = apppbx->next;
207 SPRINT(err_txt, "Cannot reload routing, because %d endpoints active\n", n);
212 if (!(ruleset_new = ruleset_parse()))
214 SPRINT(err_txt, ruleset_error);
218 ruleset_free(ruleset_first);
219 ruleset_first = ruleset_new;
220 ruleset_main = getrulesetbyname("main");
223 SPRINT(err_txt, "Ruleset reloaded, but rule 'main' not found.\n");
226 apppbx = apppbx_first;
229 if (apppbx->e_action)
231 switch(apppbx->e_action->index)
233 case ACTION_INTERNAL:
234 apppbx->e_action = &action_internal;
236 case ACTION_EXTERNAL:
237 apppbx->e_action = &action_external;
240 apppbx->e_action = &action_chan;
242 case ACTION_VBOX_RECORD:
243 apppbx->e_action = &action_vbox;
245 case ACTION_PARTYLINE:
246 apppbx->e_action = &action_partyline;
251 } else if (apppbx->e_state != EPOINT_STATE_CONNECT)
254 apppbx->e_callback = 0;
255 apppbx->e_action = NULL;
256 apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
259 nationalize(apppbx->e_callerinfo.id, apppbx->e_callerinfo.ntype),
260 apppbx->e_dialinginfo.number,
264 "KICK (reload routing)");
267 apppbx->e_action_timeout = NULL;
268 apppbx->e_rule = NULL;
269 apppbx->e_ruleset = NULL;
271 apppbx = apppbx->next;
275 /* create state response */
276 response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message));
280 memset(response, 0, sizeof(admin_queue));
283 response->am[0].message = ADMIN_RESPONSE_CMD_ROUTE;
285 response->am[0].u.x.error = err;
287 SCPY(response->am[0].u.x.message, err_txt);
288 /* attach to response chain */
289 *responsep = response;
290 responsep = &response->next;
299 int admin_dial(struct admin_queue **responsep, char *message)
301 struct extension ext; /* temporary extension's settings */
302 struct admin_queue *response; /* response pointer */
303 char *p; /* pointer to dialing digits */
305 /* create state response */
306 response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message));
310 memset(response, 0, sizeof(admin_queue));
313 response->am[0].message = ADMIN_RESPONSE_CMD_DIAL;
315 /* process request */
316 if (!(p = strchr(message,':')))
318 response->am[0].u.x.error = -EINVAL;
319 SPRINT(response->am[0].u.x.message, "no seperator ':' in message to seperate number from extension");
324 /* modify extension */
325 if (!read_extension(&ext, message))
327 response->am[0].u.x.error = -EINVAL;
328 SPRINT(response->am[0].u.x.message, "extension doesn't exist");
332 write_extension(&ext, message);
335 /* attach to response chain */
336 *responsep = response;
337 responsep = &response->next;
345 int admin_release(struct admin_queue **responsep, char *message)
348 struct admin_queue *response; /* response pointer */
349 class EndpointAppPBX *apppbx;
351 /* create state response */
352 response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message));
356 memset(response, 0, sizeof(admin_queue));
359 response->am[0].message = ADMIN_RESPONSE_CMD_RELEASE;
362 apppbx = apppbx_first;
365 if (apppbx->ea_endpoint->ep_serial == id)
367 apppbx = apppbx->next;
371 response->am[0].u.x.error = -EINVAL;
372 SPRINT(response->am[0].u.x.message, "Given endpoint %d doesn't exist.", id);
376 apppbx->e_callback = 0;
377 apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
380 /* attach to response chain */
381 *responsep = response;
382 responsep = &response->next;
390 int admin_call(struct admin_list *admin, struct admin_message *msg)
392 class Endpoint *epoint;
393 class EndpointAppPBX *apppbx;
395 if (!(epoint = new Endpoint(0,0)))
398 if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint)))
400 PERROR("no memory for application\n");
403 apppbx->e_adminid = admin->sockserial;
404 admin->epointid = epoint->ep_serial;
405 SCPY(apppbx->e_callerinfo.id, nationalize_callerinfo(msg->u.call.callerid, &apppbx->e_callerinfo.ntype));
406 if (msg->u.call.present)
407 apppbx->e_callerinfo.present = INFO_PRESENT_ALLOWED;
409 apppbx->e_callerinfo.present = INFO_PRESENT_RESTRICTED;
410 apppbx->e_callerinfo.screen = INFO_SCREEN_NETWORK;
412 //printf("hh=%d\n", apppbx->e_capainfo.hlc);
414 apppbx->e_capainfo.bearer_capa = msg->u.call.bc_capa;
415 apppbx->e_capainfo.bearer_mode = msg->u.call.bc_mode;
416 apppbx->e_capainfo.bearer_info1 = msg->u.call.bc_info1;
417 apppbx->e_capainfo.hlc = msg->u.call.hlc;
418 apppbx->e_capainfo.exthlc = msg->u.call.exthlc;
419 SCPY(apppbx->e_dialinginfo.number, msg->u.call.dialing);
420 SCPY(apppbx->e_dialinginfo.interfaces, msg->u.call.interface);
421 apppbx->e_dialinginfo.sending_complete = 1;
423 apppbx->new_state(PORT_STATE_OUT_SETUP);
430 * this function is called for response whenever a call state changes.
432 void admin_call_response(int adminid, int message, char *connected, int cause, int location, int notify)
434 struct admin_list *admin;
435 struct admin_queue *response, **responsep; /* response pointer */
437 /* searching for admin id
438 * maybe there is no admin instance, because the calling port was not
439 * initiated by admin_call */
443 if (adminid == admin->sockserial)
450 /* seek to end of response list */
451 response = admin->response;
452 responsep = &admin->response;
455 responsep = &response->next;
456 response = response->next;
459 /* create state response */
460 response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message));
464 memset(response, 0, sizeof(admin_queue));
467 response->am[0].message = message;
468 // printf("MESSAGE: %d\n", message);
470 SCPY(response->am[0].u.call.callerid, connected);
471 response->am[0].u.call.cause = cause;
472 response->am[0].u.call.location = location;
473 response->am[0].u.call.notify = notify;
475 /* attach to response chain */
476 *responsep = response;
477 responsep = &response->next;
484 int admin_state(struct admin_queue **responsep)
488 class EndpointAppPBX *apppbx;
491 struct mISDNport *mISDNport;
495 struct admin_queue *response;
497 /* create state response */
498 response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message));
502 memset(response, 0, sizeof(admin_queue));
505 response->am[0].message = ADMIN_RESPONSE_STATE;
507 SCPY(response->am[0].u.s.version_string, VERSION_STRING);
509 memcpy(&response->am[0].u.s.tm, now_tm, sizeof(struct tm));
511 SCPY(response->am[0].u.s.logfile, options.log);
512 /* interface count */
513 mISDNport = mISDNport_first;
518 mISDNport = mISDNport->next;
520 response->am[0].u.s.interfaces = i;
529 response->am[0].u.s.calls = i;
531 apppbx = apppbx_first;
536 apppbx = apppbx->next;
538 response->am[0].u.s.epoints = i;
547 response->am[0].u.s.ports = i;
548 /* attach to response chain */
549 *responsep = response;
550 responsep = &response->next;
552 /* create response for all interfaces */
553 num = (response->am[0].u.s.interfaces)+(response->am[0].u.s.calls)+(response->am[0].u.s.epoints)+(response->am[0].u.s.ports);
554 response = (struct admin_queue *)malloc(sizeof(admin_queue)+(num*sizeof(admin_message)));
558 memset(response, 0, sizeof(admin_queue)+(num*sizeof(admin_queue)));
560 *responsep = response;
561 responsep = &response->next;
562 mISDNport = mISDNport_first;
567 response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
569 response->am[num].u.i.portnum = mISDNport->portnum;
571 SCPY(response->am[num].u.i.interface_name, mISDNport->interface_name);
573 response->am[num].u.i.iftype = mISDNport->iftype;
575 response->am[num].u.i.ptp = mISDNport->ptp;
577 response->am[num].u.i.ntmode = mISDNport->ntmode;
579 response->am[num].u.i.pri = mISDNport->pri;
581 response->am[num].u.i.use = mISDNport->use;
583 response->am[num].u.i.l1link = mISDNport->l1link;
585 response->am[num].u.i.l2link = mISDNport->l2link;
587 response->am[num].u.i.channels = mISDNport->b_num;
591 while(i < mISDNport->b_num)
593 response->am[num].u.i.busy[i] = mISDNport->b_state[i];
594 if (mISDNport->b_port[i])
595 response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial;
598 mISDNport = mISDNport->next;
602 /* create response for all calls */
607 response->am[num].message = ADMIN_RESPONSE_S_CALL;
609 response->am[num].u.c.serial = call->c_serial;
611 if (call->c_type == CALL_TYPE_PBX)
612 response->am[num].u.c.partyline = ((class CallPBX *)call)->c_partyline;
618 /* create response for all endpoint */
619 apppbx = apppbx_first;
623 response->am[num].message = ADMIN_RESPONSE_S_EPOINT;
625 response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial;
627 response->am[num].u.e.call = apppbx->ea_endpoint->ep_call_id;
628 /* rx notification */
629 response->am[num].u.e.rx_state = apppbx->e_rx_state;
630 /* tx notification */
631 response->am[num].u.e.tx_state = apppbx->e_tx_state;
633 switch(apppbx->e_state)
635 case EPOINT_STATE_IN_SETUP:
636 response->am[num].u.e.state = ADMIN_STATE_IN_SETUP;
638 case EPOINT_STATE_OUT_SETUP:
639 response->am[num].u.e.state = ADMIN_STATE_OUT_SETUP;
641 case EPOINT_STATE_IN_OVERLAP:
642 response->am[num].u.e.state = ADMIN_STATE_IN_OVERLAP;
644 case EPOINT_STATE_OUT_OVERLAP:
645 response->am[num].u.e.state = ADMIN_STATE_OUT_OVERLAP;
647 case EPOINT_STATE_IN_PROCEEDING:
648 response->am[num].u.e.state = ADMIN_STATE_IN_PROCEEDING;
650 case EPOINT_STATE_OUT_PROCEEDING:
651 response->am[num].u.e.state = ADMIN_STATE_OUT_PROCEEDING;
653 case EPOINT_STATE_IN_ALERTING:
654 response->am[num].u.e.state = ADMIN_STATE_IN_ALERTING;
656 case EPOINT_STATE_OUT_ALERTING:
657 response->am[num].u.e.state = ADMIN_STATE_OUT_ALERTING;
659 case EPOINT_STATE_CONNECT:
660 response->am[num].u.e.state = ADMIN_STATE_CONNECT;
662 case EPOINT_STATE_IN_DISCONNECT:
663 response->am[num].u.e.state = ADMIN_STATE_IN_DISCONNECT;
665 case EPOINT_STATE_OUT_DISCONNECT:
666 response->am[num].u.e.state = ADMIN_STATE_OUT_DISCONNECT;
669 response->am[num].u.e.state = ADMIN_STATE_IDLE;
672 SCPY(response->am[num].u.e.terminal, apppbx->e_ext.number);
674 SCPY(response->am[num].u.e.callerid, apppbx->e_callerinfo.id);
676 SCPY(response->am[num].u.e.dialing, apppbx->e_dialinginfo.number);
678 if (apppbx->e_action)
679 SCPY(response->am[num].u.e.action, action_defs[apppbx->e_action->index].name);
680 // if (apppbx->e_action)
681 // printf("action=%s\n",action_defs[apppbx->e_action->index].name);
683 response->am[num].u.e.park = apppbx->ea_endpoint->ep_park;
684 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))
685 memcpy(response->am[num].u.e.park_callid, apppbx->ea_endpoint->ep_park_callid, apppbx->ea_endpoint->ep_park_len);
686 response->am[num].u.e.park_len = apppbx->ea_endpoint->ep_park_len;
688 if (apppbx->e_crypt == CRYPT_ON)
689 response->am[num].u.e.crypt = 1;
691 apppbx = apppbx->next;
695 /* create response for all ports */
700 response->am[num].message = ADMIN_RESPONSE_S_PORT;
702 response->am[num].u.p.serial = port->p_serial;
704 SCPY(response->am[num].u.p.name, port->p_name);
706 response->am[num].u.p.epoint = ACTIVE_EPOINT(port->p_epointlist);
708 switch(port->p_state)
710 case PORT_STATE_IN_SETUP:
711 response->am[num].u.p.state = ADMIN_STATE_IN_SETUP;
713 case PORT_STATE_OUT_SETUP:
714 response->am[num].u.p.state = ADMIN_STATE_OUT_SETUP;
716 case PORT_STATE_IN_OVERLAP:
717 response->am[num].u.p.state = ADMIN_STATE_IN_OVERLAP;
719 case PORT_STATE_OUT_OVERLAP:
720 response->am[num].u.p.state = ADMIN_STATE_OUT_OVERLAP;
722 case PORT_STATE_IN_PROCEEDING:
723 response->am[num].u.p.state = ADMIN_STATE_IN_PROCEEDING;
725 case PORT_STATE_OUT_PROCEEDING:
726 response->am[num].u.p.state = ADMIN_STATE_OUT_PROCEEDING;
728 case PORT_STATE_IN_ALERTING:
729 response->am[num].u.p.state = ADMIN_STATE_IN_ALERTING;
731 case PORT_STATE_OUT_ALERTING:
732 response->am[num].u.p.state = ADMIN_STATE_OUT_ALERTING;
734 case PORT_STATE_CONNECT:
735 response->am[num].u.p.state = ADMIN_STATE_CONNECT;
737 case PORT_STATE_IN_DISCONNECT:
738 response->am[num].u.p.state = ADMIN_STATE_IN_DISCONNECT;
740 case PORT_STATE_OUT_DISCONNECT:
741 response->am[num].u.p.state = ADMIN_STATE_OUT_DISCONNECT;
744 response->am[num].u.p.state = ADMIN_STATE_IDLE;
747 if ((port->p_type&PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1)
749 response->am[num].u.p.isdn = 1;
750 pdss1 = (class Pdss1 *)port;
751 response->am[num].u.p.isdn_chan = pdss1->p_m_b_channel;
752 response->am[num].u.p.isdn_hold = pdss1->p_m_hold;
753 response->am[num].u.p.isdn_ces = pdss1->p_m_d_ces;
762 int sockserial = 1; // must start with 1, because 0 is used if no serial is set
764 * handle admin socket (non blocking)
766 int admin_handle(void)
768 struct admin_list *admin, **adminp;
770 struct admin_message msg;
773 socklen_t sock_len = sizeof(sock_address);
774 unsigned long on = 1;
775 int work = 0; /* if work was done */
776 struct Endpoint *epoint;
781 /* check for new incomming connections */
782 if ((new_sock = accept(sock, (struct sockaddr *)&sock_address, &sock_len)) >= 0)
785 /* insert new socket */
786 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
789 if (ioctl(new_sock, FIONBIO, (unsigned char *)(&on)) >= 0)
792 // PERROR("DEBUG incomming socket %d, serial=%d\n", new_sock, sockserial);
795 memset(admin, 0, sizeof(struct admin_list));
796 admin->sockserial = sockserial++;
797 admin->next = admin_list;
799 admin->sock = new_sock;
808 if (errno != EWOULDBLOCK)
810 PERROR("Failed to accept connection from socket \"%s\". (errno=%d) Closing socket.\n", sock_address.sun_path, errno);
816 /* loop all current socket connections */
818 adminp = &admin_list;
822 len = read(admin->sock, &msg, sizeof(msg));
825 if (errno != EWOULDBLOCK)
829 printf("Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
830 PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
831 *adminp = admin->next;
832 free_connection(admin);
840 //PERROR("DEBUG socket %d got data. serial=%d\n", admin->sock, admin->sockserial);
845 /*release endpoint if exists */
848 epoint = find_epoint_id(admin->epointid);
851 ((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)->
852 release(RELEASE_ALL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, 0, 0);
857 //PERROR("DEBUG socket %d closed by remote.\n", admin->sock);
858 *adminp = admin->next;
859 free_connection(admin);
861 //PERROR("DEBUG (admin_list=%x)\n", admin_list);
864 if (len != sizeof(msg))
866 PERROR("Short/long read on socket %d. (len=%d != size=%d).\n", admin->sock, len, sizeof(msg));
867 *adminp = admin->next;
868 free_connection(admin);
872 /* process socket command */
875 PERROR("Data from socket %d while sending response.\n", admin->sock);
876 *adminp = admin->next;
877 free_connection(admin);
883 case ADMIN_REQUEST_CMD_INTERFACE:
884 if (admin_interface(&admin->response) < 0)
886 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
891 case ADMIN_REQUEST_CMD_ROUTE:
892 if (admin_route(&admin->response) < 0)
894 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
899 case ADMIN_REQUEST_CMD_DIAL:
900 if (admin_dial(&admin->response, msg.u.x.message) < 0)
902 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
907 case ADMIN_REQUEST_CMD_RELEASE:
908 if (admin_release(&admin->response, msg.u.x.message) < 0)
910 PERROR("Failed to create release response for socket %d.\n", admin->sock);
915 case ADMIN_REQUEST_STATE:
916 if (admin_state(&admin->response) < 0)
918 PERROR("Failed to create state response for socket %d.\n", admin->sock);
921 case ADMIN_REQUEST_MESSAGE:
922 if (admin_message(&admin->response) < 0)
924 PERROR("Failed to create message response for socket %d.\n", admin->sock);
926 *adminp = admin->next;
927 free_connection(admin);
934 struct admin_queue *response;
936 response = admin->response;
939 printf("%c", '0'+response->am[0].message);
940 response=response->next;
947 case ADMIN_CALL_SETUP:
948 if (admin_call(admin, &msg))
950 PERROR("Failed to create call for socket %d.\n", admin->sock);
956 PERROR("Invalid message %d from socket %d.\n", msg.message, admin->sock);
957 *adminp = admin->next;
958 free_connection(admin);
967 //PERROR("DEBUG socket %d sending data.\n", admin->sock);
968 len = write(admin->sock, ((unsigned char *)(admin->response->am))+admin->response->offset, sizeof(struct admin_message)*(admin->response->num)-admin->response->offset);
971 if (errno != EWOULDBLOCK)
981 if (len < (int)(sizeof(struct admin_message)*(admin->response->num)-admin->response->offset))
983 admin->response->offset+=len;
987 temp = admin->response;
988 admin->response = admin->response->next;
993 /* done with socket instance */
995 adminp = &admin->next;