X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=socket_server.c;h=4b5a841466b703c2bf34c6d06733991bf59dbe96;hp=6565602ab18e7e790591460733a49f19b5ef8962;hb=b2a665f8f1cdeb7d02c3f665d95e6a80297e21d1;hpb=0b71471f0de4aa2ab3e4925f41188abb420c2118 diff --git a/socket_server.c b/socket_server.c index 6565602..4b5a841 100644 --- a/socket_server.c +++ b/socket_server.c @@ -9,26 +9,13 @@ ** ** \*****************************************************************************/ -#include -//#include -//#include -#include -//#include -//#include -//#include -//#include -#include -//#include -//#include -//#include -//#include +#include "main.h" #include #include #include -#include "main.h" -char *socket_name = SOCKET_NAME; +char socket_name[128]; int sock = -1; struct sockaddr_un sock_address; @@ -39,7 +26,7 @@ struct admin_list *admin_first = NULL; */ int admin_init(void) { - unsigned long on = 1; + unsigned int on = 1; /* open and bind socket */ if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) @@ -49,6 +36,7 @@ int admin_init(void) } fhuse++; memset(&sock_address, 0, sizeof(sock_address)); + SPRINT(socket_name, SOCKET_NAME, options.lock); sock_address.sun_family = AF_UNIX; UCPY(sock_address.sun_path, socket_name); unlink(socket_name); @@ -79,6 +67,10 @@ int admin_init(void) PERROR("Failed to set socket \"%s\" into non-blocking mode. (errno=%d)\n", sock_address.sun_path, errno); return(-1); } + if (chmod(socket_name, options.socketrights) < 0) + { + PERROR("Failed to change socket rigts to %d. (errno=%d)\n", options.socketrights, errno); + } return(0); } @@ -93,10 +85,42 @@ void free_connection(struct admin_list *admin) void *temp; union parameter param; class Join *join, *joinnext; + struct mISDNport *mISDNport; + int i, ii; /* free remote joins */ if (admin->remote_name[0]) { + start_trace(0, + NULL, + NULL, + NULL, + DIRECTION_NONE, + 0, + 0, + "REMOTE APP release"); + add_trace("app", "name", "%s", admin->remote_name); + end_trace(); + /* release all exported channels */ + mISDNport = mISDNport_first; + while(mISDNport) + { + i = 0; + ii = mISDNport->b_num; + while(i < ii) + { + if (mISDNport->b_remote_id[i] == admin->sock) + { + mISDNport->b_state[i] = B_STATE_IDLE; + mISDNport->b_timer[i] = 0; + mISDNport->b_remote_id[i] = 0; + mISDNport->b_remote_ref[i] = 0; + } + i++; + } + mISDNport = mISDNport->next; + } + /* release join */ join = join_first; while(join) { @@ -157,6 +181,8 @@ void admin_cleanup(void) close(sock); fhuse--; } + + unlink(socket_name); } @@ -166,7 +192,7 @@ void admin_cleanup(void) int admin_interface(struct admin_queue **responsep) { struct admin_queue *response; /* response pointer */ - char *err_txt = ""; + const char *err_txt = ""; int err = 0; if (read_interfaces()) @@ -274,7 +300,7 @@ int admin_route(struct admin_queue **responsep) apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); start_trace(0, NULL, - numberrize_callerinfo(apppbx->e_callerinfo.id, apppbx->e_callerinfo.ntype), + numberrize_callerinfo(apppbx->e_callerinfo.id, apppbx->e_callerinfo.ntype, options.national, options.international), apppbx->e_dialinginfo.id, DIRECTION_NONE, CATEGORY_EP, @@ -465,7 +491,7 @@ int admin_block(struct admin_queue **responsep, int portnum, int block) */ int admin_release(struct admin_queue **responsep, char *message) { - unsigned long id; + unsigned int id; struct admin_queue *response; /* response pointer */ class EndpointAppPBX *apppbx; @@ -516,7 +542,7 @@ int admin_call(struct admin_list *admin, struct admin_message *msg) 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)); + SCPY(apppbx->e_callerinfo.id, nationalize_callerinfo(msg->u.call.callerid, &apppbx->e_callerinfo.ntype, options.national, options.international)); if (msg->u.call.present) apppbx->e_callerinfo.present = INFO_PRESENT_ALLOWED; else @@ -543,7 +569,7 @@ int admin_call(struct admin_list *admin, struct admin_message *msg) /* * this function is called for response whenever a call state changes. */ -void admin_call_response(int adminid, int message, char *connected, int cause, int location, int notify) +void admin_call_response(int adminid, int message, const char *connected, int cause, int location, int notify) { struct admin_list *admin; struct admin_queue *response, **responsep; /* response pointer */ @@ -592,39 +618,49 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i /* * send data to the remote socket join instance */ -int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) +int admin_message_to_join(struct admin_msg *msg, struct admin_list *admin) { class Join *join; - struct admin_list *admin; + struct admin_list *temp; /* hello message */ if (msg->type == MESSAGE_HELLO) { - if (remote_name[0]) + if (admin->remote_name[0]) { PERROR("Remote application repeats hello message.\n"); return(-1); } /* look for second application */ - admin = admin_first; - while(admin) + temp = admin_first; + while(temp) { - if (!strcmp(admin->remote_name, msg->param.hello.application)) + if (!strcmp(temp->remote_name, msg->param.hello.application)) break; - admin = admin->next; + temp = temp->next; } - if (admin) + if (temp) { PERROR("Remote application connects twice??? (ignoring)\n"); return(-1); } /* set remote socket instance */ - SCPY(remote_name, msg->param.hello.application); + SCPY(admin->remote_name, msg->param.hello.application); + start_trace(0, + NULL, + NULL, + NULL, + DIRECTION_NONE, + 0, + 0, + "REMOTE APP registers"); + add_trace("app", "name", "%s", admin->remote_name); + end_trace(); return(0); } /* check we have no application name */ - if (remote_name[0]) + if (!admin->remote_name[0]) { PERROR("Remote application did not send us a hello message.\n"); return(-1); @@ -634,9 +670,12 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) 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 + join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected if (!join) + { FATAL("No memory for remote join instance\n"); + return(-1); + } return(0); } @@ -644,10 +683,11 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) * 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) + || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK + || msg->param.bchannel.type == BCHANNEL_RELEASE) { /* no ref, but address */ - message_bchannel_from_join(NULL, msg->param.bchannel.type, msg->param.bchannel.handle); + message_bchannel_from_remote(NULL, msg->param.bchannel.type, msg->param.bchannel.handle); return(0); } @@ -668,8 +708,8 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) } if (!join) { - PERROR("No join found with serial %d.\n", msg->ref); - return(-1); + PDEBUG(DEBUG_LOG, "No join found with serial %d. (May have been already released.)\n", msg->ref); + return(0); } /* check application */ @@ -678,9 +718,9 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) 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) + if (admin->sock != ((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); + 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); return(-1); } @@ -694,10 +734,10 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id) /* * this function is called for every message to remote socket */ -int admin_message_from_join(int remote_id, unsigned long ref, int message_type, union parameter *param) +int admin_message_from_join(int remote_id, unsigned int ref, int message_type, union parameter *param) { struct admin_list *admin; - struct admin_queue *response, **responsep; /* response pointer */ + struct admin_queue **responsep; /* response pointer */ /* searching for admin id * maybe there is no given remote application @@ -714,27 +754,22 @@ int admin_message_from_join(int remote_id, unsigned long ref, int message_type, return(-1); /* seek to end of response list */ - response = admin->response; responsep = &admin->response; - while(response) + while(*responsep) { - responsep = &response->next; - response = response->next; + responsep = &(*responsep)->next; } /* create state response */ - response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); + *responsep = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message)); memuse++; - response->num = 1; + (*responsep)->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; + (*responsep)->am[0].message = ADMIN_MESSAGE; + (*responsep)->am[0].u.msg.type = message_type; + (*responsep)->am[0].u.msg.ref = ref; + memcpy(&(*responsep)->am[0].u.msg.param, param, sizeof(union parameter)); return(0); } @@ -826,8 +861,12 @@ int admin_state(struct admin_queue **responsep) *responsep = response; responsep = &response->next; - /* create response for all interfaces */ - 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); + /* create response for all instances */ + num = (response->am[0].u.s.interfaces) + + (response->am[0].u.s.remotes) + + (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))); @@ -848,6 +887,8 @@ int admin_state(struct admin_queue **responsep) SCPY(response->am[num].u.i.interface_name, interface->name); /* portnum */ response->am[num].u.i.portnum = ifport->portnum; + /* portname */ + SCPY(response->am[num].u.i.portname, ifport->portname); /* iftype */ response->am[num].u.i.extension = interface->extension; /* block */ @@ -868,6 +909,15 @@ int admin_state(struct admin_queue **responsep) response->am[num].u.i.l1link = mISDNport->l1link; /* l2link */ response->am[num].u.i.l2link = mISDNport->l2link; + /* los */ + response->am[num].u.i.los = mISDNport->los; + /* ais */ + response->am[num].u.i.ais = mISDNport->ais; + /* rdi */ + response->am[num].u.i.rdi = mISDNport->rdi; + /* slip */ + response->am[num].u.i.slip_tx = mISDNport->slip_tx; + response->am[num].u.i.slip_rx = mISDNport->slip_rx; /* channels */ response->am[num].u.i.channels = mISDNport->b_num; /* channel info */ @@ -878,6 +928,7 @@ int admin_state(struct admin_queue **responsep) response->am[num].u.i.busy[i] = mISDNport->b_state[i]; if (mISDNport->b_port[i]) response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial; + response->am[num].u.i.mode[i] = mISDNport->b_mode[i]; i++; } } @@ -1079,7 +1130,7 @@ int admin_handle(void) int len; int new_sock; socklen_t sock_len = sizeof(sock_address); - unsigned long on = 1; + unsigned int on = 1; int work = 0; /* if work was done */ struct Endpoint *epoint; @@ -1129,7 +1180,6 @@ int admin_handle(void) { work = 1; brokenpipe: - printf("Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno); PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno); *adminp = admin->next; free_connection(admin); @@ -1173,7 +1223,7 @@ int admin_handle(void) continue; } /* process socket command */ - if (admin->response) + if (admin->response && msg.message != ADMIN_MESSAGE) { PERROR("Data from socket %d while sending response.\n", admin->sock); *adminp = admin->next; @@ -1240,7 +1290,7 @@ int admin_handle(void) break; case ADMIN_MESSAGE: - if (admin_message_to_join(&msg.u.msg, admin->remote_name, admin->sock) < 0) + if (admin_message_to_join(&msg.u.msg, admin) < 0) { PERROR("Failed to deliver message for socket %d.\n", admin->sock); goto response_error; @@ -1299,7 +1349,7 @@ int admin_handle(void) work = 1; if (len == 0) goto end; - if (len < (int)(sizeof(struct admin_message)*(admin->response->num)-admin->response->offset)) + if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset)) { admin->response->offset+=len; goto next;