You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/src/modules/app_python/apy_kemi.c

1551 lines
44 KiB

/**
* Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com)
*
* This file is part of Kamailio, a free SIP server.
*
* Kamailio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* Kamailio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <Python.h>
#include <frameobject.h>
#include "../../core/dprint.h"
#include "../../core/route.h"
#include "../../core/fmsg.h"
#include "../../core/kemi.h"
#include "../../core/pvar.h"
#include "../../core/timer.h"
#include "../../core/mem/pkg.h"
#include "../../core/mem/shm.h"
#include "../../core/rpc.h"
#include "../../core/rpc_lookup.h"
#include "msgobj_struct.h"
#include "python_exec.h"
#include "apy_kemi_export.h"
#include "apy_kemi.h"
int *_sr_python_reload_version = NULL;
int _sr_python_local_version = 0;
extern str _sr_python_load_file;
extern int _apy_process_rank;
/**
*
*/
int sr_kemi_config_engine_python(sip_msg_t *msg, int rtype, str *rname,
str *rparam)
{
int ret;
ret = -1;
if(rtype==REQUEST_ROUTE) {
if(rname!=NULL && rname->s!=NULL) {
ret = apy_exec(msg, rname->s,
(rparam && rparam->s)?rparam->s:NULL, 0);
} else {
ret = apy_exec(msg, "ksr_request_route", NULL, 1);
}
} else if(rtype==CORE_ONREPLY_ROUTE) {
if(kemi_reply_route_callback.len>0) {
ret = apy_exec(msg, kemi_reply_route_callback.s, NULL, 0);
}
} else if(rtype==BRANCH_ROUTE) {
if(rname!=NULL && rname->s!=NULL) {
ret = apy_exec(msg, rname->s, NULL, 0);
}
} else if(rtype==FAILURE_ROUTE) {
if(rname!=NULL && rname->s!=NULL) {
ret = apy_exec(msg, rname->s, NULL, 0);
}
} else if(rtype==BRANCH_FAILURE_ROUTE) {
if(rname!=NULL && rname->s!=NULL) {
ret = apy_exec(msg, rname->s, NULL, 0);
}
} else if(rtype==TM_ONREPLY_ROUTE) {
if(rname!=NULL && rname->s!=NULL) {
ret = apy_exec(msg, rname->s, NULL, 0);
}
} else if(rtype==ONSEND_ROUTE) {
if(kemi_onsend_route_callback.len>0) {
ret = apy_exec(msg, kemi_onsend_route_callback.s, NULL, 0);
}
return 1;
} else if(rtype==EVENT_ROUTE) {
if(rname!=NULL && rname->s!=NULL) {
ret = apy_exec(msg, rname->s,
(rparam && rparam->s)?rparam->s:NULL, 0);
}
} else {
if(rname!=NULL) {
LM_ERR("route type %d with name [%.*s] not implemented\n",
rtype, rname->len, rname->s);
} else {
LM_ERR("route type %d with no name not implemented\n",
rtype);
}
}
if(rname!=NULL) {
LM_DBG("execution of route type %d with name [%.*s] returned %d\n",
rtype, rname->len, rname->s, ret);
} else {
LM_DBG("execution of route type %d with no name returned %d\n",
rtype, ret);
}
return 1;
}
/**
*
*/
PyObject *sr_kemi_apy_return_true(void)
{
Py_INCREF(Py_True);
return Py_True;
}
/**
*
*/
PyObject *sr_kemi_apy_return_false(void)
{
Py_INCREF(Py_False);
return Py_False;
}
/**
*
*/
PyObject *sr_apy_kemi_return_none(void)
{
Py_INCREF(Py_None);
return Py_None;
}
/**
*
*/
PyObject *sr_kemi_apy_return_int(sr_kemi_t *ket, int rval)
{
if(ket!=NULL && ket->rtype==SR_KEMIP_BOOL) {
if(rval==SR_KEMI_TRUE) {
return sr_kemi_apy_return_true();
} else {
return sr_kemi_apy_return_false();
}
}
return PyInt_FromLong((long)rval);
}
/**
*
*/
PyObject *sr_apy_kemi_return_str(sr_kemi_t *ket, char *sval, int slen)
{
return PyString_FromStringAndSize(sval, slen);
}
/**
*
*/
PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self,
PyObject *args, int idx)
{
str fname;
int i;
int ret;
sr_kemi_val_t vps[SR_KEMI_PARAMS_MAX];
sr_apy_env_t *env_P;
sip_msg_t *lmsg = NULL;
env_P = sr_apy_env_get();
if(env_P==NULL) {
LM_ERR("invalid Python environment attributes\n");
return sr_kemi_apy_return_false();
}
if(env_P->msg==NULL) {
lmsg = faked_msg_next();
} else {
lmsg = env_P->msg;
}
if(ket->mname.len>0) {
LM_DBG("execution of method: %.*s\n", ket->fname.len, ket->fname.s);
} else {
LM_DBG("execution of method: %.*s.%.*s\n",
ket->mname.len, ket->mname.s,
ket->fname.len, ket->fname.s);
}
fname = ket->fname;
if(ket->ptypes[0]==SR_KEMIP_NONE) {
ret = ((sr_kemi_fm_f)(ket->func))(lmsg);
return sr_kemi_apy_return_int(ket, ret);
}
memset(vps, 0, SR_KEMI_PARAMS_MAX*sizeof(sr_kemi_val_t));
if(ket->ptypes[1]==SR_KEMIP_NONE) {
i = 1;
if(ket->ptypes[0]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "i:kemi-param-n", &vps[0].n)) {
LM_ERR("unable to retrieve int param %d\n", 0);
return sr_kemi_apy_return_false();
}
LM_DBG("param[%d] for: %.*s is int: %d\n", i,
fname.len, fname.s, vps[0].n);
} else {
if(!PyArg_ParseTuple(args, "s:kemi-param-s", &vps[0].s.s)) {
LM_ERR("unable to retrieve str param %d\n", 0);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
LM_DBG("param[%d] for: %.*s is str: %.*s\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s);
}
} else if(ket->ptypes[2]==SR_KEMIP_NONE) {
i = 2;
if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "ii:kemi-param-nn", &vps[0].n, &vps[1].n)) {
LM_ERR("unable to retrieve int-int params %d\n", i);
return sr_kemi_apy_return_false();
}
LM_DBG("params[%d] for: %.*s are int-int: [%d] [%d]\n", i,
fname.len, fname.s, vps[0].n, vps[1].n);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "is:kemi-param-ns", &vps[0].n, &vps[1].s.s)) {
LM_ERR("unable to retrieve int-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[1].s.len = strlen(vps[1].s.s);
LM_DBG("params[%d] for: %.*s are int-str: [%d] [%.*s]\n", i,
fname.len, fname.s, vps[0].n, vps[1].s.len, vps[1].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "si:kemi-param-sn", &vps[0].s.s, &vps[1].n)) {
LM_ERR("unable to retrieve str-int params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
LM_DBG("params[%d] for: %.*s are str-int: [%.*s] [%d]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s, vps[1].n);
} else {
if(!PyArg_ParseTuple(args, "ss:kemi-param-ss", &vps[0].s.s, &vps[1].s.s)) {
LM_ERR("unable to retrieve str-str param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s);
}
} else if(ket->ptypes[3]==SR_KEMIP_NONE) {
i = 3;
if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "iii:kemi-param-nnn", &vps[0].n,
&vps[1].n, &vps[2].n)) {
LM_ERR("unable to retrieve int-int-int params %d\n", i);
return sr_kemi_apy_return_false();
}
LM_DBG("params[%d] for: %.*s are int-int-int: [%d] [%d] [%d]\n",
i, fname.len, fname.s, vps[0].n, vps[1].n, vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "iis:kemi-param-nns", &vps[0].n,
&vps[1].n, &vps[2].s.s)) {
LM_ERR("unable to retrieve int-int-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are int-int-str: [%d] [%d] [%.*s]\n", i,
fname.len, fname.s, vps[0].n, vps[1].n, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "isi:kemi-param-nsn", &vps[0].n,
&vps[1].s.s, &vps[2].n)) {
LM_ERR("unable to retrieve int-str-int params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[1].s.len = strlen(vps[1].s.s);
LM_DBG("params[%d] for: %.*s are int-str-int: [%d] [%.*s] [%d]\n", i,
fname.len, fname.s, vps[0].n, vps[1].s.len, vps[1].s.s, vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "iss:kemi-param-nss", &vps[0].n,
&vps[1].s.s, &vps[2].s.s)) {
LM_ERR("unable to retrieve int-str-str param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are int-str-str: [%d] [%.*s]"
" [%.*s]\n", i, fname.len, fname.s,
vps[0].n, vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "sii:kemi-param-snn", &vps[0].s.s,
&vps[1].n, &vps[2].n)) {
LM_ERR("unable to retrieve str-int-int params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
LM_DBG("params[%d] for: %.*s are str-int: [%.*s] [%d] [%d]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s, vps[1].n,
vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "sis:kemi-param-ssn", &vps[0].s.s,
&vps[1].n, &vps[2].s.s)) {
LM_ERR("unable to retrieve str-int-str param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are str-str-int: [%.*s] [%d] [%.*s]\n",
i, fname.len, fname.s,
vps[0].s.len, vps[0].s.s,
vps[1].n, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "ssi:kemi-param-ssn", &vps[0].s.s,
&vps[1].s.s, &vps[2].n)) {
LM_ERR("unable to retrieve str-str-int param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
LM_DBG("params[%d] for: %.*s are str-str-int: [%.*s] [%.*s]"
" [%d]\n", i, fname.len, fname.s,
vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "sss:kemi-param-sss", &vps[0].s.s,
&vps[1].s.s, &vps[2].s.s)) {
LM_ERR("unable to retrieve str-str-str param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are str-str-str: [%.*s] [%.*s]"
" [%.*s]\n", i, fname.len, fname.s,
vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s);
} else {
LM_ERR("not implemented yet\n");
return sr_kemi_apy_return_false();
}
} else if(ket->ptypes[4]==SR_KEMIP_NONE) {
i = 4;
if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "ssss:kemi-param-ssss",
&vps[0].s.s, &vps[1].s.s, &vps[2].s.s, &vps[3].s.s)) {
LM_ERR("unable to retrieve str-str-str-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
vps[3].s.len = strlen(vps[3].s.s);
LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]"
" [%.*s] [%.*s]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s,
vps[3].s.len, vps[3].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "sssi:kemi-param-sssn",
&vps[0].s.s, &vps[1].s.s, &vps[2].s.s, &vps[3].n)) {
LM_ERR("unable to retrieve str-str-int-int params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]"
" [%.*s] [%d]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s, vps[3].n);
} else if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT
&& ket->ptypes[3]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "ssii:kemi-param-ssnn",
&vps[0].s.s, &vps[1].s.s, &vps[2].n, &vps[3].n)) {
LM_ERR("unable to retrieve str-str-int-int params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]"
" [%d] [%d]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].n, vps[3].n);
} else {
LM_ERR("not implemented yet\n");
return sr_kemi_apy_return_false();
}
} else if(ket->ptypes[5]==SR_KEMIP_NONE) {
i = 5;
if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_STR
&& ket->ptypes[4]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "sssss:kemi-param-sssss",
&vps[0].s.s, &vps[1].s.s, &vps[2].s.s, &vps[3].s.s,
&vps[4].s.s)) {
LM_ERR("unable to retrieve str-str-str-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
vps[3].s.len = strlen(vps[3].s.s);
vps[4].s.len = strlen(vps[4].s.s);
LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]"
" [%.*s] [%.*s] [%.*s]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s,
vps[3].s.len, vps[3].s.s, vps[4].s.len, vps[4].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT
&& ket->ptypes[3]==SR_KEMIP_INT
&& ket->ptypes[4]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "ssiis:kemi-param-ssnns",
&vps[0].s.s, &vps[1].s.s, &vps[2].n, &vps[3].n,
&vps[4].s.s)) {
LM_ERR("unable to retrieve str-str-int-int-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
vps[4].s.len = strlen(vps[4].s.s);
LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]"
" [%d] [%d] [%.*s]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].n, vps[3].n,
vps[4].s.len, vps[4].s.s);
} else {
LM_ERR("not implemented yet\n");
return sr_kemi_apy_return_false();
}
} else {
i = 6;
if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_STR
&& ket->ptypes[4]==SR_KEMIP_STR
&& ket->ptypes[5]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "ssssss:kemi-param-ssssss",
&vps[0].s.s, &vps[1].s.s, &vps[2].s.s, &vps[3].s.s,
&vps[4].s.s, &vps[5].s.s)) {
LM_ERR("unable to retrieve str-str-str-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
vps[3].s.len = strlen(vps[3].s.s);
vps[4].s.len = strlen(vps[4].s.s);
vps[5].s.len = strlen(vps[5].s.s);
LM_DBG("params[%d] for: %.*s are str: [%.*s] [%.*s]"
" [%.*s] [%.*s] [%.*s] [%.*s]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s,
vps[3].s.len, vps[3].s.s, vps[4].s.len, vps[4].s.s,
vps[5].s.len, vps[5].s.s);
} else {
LM_ERR("not implemented yet\n");
return sr_kemi_apy_return_false();
}
}
switch(i) {
case 1:
if(ket->ptypes[0]==SR_KEMIP_INT) {
ret = ((sr_kemi_fmn_f)(ket->func))(lmsg, vps[0].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_STR) {
ret = ((sr_kemi_fms_f)(ket->func))(lmsg, &vps[0].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
break;
case 2:
if(ket->ptypes[0]==SR_KEMIP_INT) {
if(ket->ptypes[1]==SR_KEMIP_INT) {
ret = ((sr_kemi_fmnn_f)(ket->func))(lmsg, vps[0].n, vps[1].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[1]==SR_KEMIP_STR) {
ret = ((sr_kemi_fmns_f)(ket->func))(lmsg, vps[0].n, &vps[1].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
} else if(ket->ptypes[0]==SR_KEMIP_STR) {
if(ket->ptypes[1]==SR_KEMIP_INT) {
ret = ((sr_kemi_fmsn_f)(ket->func))(lmsg, &vps[0].s, vps[1].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[1]==SR_KEMIP_STR) {
ret = ((sr_kemi_fmss_f)(ket->func))(lmsg, &vps[0].s, &vps[1].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
break;
case 3:
if(ket->ptypes[0]==SR_KEMIP_INT) {
if(ket->ptypes[1]==SR_KEMIP_INT) {
if(ket->ptypes[2]==SR_KEMIP_INT) {
/* nnn */
ret = ((sr_kemi_fmnnn_f)(ket->func))(lmsg,
vps[0].n, vps[1].n, vps[2].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[2]==SR_KEMIP_STR) {
/* nns */
ret = ((sr_kemi_fmnns_f)(ket->func))(lmsg,
vps[0].n, vps[1].n, &vps[2].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
} else if(ket->ptypes[1]==SR_KEMIP_STR) {
if(ket->ptypes[2]==SR_KEMIP_INT) {
/* nsn */
ret = ((sr_kemi_fmnsn_f)(ket->func))(lmsg,
vps[0].n, &vps[1].s, vps[2].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[2]==SR_KEMIP_STR) {
/* nss */
ret = ((sr_kemi_fmnss_f)(ket->func))(lmsg,
vps[0].n, &vps[1].s, &vps[2].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
} else if(ket->ptypes[0]==SR_KEMIP_STR) {
if(ket->ptypes[1]==SR_KEMIP_INT) {
if(ket->ptypes[2]==SR_KEMIP_INT) {
/* snn */
ret = ((sr_kemi_fmsnn_f)(ket->func))(lmsg,
&vps[0].s, vps[1].n, vps[2].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[2]==SR_KEMIP_STR) {
/* sns */
ret = ((sr_kemi_fmsns_f)(ket->func))(lmsg,
&vps[0].s, vps[1].n, &vps[2].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
} else if(ket->ptypes[1]==SR_KEMIP_STR) {
if(ket->ptypes[2]==SR_KEMIP_INT) {
/* ssn */
ret = ((sr_kemi_fmssn_f)(ket->func))(lmsg,
&vps[0].s, &vps[1].s, vps[2].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[2]==SR_KEMIP_STR) {
/* sss */
ret = ((sr_kemi_fmsss_f)(ket->func))(lmsg,
&vps[0].s, &vps[1].s, &vps[2].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
break;
case 4:
if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_STR) {
/* ssss */
ret = ((sr_kemi_fmssss_f)(ket->func))(lmsg,
&vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_INT) {
/* ssnn */
ret = ((sr_kemi_fmsssn_f)(ket->func))(lmsg,
&vps[0].s, &vps[1].s, &vps[2].s, vps[3].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT
&& ket->ptypes[3]==SR_KEMIP_INT) {
/* ssnn */
ret = ((sr_kemi_fmssnn_f)(ket->func))(lmsg,
&vps[0].s, &vps[1].s, vps[2].n, vps[3].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_INT
&& ket->ptypes[3]==SR_KEMIP_INT) {
/* snnn */
ret = ((sr_kemi_fmsnnn_f)(ket->func))(lmsg,
&vps[0].s, vps[1].n, vps[2].n, vps[3].n);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_INT
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_STR) {
/* nsss */
ret = ((sr_kemi_fmnsss_f)(ket->func))(lmsg,
vps[0].n, &vps[1].s, &vps[2].s, &vps[3].s);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_INT
&& ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_STR) {
/* nnss */
ret = ((sr_kemi_fmnnss_f)(ket->func))(lmsg,
vps[0].n, vps[1].n, &vps[2].s, &vps[3].s);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_INT
&& ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_INT
&& ket->ptypes[3]==SR_KEMIP_STR) {
/* nnns */
ret = ((sr_kemi_fmnnns_f)(ket->func))(lmsg,
vps[0].n, vps[1].n, vps[2].n, &vps[3].s);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_INT
&& ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_INT
&& ket->ptypes[3]==SR_KEMIP_INT) {
/* nnnn */
ret = ((sr_kemi_fmnnnn_f)(ket->func))(lmsg,
vps[0].n, vps[1].n, vps[2].n, vps[3].n);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
break;
case 5:
if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_STR
&& ket->ptypes[4]==SR_KEMIP_STR) {
/* sssss */
ret = ((sr_kemi_fmsssss_f)(ket->func))(lmsg,
&vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s,
&vps[4].s);
return sr_kemi_apy_return_int(ket, ret);
} else if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT
&& ket->ptypes[3]==SR_KEMIP_INT
&& ket->ptypes[4]==SR_KEMIP_STR) {
/* ssnns */
ret = ((sr_kemi_fmssnns_f)(ket->func))(lmsg,
&vps[0].s, &vps[1].s, vps[2].n, vps[3].n,
&vps[4].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
break;
case 6:
if(ket->ptypes[0]==SR_KEMIP_STR
&& ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR
&& ket->ptypes[3]==SR_KEMIP_STR
&& ket->ptypes[4]==SR_KEMIP_STR
&& ket->ptypes[5]==SR_KEMIP_STR) {
/* ssssss */
ret = ((sr_kemi_fmssssss_f)(ket->func))(lmsg,
&vps[0].s, &vps[1].s, &vps[2].s, &vps[3].s,
&vps[4].s, &vps[5].s);
return sr_kemi_apy_return_int(ket, ret);
} else {
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
break;
default:
LM_ERR("invalid parameters for: %.*s\n",
fname.len, fname.s);
return sr_kemi_apy_return_false();
}
}
/**
*
*/
PyObject *sr_apy_kemi_exec_func(PyObject *self, PyObject *args, int idx)
{
sr_kemi_t *ket = NULL;
PyObject *ret = NULL;
PyThreadState *pstate = NULL;
PyFrameObject *pframe = NULL;
struct timeval tvb, tve;
struct timezone tz;
unsigned int tdiff;
ket = sr_apy_kemi_export_get(idx);
if(ket==NULL) {
return sr_kemi_apy_return_false();
}
if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0)
&& is_printable(cfg_get(core, core_cfg, latency_log))) {
gettimeofday(&tvb, &tz);
}
ret = sr_apy_kemi_exec_func_ex(ket, self, args, idx);
if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0)
&& is_printable(cfg_get(core, core_cfg, latency_log))) {
gettimeofday(&tve, &tz);
tdiff = (tve.tv_sec - tvb.tv_sec) * 1000000
+ (tve.tv_usec - tvb.tv_usec);
if(tdiff >= cfg_get(core, core_cfg, latency_limit_action)) {
pstate = PyThreadState_GET();
if (pstate != NULL && pstate->frame != NULL) {
pframe = pstate->frame;
}
LOG(cfg_get(core, core_cfg, latency_log),
"alert - action KSR.%s%s%s(...)"
" took too long [%u us] (file:%s func:%s line:%d)\n",
(ket->mname.len>0)?ket->mname.s:"",
(ket->mname.len>0)?".":"", ket->fname.s, tdiff,
(pframe)?PyString_AsString(pframe->f_code->co_filename):"",
(pframe)?PyString_AsString(pframe->f_code->co_name):"",
(pframe)?PyCode_Addr2Line(pframe->f_code, pframe->f_lasti):0);
}
}
return ret;
}
/**
*
*/
PyObject *_sr_apy_ksr_module = NULL;
PyObject *_sr_apy_ksr_module_dict = NULL;
PyObject **_sr_apy_ksr_modules_list = NULL;
PyMethodDef *_sr_KSRMethods = NULL;
#define SR_APY_KSR_MODULES_SIZE 256
#define SR_APY_KSR_METHODS_SIZE (SR_APY_KEMI_EXPORT_SIZE + SR_APY_KSR_MODULES_SIZE)
/**
*
*/
static int sr_apy_kemi_f_ktest(sip_msg_t *msg, str *txt)
{
if(txt!=NULL && txt->s!=NULL)
LM_DBG("%.*s", txt->len, txt->s);
return 0;
}
/**
*
*/
static sr_kemi_t _sr_apy_kemi_test[] = {
{ str_init(""), str_init("ktest"),
SR_KEMIP_NONE, sr_apy_kemi_f_ktest,
{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
};
/**
*
*/
PyObject *sr_apy_kemi_return_none_mode(int rmode)
{
if(rmode==1) {
return sr_apy_kemi_return_str(NULL, "<<null>>", 8);
} else if(rmode==2) {
return sr_apy_kemi_return_str(NULL, "", 0);
} else {
return sr_apy_kemi_return_none();
}
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_get_mode(PyObject *self, PyObject *args,
char *pfmt, int rmode)
{
str pvn;
pv_spec_t *pvs;
pv_value_t val;
int pl;
sr_apy_env_t *env_P;
sip_msg_t *lmsg = NULL;
env_P = sr_apy_env_get();
if(env_P==NULL) {
LM_ERR("invalid Python environment attributes\n");
return sr_apy_kemi_return_none_mode(rmode);
}
if(env_P->msg==NULL) {
lmsg = faked_msg_next();
} else {
lmsg = env_P->msg;
}
if(!PyArg_ParseTuple(args, pfmt, &pvn.s)) {
LM_ERR("unable to retrieve str param\n");
return sr_apy_kemi_return_none_mode(rmode);
}
if(pvn.s==NULL || lmsg==NULL) {
LM_ERR("invalid context attributes\n");
return sr_apy_kemi_return_none_mode(rmode);
}
pvn.len = strlen(pvn.s);
LM_DBG("pv get: %s\n", pvn.s);
pl = pv_locate_name(&pvn);
if(pl != pvn.len) {
LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
return sr_apy_kemi_return_none_mode(rmode);
}
pvs = pv_cache_get(&pvn);
if(pvs==NULL) {
LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
return sr_apy_kemi_return_none_mode(rmode);
}
memset(&val, 0, sizeof(pv_value_t));
if(pv_get_spec_value(lmsg, pvs, &val) != 0)
{
LM_ERR("unable to get pv value for [%s]\n", pvn.s);
return sr_apy_kemi_return_none_mode(rmode);
}
if(val.flags&PV_VAL_NULL) {
return sr_apy_kemi_return_none_mode(rmode);
}
if(val.flags&PV_TYPE_INT) {
return sr_kemi_apy_return_int(NULL, val.ri);
}
return sr_apy_kemi_return_str(NULL, val.rs.s, val.rs.len);
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_get(PyObject *self, PyObject *args)
{
return sr_apy_kemi_f_pv_get_mode(self, args, "s:pv.get", 0);
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_getw(PyObject *self, PyObject *args)
{
return sr_apy_kemi_f_pv_get_mode(self, args, "s:pv.getw", 1);
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_gete(PyObject *self, PyObject *args)
{
return sr_apy_kemi_f_pv_get_mode(self, args, "s:pv.gete", 2);
}
/**
*
*/
static PyObject *sr_apy_kemi_pv_push_valx(int rmode, int xival, str *xsval)
{
if(rmode==1) {
return sr_kemi_apy_return_int(NULL, xival);
} else {
return sr_apy_kemi_return_str(NULL, xsval->s, xsval->len);
}
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_get_valx(PyObject *self, PyObject *args,
int rmode)
{
str pvn;
pv_spec_t *pvs;
pv_value_t val;
int pl;
sr_apy_env_t *env_P;
sip_msg_t *lmsg = NULL;
int xival = 0;
str xsval = str_init("");
env_P = sr_apy_env_get();
if(env_P==NULL) {
LM_ERR("invalid Python environment attributes\n");
return sr_apy_kemi_return_none_mode(rmode);
}
if(env_P->msg==NULL) {
lmsg = faked_msg_next();
} else {
lmsg = env_P->msg;
}
memset(&val, 0, sizeof(pv_value_t));
if(rmode==1) {
if(!PyArg_ParseTuple(args, "si:pv.getvn", &pvn.s, &xival)) {
LM_ERR("unable to retrieve str-int params\n");
return sr_apy_kemi_return_none_mode(rmode);
}
} else {
if(!PyArg_ParseTuple(args, "ss:pv.getvs", &pvn.s, &xival)) {
LM_ERR("unable to retrieve str-int params\n");
return sr_apy_kemi_return_none_mode(rmode);
}
}
if(pvn.s==NULL || lmsg==NULL) {
LM_ERR("invalid context attributes\n");
return sr_apy_kemi_pv_push_valx(rmode, xival, &xsval);
}
val.flags |= PV_TYPE_INT|PV_VAL_INT;
pvn.len = strlen(pvn.s);
LM_DBG("pv set: %s\n", pvn.s);
pl = pv_locate_name(&pvn);
if(pl != pvn.len) {
LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
return sr_apy_kemi_pv_push_valx(rmode, xival, &xsval);
}
pvs = pv_cache_get(&pvn);
if(pvs==NULL) {
LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
return sr_apy_kemi_pv_push_valx(rmode, xival, &xsval);
}
memset(&val, 0, sizeof(pv_value_t));
if(pv_get_spec_value(lmsg, pvs, &val) != 0) {
LM_ERR("unable to get pv value for [%s]\n", pvn.s);
return sr_apy_kemi_pv_push_valx(rmode, xival, &xsval);
}
if(val.flags&PV_VAL_NULL) {
return sr_apy_kemi_pv_push_valx(rmode, xival, &xsval);
}
if(val.flags&PV_TYPE_INT) {
return sr_kemi_apy_return_int(NULL, val.ri);
}
return sr_apy_kemi_return_str(NULL, val.rs.s, val.rs.len);
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_getvs(PyObject *self, PyObject *args)
{
return sr_apy_kemi_f_pv_get_valx(self, args, 0);
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_getvn(PyObject *self, PyObject *args)
{
return sr_apy_kemi_f_pv_get_valx(self, args, 1);
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_seti(PyObject *self, PyObject *args)
{
str pvn;
pv_spec_t *pvs;
pv_value_t val;
int pl;
sr_apy_env_t *env_P;
sip_msg_t *lmsg = NULL;
env_P = sr_apy_env_get();
if(env_P==NULL) {
LM_ERR("invalid Python environment attributes\n");
return sr_kemi_apy_return_false();
}
if(env_P->msg==NULL) {
lmsg = faked_msg_next();
} else {
lmsg = env_P->msg;
}
memset(&val, 0, sizeof(pv_value_t));
if(!PyArg_ParseTuple(args, "si:pv.seti", &pvn.s, &val.ri)) {
LM_ERR("unable to retrieve str-int params\n");
return sr_kemi_apy_return_false();
}
if(pvn.s==NULL || lmsg==NULL) {
LM_ERR("invalid context attributes\n");
return sr_kemi_apy_return_false();
}
val.flags |= PV_TYPE_INT|PV_VAL_INT;
pvn.len = strlen(pvn.s);
LM_DBG("pv set: %s\n", pvn.s);
pl = pv_locate_name(&pvn);
if(pl != pvn.len) {
LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
return sr_kemi_apy_return_false();
}
pvs = pv_cache_get(&pvn);
if(pvs==NULL) {
LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
return sr_kemi_apy_return_false();
}
if(pv_set_spec_value(lmsg, pvs, 0, &val)<0)
{
LM_ERR("unable to set pv [%s]\n", pvn.s);
return sr_kemi_apy_return_false();
}
return sr_kemi_apy_return_true();
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_sets(PyObject *self, PyObject *args)
{
str pvn;
pv_spec_t *pvs;
pv_value_t val;
int pl;
sr_apy_env_t *env_P;
sip_msg_t *lmsg = NULL;
env_P = sr_apy_env_get();
if(env_P==NULL) {
LM_ERR("invalid Python environment attributes\n");
return sr_kemi_apy_return_false();
}
if(env_P->msg==NULL) {
lmsg = faked_msg_next();
} else {
lmsg = env_P->msg;
}
memset(&val, 0, sizeof(pv_value_t));
if(!PyArg_ParseTuple(args, "ss:pv.sets", &pvn.s, &val.rs.s)) {
LM_ERR("unable to retrieve str-int params\n");
return sr_kemi_apy_return_false();
}
if(pvn.s==NULL || val.rs.s==NULL || lmsg==NULL) {
LM_ERR("invalid context attributes\n");
return sr_kemi_apy_return_false();
}
val.rs.len = strlen(val.rs.s);
val.flags |= PV_VAL_STR;
pvn.len = strlen(pvn.s);
LM_DBG("pv set: %s\n", pvn.s);
pl = pv_locate_name(&pvn);
if(pl != pvn.len) {
LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
return sr_kemi_apy_return_false();
}
pvs = pv_cache_get(&pvn);
if(pvs==NULL) {
LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
return sr_kemi_apy_return_false();
}
if(pv_set_spec_value(lmsg, pvs, 0, &val)<0) {
LM_ERR("unable to set pv [%s]\n", pvn.s);
return sr_kemi_apy_return_false();
}
return sr_kemi_apy_return_true();
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_unset(PyObject *self, PyObject *args)
{
str pvn;
pv_spec_t *pvs;
pv_value_t val;
int pl;
sr_apy_env_t *env_P;
sip_msg_t *lmsg = NULL;
env_P = sr_apy_env_get();
if(env_P==NULL) {
LM_ERR("invalid Python environment attributes\n");
return sr_kemi_apy_return_false();
}
if(env_P->msg==NULL) {
lmsg = faked_msg_next();
} else {
lmsg = env_P->msg;
}
if(!PyArg_ParseTuple(args, "s:pv.unset", &pvn.s)) {
LM_ERR("unable to retrieve str param\n");
return sr_kemi_apy_return_false();
}
if(pvn.s==NULL || lmsg==NULL) {
LM_ERR("invalid context attributes\n");
return sr_kemi_apy_return_false();
}
pvn.len = strlen(pvn.s);
LM_DBG("pv unset: %s\n", pvn.s);
pl = pv_locate_name(&pvn);
if(pl != pvn.len) {
LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
return sr_kemi_apy_return_false();
}
pvs = pv_cache_get(&pvn);
if(pvs==NULL) {
LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
return sr_kemi_apy_return_false();
}
memset(&val, 0, sizeof(pv_value_t));
val.flags |= PV_VAL_NULL;
if(pv_set_spec_value(lmsg, pvs, 0, &val)<0) {
LM_ERR("unable to unset pv [%s]\n", pvn.s);
return sr_kemi_apy_return_false();
}
return sr_kemi_apy_return_true();
}
/**
*
*/
static PyObject *sr_apy_kemi_f_pv_is_null(PyObject *self, PyObject *args)
{
str pvn;
pv_spec_t *pvs;
pv_value_t val;
int pl;
sr_apy_env_t *env_P;
sip_msg_t *lmsg = NULL;
env_P = sr_apy_env_get();
if(env_P==NULL) {
LM_ERR("invalid Python environment attributes\n");
return sr_kemi_apy_return_false();
}
if(env_P->msg==NULL) {
lmsg = faked_msg_next();
} else {
lmsg = env_P->msg;
}
if(!PyArg_ParseTuple(args, "s:pv.unset", &pvn.s)) {
LM_ERR("unable to retrieve str param\n");
return sr_kemi_apy_return_false();
}
if(pvn.s==NULL || lmsg==NULL) {
LM_ERR("invalid context attributes\n");
return sr_kemi_apy_return_false();
}
pvn.len = strlen(pvn.s);
LM_DBG("pv is null test: %s\n", pvn.s);
pl = pv_locate_name(&pvn);
if(pl != pvn.len) {
LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
return sr_kemi_apy_return_false();
}
pvs = pv_cache_get(&pvn);
if(pvs==NULL) {
LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
return sr_kemi_apy_return_true();
}
memset(&val, 0, sizeof(pv_value_t));
if(pv_get_spec_value(lmsg, pvs, &val) != 0) {
LM_NOTICE("unable to get pv value for [%s]\n", pvn.s);
return sr_kemi_apy_return_true();
}
if(val.flags&PV_VAL_NULL) {
return sr_kemi_apy_return_true();
} else {
return sr_kemi_apy_return_false();
}
}
static PyMethodDef _sr_apy_kemi_pv_Methods[] = {
{"get", sr_apy_kemi_f_pv_get, METH_VARARGS,
NAME " - pv get value"},
{"getw", sr_apy_kemi_f_pv_getw, METH_VARARGS,
NAME " - pv get value or <<null>>"},
{"getvs", sr_apy_kemi_f_pv_getvs, METH_VARARGS,
NAME " - pv get value of pv or str val param"},
{"getvn", sr_apy_kemi_f_pv_getvn, METH_VARARGS,
NAME " - pv get value of pv or int val param"},
{"gete", sr_apy_kemi_f_pv_gete, METH_VARARGS,
NAME " - pv get value or empty string"},
{"seti", sr_apy_kemi_f_pv_seti, METH_VARARGS,
NAME " - pv set int value"},
{"sets", sr_apy_kemi_f_pv_sets, METH_VARARGS,
NAME " - pv set str value"},
{"unset", sr_apy_kemi_f_pv_unset, METH_VARARGS,
NAME " - pv uset value (assign $null)"},
{"is_null", sr_apy_kemi_f_pv_is_null, METH_VARARGS,
NAME " - pv test if it is $null"},
{NULL, NULL, 0, NULL}
};
/**
*
*/
static PyMethodDef _sr_apy_kemi_x_Methods[] = {
{"modf", (PyCFunction)msg_call_function, METH_VARARGS,
"Invoke function exported by the other module."},
{NULL, NULL, 0, NULL} /* sentinel */
};
/**
*
*/
int sr_apy_init_ksr(void)
{
PyMethodDef *_sr_crt_KSRMethods = NULL;
sr_kemi_module_t *emods = NULL;
int emods_size = 0;
int i;
int k;
int m;
int n;
char mname[128];
/* init faked sip msg */
if(faked_msg_init()<0)
{
LM_ERR("failed to init local faked sip msg\n");
return -1;
}
_sr_KSRMethods = malloc(SR_APY_KSR_METHODS_SIZE * sizeof(PyMethodDef));
if(_sr_KSRMethods==NULL) {
LM_ERR("no more pkg memory\n");
return -1;
}
_sr_apy_ksr_modules_list = malloc(SR_APY_KSR_MODULES_SIZE * sizeof(PyObject*));
if(_sr_apy_ksr_modules_list==NULL) {
LM_ERR("no more pkg memory\n");
return -1;
}
memset(_sr_KSRMethods, 0, SR_APY_KSR_METHODS_SIZE * sizeof(PyMethodDef));
memset(_sr_apy_ksr_modules_list, 0, SR_APY_KSR_MODULES_SIZE * sizeof(PyObject*));
emods_size = sr_kemi_modules_size_get();
emods = sr_kemi_modules_get();
n = 0;
_sr_crt_KSRMethods = _sr_KSRMethods;
if(emods_size==0 || emods[0].kexp==NULL) {
LM_DBG("exporting KSR.%s(...)\n", _sr_apy_kemi_test[0].fname.s);
_sr_crt_KSRMethods[0].ml_name = _sr_apy_kemi_test[0].fname.s;
_sr_crt_KSRMethods[0].ml_meth = sr_apy_kemi_export_associate(&_sr_apy_kemi_test[0]);
_sr_crt_KSRMethods[0].ml_flags = METH_VARARGS;
_sr_crt_KSRMethods[0].ml_doc = NAME " exported function";
} else {
for(i=0; emods[0].kexp[i].func!=NULL; i++) {
LM_DBG("exporting KSR.%s(...)\n", emods[0].kexp[i].fname.s);
_sr_crt_KSRMethods[i].ml_name = emods[0].kexp[i].fname.s;
_sr_crt_KSRMethods[i].ml_meth =
sr_apy_kemi_export_associate(&emods[0].kexp[i]);
if(_sr_crt_KSRMethods[i].ml_meth == NULL) {
LM_ERR("failed to associate kemi function with python export\n");
free(_sr_KSRMethods);
_sr_KSRMethods = NULL;
return -1;
}
_sr_crt_KSRMethods[i].ml_flags = METH_VARARGS;
_sr_crt_KSRMethods[i].ml_doc = NAME " exported function";
n++;
}
}
_sr_apy_ksr_module = Py_InitModule("KSR", _sr_crt_KSRMethods);
_sr_apy_ksr_module_dict = PyModule_GetDict(_sr_apy_ksr_module);
Py_INCREF(_sr_apy_ksr_module);
m = 0;
/* special sub-modules - pv.get() can return int or string */
_sr_apy_ksr_modules_list[m] = Py_InitModule("KSR.pv",
_sr_apy_kemi_pv_Methods);
PyDict_SetItemString(_sr_apy_ksr_module_dict,
"pv", _sr_apy_ksr_modules_list[m]);
Py_INCREF(_sr_apy_ksr_modules_list[m]);
m++;
/* special sub-modules - x.modf() can have variable number of params */
_sr_apy_ksr_modules_list[m] = Py_InitModule("KSR.x",
_sr_apy_kemi_x_Methods);
PyDict_SetItemString(_sr_apy_ksr_module_dict,
"x", _sr_apy_ksr_modules_list[m]);
Py_INCREF(_sr_apy_ksr_modules_list[m]);
m++;
if(emods_size>1) {
for(k=1; k<emods_size; k++) {
n++;
_sr_crt_KSRMethods = _sr_KSRMethods + n;
snprintf(mname, 128, "KSR.%s", emods[k].kexp[0].mname.s);
for(i=0; emods[k].kexp[i].func!=NULL; i++) {
LM_DBG("exporting %s.%s(...)\n", mname,
emods[k].kexp[i].fname.s);
_sr_crt_KSRMethods[i].ml_name = emods[k].kexp[i].fname.s;
_sr_crt_KSRMethods[i].ml_meth =
sr_apy_kemi_export_associate(&emods[k].kexp[i]);
if(_sr_crt_KSRMethods[i].ml_meth == NULL) {
LM_ERR("failed to associate kemi function with python export\n");
free(_sr_KSRMethods);
_sr_KSRMethods = NULL;
return -1;
}
_sr_crt_KSRMethods[i].ml_flags = METH_VARARGS;
_sr_crt_KSRMethods[i].ml_doc = NAME " exported function";
n++;
}
LM_DBG("initializing kemi sub-module: %s (%s)\n", mname,
emods[k].kexp[0].mname.s);
_sr_apy_ksr_modules_list[m] = Py_InitModule(mname, _sr_crt_KSRMethods);
PyDict_SetItemString(_sr_apy_ksr_module_dict,
emods[k].kexp[0].mname.s, _sr_apy_ksr_modules_list[m]);
Py_INCREF(_sr_apy_ksr_modules_list[m]);
m++;
}
}
LM_DBG("module 'KSR' has been initialized\n");
return 0;
}
/**
*
*/
void sr_apy_destroy_ksr(void)
{
if(_sr_apy_ksr_module!=NULL) {
Py_XDECREF(_sr_apy_ksr_module);
_sr_apy_ksr_module = NULL;
}
if(_sr_apy_ksr_module_dict!=NULL) {
Py_XDECREF(_sr_apy_ksr_module_dict);
_sr_apy_ksr_module_dict = NULL;
}
if(_sr_KSRMethods!=NULL) {
free(_sr_KSRMethods);
_sr_KSRMethods = NULL;
}
LM_DBG("module 'KSR' has been destroyed\n");
}
/**
*
*/
int apy_sr_init_mod(void)
{
if(_sr_python_reload_version == NULL) {
_sr_python_reload_version = (int*)shm_malloc(sizeof(int));
if(_sr_python_reload_version == NULL) {
LM_ERR("failed to allocated reload version\n");
return -1;
}
*_sr_python_reload_version = 0;
}
return 0;
}
static const char* app_python_rpc_reload_doc[2] = {
"Reload python file",
0
};
static void app_python_rpc_reload(rpc_t* rpc, void* ctx)
{
void *vh;
if(_sr_python_load_file.s == NULL && _sr_python_load_file.len<=0) {
LM_WARN("script file path not provided\n");
rpc->fault(ctx, 500, "No script file");
return;
}
if(_sr_python_reload_version == NULL) {
LM_WARN("reload not enabled\n");
rpc->fault(ctx, 500, "Reload not enabled");
return;
}
*_sr_python_reload_version += 1;
LM_INFO("marking for reload Python script file: %.*s (%d)\n",
_sr_python_load_file.len, _sr_python_load_file.s,
*_sr_python_reload_version);
if (rpc->add(ctx, "{", &vh) < 0) {
rpc->fault(ctx, 500, "Server error");
return;
}
rpc->struct_add(vh, "dd",
"old", *_sr_python_reload_version-1,
"new", *_sr_python_reload_version);
return;
}
static const char* app_python_rpc_api_list_doc[2] = {
"List kemi exports to javascript",
0
};
static void app_python_rpc_api_list(rpc_t* rpc, void* ctx)
{
int i;
int n;
sr_kemi_t *ket;
void* th;
void* sh;
void* ih;
if (rpc->add(ctx, "{", &th) < 0) {
rpc->fault(ctx, 500, "Internal error root reply");
return;
}
n = 0;
for(i=0; i<SR_APY_KSR_METHODS_SIZE ; i++) {
ket = sr_apy_kemi_export_get(i);
if(ket==NULL) continue;
n++;
}
if(rpc->struct_add(th, "d[",
"msize", n,
"methods", &ih)<0)
{
rpc->fault(ctx, 500, "Internal error array structure");
return;
}
for(i=0; i<SR_APY_KSR_METHODS_SIZE; i++) {
ket = sr_apy_kemi_export_get(i);
if(ket==NULL) continue;
if(rpc->struct_add(ih, "{", "func", &sh)<0) {
rpc->fault(ctx, 500, "Internal error internal structure");
return;
}
if(rpc->struct_add(sh, "SSSS",
"ret", sr_kemi_param_map_get_name(ket->rtype),
"module", &ket->mname,
"name", &ket->fname,
"params", sr_kemi_param_map_get_params(ket->ptypes))<0) {
LM_ERR("failed to add the structure with attributes (%d)\n", i);
rpc->fault(ctx, 500, "Internal error creating dest struct");
return;
}
}
}
rpc_export_t app_python_rpc_cmds[] = {
{"app_python.reload", app_python_rpc_reload,
app_python_rpc_reload_doc, 0},
{"app_python.api_list", app_python_rpc_api_list,
app_python_rpc_api_list_doc, 0},
{0, 0, 0, 0}
};
/**
* register RPC commands
*/
int app_python_init_rpc(void)
{
if (rpc_register_array(app_python_rpc_cmds)!=0)
{
LM_ERR("failed to register RPC commands\n");
return -1;
}
return 0;
}