Bläddra i källkod

core: kemi - functions for KSR.pv module implemented in core

- to replace those implemented in each interpreter module for better
coherence and make it easier to extend the KSR.pv sub-module in the future
Daniel-Constantin Mierla 6 år sedan
förälder
incheckning
64f744e9c7
2 ändrade filer med 363 tillägg och 1 borttagningar
  1. 360 0
      src/core/kemi.c
  2. 3 1
      src/core/kemi.h

+ 360 - 0
src/core/kemi.c

@@ -32,6 +32,7 @@
 #include "data_lump_rpl.h"
 #include "strutils.h"
 #include "select_buf.h"
+#include "pvar.h"
 #include "mem/shm.h"
 #include "parser/parse_uri.h"
 #include "parser/parse_from.h"
@@ -2011,6 +2012,365 @@ static sr_kemi_t _sr_kemi_hdr[] = {
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
 };
 
+
+/**
+ *
+ */
+static void sr_kemi_xval_pv_null(sr_kemi_xval_t *xval, int rmode)
+{
+	if(rmode==1) {
+		xval->vtype = SR_KEMIP_STR;
+		xval->v.s = *pv_get_null_str();
+	} else if(rmode==2) {
+		xval->vtype = SR_KEMIP_STR;
+		xval->v.s = *pv_get_empty_str();
+	} else {
+		xval->vtype = SR_KEMIP_NULL;
+		xval->v.s.s = NULL;
+		xval->v.s.len = 0;
+	}
+}
+
+/**
+ *
+ */
+static sr_kemi_xval_t _sr_kemi_xval = {0};
+
+/**
+ *
+ */
+static sr_kemi_xval_t* sr_kemi_pv_get_mode(sip_msg_t *msg, str *pvn, int rmode)
+{
+	pv_spec_t *pvs;
+	pv_value_t val;
+	int pl;
+
+	memset(&_sr_kemi_xval, 0, sizeof(sr_kemi_xval_t));
+
+	LM_DBG("pv get: %.*s\n", pvn->len, pvn->s);
+	pl = pv_locate_name(pvn);
+	if(pl != pvn->len) {
+		LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
+		sr_kemi_xval_pv_null(&_sr_kemi_xval, rmode);
+		return &_sr_kemi_xval;
+	}
+	pvs = pv_cache_get(pvn);
+	if(pvs==NULL) {
+		LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
+		sr_kemi_xval_pv_null(&_sr_kemi_xval, rmode);
+		return &_sr_kemi_xval;
+	}
+
+	memset(&val, 0, sizeof(pv_value_t));
+	if(pv_get_spec_value(msg, pvs, &val) != 0) {
+		LM_ERR("unable to get pv value for [%.*s]\n", pvn->len, pvn->s);
+		sr_kemi_xval_pv_null(&_sr_kemi_xval, rmode);
+		return &_sr_kemi_xval;
+	}
+	if(val.flags&PV_VAL_NULL) {
+		sr_kemi_xval_pv_null(&_sr_kemi_xval, rmode);
+		return &_sr_kemi_xval;
+	}
+	if(val.flags&PV_TYPE_INT) {
+		_sr_kemi_xval.vtype = SR_KEMIP_INT;
+		_sr_kemi_xval.v.n = val.ri;
+		return &_sr_kemi_xval;
+	}
+	_sr_kemi_xval.vtype = SR_KEMIP_STR;
+	_sr_kemi_xval.v.s = val.rs;
+	return &_sr_kemi_xval;
+}
+
+/**
+ *
+ */
+static sr_kemi_xval_t* sr_kemi_pv_get(sip_msg_t *msg, str *pvn)
+{
+	return sr_kemi_pv_get_mode(msg, pvn, 0);
+}
+
+/**
+ *
+ */
+static sr_kemi_xval_t* sr_kemi_pv_getw(sip_msg_t *msg, str *pvn)
+{
+	return sr_kemi_pv_get_mode(msg, pvn, 1);
+}
+
+/**
+ *
+ */
+static sr_kemi_xval_t* sr_kemi_pv_gete(sip_msg_t *msg, str *pvn)
+{
+	return sr_kemi_pv_get_mode(msg, pvn, 2);
+}
+
+/**
+ *
+ */
+static void sr_kemi_pv_push_valx (sr_kemi_xval_t *xval, int rmode, int vi, str *vs)
+{
+	if(rmode==1) {
+		xval->vtype = SR_KEMIP_INT;
+		xval->v.n = vi;
+	} else {
+		xval->vtype = SR_KEMIP_STR;
+		xval->v.s = *vs;
+	}
+}
+
+/**
+ *
+ */
+static sr_kemi_xval_t* sr_kemi_pv_get_valx (sip_msg_t *msg, str *pvn, str *xsval,
+		int xival, int rmode)
+{
+	pv_spec_t *pvs;
+	pv_value_t val;
+	int pl;
+
+	memset(&_sr_kemi_xval, 0, sizeof(sr_kemi_xval_t));
+
+	LM_DBG("pv get: %.*s\n", pvn->len, pvn->s);
+	pl = pv_locate_name(pvn);
+	if(pl != pvn->len) {
+		LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
+		sr_kemi_pv_push_valx(&_sr_kemi_xval, rmode, xival, xsval);
+		return &_sr_kemi_xval;
+	}
+	pvs = pv_cache_get(pvn);
+	if(pvs==NULL) {
+		LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
+		sr_kemi_pv_push_valx(&_sr_kemi_xval, rmode, xival, xsval);
+		return &_sr_kemi_xval;
+	}
+
+	memset(&val, 0, sizeof(pv_value_t));
+	if(pv_get_spec_value(msg, pvs, &val) != 0) {
+		LM_ERR("unable to get pv value for [%.*s]\n", pvn->len, pvn->s);
+		sr_kemi_pv_push_valx(&_sr_kemi_xval, rmode, xival, xsval);
+		return &_sr_kemi_xval;
+	}
+	if(val.flags&PV_VAL_NULL) {
+		sr_kemi_pv_push_valx(&_sr_kemi_xval, rmode, xival, xsval);
+		return &_sr_kemi_xval;
+	}
+	if(val.flags&PV_TYPE_INT) {
+		_sr_kemi_xval.vtype = SR_KEMIP_INT;
+		_sr_kemi_xval.v.n = val.ri;
+		return &_sr_kemi_xval;
+	}
+	_sr_kemi_xval.vtype = SR_KEMIP_STR;
+	_sr_kemi_xval.v.s = val.rs;
+	return &_sr_kemi_xval;
+}
+
+/**
+ *
+ */
+static sr_kemi_xval_t* sr_kemi_pv_getvs (sip_msg_t *msg, str *pvn, str *xsval)
+{
+	return sr_kemi_pv_get_valx (msg, pvn, xsval, 0, 0);
+}
+
+/**
+ *
+ */
+static sr_kemi_xval_t* sr_kemi_pv_getvn (sip_msg_t *msg, str *pvn, int xival)
+{
+	return sr_kemi_pv_get_valx (msg, pvn, NULL, xival, 1);
+}
+
+/**
+ *
+ */
+static int sr_kemi_pv_seti (sip_msg_t *msg, str *pvn, int ival)
+{
+	pv_spec_t *pvs;
+	pv_value_t val;
+	int pl;
+
+	LM_DBG("pv get: %.*s\n", pvn->len, pvn->s);
+	pl = pv_locate_name(pvn);
+	if(pl != pvn->len) {
+		LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
+		return SR_KEMI_FALSE;
+	}
+	pvs = pv_cache_get(pvn);
+	if(pvs==NULL) {
+		LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
+		return SR_KEMI_FALSE;
+	}
+
+	memset(&val, 0, sizeof(pv_value_t));
+	val.ri = ival;
+	val.flags |= PV_TYPE_INT|PV_VAL_INT;
+
+	if(pv_set_spec_value(msg, pvs, 0, &val)<0) {
+		LM_ERR("unable to set pv [%.*s]\n", pvn->len, pvn->s);
+		return SR_KEMI_FALSE;
+	}
+
+	return SR_KEMI_TRUE;
+}
+
+/**
+ *
+ */
+static int sr_kemi_pv_sets (sip_msg_t *msg, str *pvn, str *sval)
+{
+	pv_spec_t *pvs;
+	pv_value_t val;
+	int pl;
+
+	LM_DBG("pv set: %.*s\n", pvn->len, pvn->s);
+	pl = pv_locate_name(pvn);
+	if(pl != pvn->len) {
+		LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
+		return SR_KEMI_FALSE;
+	}
+	pvs = pv_cache_get(pvn);
+	if(pvs==NULL) {
+		LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
+		return SR_KEMI_FALSE;
+	}
+
+	memset(&val, 0, sizeof(pv_value_t));
+	val.rs = *sval;
+	val.flags |= PV_VAL_STR;
+
+	if(pv_set_spec_value(msg, pvs, 0, &val)<0) {
+		LM_ERR("unable to set pv [%.*s]\n", pvn->len, pvn->s);
+		return SR_KEMI_FALSE;
+	}
+
+	return SR_KEMI_TRUE;
+}
+
+/**
+ *
+ */
+static int sr_kemi_pv_unset (sip_msg_t *msg, str *pvn)
+{
+	pv_spec_t *pvs;
+	pv_value_t val;
+	int pl;
+
+	LM_DBG("pv unset: %.*s\n", pvn->len, pvn->s);
+	pl = pv_locate_name(pvn);
+	if(pl != pvn->len) {
+		LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
+		return SR_KEMI_FALSE;
+	}
+	pvs = pv_cache_get(pvn);
+	if(pvs==NULL) {
+		LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
+		return SR_KEMI_FALSE;
+	}
+	memset(&val, 0, sizeof(pv_value_t));
+	val.flags |= PV_VAL_NULL;
+	if(pv_set_spec_value(msg, pvs, 0, &val)<0) {
+		LM_ERR("unable to unset pv [%.*s]\n", pvn->len, pvn->s);
+		return SR_KEMI_FALSE;
+	}
+
+	return SR_KEMI_TRUE;
+}
+
+/**
+ *
+ */
+static int sr_kemi_pv_is_null (sip_msg_t *msg, str *pvn)
+{
+	pv_spec_t *pvs;
+	pv_value_t val;
+	int pl;
+
+	LM_DBG("pv is null test: %.*s\n", pvn->len, pvn->s);
+	pl = pv_locate_name(pvn);
+	if(pl != pvn->len) {
+		LM_ERR("invalid pv [%.*s] (%d/%d)\n", pvn->len, pvn->s, pl, pvn->len);
+		return SR_KEMI_TRUE;
+	}
+	pvs = pv_cache_get(pvn);
+	if(pvs==NULL) {
+		LM_ERR("cannot get pv spec for [%.*s]\n", pvn->len, pvn->s);
+		return SR_KEMI_TRUE;
+	}
+
+	memset(&val, 0, sizeof(pv_value_t));
+	if(pv_get_spec_value(msg, pvs, &val) != 0) {
+		LM_NOTICE("unable to get pv value for [%.*s]\n", pvn->len, pvn->s);
+		return SR_KEMI_TRUE;
+	}
+	if(val.flags&PV_VAL_NULL) {
+		return SR_KEMI_TRUE;
+	} else {
+		return SR_KEMI_FALSE;
+	}
+}
+
+/**
+ *
+ */
+static sr_kemi_t _sr_kemi_pv[] = {
+	{ str_init("pv"), str_init("get"),
+		SR_KEMIP_XVAL, sr_kemi_pv_get,
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("pv"), str_init("getw"),
+		SR_KEMIP_XVAL, sr_kemi_pv_getw,
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("pv"), str_init("gete"),
+		SR_KEMIP_XVAL, sr_kemi_pv_gete,
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("pv"), str_init("getvn"),
+		SR_KEMIP_XVAL, sr_kemi_pv_getvn,
+		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("pv"), str_init("getvs"),
+		SR_KEMIP_XVAL, sr_kemi_pv_getvs,
+		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("pv"), str_init("seti"),
+		SR_KEMIP_BOOL, sr_kemi_pv_seti,
+		{ SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("pv"), str_init("sets"),
+		SR_KEMIP_BOOL, sr_kemi_pv_sets,
+		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("pv"), str_init("unset"),
+		SR_KEMIP_BOOL, sr_kemi_pv_unset,
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
+	{ str_init("pv"), str_init("is_null"),
+		SR_KEMIP_BOOL, sr_kemi_pv_is_null,
+		{ 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 } }
+};
+
+/**
+ *
+ */
+sr_kemi_t* sr_kemi_exports_get_pv(void)
+{
+	return _sr_kemi_pv;
+}
+
 #define SR_KEMI_MODULES_MAX_SIZE	1024
 static int _sr_kemi_modules_size = 0;
 static sr_kemi_module_t _sr_kemi_modules[SR_KEMI_MODULES_MAX_SIZE];

+ 3 - 1
src/core/kemi.h

@@ -70,7 +70,7 @@ typedef struct sr_kemi_xval {
 	int vtype;
 	union {
 		int n;
-		str *s;
+		str s;
 	} v;
 } sr_kemi_xval_t;
 
@@ -189,4 +189,6 @@ int sr_kemi_route(sr_kemi_eng_t *keng, sip_msg_t *msg, int rtype,
 int sr_kemi_ctx_route(sr_kemi_eng_t *keng, run_act_ctx_t *ctx, sip_msg_t *msg,
 		int rtype, str *ename, str *edata);
 
+sr_kemi_t* sr_kemi_exports_get_pv(void);
+
 #endif