Browse code

pv: added $ccp(gname.vname) variable

- get the config custom parameter value
- direct access without running through select variable

Daniel-Constantin Mierla authored on 14/05/2021 08:41:29
Showing 3 changed files
... ...
@@ -540,6 +540,8 @@ static pv_export_t mod_pvs[] = {
540 540
 		pv_parse_ksr_attrs_name, 0, 0, 0 },
541 541
 	{{"rpl", (sizeof("rpl")-1)}, PVT_OTHER, pv_get_rpl_attrs, 0,
542 542
 		pv_parse_rpl_attrs_name, 0, 0, 0},
543
+	{{"ccp", (sizeof("ccp")-1)}, PVT_OTHER, pv_get_ccp_attrs, 0,
544
+		pv_parse_ccp_attrs_name, 0, 0, 0},
543 545
 
544 546
 	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
545 547
 };
... ...
@@ -692,6 +694,10 @@ static int mod_init(void)
692 694
 		LM_ERR("failed to register RPC commands\n");
693 695
 		return -1;
694 696
 	}
697
+	if(pv_ccp_ctx_init()!=0) {
698
+		LM_ERR("failed to initialize var ccp context\n");
699
+		return -1;
700
+	}
695 701
 	pv_init_sbranch();
696 702
 
697 703
 	return 0;
... ...
@@ -35,6 +35,8 @@
35 35
 #include "../../core/ppcfg.h"
36 36
 #include "../../core/trim.h"
37 37
 #include "../../core/msg_translator.h"
38
+#include "../../core/cfg/cfg.h"
39
+#include "../../core/cfg/cfg_ctx.h"
38 40
 
39 41
 #include "../../core/parser/parse_from.h"
40 42
 #include "../../core/parser/parse_uri.h"
... ...
@@ -3917,3 +3919,141 @@ int pv_get_rpl_attrs(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
3917 3919
 			return pv_get_null(msg, param, res);
3918 3920
 	}
3919 3921
 }
3922
+
3923
+
3924
+/**
3925
+ *
3926
+ */
3927
+static cfg_ctx_t *_pv_ccp_ctx = NULL;
3928
+
3929
+/**
3930
+ *
3931
+ */
3932
+int pv_ccp_ctx_init(void)
3933
+{
3934
+	if (cfg_register_ctx(&_pv_ccp_ctx, NULL)) {
3935
+		LM_ERR("failed to register cfg context\n");
3936
+		return -1;
3937
+	}
3938
+
3939
+	return 0;
3940
+}
3941
+
3942
+/**
3943
+ *
3944
+ */
3945
+void pv_free_ccp_attrs_name(void *p)
3946
+{
3947
+	pv_name_t *pn;
3948
+
3949
+	if(p==NULL) {
3950
+		return;
3951
+	}
3952
+
3953
+	pn = (pv_name_t*)p;
3954
+	if(pn->u.isname.name.s.s) {
3955
+		pkg_free(pn->u.isname.name.s.s);
3956
+		pn->u.isname.name.s.s = 0;
3957
+		pn->u.isname.name.s.len = 0;
3958
+	}
3959
+}
3960
+
3961
+/**
3962
+ *
3963
+ */
3964
+int pv_parse_ccp_attrs_name(pv_spec_p sp, str *in)
3965
+{
3966
+	int i;
3967
+
3968
+	if(sp==NULL || in==NULL || in->len<=0) {
3969
+		return -1;
3970
+	}
3971
+
3972
+	for(i=0; i<in->len; i++) {
3973
+		if(in->s[i] == '.') {
3974
+			break;
3975
+		}
3976
+	}
3977
+	if(i==0 || i>=in->len-1) {
3978
+		LM_ERR("invalid PV ccp key: %.*s\n", in->len, in->s);
3979
+		goto error;
3980
+	}
3981
+
3982
+	sp->pvp.pvn.u.isname.name.s.s = (char*)pkg_malloc(in->len+1);
3983
+	if(sp->pvp.pvn.u.isname.name.s.s==NULL) {
3984
+		PKG_MEM_ERROR;
3985
+		goto error;
3986
+	}
3987
+
3988
+	memcpy(sp->pvp.pvn.u.isname.name.s.s, in->s, in->len);
3989
+	sp->pvp.pvn.u.isname.name.s.s[in->len] = '\0';
3990
+	sp->pvp.pvn.u.isname.name.s.len = in->len;
3991
+
3992
+	sp->pvp.pvn.nfree = pv_free_ccp_attrs_name;
3993
+
3994
+	sp->pvp.pvn.type = PV_NAME_INTSTR;
3995
+	sp->pvp.pvn.u.isname.type = 0;
3996
+
3997
+	return 0;
3998
+
3999
+error:
4000
+	return -1;
4001
+}
4002
+
4003
+/**
4004
+ *
4005
+ */
4006
+int pv_get_ccp_attrs(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
4007
+{
4008
+	str gname = STR_NULL;
4009
+	str vname = STR_NULL;
4010
+	unsigned int *grpid = NULL;
4011
+	str s = STR_NULL;
4012
+	char *sep = NULL;
4013
+	void *val = NULL;
4014
+	unsigned int vtype = 0;
4015
+	int ret = 0;
4016
+
4017
+	s = param->pvn.u.isname.name.s;
4018
+
4019
+	sep = q_memrchr(s.s, '.', s.len);
4020
+	if(sep==NULL) {
4021
+		LM_ERR("invalid pv name [%.*s]\n", s.len, s.s);
4022
+		return pv_get_null(msg, param, res);
4023
+	}
4024
+	gname.s = s.s;
4025
+	gname.len = sep - s.s;
4026
+	vname.s = sep + 1;
4027
+	vname.len = s.s + s.len - sep - 1;
4028
+
4029
+	if (cfg_get_group_id(&gname, &grpid)) {
4030
+		LM_ERR("wrong group syntax. Use either 'group', or 'group[id]'\n");
4031
+		return pv_get_null(msg, param, res);;
4032
+	}
4033
+
4034
+	LM_DBG("getting value for variable: %.*s.%.*s\n", gname.len, gname.s,
4035
+				vname.len, vname.s);
4036
+	ret = cfg_get_by_name(_pv_ccp_ctx, &gname, grpid, &vname,
4037
+			&val, &vtype);
4038
+	if (ret < 0) {
4039
+		LM_ERR("failed to get the variable [%.*s]\n", s.len, s.s);
4040
+		return pv_get_null(msg, param, res);
4041
+	} else if (ret > 0) {
4042
+		LM_ERR("variable exists, but it is not readable: %.*s\n", s.len, s.s);
4043
+		return pv_get_null(msg, param, res);
4044
+	}
4045
+	switch (vtype) {
4046
+		case CFG_VAR_INT:
4047
+			return pv_get_sintval(msg, param, res, (int)(long)val);
4048
+		case CFG_VAR_STRING:
4049
+			return pv_get_strzval(msg, param, res, (char*)val);
4050
+		case CFG_VAR_STR:
4051
+			return pv_get_strval(msg, param, res, (str*)val);
4052
+		case CFG_VAR_POINTER:
4053
+			LM_ERR("pointer value for variable [%.*s]\n", s.len, s.s);
4054
+			return pv_get_null(msg, param, res);
4055
+	}
4056
+
4057
+	LM_ERR("unknown type for variable [%.*s]\n", s.len, s.s);
4058
+	return pv_get_null(msg, param, res);
4059
+}
... ...
@@ -398,5 +398,10 @@ int pv_parse_rpl_attrs_name(pv_spec_p sp, str *in);
398 398
 int pv_get_rpl_attrs(sip_msg_t *msg, pv_param_t *param,
399 399
 		pv_value_t *res);
400 400
 
401
+int pv_ccp_ctx_init(void);
402
+int pv_parse_ccp_attrs_name(pv_spec_p sp, str *in);
403
+int pv_get_ccp_attrs(sip_msg_t *msg, pv_param_t *param,
404
+		pv_value_t *res);
405
+
401 406
 #endif
402 407