1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** Socket link server **
10 \*****************************************************************************/
13 #include <sys/socket.h>
19 char socket_name[128];
21 struct sockaddr_un sock_address;
22 extern unsigned int new_remote;
24 struct admin_list *admin_first = NULL;
25 static struct lcr_fd admin_fd;
27 int admin_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index);
30 * initialize admin socket
34 /* open and bind socket */
35 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
36 PERROR("Failed to create admin socket. (errno=%d)\n", errno);
40 memset(&sock_address, 0, sizeof(sock_address));
41 SPRINT(socket_name, SOCKET_NAME, options.lock);
42 sock_address.sun_family = AF_UNIX;
43 UCPY(sock_address.sun_path, socket_name);
45 if (bind(sock, (struct sockaddr *)(&sock_address), SUN_LEN(&sock_address)) < 0) {
50 PERROR("Failed to bind admin socket to \"%s\". (errno=%d)\n", sock_address.sun_path, errno);
53 if (listen(sock, 5) < 0) {
58 PERROR("Failed to listen to socket \"%s\". (errno=%d)\n", sock_address.sun_path, errno);
61 memset(&admin_fd, 0, sizeof(admin_fd));
63 register_fd(&admin_fd, LCR_FD_READ | LCR_FD_EXCEPT, admin_handle, NULL, 0);
64 if (chmod(socket_name, options.socketrights) < 0) {
65 PERROR("Failed to change socket rights to %d. (errno=%d)\n", options.socketrights, errno);
67 if (chown(socket_name, options.socketuser, options.socketgroup) < 0) {
68 PERROR("Failed to change socket user/group to %d/%d. (errno=%d)\n", options.socketuser, options.socketgroup, errno);
77 * also releases all remote joins
79 void free_connection(struct admin_list *admin)
81 struct admin_queue *response;
83 union parameter param;
84 class Join *join, *joinnext;
85 struct mISDNport *mISDNport;
87 struct admin_list **adminp;
88 class Port *port, *portnext;
89 class Premote *remote;
91 /* free remote joins */
92 if (admin->remote_name[0]) {
100 "REMOTE APP release");
101 add_trace("app", "name", "%s", admin->remote_name);
103 /* release all exported channels */
104 mISDNport = mISDNport_first;
107 ii = mISDNport->b_num;
109 if (mISDNport->b_remote_id[i] == admin->sock) {
110 mISDNport->b_state[i] = B_STATE_IDLE;
111 unsched_timer(&mISDNport->b_timer[i]);
112 mISDNport->b_remote_id[i] = 0;
113 mISDNport->b_remote_ref[i] = 0;
117 mISDNport = mISDNport->next;
122 joinnext = join->next;
123 if (join->j_type==JOIN_TYPE_REMOTE) if (((class JoinRemote *)join)->j_remote_id == admin->sock) {
124 memset(¶m, 0, sizeof(param));
125 param.disconnectinfo.cause = CAUSE_OUTOFORDER;
126 param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
127 ((class JoinRemote *)join)->message_remote(MESSAGE_RELEASE, ¶m);
128 /* join is now destroyed, so we go to next join */
132 /* release remote port */
135 portnext = port->next;
136 if ((port->p_type & PORT_CLASS_MASK) == PORT_CLASS_REMOTE) {
137 remote = (class Premote *) port;
138 if (remote->p_m_r_remote_id == admin->sock) {
139 memset(¶m, 0, sizeof(param));
140 param.disconnectinfo.cause = CAUSE_OUTOFORDER;
141 param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
142 remote->message_remote(MESSAGE_RELEASE, ¶m);
143 /* port is now destroyed, so we go to next join */
150 if (admin->sock >= 0) {
151 unregister_fd(&admin->fd);
155 response = admin->response;
157 temp = response->next;
160 response = (struct admin_queue *)temp;
163 adminp = &admin_first;
165 if (*adminp == admin)
167 adminp = &((*adminp)->next);
170 *adminp = (*adminp)->next;
178 * cleanup admin socket
180 void admin_cleanup(void)
182 struct admin_list *admin, *next;;
187 free_connection(admin);
192 unregister_fd(&admin_fd);
202 * do interface reload
204 int admin_interface(struct admin_queue **responsep)
206 struct admin_queue *response; /* response pointer */
207 const char *err_txt = "";
210 if (read_interfaces()) {
212 free_interfaces(interface_first);
213 interface_first = interface_newlist;
214 interface_newlist = NULL;
216 err_txt = interface_error;
219 /* create state response */
220 response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
224 response->am[0].message = ADMIN_RESPONSE_CMD_INTERFACE;
226 response->am[0].u.x.error = err;
228 SCPY(response->am[0].u.x.message, err_txt);
229 /* attach to response chain */
230 *responsep = response;
231 responsep = &response->next;
239 int admin_route(struct admin_queue **responsep)
241 struct route_ruleset *ruleset_new;
242 struct admin_queue *response; /* response pointer */
243 char err_txt[256] = "";
248 class EndpointAppPBX *apppbx;
252 apppbx = apppbx_first;
255 apppbx = apppbx->next;
258 SPRINT(err_txt, "Cannot reload routing, because %d endpoints active\n", n);
263 if (!(ruleset_new = ruleset_parse())) {
264 SPRINT(err_txt, ruleset_error);
268 ruleset_free(ruleset_first);
269 ruleset_first = ruleset_new;
270 ruleset_main = getrulesetbyname("main");
272 SPRINT(err_txt, "Ruleset reloaded, but rule 'main' not found.\n");
275 apppbx = apppbx_first;
277 if (apppbx->e_action) {
278 switch(apppbx->e_action->index) {
279 case ACTION_INTERNAL:
280 apppbx->e_action = &action_internal;
282 case ACTION_EXTERNAL:
283 apppbx->e_action = &action_external;
286 apppbx->e_action = &action_remote;
288 case ACTION_VBOX_RECORD:
289 apppbx->e_action = &action_vbox;
291 case ACTION_PARTYLINE:
292 apppbx->e_action = &action_partyline;
297 } else if (apppbx->e_state != EPOINT_STATE_CONNECT) {
299 unsched_timer(&apppbx->e_callback_timeout);
300 apppbx->e_action = NULL;
301 apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
304 numberrize_callerinfo(apppbx->e_callerinfo.id, apppbx->e_callerinfo.ntype, options.national, options.international),
305 apppbx->e_dialinginfo.id,
308 apppbx->ea_endpoint->ep_serial,
309 "KICK (reload routing)");
313 unsched_timer(&apppbx->e_action_timeout);
314 apppbx->e_rule = NULL;
315 apppbx->e_ruleset = NULL;
317 apppbx = apppbx->next;
321 /* create state response */
322 response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
326 response->am[0].message = ADMIN_RESPONSE_CMD_ROUTE;
328 response->am[0].u.x.error = err;
330 SCPY(response->am[0].u.x.message, err_txt);
331 /* attach to response chain */
332 *responsep = response;
333 responsep = &response->next;
341 int admin_dial(struct admin_queue **responsep, char *message)
343 struct extension ext; /* temporary extension's settings */
344 struct admin_queue *response; /* response pointer */
345 char *p; /* pointer to dialing digits */
347 /* create state response */
348 response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
352 response->am[0].message = ADMIN_RESPONSE_CMD_DIAL;
354 /* process request */
355 if (!(p = strchr(message,':'))) {
356 response->am[0].u.x.error = -EINVAL;
357 SPRINT(response->am[0].u.x.message, "no seperator ':' in message to seperate number from extension");
362 /* modify extension */
363 if (!read_extension(&ext, message)) {
364 response->am[0].u.x.error = -EINVAL;
365 SPRINT(response->am[0].u.x.message, "extension doesn't exist");
369 write_extension(&ext, message);
372 /* attach to response chain */
373 *responsep = response;
374 responsep = &response->next;
382 int admin_trace(struct admin_list *admin, struct admin_trace_req *trace)
384 memcpy(&admin->trace, trace, sizeof(struct admin_trace_req));
392 * 0 = make port available
393 * 1 = make port administratively blocked
395 * the result is returned:
396 * 0 = port is now available
397 * 1 = port is now blocked
398 * 2 = port cannot be loaded or has been unloaded
399 * -1 = port doesn't exist
401 int admin_block(struct admin_queue **responsep, int portnum, int block)
403 struct admin_queue *response; /* response pointer */
404 struct interface *interface;
405 struct interface_port *ifport;
407 /* create block response */
408 response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
412 response->am[0].message = ADMIN_RESPONSE_CMD_BLOCK;
413 response->am[0].u.x.portnum = portnum;
415 /* search for port */
417 interface = interface_first;
419 ifport = interface->ifport;
421 if (ifport->portnum == portnum)
423 ifport = ifport->next;
427 interface = interface->next;
429 /* not found, we return -1 */
431 response->am[0].u.x.block = -1;
432 response->am[0].u.x.error = 1;
433 SPRINT(response->am[0].u.x.message, "Port %d does not exist.", portnum);
438 if (!ifport->mISDNport) {
439 /* not loaded anyway */
441 response->am[0].u.x.block = 2;
445 /* try loading interface */
446 ifport->block = block;
449 /* port cannot load */
450 if (ifport->block >= 2) {
451 response->am[0].u.x.block = 2;
452 response->am[0].u.x.error = 1;
453 SPRINT(response->am[0].u.x.message, "Port %d will not load.", portnum);
458 response->am[0].u.x.block = ifport->block;
462 /* if we shall unload interface */
464 mISDNport_close(ifport->mISDNport);
465 ifport->mISDNport = 0;
470 /* port new blocking state */
471 ifport->block = response->am[0].u.x.block = block;
474 /* attach to response chain */
475 *responsep = response;
476 responsep = &response->next;
484 int admin_release(struct admin_queue **responsep, char *message)
487 struct admin_queue *response; /* response pointer */
488 class EndpointAppPBX *apppbx;
490 /* create state response */
491 response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
495 response->am[0].message = ADMIN_RESPONSE_CMD_RELEASE;
498 apppbx = apppbx_first;
500 if (apppbx->ea_endpoint->ep_serial == id)
502 apppbx = apppbx->next;
505 response->am[0].u.x.error = -EINVAL;
506 SPRINT(response->am[0].u.x.message, "Given endpoint %d doesn't exist.", id);
510 unsched_timer(&apppbx->e_callback_timeout);
511 apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
514 /* attach to response chain */
515 *responsep = response;
516 responsep = &response->next;
524 int admin_call(struct admin_list *admin, struct admin_message *msg)
526 class Endpoint *epoint;
527 class EndpointAppPBX *apppbx;
529 if (!(epoint = new Endpoint(0, 0)))
530 FATAL("No memory for Endpoint instance\n");
531 if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing
532 FATAL("No memory for Endpoint Application instance\n");
533 apppbx->e_adminid = admin->sockserial;
534 admin->epointid = epoint->ep_serial;
535 SCPY(apppbx->e_callerinfo.id, nationalize_callerinfo(msg->u.call.callerid, &apppbx->e_callerinfo.ntype, options.national, options.international));
536 if (msg->u.call.present)
537 apppbx->e_callerinfo.present = INFO_PRESENT_ALLOWED;
539 apppbx->e_callerinfo.present = INFO_PRESENT_RESTRICTED;
540 apppbx->e_callerinfo.screen = INFO_SCREEN_NETWORK;
543 apppbx->e_capainfo.bearer_capa = msg->u.call.bc_capa;
544 apppbx->e_capainfo.bearer_mode = msg->u.call.bc_mode;
545 apppbx->e_capainfo.bearer_info1 = msg->u.call.bc_info1;
546 apppbx->e_capainfo.hlc = msg->u.call.hlc;
547 apppbx->e_capainfo.exthlc = msg->u.call.exthlc;
548 SCPY(apppbx->e_dialinginfo.id, msg->u.call.dialing);
549 SCPY(apppbx->e_dialinginfo.interfaces, msg->u.call.interface);
550 apppbx->e_dialinginfo.sending_complete = 1;
552 apppbx->new_state(PORT_STATE_OUT_SETUP);
553 apppbx->out_setup(0);
559 * this function is called for response whenever a call state changes.
561 void admin_call_response(int adminid, int message, const char *connected, int cause, int location, int notify_progress)
563 struct admin_list *admin;
564 struct admin_queue *response, **responsep; /* response pointer */
566 /* searching for admin id
567 * maybe there is no admin instance, because the calling port was not
568 * initiated by admin_call */
571 if (adminid == admin->sockserial)
578 /* seek to end of response list */
579 response = admin->response;
580 responsep = &admin->response;
582 responsep = &response->next;
583 response = response->next;
586 /* create state response */
587 response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
591 response->am[0].message = message;
593 SCPY(response->am[0].u.call.callerid, connected);
594 response->am[0].u.call.cause = cause;
595 response->am[0].u.call.location = location;
596 response->am[0].u.call.notify_progress = notify_progress;
598 /* attach to response chain */
599 *responsep = response;
600 responsep = &response->next;
601 admin->fd.when |= LCR_FD_WRITE;
606 * send data to the remote socket join instance
608 int admin_message_to_lcr(struct admin_msg *msg, struct admin_list *admin)
610 struct mISDNport *mISDNport;
612 class JoinRemote *joinremote = NULL; /* make GCC happy */
614 class Premote *remote = NULL; /* make GCC happy */
615 struct admin_list *temp;
618 if (msg->type == MESSAGE_HELLO) {
619 if (admin->remote_name[0]) {
620 PERROR("Remote application repeats hello message.\n");
623 /* look for second application */
626 if (!strcmp(temp->remote_name, msg->param.hello.application))
631 PERROR("Remote application connects twice??? (ignoring)\n");
634 /* set remote socket instance */
635 SCPY(admin->remote_name, msg->param.hello.application);
643 "REMOTE APP registers");
644 add_trace("app", "name", "%s", admin->remote_name);
649 /* check we have no application name */
650 if (!admin->remote_name[0]) {
651 PERROR("Remote application did not send us a hello message.\n");
655 /* new join. the reply (NEWREF assignment) is sent from constructor */
656 if (msg->type == MESSAGE_NEWREF) {
657 if (msg->param.newref.mode) {
659 /* find remote port */
660 mISDNport = mISDNport_first;
662 if (mISDNport->ifport->remote && !strcmp(mISDNport->ifport->remote_app, admin->remote_name))
664 mISDNport = mISDNport->next;
667 unsigned int remote_ref = new_remote++;
668 union parameter param;
670 memset(¶m, 0, sizeof(union parameter));
671 admin_message_from_lcr(mISDNport->ifport->remote, remote_ref, MESSAGE_NEWREF, ¶m);
672 memset(¶m, 0, sizeof(union parameter));
673 param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
674 param.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
675 admin_message_from_lcr(mISDNport->ifport->remote, remote_ref, MESSAGE_RELEASE, ¶m);
678 /* creating port object, transparent until setup with hdlc */
679 SPRINT(name, "%s-%s-in", mISDNport->ifport->interface->name, mISDNport->ifport->remote_app);
680 if (!(remote = new Premote(PORT_TYPE_REMOTE_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT, admin->sock)))
682 FATAL("Cannot create Port instance.\n");
684 /* create new join instance */
685 join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
687 FATAL("No memory for remote join instance\n");
695 * no ref given for *_ack */
696 if (msg->type == MESSAGE_BCHANNEL)
697 if (msg->param.bchannel.type == BCHANNEL_ASSIGN_ACK
698 || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK
699 || msg->param.bchannel.type == BCHANNEL_RELEASE) {
700 #warning TODO: depending on the mode (join / remoteport) forward message
701 /* no ref, but address */
702 message_bchannel_from_remote(NULL, msg->param.bchannel.type, msg->param.bchannel.handle);
708 PERROR("Remote application did not send us a valid ref with a message.\n");
712 /* find join instance */
715 if (join->j_type != JOIN_TYPE_REMOTE) {
716 joinremote = (class JoinRemote *)join;
717 if (joinremote->j_remote_ref == msg->ref)
723 if (admin->sock != joinremote->j_remote_id) {
724 PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, joinremote->j_remote_name, admin->remote_name);
728 joinremote->message_remote(msg->type, &msg->param);
733 /* find port instance */
736 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_REMOTE) {
737 remote = (class Premote *) port;
738 if (remote->p_m_r_ref == msg->ref)
744 if (admin->sock != remote->p_m_r_remote_id) {
745 PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, remote->p_m_r_remote_app, admin->remote_name);
750 remote->message_remote(msg->type, &msg->param);
755 PDEBUG(DEBUG_LOG, "No remote instance found with ref %d. (May have been already released.)\n", msg->ref);
762 * this function is called for every message to remote socket
764 int admin_message_from_lcr(int remote_id, unsigned int ref, int message_type, union parameter *param)
766 struct admin_list *admin;
767 struct admin_queue **responsep; /* response pointer */
769 /* searching for admin id
770 * maybe there is no given remote application
774 if (admin->remote_name[0] && admin->sock==remote_id)
778 /* no given remote application connected */
782 /* seek to end of response list */
783 responsep = &admin->response;
785 responsep = &(*responsep)->next;
788 /* create state response */
789 *responsep = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
791 (*responsep)->num = 1;
794 (*responsep)->am[0].message = ADMIN_MESSAGE;
795 (*responsep)->am[0].u.msg.type = message_type;
796 (*responsep)->am[0].u.msg.ref = ref;
797 memcpy(&(*responsep)->am[0].u.msg.param, param, sizeof(union parameter));
798 admin->fd.when |= LCR_FD_WRITE;
806 int admin_state(struct admin_queue **responsep)
809 class EndpointAppPBX *apppbx;
812 struct interface *interface;
813 struct interface_port *ifport;
814 struct mISDNport *mISDNport;
815 struct select_channel *selchannel;
819 struct admin_queue *response;
820 struct admin_list *admin;
824 /* create state response */
825 response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
829 response->am[0].message = ADMIN_RESPONSE_STATE;
831 SCPY(response->am[0].u.s.version_string, VERSION_STRING);
834 now_tm = localtime(&now);
835 memcpy(&response->am[0].u.s.tm, now_tm, sizeof(struct tm));
837 SCPY(response->am[0].u.s.logfile, options.log);
838 /* interface count */
840 interface = interface_first;
842 ifport = interface->ifport;
845 ifport = ifport->next;
847 interface = interface->next;
849 response->am[0].u.s.interfaces = i;
850 /* remote connection count */
854 if (admin->remote_name[0])
858 response->am[0].u.s.remotes = i;
866 response->am[0].u.s.joins = i;
868 apppbx = apppbx_first;
872 apppbx = apppbx->next;
874 response->am[0].u.s.epoints = i;
882 response->am[0].u.s.ports = i;
883 /* attach to response chain */
884 *responsep = response;
885 responsep = &response->next;
887 /* create response for all instances */
888 num = (response->am[0].u.s.interfaces)
889 + (response->am[0].u.s.remotes)
890 + (response->am[0].u.s.joins)
891 + (response->am[0].u.s.epoints)
892 + (response->am[0].u.s.ports);
895 response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message)));
898 *responsep = response;
899 responsep = &response->next;
900 interface = interface_first;
903 ifport = interface->ifport;
906 response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
908 SCPY(response->am[num].u.i.interface_name, interface->name);
910 response->am[num].u.i.portnum = ifport->portnum;
912 SCPY(response->am[num].u.i.portname, ifport->portname);
914 response->am[num].u.i.extension = interface->extension;
916 response->am[num].u.i.block = ifport->block;
917 if (ifport->mISDNport) {
918 mISDNport = ifport->mISDNport;
921 response->am[num].u.i.ptp = mISDNport->ptp;
923 response->am[num].u.i.l1hold = mISDNport->l1hold;
925 response->am[num].u.i.l2hold = mISDNport->l2hold;
927 response->am[num].u.i.ntmode = mISDNport->ntmode;
929 response->am[num].u.i.pri = mISDNport->pri;
931 response->am[num].u.i.use = mISDNport->use;
933 response->am[num].u.i.l1link = mISDNport->l1link;
935 response->am[num].u.i.l2link = mISDNport->l2link;
936 memcpy(response->am[num].u.i.l2mask, mISDNport->l2mask, 16);
938 response->am[num].u.i.los = mISDNport->los;
940 response->am[num].u.i.ais = mISDNport->ais;
942 response->am[num].u.i.rdi = mISDNport->rdi;
944 response->am[num].u.i.slip_tx = mISDNport->slip_tx;
945 response->am[num].u.i.slip_rx = mISDNport->slip_rx;
947 response->am[num].u.i.channels = mISDNport->b_num;
948 /* channel selection */
949 selchannel = ifport->out_channel;
950 if (ifport->channel_force)
951 SCAT(response->am[num].u.i.out_channel, "force");
953 if (response->am[num].u.i.out_channel[0])
954 SCAT(response->am[num].u.i.out_channel, ",");
955 switch (selchannel->channel) {
957 SCAT(response->am[num].u.i.out_channel, "no");
960 SCAT(response->am[num].u.i.out_channel, "any");
963 SCAT(response->am[num].u.i.out_channel, "free");
966 SPRINT(strchr(response->am[num].u.i.out_channel, '\0'), "%d", selchannel->channel);
968 selchannel = selchannel->next;
970 selchannel = ifport->in_channel;
972 switch (selchannel->channel) {
974 SCAT(response->am[num].u.i.in_channel, "free");
977 SPRINT(strchr(response->am[num].u.i.in_channel, '\0'), "%d", selchannel->channel);
979 selchannel = selchannel->next;
984 while(i < mISDNport->b_num) {
985 response->am[num].u.i.busy[i] = mISDNport->b_state[i];
986 if (mISDNport->b_port[i])
987 response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial;
988 response->am[num].u.i.mode[i] = mISDNport->b_mode[i];
994 ifport = ifport->next;
996 interface = interface->next;
999 /* create response for all remotes */
1000 admin = admin_first;
1002 if (admin->remote_name[0]) {
1004 response->am[num].message = ADMIN_RESPONSE_S_REMOTE;
1006 SCPY(response->am[num].u.r.name, admin->remote_name);
1010 admin = admin->next;
1013 /* create response for all joins */
1017 response->am[num].message = ADMIN_RESPONSE_S_JOIN;
1019 response->am[num].u.j.serial = join->j_serial;
1021 if (join->j_type == JOIN_TYPE_PBX)
1022 response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
1023 /* remote application */
1024 if (join->j_type == JOIN_TYPE_REMOTE)
1025 SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote_name);
1031 /* create response for all endpoint */
1032 apppbx = apppbx_first;
1035 response->am[num].message = ADMIN_RESPONSE_S_EPOINT;
1037 response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial;
1039 response->am[num].u.e.join = apppbx->ea_endpoint->ep_join_id;
1040 /* rx notification */
1041 response->am[num].u.e.rx_state = apppbx->e_rx_state;
1042 /* tx notification */
1043 response->am[num].u.e.tx_state = apppbx->e_tx_state;
1045 switch(apppbx->e_state) {
1046 case EPOINT_STATE_IN_SETUP:
1047 response->am[num].u.e.state = ADMIN_STATE_IN_SETUP;
1049 case EPOINT_STATE_OUT_SETUP:
1050 response->am[num].u.e.state = ADMIN_STATE_OUT_SETUP;
1052 case EPOINT_STATE_IN_OVERLAP:
1053 response->am[num].u.e.state = ADMIN_STATE_IN_OVERLAP;
1055 case EPOINT_STATE_OUT_OVERLAP:
1056 response->am[num].u.e.state = ADMIN_STATE_OUT_OVERLAP;
1058 case EPOINT_STATE_IN_PROCEEDING:
1059 response->am[num].u.e.state = ADMIN_STATE_IN_PROCEEDING;
1061 case EPOINT_STATE_OUT_PROCEEDING:
1062 response->am[num].u.e.state = ADMIN_STATE_OUT_PROCEEDING;
1064 case EPOINT_STATE_IN_ALERTING:
1065 response->am[num].u.e.state = ADMIN_STATE_IN_ALERTING;
1067 case EPOINT_STATE_OUT_ALERTING:
1068 response->am[num].u.e.state = ADMIN_STATE_OUT_ALERTING;
1070 case EPOINT_STATE_CONNECT:
1071 response->am[num].u.e.state = ADMIN_STATE_CONNECT;
1073 case EPOINT_STATE_IN_DISCONNECT:
1074 response->am[num].u.e.state = ADMIN_STATE_IN_DISCONNECT;
1076 case EPOINT_STATE_OUT_DISCONNECT:
1077 response->am[num].u.e.state = ADMIN_STATE_OUT_DISCONNECT;
1080 response->am[num].u.e.state = ADMIN_STATE_IDLE;
1083 SCPY(response->am[num].u.e.terminal, apppbx->e_ext.number);
1085 SCPY(response->am[num].u.e.callerid, apppbx->e_callerinfo.id);
1087 SCPY(response->am[num].u.e.dialing, apppbx->e_dialinginfo.id);
1089 if (apppbx->e_action)
1090 SCPY(response->am[num].u.e.action, action_defs[apppbx->e_action->index].name);
1091 // if (apppbx->e_action)
1092 // printf("action=%s\n",action_defs[apppbx->e_action->index].name);
1094 response->am[num].u.e.park = apppbx->ea_endpoint->ep_park;
1095 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))
1096 memcpy(response->am[num].u.e.park_callid, apppbx->ea_endpoint->ep_park_callid, apppbx->ea_endpoint->ep_park_len);
1097 response->am[num].u.e.park_len = apppbx->ea_endpoint->ep_park_len;
1099 if (apppbx->e_crypt == CRYPT_ON)
1100 response->am[num].u.e.crypt = 1;
1102 apppbx = apppbx->next;
1106 /* create response for all ports */
1110 response->am[num].message = ADMIN_RESPONSE_S_PORT;
1112 response->am[num].u.p.serial = port->p_serial;
1114 SCPY(response->am[num].u.p.name, port->p_name);
1116 response->am[num].u.p.epoint = ACTIVE_EPOINT(port->p_epointlist);
1118 switch(port->p_state) {
1119 case PORT_STATE_IN_SETUP:
1120 response->am[num].u.p.state = ADMIN_STATE_IN_SETUP;
1122 case PORT_STATE_OUT_SETUP:
1123 response->am[num].u.p.state = ADMIN_STATE_OUT_SETUP;
1125 case PORT_STATE_IN_OVERLAP:
1126 response->am[num].u.p.state = ADMIN_STATE_IN_OVERLAP;
1128 case PORT_STATE_OUT_OVERLAP:
1129 response->am[num].u.p.state = ADMIN_STATE_OUT_OVERLAP;
1131 case PORT_STATE_IN_PROCEEDING:
1132 response->am[num].u.p.state = ADMIN_STATE_IN_PROCEEDING;
1134 case PORT_STATE_OUT_PROCEEDING:
1135 response->am[num].u.p.state = ADMIN_STATE_OUT_PROCEEDING;
1137 case PORT_STATE_IN_ALERTING:
1138 response->am[num].u.p.state = ADMIN_STATE_IN_ALERTING;
1140 case PORT_STATE_OUT_ALERTING:
1141 response->am[num].u.p.state = ADMIN_STATE_OUT_ALERTING;
1143 case PORT_STATE_CONNECT:
1144 response->am[num].u.p.state = ADMIN_STATE_CONNECT;
1146 case PORT_STATE_IN_DISCONNECT:
1147 response->am[num].u.p.state = ADMIN_STATE_IN_DISCONNECT;
1149 case PORT_STATE_OUT_DISCONNECT:
1150 response->am[num].u.p.state = ADMIN_STATE_OUT_DISCONNECT;
1152 case PORT_STATE_RELEASE:
1153 response->am[num].u.p.state = ADMIN_STATE_RELEASE;
1156 response->am[num].u.p.state = ADMIN_STATE_IDLE;
1159 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
1160 response->am[num].u.p.isdn = 1;
1161 pdss1 = (class Pdss1 *)port;
1162 response->am[num].u.p.isdn_chan = pdss1->p_m_b_channel;
1163 response->am[num].u.p.isdn_hold = pdss1->p_m_hold;
1164 response->am[num].u.p.isdn_ces = pdss1->p_m_d_ces;
1173 int sockserial = 1; // must start with 1, because 0 is used if no serial is set
1175 * handle admin socket (non blocking)
1177 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index);
1179 int admin_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1182 socklen_t sock_len = sizeof(sock_address);
1183 struct admin_list *admin;
1185 /* check for new incoming connections */
1186 if ((new_sock = accept(sock, (struct sockaddr *)&sock_address, &sock_len)) >= 0) {
1187 /* insert new socket */
1188 admin = (struct admin_list *)MALLOC(sizeof(struct admin_list));
1191 admin->sockserial = sockserial++;
1192 admin->next = admin_first;
1193 admin_first = admin;
1194 admin->sock = new_sock;
1195 admin->fd.fd = new_sock;
1196 register_fd(&admin->fd, LCR_FD_READ | LCR_FD_EXCEPT, admin_handle_con, admin, 0);
1198 if (errno != EWOULDBLOCK) {
1199 PERROR("Failed to accept connection from socket \"%s\". (errno=%d) Closing socket.\n", sock_address.sun_path, errno);
1208 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1210 struct admin_list *admin = (struct admin_list *)instance;
1212 struct admin_message msg;
1214 struct Endpoint *epoint;
1216 if ((what & LCR_FD_READ)) {
1218 len = read(admin->sock, &msg, sizeof(msg));
1221 PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
1222 free_connection(admin);
1228 /*release endpoint if exists */
1229 if (admin->epointid) {
1230 epoint = find_epoint_id(admin->epointid);
1232 ((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)->
1233 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
1237 free_connection(admin);
1240 if (len != sizeof(msg)) {
1241 PERROR("Short/long read on socket %d. (len=%d != size=%d).\n", admin->sock, len, sizeof(msg));
1242 free_connection(admin);
1245 /* process socket command */
1246 if (admin->response && msg.message != ADMIN_MESSAGE) {
1247 PERROR("Data from socket %d while sending response.\n", admin->sock);
1248 free_connection(admin);
1251 switch (msg.message) {
1252 case ADMIN_REQUEST_CMD_INTERFACE:
1253 if (admin_interface(&admin->response) < 0) {
1254 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1255 goto response_error;
1257 admin->fd.when |= LCR_FD_WRITE;
1260 case ADMIN_REQUEST_CMD_ROUTE:
1261 if (admin_route(&admin->response) < 0) {
1262 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1263 goto response_error;
1265 admin->fd.when |= LCR_FD_WRITE;
1268 case ADMIN_REQUEST_CMD_DIAL:
1269 if (admin_dial(&admin->response, msg.u.x.message) < 0) {
1270 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1271 goto response_error;
1273 admin->fd.when |= LCR_FD_WRITE;
1276 case ADMIN_REQUEST_CMD_RELEASE:
1277 if (admin_release(&admin->response, msg.u.x.message) < 0) {
1278 PERROR("Failed to create release response for socket %d.\n", admin->sock);
1279 goto response_error;
1281 admin->fd.when |= LCR_FD_WRITE;
1284 case ADMIN_REQUEST_STATE:
1285 if (admin_state(&admin->response) < 0) {
1286 PERROR("Failed to create state response for socket %d.\n", admin->sock);
1287 goto response_error;
1289 admin->fd.when |= LCR_FD_WRITE;
1292 case ADMIN_TRACE_REQUEST:
1293 if (admin_trace(admin, &msg.u.trace_req) < 0) {
1294 PERROR("Failed to create trace response for socket %d.\n", admin->sock);
1295 goto response_error;
1297 admin->fd.when |= LCR_FD_WRITE;
1300 case ADMIN_REQUEST_CMD_BLOCK:
1301 if (admin_block(&admin->response, msg.u.x.portnum, msg.u.x.block) < 0) {
1302 PERROR("Failed to create block response for socket %d.\n", admin->sock);
1303 goto response_error;
1305 admin->fd.when |= LCR_FD_WRITE;
1309 if (admin_message_to_lcr(&msg.u.msg, admin) < 0) {
1310 PERROR("Failed to deliver message for socket %d.\n", admin->sock);
1311 goto response_error;
1315 case ADMIN_CALL_SETUP:
1316 if (admin_call(admin, &msg) < 0) {
1317 PERROR("Failed to create call for socket %d.\n", admin->sock);
1319 free_connection(admin);
1325 PERROR("Invalid message %d from socket %d.\n", msg.message, admin->sock);
1326 free_connection(admin);
1331 if ((what & LCR_FD_WRITE)) {
1333 if (admin->response) {
1334 len = write(admin->sock, ((unsigned char *)(admin->response->am))+admin->response->offset, sizeof(struct admin_message)*(admin->response->num)-admin->response->offset);
1340 if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset)) {
1341 admin->response->offset+=len;
1344 temp = admin->response;
1345 admin->response = admin->response->next;
1350 admin->fd.when &= ~LCR_FD_WRITE;
1356 void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type, int isloopback)
1358 union parameter param;
1360 memset(¶m, 0, sizeof(union parameter));
1361 param.bchannel.isloopback = isloopback;
1362 param.bchannel.type = type;
1363 param.bchannel.handle = handle;
1364 param.bchannel.tx_gain = tx_gain;
1365 param.bchannel.rx_gain = rx_gain;
1367 SCPY(param.bchannel.pipeline, pipeline);
1369 memcpy(param.bchannel.crypt, crypt, crypt_len);
1370 param.bchannel.crypt_type = crypt_type;
1371 if (admin_message_from_lcr(remote_id, ref, MESSAGE_BCHANNEL, ¶m)<0) {
1372 PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);