X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=admin_server.c;h=117611876402a20d50e89ff71996a975afafe40b;hp=ad40516c8283f3b0165236d37b759794b9f9cdf1;hb=5a22e57828617abc14e27814ee918cc63b96fd46;hpb=3754d8f73ff7cb55e204f7ede6569028407a00e5 diff --git a/admin_server.c b/admin_server.c index ad40516..1176118 100644 --- a/admin_server.c +++ b/admin_server.c @@ -1,11 +1,11 @@ /*****************************************************************************\ ** ** -** PBX4Linux ** +** Linux Call Router ** ** ** **---------------------------------------------------------------------------** ** Copyright: Andreas Eversberg ** ** ** -** Socket link ** +** Socket link server ** ** ** \*****************************************************************************/ @@ -86,11 +86,33 @@ int admin_init(void) /* * free connection + * also releases all asterisk joins */ void free_connection(struct admin_list *admin) { struct admin_queue *response; void *temp; + union parameter param; + class Join *join, *joinnext; + + /* free asterisk joins */ + if (admin->asterisk) + { + join = join_first; + while(join) + { + joinnext = join->next; + if (join->c_type == JOIN_TYPE_ASTERISK) + { + 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); + /* join is now destroyed, so we go to next join */ + } + join = joinnext; + } + } if (admin->sock >= 0) { @@ -104,12 +126,12 @@ void free_connection(struct admin_list *admin) //#warning // printf("%x\n", response); temp = response->next; - free(response); + FREE(response, 0); memuse--; response = (struct admin_queue *)temp; } // printf("new2\n", response); - free(admin); + FREE(admin, 0); // printf("new3\n", response); memuse--; } @@ -160,11 +182,8 @@ int admin_interface(struct admin_queue **responsep) err = -1; } /* create state response */ - response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message)); - if (!response) - return(-1); + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - memset(response, 0, sizeof(admin_queue)+sizeof(admin_message)); response->num = 1; /* message */ response->am[0].message = ADMIN_RESPONSE_CMD_INTERFACE; @@ -262,6 +281,7 @@ int admin_route(struct admin_queue **responsep) CATEGORY_EP, apppbx->ea_endpoint->ep_serial, "KICK (reload routing)"); + end_trace(); } apppbx->e_action_timeout = NULL; @@ -273,11 +293,8 @@ int admin_route(struct admin_queue **responsep) response: /* create state response */ - response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message)); - if (!response) - return(-1); + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - memset(response, 0, sizeof(admin_queue)+sizeof(admin_message)); response->num = 1; /* message */ response->am[0].message = ADMIN_RESPONSE_CMD_ROUTE; @@ -303,11 +320,8 @@ int admin_dial(struct admin_queue **responsep, char *message) char *p; /* pointer to dialing digits */ /* create state response */ - response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message)); - if (!response) - return(-1); + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - memset(response, 0, sizeof(admin_queue)+sizeof(admin_message)); response->num = 1; /* message */ response->am[0].message = ADMIN_RESPONSE_CMD_DIAL; @@ -340,6 +354,16 @@ int admin_dial(struct admin_queue **responsep, char *message) /* + * do tracing + */ +int admin_trace(struct admin_list *admin, struct admin_trace_req *trace) +{ + memcpy(&admin->trace, trace, sizeof(struct admin_trace_req)); + return(0); +} + + +/* * do blocking * * 0 = make port available @@ -358,11 +382,8 @@ int admin_block(struct admin_queue **responsep, int portnum, int block) struct interface_port *ifport; /* create block response */ - response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message)); - if (!response) - return(-1); + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - memset(response, 0, sizeof(admin_queue)+sizeof(admin_message)); response->num = 1; /* message */ response->am[0].message = ADMIN_RESPONSE_CMD_BLOCK; @@ -450,11 +471,8 @@ int admin_release(struct admin_queue **responsep, char *message) class EndpointAppPBX *apppbx; /* create state response */ - response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message)); - if (!response) - return(-1); + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - memset(response, 0, sizeof(admin_queue)+sizeof(admin_message)); response->num = 1; /* message */ response->am[0].message = ADMIN_RESPONSE_CMD_RELEASE; @@ -493,14 +511,10 @@ int admin_call(struct admin_list *admin, struct admin_message *msg) class Endpoint *epoint; class EndpointAppPBX *apppbx; - if (!(epoint = new Endpoint(0,0))) - return(-1); - - if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint))) - { - PERROR("no memory for application\n"); - exit(-1); - } + if (!(epoint = new Endpoint(0, 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"); apppbx->e_adminid = admin->sockserial; admin->epointid = epoint->ep_serial; SCPY(apppbx->e_callerinfo.id, nationalize_callerinfo(msg->u.call.callerid, &apppbx->e_callerinfo.ntype)); @@ -558,11 +572,8 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i } /* create state response */ - response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message)); - if (!response) - return; + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - memset(response, 0, sizeof(admin_queue)+sizeof(admin_message)); response->num = 1; /* message */ response->am[0].message = message; @@ -580,6 +591,116 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i /* + * send data to the asterisk join instance + */ +int admin_message_to_join(struct admin_msg *msg) +{ + class Join *join; + struct admin_list *admin; + + /* dummy callref means: asterisk is here */ + if (msg->type == MESSAGE_HELLO) + { + /* look for second asterisk */ + admin = admin_list; + while(admin) + { + if (admin->asterisk) + break; + admin = admin->next; + } + if (admin) + { + PERROR("Asterisk connects twice??? (ignoring)\n"); + return(-1); + } + /* set asterisk socket instance */ + admin->asterisk = 1; + } + + /* find join instance */ + join = join_first; + while(join) + { + if (join->c_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); + } + + /* 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"); + } + + /* 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); + + return(0); +} + + +/* + * this function is called for every message to asterisk + */ +int admin_message_from_join(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 + */ + admin = admin_list; + while(admin) + { + if (admin->asterisk) + break; + admin = admin->next; + } + /* no asterisk connected */ + if (!admin) + return(-1); + + /* seek to end of response list */ + response = admin->response; + responsep = &admin->response; + while(response) + { + responsep = &response->next; + response = response->next; + } + + /* create state response */ + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); + memuse++; + response->num = 1; + + /* message */ + response->am[0].u.msg.type = message_type; + response->am[0].u.msg.ref = ref; + memcpy(&response->am[0].u.msg.param, param, sizeof(union parameter)); + + /* attach to response chain */ + *responsep = response; + responsep = &response->next; + + return(0); +} + + +/* * do state debugging */ int admin_state(struct admin_queue **responsep) @@ -587,7 +708,7 @@ int admin_state(struct admin_queue **responsep) class Port *port; class EndpointAppPBX *apppbx; - class Call *call; + class Join *join; class Pdss1 *pdss1; struct interface *interface; struct interface_port *ifport; @@ -598,11 +719,8 @@ int admin_state(struct admin_queue **responsep) struct admin_queue *response; /* create state response */ - response = (struct admin_queue *)malloc(sizeof(struct admin_queue)+sizeof(admin_message)); - if (!response) - return(-1); + response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - memset(response, 0, sizeof(admin_queue)+sizeof(admin_message)); response->num = 1; /* message */ response->am[0].message = ADMIN_RESPONSE_STATE; @@ -626,15 +744,15 @@ int admin_state(struct admin_queue **responsep) interface = interface->next; } response->am[0].u.s.interfaces = i; - /* call count */ - call = call_first; + /* join count */ + join = join_first; i = 0; - while(call) + while(join) { i++; - call = call->next; + join = join->next; } - response->am[0].u.s.calls = i; + response->am[0].u.s.joins = i; /* apppbx count */ apppbx = apppbx_first; i = 0; @@ -658,14 +776,11 @@ int admin_state(struct admin_queue **responsep) responsep = &response->next; /* create response for all interfaces */ - 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); + num = (response->am[0].u.s.interfaces)+(response->am[0].u.s.joins)+(response->am[0].u.s.epoints)+(response->am[0].u.s.ports); if (num == 0) return(0); - response = (struct admin_queue *)malloc(sizeof(admin_queue)+(num*sizeof(admin_message))); - if (!response) - return(-1); + response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message))); memuse++; - memset(response, 0, sizeof(admin_queue)+(num*sizeof(admin_message))); response->num = num; *responsep = response; responsep = &response->next; @@ -722,19 +837,19 @@ int admin_state(struct admin_queue **responsep) interface = interface->next; } - /* create response for all calls */ - call = call_first; - while(call) + /* create response for all joins */ + join = join_first; + while(join) { /* message */ - response->am[num].message = ADMIN_RESPONSE_S_CALL; + response->am[num].message = ADMIN_RESPONSE_S_JOIN; /* serial */ - response->am[num].u.c.serial = call->c_serial; + response->am[num].u.j.serial = join->c_serial; /* partyline */ - if (call->c_type == CALL_TYPE_PBX) - response->am[num].u.c.partyline = ((class CallPBX *)call)->c_partyline; + if (join->c_type == JOIN_TYPE_PBX) + response->am[num].u.j.partyline = ((class JoinPBX *)join)->c_partyline; /* */ - call = call->next; + join = join->next; num++; } @@ -746,8 +861,8 @@ int admin_state(struct admin_queue **responsep) response->am[num].message = ADMIN_RESPONSE_S_EPOINT; /* serial */ response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial; - /* call */ - response->am[num].u.e.call = apppbx->ea_endpoint->ep_call_id; + /* join */ + response->am[num].u.e.join = apppbx->ea_endpoint->ep_join_id; /* rx notification */ response->am[num].u.e.rx_state = apppbx->e_rx_state; /* tx notification */ @@ -906,26 +1021,21 @@ int admin_handle(void) { work = 1; /* insert new socket */ - admin = (struct admin_list *)malloc(sizeof(struct admin_list)); - if (admin) + admin = (struct admin_list *)MALLOC(sizeof(struct admin_list)); + if (ioctl(new_sock, FIONBIO, (unsigned char *)(&on)) >= 0) { - if (ioctl(new_sock, FIONBIO, (unsigned char *)(&on)) >= 0) - { //#warning // PERROR("DEBUG incomming socket %d, serial=%d\n", new_sock, sockserial); - memuse++; - fhuse++; - memset(admin, 0, sizeof(struct admin_list)); - admin->sockserial = sockserial++; - admin->next = admin_list; - admin_list = admin; - admin->sock = new_sock; - } else { - close(new_sock); - free(admin); - } - } else + memuse++; + fhuse++; + admin->sockserial = sockserial++; + admin->next = admin_list; + admin_list = admin; + admin->sock = new_sock; + } else { close(new_sock); + FREE(admin, sizeof(struct admin_list)); + } } else { if (errno != EWOULDBLOCK) @@ -1043,6 +1153,14 @@ int admin_handle(void) } break; + case ADMIN_TRACE_REQUEST: + if (admin_trace(admin, &msg.u.trace_req) < 0) + { + PERROR("Failed to create trace response for socket %d.\n", admin->sock); + goto response_error; + } + break; + case ADMIN_REQUEST_CMD_BLOCK: if (admin_block(&admin->response, msg.u.x.portnum, msg.u.x.block) < 0) { @@ -1051,15 +1169,12 @@ int admin_handle(void) } break; -#warning interface tbd -#if 0 case ADMIN_MESSAGE: - if (admin_message(&admin->response) < 0) + if (admin_message_to_join(&msg.u.msg) < 0) { - PERROR("Failed to create message response for socket %d.\n", admin->sock); + PERROR("Failed to deliver message for socket %d.\n", admin->sock); goto response_error; } -#endif #if 0 #warning DEBUGGING { @@ -1077,7 +1192,7 @@ int admin_handle(void) break; case ADMIN_CALL_SETUP: - if (admin_call(admin, &msg)) + if (admin_call(admin, &msg) < 0) { PERROR("Failed to create call for socket %d.\n", admin->sock); response_error: @@ -1122,7 +1237,7 @@ int admin_handle(void) { temp = admin->response; admin->response = admin->response->next; - free(temp); + FREE(temp, 0); memuse--; } }