int jsonrpc_notification(struct sip_msg* _m, char* _method, char* _params) { str method; str params; if (fixup_get_svalue(_m, (gparam_p)_method, &method) != 0) { LM_ERR("cannot get method value\n"); return -1; } if (fixup_get_svalue(_m, (gparam_p)_params, ¶ms) != 0) { LM_ERR("cannot get params value\n"); return -1; } struct jsonrpc_pipe_cmd *cmd; if (!(cmd = (struct jsonrpc_pipe_cmd *) shm_malloc(sizeof(struct jsonrpc_pipe_cmd)))) return memory_error(); memset(cmd, 0, sizeof(struct jsonrpc_pipe_cmd)); cmd->method = shm_strdup(&method); cmd->params = shm_strdup(¶ms); cmd->notify_only = 1; if (write(cmd_pipe, &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to write to io pipe: %s\n", strerror(errno)); return -1; } return 1; }
static int xmpp_send_pipe_cmd(enum xmpp_pipe_cmd_type type, str *from, str *to, str *body, str *id) { struct xmpp_pipe_cmd *cmd; /* todo: make shm allocation for one big chunk to include all fields */ cmd = (struct xmpp_pipe_cmd *) shm_malloc(sizeof(struct xmpp_pipe_cmd)); memset(cmd, 0, sizeof(struct xmpp_pipe_cmd)); cmd->type = type; cmd->from = shm_strdup(from); cmd->to = shm_strdup(to); cmd->body = shm_strdup(body); cmd->id = shm_strdup(id); if (write(pipe_fds[1], &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to write to command pipe: %s\n", strerror(errno)); xmpp_free_pipe_cmd(cmd); return -1; } return 0; }
static int xmpp_send_pipe_cmd(enum xmpp_pipe_cmd_type type, str *from, str *to, str *body, str *id) { struct xmpp_pipe_cmd *cmd; /* todo: make shm allocation for one big chunk to include all fields */ cmd = (struct xmpp_pipe_cmd *) shm_malloc(sizeof(struct xmpp_pipe_cmd)); memset(cmd, 0, sizeof(struct xmpp_pipe_cmd)); cmd->type = type; cmd->from = shm_strdup(from); cmd->to = shm_strdup(to); cmd->body = shm_strdup(body); cmd->id = shm_strdup(id); if(pid == *xmpp_pid) /* if attempting to send from the xmpp extra process */ { LM_DBG("I am the XMPP extra process\n"); if(backend_mode == XMPP_COMP) { struct xmpp_private_data priv; priv.fd = curr_fd; priv.running = 1; xmpp_component_net_send(cmd, &priv); } else { xmpp_server_net_send(cmd); } } else { if (write(pipe_fds[1], &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to write to command pipe: %s\n", strerror(errno)); xmpp_free_pipe_cmd(cmd); return -1; } } return 0; }
int jsonrpc_request(struct sip_msg* _m, char* _method, char* _params, char* _cb_route, char* _err_route, char* _cb_pv) { str method; str params; str cb_route; str err_route; if (fixup_get_svalue(_m, (gparam_p)_method, &method) != 0) { LM_ERR("cannot get method value\n"); return -1; } if (fixup_get_svalue(_m, (gparam_p)_params, ¶ms) != 0) { LM_ERR("cannot get params value\n"); return -1; } if (fixup_get_svalue(_m, (gparam_p)_cb_route, &cb_route) != 0) { LM_ERR("cannot get cb_route value\n"); return -1; } if (fixup_get_svalue(_m, (gparam_p)_err_route, &err_route) != 0) { LM_ERR("cannot get err_route value\n"); return -1; } tm_cell_t *t = 0; t = tmb.t_gett(); if (t==NULL || t==T_UNDEFINED) { if(tmb.t_newtran(_m)<0) { LM_ERR("cannot create the transaction\n"); return -1; } t = tmb.t_gett(); if (t==NULL || t==T_UNDEFINED) { LM_ERR("cannot look up the transaction\n"); return -1; } } unsigned int hash_index; unsigned int label; if (tmb.t_suspend(_m, &hash_index, &label) < 0) { LM_ERR("t_suspend() failed\n"); return -1; } struct jsonrpc_pipe_cmd *cmd; if (!(cmd = (struct jsonrpc_pipe_cmd *) shm_malloc(sizeof(struct jsonrpc_pipe_cmd)))) return memory_error(); memset(cmd, 0, sizeof(struct jsonrpc_pipe_cmd)); pv_spec_t *cb_pv = (pv_spec_t*)shm_malloc(sizeof(pv_spec_t)); if (!cb_pv) return memory_error(); cb_pv = memcpy(cb_pv, (pv_spec_t *)_cb_pv, sizeof(pv_spec_t)); cmd->method = shm_strdup(&method); cmd->params = shm_strdup(¶ms); cmd->cb_route = shm_strdup(&cb_route); cmd->err_route = shm_strdup(&err_route); cmd->cb_pv = cb_pv; cmd->msg = _m; cmd->t_hash = hash_index; cmd->t_label = label; if (write(cmd_pipe, &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to write to io pipe: %s\n", strerror(errno)); return -1; } return 0; }
int cmd_erlang_info(struct sip_msg* msg, char *cn, char *rp, char *ar) { #define AVP_PRINTBUF_SIZE 1024 static char printbuf[AVP_PRINTBUF_SIZE]; int printbuf_len, bytessent; ei_x_buff argbuf; struct nodes_list* node; struct erlang_cmd *erl_cmd; erlang_pid erl_pid; str conname, regproc; int retcode = -1; if(msg==NULL) { LM_ERR("cmd_erlang_info: received null msg\n"); return -1; } if(fixup_get_svalue(msg, (gparam_p)cn, &conname)<0) { LM_ERR("cmd_erlang_info: cannot get the connection name\n"); return -1; } for(node=nodes_lst;node;node=node->next) { LM_DBG("cmd_erlang_info: matching %s with %.*s\n",node->name,conname.len,conname.s); if(strcmp(node->name, conname.s)==0) break; } if(node==0){ LM_ERR("cmd_erlang_info: no such connection %.*s\n",conname.len,conname.s); return -1; } if(fixup_get_svalue(msg, (gparam_p)rp, ®proc)<0) { LM_ERR("cmd_erlang_info: cannot get the regproc name\n"); return -1; } printbuf_len = AVP_PRINTBUF_SIZE-1; if(pv_printf(msg, (pv_elem_p)ar, printbuf, &printbuf_len)<0 || printbuf_len<=0) { LM_ERR("cmd_erlang_info: cannot expand erlang message body\n"); return -1; } erl_cmd=shm_malloc(sizeof(struct erlang_cmd)); if(!erl_cmd) { LM_ERR("no shm"); return -1; } memset(erl_cmd,0,sizeof(struct erlang_cmd)); erl_cmd->erlbuf=shm_malloc(AVP_PRINTBUF_SIZE); if (!erl_cmd->erlbuf) { LM_ERR("no shm memory\n\n"); goto error; } if(lock_init(&(erl_cmd->lock))==NULL) { LM_ERR("cannot init the lock\n"); goto error; } erl_cmd->reg_name=shm_strdup(®proc); if (!erl_cmd->reg_name) { LM_ERR("no shm memory\n\n"); goto error; } LM_DBG("cmd_erlang_info: %.*s %.*s %.*s\n",conname.len,conname.s, regproc.len,regproc.s, printbuf_len,printbuf); erl_cmd->cmd=ERLANG_INFO; erl_cmd->node=node; argbuf.buff=erl_cmd->erlbuf; argbuf.buffsz=AVP_PRINTBUF_SIZE-1; argbuf.index=0; ei_x_encode_version(&argbuf); //User passed term will be sedond element of tuple, first is our erlang pid ei_x_encode_tuple_header(&argbuf, 2); // we are hacking erlang pid so we can have worker system pid here memcpy(&erl_pid,ei_self(&(node->ec)),sizeof(erlang_pid)); erl_pid.num=getpid(); ei_x_encode_pid(&argbuf, &erl_pid); //so much for pid, now encode term if(ei_x_format_wo_ver(&argbuf, printbuf)!=0) { LM_ERR("cannot fromat erlang binary from arg string\n"); goto error; } // ei_x_encode_atom(&argbuf,"user"); erl_cmd->erlbuf_len=argbuf.index; lock_get(&(erl_cmd->lock)); bytessent=write(pipe_fds[1], &erl_cmd, sizeof(erl_cmd)); LM_DBG("cmd_erlang_info: locked, sent %d %d %s %d %p %p, waiting for release\n",bytessent, erl_cmd->cmd,erl_cmd->reg_name,erl_cmd->erlbuf_len,erl_cmd->erlbuf, erl_cmd); lock_get(&(erl_cmd->lock)); LM_DBG("after lock\n"); if (erl_cmd->retcode <0) { retcode=erl_cmd->retcode; LM_DBG("cmd_erlang_info: failed %d\n",retcode); goto error; } retcode=1; error: if(erl_cmd) { if(erl_cmd->erlbuf) shm_free(erl_cmd->erlbuf); if(erl_cmd->reg_name) shm_free(erl_cmd->reg_name); shm_free(erl_cmd); } return retcode; }
int cmd_erlang_rex(struct sip_msg* msg, char *cn , char *mo, char *fu, char *ar, char *_ret_pv) { #define AVP_PRINTBUF_SIZE 1024 static char printbuf[AVP_PRINTBUF_SIZE]; int printbuf_len, bytessent; ei_x_buff argbuf; struct nodes_list* node; struct erlang_cmd *erl_cmd; erlang_pid erl_pid; str conname, regproc; str mod, fun; int retcode = -1; if(msg==NULL) { LM_ERR("cmd_erlang_rex: received null msg\n"); return -1; } if(fixup_get_svalue(msg, (gparam_p)cn, &conname)<0) { LM_ERR("cmd_erlang_rex: cannot get the connection name\n"); return -1; } for(node=nodes_lst;node;node=node->next) { LM_DBG("matching %s with %.*s\n",node->name,conname.len,conname.s); if(strcmp(node->name, conname.s)==0) break; } if(node==0){ LM_ERR("cmd_erlang_rex: no such connection %.*s\n",conname.len,conname.s); return -1; } if(fixup_get_svalue(msg, (gparam_p)mo, &mod)<0) { LM_ERR("cmd_erlang_rex: cannot get the mod name\n"); return -1; } if(fixup_get_svalue(msg, (gparam_p)fu, &fun)<0) { LM_ERR("cmd_erlang_rex: cannot get the fun name\n"); return -1; } printbuf_len = AVP_PRINTBUF_SIZE-1; if(pv_printf(msg, (pv_elem_p)ar, printbuf, &printbuf_len)<0 || printbuf_len<=0) { LM_ERR("erlang_cmd_rex: cannot expand args expression.\n"); return -1; } erl_cmd=shm_malloc(sizeof(struct erlang_cmd)); if(!erl_cmd) { LM_ERR("no shm"); return -1; } memset(erl_cmd,0,sizeof(struct erlang_cmd)); erl_cmd->erlbuf=shm_malloc(AVP_PRINTBUF_SIZE); if (!erl_cmd->erlbuf) { LM_ERR("no shm memory\n\n"); goto error; } erl_cmd->ret_pv = (pv_spec_t*)shm_malloc(sizeof(pv_spec_t)); if (!erl_cmd->ret_pv) { LM_ERR("no shm memory\n\n"); goto error; } memcpy(erl_cmd->ret_pv, (pv_spec_t *)_ret_pv, sizeof(pv_spec_t)); if(lock_init(&(erl_cmd->lock))==NULL) { LM_ERR("cannot init the lock\n"); goto error; } regproc.s="rex"; regproc.len=3; erl_cmd->reg_name=shm_strdup(®proc); if (!erl_cmd->reg_name) { LM_ERR("no shm memory\n\n"); goto error; } LM_DBG("cmd_erlang_rex: %.*s rex %.*s\n",conname.len,conname.s, printbuf_len,printbuf); erl_cmd->cmd=ERLANG_REX; erl_cmd->node=node; argbuf.buff=erl_cmd->erlbuf; argbuf.buffsz=AVP_PRINTBUF_SIZE-1; argbuf.index=0; ei_x_encode_version(&argbuf); //User passed term will be second element of tuple, first is our (hacked) erlang pid ei_x_encode_tuple_header(&argbuf, 2); // we are hacking erlang pid so we can have worker system pid here memcpy(&erl_pid,ei_self(&(node->ec)),sizeof(erlang_pid)); erl_pid.num=getpid(); ei_x_encode_pid(&argbuf, &erl_pid); erl_cmd->num=erl_pid.num; erl_cmd->serial=erl_pid.serial; //so much for pid, now encode rex call tuple {call, mod, fun, arg, user} ei_x_encode_tuple_header(&argbuf, 5); ei_x_encode_atom(&argbuf,"call"); ei_x_encode_atom_len(&argbuf, mod.s, mod.len); ei_x_encode_atom_len(&argbuf, fun.s, fun.len); if(ei_x_format_wo_ver(&argbuf, printbuf)!=0) { LM_ERR("cannot fromat erlang binary from arg string\n"); goto error; } ei_x_encode_atom(&argbuf,"user"); erl_cmd->erlbuf_len=argbuf.index; lock_get(&(erl_cmd->lock)); bytessent=write(pipe_fds[1], &erl_cmd, sizeof(erl_cmd)); LM_DBG("cmd_erlang_call: locked, sent %d %d %s %d %p %p, waiting for release\n",bytessent, erl_cmd->cmd,erl_cmd->reg_name,erl_cmd->erlbuf_len,erl_cmd->erlbuf, erl_cmd); lock_get(&(erl_cmd->lock)); LM_DBG("after lock\n"); if (erl_cmd->retcode <0) { retcode=erl_cmd->retcode; LM_DBG("cmd_erlang_call: failed %d\n",retcode); goto error; } //reuse argbuf.buff=erl_cmd->erlbuf; argbuf.buffsz=erl_cmd->erlbuf_len; argbuf.index=erl_cmd->decode_index; fill_retpv(erl_cmd->ret_pv,&argbuf,&(argbuf.index)); retcode=1; error: if(erl_cmd) { if(erl_cmd->ret_pv) shm_free(erl_cmd->ret_pv); if(erl_cmd->erlbuf) shm_free(erl_cmd->erlbuf); if(erl_cmd->reg_name) shm_free(erl_cmd->reg_name); shm_free(erl_cmd); } return retcode; }