X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=admin_server.c;h=6b0647b243c8fa3221860a816060672a904e5193;hp=117611876402a20d50e89ff71996a975afafe40b;hb=cbe9d412a37e75b61cc74e8a65b0293923eb5160;hpb=5a22e57828617abc14e27814ee918cc63b96fd46 diff --git a/admin_server.c b/admin_server.c index 1176118..6b0647b 100644 --- a/admin_server.c +++ b/admin_server.c @@ -33,7 +33,7 @@ char *socket_name = SOCKET_NAME; int sock = -1; struct sockaddr_un sock_address; -struct admin_list *admin_list = NULL; +struct admin_list *admin_first = NULL; /* * initialize admin socket @@ -86,7 +86,7 @@ int admin_init(void) /* * free connection - * also releases all asterisk joins + * also releases all remote joins */ void free_connection(struct admin_list *admin) { @@ -95,19 +95,19 @@ void free_connection(struct admin_list *admin) union parameter param; class Join *join, *joinnext; - /* free asterisk joins */ - if (admin->asterisk) + /* free remote joins */ + if (admin->remote_name[0]) { join = join_first; while(join) { joinnext = join->next; - if (join->c_type == JOIN_TYPE_ASTERISK) + if (join->j_type==JOIN_TYPE_REMOTE) if (((class JoinRemote *)join)->j_remote_id == admin->sock) { memset(¶m, 0, sizeof(param)); param.disconnectinfo.cause = CAUSE_OUTOFORDER; param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; - ((class JoinAsterisk *)join)->message_asterisk(0, MESSAGE_RELEASE, ¶m); + ((class JoinRemote *)join)->message_remote(MESSAGE_RELEASE, ¶m); /* join is now destroyed, so we go to next join */ } join = joinnext; @@ -144,7 +144,7 @@ void admin_cleanup(void) { struct admin_list *admin, *next;; - admin = admin_list; + admin = admin_first; while(admin) { //printf("clean\n"); @@ -255,8 +255,8 @@ int admin_route(struct admin_queue **responsep) case ACTION_EXTERNAL: apppbx->e_action = &action_external; break; - case ACTION_CHAN: - apppbx->e_action = &action_chan; + case ACTION_REMOTE: + apppbx->e_action = &action_remote; break; case ACTION_VBOX_RECORD: apppbx->e_action = &action_vbox; @@ -511,7 +511,7 @@ int admin_call(struct admin_list *admin, struct admin_message *msg) class Endpoint *epoint; class EndpointAppPBX *apppbx; - if (!(epoint = new Endpoint(0, 0, 0))) + if (!(epoint = new Endpoint(0, 0))) FATAL("No memory for Endpoint instance\n"); if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint))) FATAL("No memory for Endpoint Application instance\n"); @@ -552,7 +552,7 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i /* searching for admin id * maybe there is no admin instance, because the calling port was not * initiated by admin_call */ - admin = admin_list; + admin = admin_first; while(admin) { if (adminid == admin->sockserial) @@ -591,85 +591,126 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i /* - * send data to the asterisk join instance + * send data to the remote socket join instance */ -int admin_message_to_join(struct admin_msg *msg) +int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) { class Join *join; struct admin_list *admin; - /* dummy callref means: asterisk is here */ + /* hello message */ if (msg->type == MESSAGE_HELLO) { - /* look for second asterisk */ - admin = admin_list; + if (remote_name[0]) + { + PERROR("Remote application repeats hello message.\n"); + return(-1); + } + /* look for second application */ + admin = admin_first; while(admin) { - if (admin->asterisk) + if (!strcmp(admin->remote_name, msg->param.hello.application)) break; admin = admin->next; } if (admin) { - PERROR("Asterisk connects twice??? (ignoring)\n"); + PERROR("Remote application connects twice??? (ignoring)\n"); return(-1); } - /* set asterisk socket instance */ - admin->asterisk = 1; + /* set remote socket instance */ + SCPY(remote_name, msg->param.hello.application); + return(0); + } + + /* check we have no application name */ + if (remote_name[0]) + { + PERROR("Remote application did not send us a hello message.\n"); + return(-1); + } + + /* new join */ + if (msg->type == MESSAGE_NEWREF) + { + /* create new join instance */ + join = new JoinRemote(0, remote_name, sock_id); // must have no serial, because no endpoint is connected + if (!join) + FATAL("No memory for remote join instance\n"); + return(0); + } + + /* bchannel message + * no ref given for *_ack */ + if (msg->type == MESSAGE_BCHANNEL) + if (msg->param.bchannel.type == BCHANNEL_ASSIGN_ACK + || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK) + { + /* no ref, but address */ + message_bchannel_from_join(NULL, msg->param.bchannel.type, msg->param.bchannel.addr); + return(0); + } + + /* check for ref */ + if (!msg->ref) + { + PERROR("Remote application did not send us a valid ref with a message.\n"); + return(-1); } /* find join instance */ join = join_first; while(join) { - if (join->c_serial == msg->ref) + if (join->j_serial == msg->ref) break; join = join->next; } - - /* create join instance if not existing */ if (!join) { - if (msg->ref < 2000000000) - { - PERROR("Asterisk sends us unknown ref %d below 2000000000.\n", msg->ref); - return(-1); - } + PERROR("No join found with serial %d.\n", msg->ref); + return(-1); + } - /* create new join instance */ - join = new JoinAsterisk(0); // must have no serial, because no endpoint is connected - if (!join) - FATAL("No memory for Asterisk join instance\n"); + /* check application */ + if (join->j_type != JOIN_TYPE_REMOTE) + { + PERROR("Ref %d does not belong to a remote join instance.\n", msg->ref); + return(-1); + } + if (sock_id != ((class JoinRemote *)join)->j_remote_id) + { + PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote_name, remote_name); + return(-1); } /* send message */ - if (join->c_type != JOIN_TYPE_ASTERISK) - FATAL("join instance %d must be of type join Asterisk\n", join->c_serial); - ((class JoinAsterisk *)join)->message_asterisk(msg->ref, msg->type, &msg->param); + ((class JoinRemote *)join)->message_remote(msg->type, &msg->param); return(0); } /* - * this function is called for every message to asterisk + * this function is called for every message to remote socket */ -int admin_message_from_join(unsigned long ref, int message_type, union parameter *param) +int admin_message_from_join(int remote_id, unsigned long ref, int message_type, union parameter *param) { struct admin_list *admin; struct admin_queue *response, **responsep; /* response pointer */ /* searching for admin id - * maybe there is no asterisk instance + * maybe there is no given remote application */ - admin = admin_list; + admin = admin_first; while(admin) { - if (admin->asterisk) + if (admin->remote_name[0] && admin->sock==remote_id) break; admin = admin->next; } - /* no asterisk connected */ + /* no given remote application connected */ if (!admin) return(-1); @@ -717,6 +758,7 @@ int admin_state(struct admin_queue **responsep) int num; int anybusy; struct admin_queue *response; + struct admin_list *admin; /* create state response */ response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); @@ -744,6 +786,16 @@ int admin_state(struct admin_queue **responsep) interface = interface->next; } response->am[0].u.s.interfaces = i; + /* remote connection count */ + i = 0; + admin = admin_first; + while(admin) + { + if (admin->remote_name[0]) + i++; + admin = admin->next; + } + response->am[0].u.s.remotes = i; /* join count */ join = join_first; i = 0; @@ -837,6 +889,22 @@ int admin_state(struct admin_queue **responsep) interface = interface->next; } + /* create response for all remotes */ + admin = admin_first; + while(admin) + { + if (admin->remote_name[0]) + { + /* message */ + response->am[num].message = ADMIN_RESPONSE_S_REMOTE; + /* name */ + SCPY(response->am[num].u.r.name, admin->remote_name); + /* */ + num++; + } + admin = admin->next; + } + /* create response for all joins */ join = join_first; while(join) @@ -844,10 +912,13 @@ int admin_state(struct admin_queue **responsep) /* message */ response->am[num].message = ADMIN_RESPONSE_S_JOIN; /* serial */ - response->am[num].u.j.serial = join->c_serial; + response->am[num].u.j.serial = join->j_serial; /* partyline */ - if (join->c_type == JOIN_TYPE_PBX) - response->am[num].u.j.partyline = ((class JoinPBX *)join)->c_partyline; + if (join->j_type == JOIN_TYPE_PBX) + response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline; + /* remote application */ + if (join->j_type == JOIN_TYPE_REMOTE) + SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote_name); /* */ join = join->next; num++; @@ -1029,8 +1100,8 @@ int admin_handle(void) memuse++; fhuse++; admin->sockserial = sockserial++; - admin->next = admin_list; - admin_list = admin; + admin->next = admin_first; + admin_first = admin; admin->sock = new_sock; } else { close(new_sock); @@ -1047,8 +1118,8 @@ int admin_handle(void) } /* loop all current socket connections */ - admin = admin_list; - adminp = &admin_list; + admin = admin_first; + adminp = &admin_first; while(admin) { /* read command */ @@ -1091,7 +1162,7 @@ int admin_handle(void) *adminp = admin->next; free_connection(admin); admin = *adminp; -//PERROR("DEBUG (admin_list=%x)\n", admin_list); +//PERROR("DEBUG (admin_first=%x)\n", admin_first); continue; } if (len != sizeof(msg)) @@ -1170,7 +1241,7 @@ int admin_handle(void) break; case ADMIN_MESSAGE: - if (admin_message_to_join(&msg.u.msg) < 0) + if (admin_message_to_join(&msg.u.msg, admin->remote_name, admin->sock) < 0) { PERROR("Failed to deliver message for socket %d.\n", admin->sock); goto response_error;