static void datagram_close_async(struct mi_root *mi_rpl,struct mi_handler *hdl, int done) { datagram_stream dtgram; int ret; my_socket_address *p; int reply_sock, flags; p = (my_socket_address *)hdl->param; LM_DBG("the socket domain is %i and af_local is %i\n", p->domain, AF_LOCAL); memset(&dtgram, 0, sizeof(dtgram)); mi_create_dtgram_replysocket(reply_sock, p->domain, err); if (mi_rpl!=0) { /*allocate the response datagram*/ dtgram.start = pkg_malloc(DATAGRAM_SOCK_BUF_SIZE); if(!dtgram.start) { LM_ERR("no more pkg memory\n"); goto err; } /*build the response*/ if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0) { LM_ERR("failed to build the response \n"); goto err; } LM_DBG("the response is %s", dtgram.start); /*send the response*/ ret = mi_send_dgram(reply_sock, dtgram.start, dtgram.current - dtgram.start, (struct sockaddr *)&p->address, p->address_len, mi_socket_timeout); if (ret>0) { LM_DBG("the response: %s has been sent in %i octets\n", dtgram.start, ret); } else { LM_ERR("failed to send the response, ret is %i\n",ret); } free_mi_tree(mi_rpl); pkg_free(dtgram.start); if (done) free_async_handler( hdl ); } else if (done) { mi_send_dgram(reply_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN, (struct sockaddr*)&reply_addr, reply_addr_len, mi_socket_timeout); free_async_handler( hdl ); } close(reply_sock); return; err: if(dtgram.start) pkg_free(dtgram.start); close(reply_sock); if (done) free_async_handler( hdl ); return; }
static void datagram_close_async(struct mi_root *mi_rpl,struct mi_handler *hdl, int done) { datagram_stream dtgram; int ret; my_socket_address *p; p = (my_socket_address *)hdl->param; if ( mi_rpl!=0 || done ) { if (mi_rpl!=0) { /*allocate the response datagram*/ dtgram.start = pkg_malloc(DATAGRAM_SOCK_BUF_SIZE); if(!dtgram.start){ LM_ERR("no more pkg memory\n"); goto err; } /*build the response*/ if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0){ LM_ERR("failed to build the response \n"); goto err1; } LM_DBG("the response is %s", dtgram.start); /*send the response*/ ret = mi_send_dgram(p->tx_sock, dtgram.start, dtgram.current - dtgram.start, (struct sockaddr *)&p->address, p->address_len, mi_socket_timeout); if (ret>0){ LM_DBG("the response: %s has been sent in %i octets\n", dtgram.start, ret); }else{ LM_ERR("failed to send the response, ret is %i\n",ret); } free_mi_tree( mi_rpl ); pkg_free(dtgram.start); } else { mi_send_dgram(p->tx_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN, (struct sockaddr*)&reply_addr, reply_addr_len, mi_socket_timeout); } } if (done) free_async_handler( hdl ); return; err1: pkg_free(dtgram.start); err: return; }
void mi_datagram_server(int rx_sock, int tx_sock) { struct mi_root *mi_cmd; struct mi_root *mi_rpl; struct mi_handler *hdl; struct mi_cmd * f; datagram_stream dtgram; int ret, len; ret = 0; f = 0; while(1){/*read the datagram*/ memset(mi_buf, 0, DATAGRAM_SOCK_BUF_SIZE); reply_addr_len = sizeof(reply_addr); /* get the client's address */ ret = recvfrom(rx_sock, mi_buf, DATAGRAM_SOCK_BUF_SIZE, 0, (struct sockaddr*)&reply_addr, &reply_addr_len); if (ret == -1) { LM_ERR("recvfrom: (%d) %s\n", errno, strerror(errno)); if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == ECONNREFUSED)) { LM_DBG("got %d (%s), going on\n", errno, strerror(errno)); continue; } LM_DBG("error in recvfrom\n"); continue; } if(ret == 0) continue; LM_DBG("received %.*s\n", ret, mi_buf); if(ret> DATAGRAM_SOCK_BUF_SIZE){ LM_ERR("buffer overflow\n"); continue; } LM_DBG("mi_buf is %s and we have received %i bytes\n",mi_buf, ret); dtgram.start = mi_buf; dtgram.len = ret; dtgram.current = dtgram.start; ret = identify_command(&dtgram, &f); /*analyze the command--from the first line*/ if(ret != 0) { LM_ERR("command not available\n"); mi_send_dgram(tx_sock, MI_COMMAND_NOT_AVAILABLE, MI_COMMAND_AVAILABLE_LEN, (struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); continue; } LM_DBG("we have a valid command \n"); /* if asyncron cmd, build the async handler */ if (f->flags&MI_ASYNC_RPL_FLAG) { hdl = build_async_handler(mi_socket_domain, &reply_addr, reply_addr_len, tx_sock); if (hdl==0) { LM_ERR("failed to build async handler\n"); mi_send_dgram(tx_sock, MI_INTERNAL_ERROR, MI_INTERNAL_ERROR_LEN,(struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); continue; } } else{ hdl = 0; } LM_DBG("after identifing the command, the received datagram is %s\n", dtgram.current); /*if no params required*/ if (f->flags&MI_NO_INPUT_FLAG) { LM_DBG("the command has no params\n"); mi_cmd = 0; } else { LM_DBG("parsing the command's params\n"); mi_cmd = mi_datagram_parse_tree(&dtgram); if (mi_cmd==NULL){ LM_ERR("failed to parse the MI tree\n"); mi_send_dgram(tx_sock, MI_PARSE_ERROR, MI_PARSE_ERROR_LEN, (struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); free_async_handler(hdl); continue; } mi_cmd->async_hdl = hdl; } LM_DBG("done parsing the mi tree\n"); if ( (mi_rpl=run_mi_cmd(f, mi_cmd, (mi_flush_f *)mi_datagram_flush_tree, &dtgram))==0 ) { /*error while running the command*/ LM_ERR("failed to process the command\n"); mi_send_dgram(tx_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN, (struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); goto failure; } /*the command exited well*/ LM_DBG("command process (%s)succeded\n",f->name.s); if (mi_rpl!=MI_ROOT_ASYNC_RPL) { if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0){ LM_ERR("failed to build the response \n"); goto failure; } len = dtgram.current - dtgram.start; ret = mi_send_dgram(tx_sock, dtgram.start,len, (struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); if (ret>0){ LM_DBG("the response: %s has been sent in %i octets\n", dtgram.start, ret); }else{ LM_ERR("failed to send the response: %s (%d)\n", strerror(errno), errno); } free_mi_tree( mi_rpl ); free_async_handler(hdl); if (mi_cmd) free_mi_tree( mi_cmd ); }else { if (mi_cmd) free_mi_tree( mi_cmd ); } continue; failure: free_async_handler(hdl); /* destroy request tree */ if (mi_cmd) free_mi_tree( mi_cmd ); /* destroy the reply tree */ if (mi_rpl) free_mi_tree(mi_rpl); continue; } }