-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy patherlang_cmd_call.c
100 lines (93 loc) · 2.7 KB
/
erlang_cmd_call.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <sys/types.h>
#include <unistd.h>
#include "erlang_mod.h"
#include "erlang_cmd.h"
#include "erlang_listener.h"
#include "../../mod_fix.h"
int fixup_cmd_erlang_call(void** param, int param_no){
if (param_no < 3)
return fixup_spve_null(param, 1);
if (param_no == 4) {
return fixup_pvar_null(param, 1);
}
if (param_no == 3) {
pv_elem_t *model=NULL;
str s;
s.s = (char*)(*param);
s.len = strlen(s.s);
if(s.len==0) {
LM_ERR("cmd_erlang_call: param %d is empty string! please use erlang empty list [].\n", param_no);
return -1;
}
if(pv_parse_format(&s ,&model) || model==NULL) {
LM_ERR("cmd_erlang_call: wrong format [%s] for value param!\n", s.s);
return -1;
}
*param = (void*)model;
return 0;
}
LM_ERR("erlang_call takes exactly 4 parameters.\n");
return -1;
}
int cmd_erlang_call(struct sip_msg* msg, char *cn, char *rp, char *ar, char *_ret_pv) {
#define AVP_PRINTBUF_SIZE 1024
static char printbuf[AVP_PRINTBUF_SIZE];
int printbuf_len;
ei_x_buff argbuf,retbuf;
struct nodes_list* node;
pv_spec_t * ret_pv;
str conname, regproc;
int retcode = -1;
if(msg==NULL) {
LM_ERR("cmd_erlang_call: received null msg\n");
return -1;
}
if(fixup_get_svalue(msg, (gparam_p)cn, &conname)<0) {
LM_ERR("cmd_erlang_call: cannot get the connection name\n");
return -1;
}
for(node=nodes_lst;node;node=node->next) {
if(strcmp(node->name, conname.s)==0) break;
}
if(node==0) {
LM_ERR("cmd_erlang_call: 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_call: cannot get the registered proc 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_call: cannot expand args expression.\n");
return -1;
}
ret_pv = (pv_spec_t*)shm_malloc(sizeof(pv_spec_t));
if (!ret_pv) {
LM_ERR("no shm memory\n\n");
return -1;
}
memcpy(ret_pv, (pv_spec_t *)_ret_pv, sizeof(pv_spec_t));
LM_DBG("cmd_erlang_call: %.*s %.*s %.*s\n",conname.len,conname.s,
regproc.len,regproc.s, printbuf_len,printbuf);
ei_x_new(&argbuf);
if(ei_x_format_wo_ver(&argbuf, printbuf)!=0) {
LM_ERR("cannot fromat erlang binary from arg string\n");
goto error;
}
retcode=do_erlang_call(&conname, ®proc, &argbuf, &retbuf);
if(retcode==1) {
int offset=retbuf.index;
fill_retpv(ret_pv,&retbuf,&(retbuf.index));
lastterm.index=0;
ei_x_append_buf(&lastterm, retbuf.buff+offset,retbuf.index-offset);
lastterm.index=0;
LM_DBG("cmd_erlang_call successful\n");
} else {
LM_ERR("cmd_erlang_call failed %d\n", retcode);
}
error:
if(retbuf.buff) shm_free(retbuf.buff);
ei_x_free(&argbuf);
return retcode;
}