Browse code

pv api updates

- fix the transformations hash table size
- complete the functions in PV&T API

Daniel-Constantin Mierla authored on 06/12/2008 22:55:08
Showing 2 changed files
... ...
@@ -34,18 +34,18 @@
34 34
 #include "mem/shm_mem.h"
35 35
 #include "ut.h"
36 36
 #include "dprint.h"
37
-#include "hashes.h"
37
+#include "hash_func.h"
38 38
 #include "pvar.h"
39 39
 
40 40
 #define is_in_str(p, in) (p<in->s+in->len && *p)
41 41
 
42 42
 #define PV_TABLE_SIZE	16
43
-#define TR_TABLE_SIZE	2
43
+#define TR_TABLE_SIZE	4
44 44
 
45
+#define core_hash(in, a, b) get_hash1_raw((in)->s, (in)->len);
45 46
 
46 47
 void tr_destroy(trans_t *t);
47 48
 void tr_free(trans_t *t);
48
-void tr_param_free(tr_param_t *tp);
49 49
 
50 50
 typedef struct _pv_item
51 51
 {
... ...
@@ -57,11 +57,10 @@ typedef struct _pv_item
57 57
 static pv_item_t* _pv_table[PV_TABLE_SIZE];
58 58
 static int _pv_table_set = 0;
59 59
 
60
-
61 60
 /**
62 61
  *
63 62
  */
64
-void pv_init_table()
63
+void pv_init_table(void)
65 64
 {
66 65
 	memset(_pv_table, 0, sizeof(pv_item_t*)*PV_TABLE_SIZE);
67 66
 	_pv_table_set = 1;
... ...
@@ -112,7 +111,8 @@ int pv_table_add(pv_export_t *e)
112 111
 		return -1;
113 112
 	}
114 113
 	found = 0;
115
-	pvid = get_hash1_raw(in->s, in->len);
114
+	//pvid = get_hash1_raw(in->s, in->len);
115
+	pvid = core_hash(in, 0, 0);
116 116
 
117 117
 	pvi = _pv_table[pvid%PV_TABLE_SIZE];
118 118
 	while(pvi)
... ...
@@ -239,6 +239,7 @@ int pv_get_sintval(struct sip_msg *msg, pv_param_t *param,
239 239
 	if(res==NULL)
240 240
 		return -1;
241 241
 
242
+	// ch = sint2str(sival, &l);
242 243
 	ch = int2str(sival, &l);
243 244
 	res->rs.s = ch;
244 245
 	res->rs.len = l;
... ...
@@ -326,7 +327,8 @@ pv_export_t* pv_lookup_spec_name(str *pvname, pv_spec_p e)
326 327
 	}
327 328
 
328 329
 	/* search in PV table */
329
-	pvid = get_hash1_raw(pvname->s, pvname->len);
330
+	// pvid = get_hash1_raw(pvname->s, pvname->len);
331
+	pvid = core_hash(pvname, 0, 0);
330 332
 	pvi = _pv_table[pvid%PV_TABLE_SIZE];
331 333
 	while(pvi)
332 334
 	{
... ...
@@ -352,6 +354,71 @@ pv_export_t* pv_lookup_spec_name(str *pvname, pv_spec_p e)
352 354
 	return NULL;
353 355
 }
354 356
 
357
+int pv_parse_index(pv_spec_p sp, str *in)
358
+{
359
+	char *p;
360
+	char *s;
361
+	int sign;
362
+	pv_spec_p nsp = 0;
363
+
364
+	if(in==NULL || in->s==NULL || sp==NULL)
365
+		return -1;
366
+	p = in->s;
367
+	if(*p==PV_MARKER)
368
+	{
369
+		nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t));
370
+		if(nsp==NULL)
371
+		{
372
+			LM_ERR("no more memory\n");
373
+			return -1;
374
+		}
375
+		s = pv_parse_spec(in, nsp);
376
+		if(s==NULL)
377
+		{
378
+			LM_ERR("invalid index [%.*s]\n", in->len, in->s);
379
+			pv_spec_free(nsp);
380
+			return -1;
381
+		}
382
+		sp->pvp.pvi.type = PV_IDX_PVAR;
383
+		sp->pvp.pvi.u.dval = (void*)nsp;
384
+		return 0;
385
+	}
386
+	if(*p=='*' && in->len==1)
387
+	{
388
+		sp->pvp.pvi.type = PV_IDX_ALL;
389
+		return 0;
390
+	}
391
+	sign = 1;
392
+	if(*p=='-')
393
+	{
394
+		sign = -1;
395
+		p++;
396
+	}
397
+	sp->pvp.pvi.u.ival = 0;
398
+	while(p<in->s+in->len && *p>='0' && *p<='9')
399
+	{
400
+		sp->pvp.pvi.u.ival = sp->pvp.pvi.u.ival * 10 + *p - '0';
401
+		p++;
402
+	}
403
+	if(p!=in->s+in->len)
404
+	{
405
+		LM_ERR("invalid index [%.*s]\n", in->len, in->s);
406
+		return -1;
407
+	}
408
+	sp->pvp.pvi.u.ival *= sign;
409
+	sp->pvp.pvi.type = PV_IDX_INT;
410
+	return 0;
411
+}
412
+
413
+int pv_init_iname(pv_spec_p sp, int param)
414
+{
415
+	if(sp==NULL)
416
+		return -1;
417
+	sp->pvp.pvn.type = PV_NAME_INTSTR;
418
+	sp->pvp.pvn.u.isname.name.n = param;
419
+	return 0;
420
+}
421
+
355 422
 char* pv_parse_spec(str *in, pv_spec_p e)
356 423
 {
357 424
 	char *p;
... ...
@@ -702,6 +769,121 @@ error:
702 769
 	return -1;
703 770
 }
704 771
 
772
+int pv_get_spec_name(struct sip_msg* msg, pv_param_p ip, pv_value_t *name)
773
+{
774
+	if(msg==NULL || ip==NULL || name==NULL)
775
+		return -1;
776
+	memset(name, 0, sizeof(pv_value_t));
777
+
778
+	if(ip->pvn.type==PV_NAME_INTSTR)
779
+	{
780
+		if(ip->pvn.u.isname.type&AVP_NAME_STR)
781
+		{
782
+			name->rs = ip->pvn.u.isname.name.s;
783
+			name->flags = PV_VAL_STR;
784
+		} else {
785
+			name->ri = ip->pvn.u.isname.name.n;
786
+			name->flags = PV_VAL_INT|PV_TYPE_INT;
787
+		}
788
+		return 0;
789
+	} else if(ip->pvn.type==PV_NAME_INTSTR) {
790
+		/* pvar */
791
+		if(pv_get_spec_value(msg, (pv_spec_p)(ip->pvn.u.dname), name)!=0)
792
+		{
793
+			LM_ERR("cannot get name value\n");
794
+			return -1;
795
+		}
796
+		if(name->flags&PV_VAL_NULL || name->flags&PV_VAL_EMPTY)
797
+		{
798
+			LM_ERR("null or empty name\n");
799
+			return -1;
800
+		}
801
+		return 0;
802
+	}
803
+	LM_ERR("name type is PV_NAME_OTHER - cannot resolve\n");
804
+	return -1;
805
+}
806
+
807
+int pv_get_avp_name(struct sip_msg* msg, pv_param_p ip, int_str *avp_name,
808
+		unsigned short *name_type)
809
+{
810
+	pv_value_t tv;
811
+	if(ip==NULL || avp_name==NULL || name_type==NULL)
812
+		return -1;
813
+	memset(avp_name, 0, sizeof(int_str));
814
+	*name_type = 0;
815
+
816
+	if(ip->pvn.type==PV_NAME_INTSTR)
817
+	{
818
+		*name_type = ip->pvn.u.isname.type;
819
+		if(ip->pvn.u.isname.type&AVP_NAME_STR)
820
+		{
821
+			avp_name->s = ip->pvn.u.isname.name.s;
822
+			*name_type |= AVP_NAME_STR;
823
+		} else {
824
+			avp_name->n = ip->pvn.u.isname.name.n;
825
+			*name_type = 0; // &= AVP_SCRIPT_MASK;
826
+		}
827
+		return 0;
828
+	}
829
+	/* pvar */
830
+	if(pv_get_spec_value(msg, (pv_spec_p)(ip->pvn.u.dname), &tv)!=0)
831
+	{
832
+		LM_ERR("cannot get avp value\n");
833
+		return -1;
834
+	}
835
+	if(tv.flags&PV_VAL_NULL || tv.flags&PV_VAL_EMPTY)
836
+	{
837
+		LM_ERR("null or empty name\n");
838
+		return -1;
839
+	}
840
+		
841
+	if((tv.flags&PV_TYPE_INT) && (tv.flags&PV_VAL_INT))
842
+	{
843
+		avp_name->n = tv.ri;
844
+	} else {
845
+		avp_name->s = tv.rs;
846
+		*name_type = AVP_NAME_STR;
847
+	}
848
+	return 0;
849
+}
850
+
851
+
852
+int pv_get_spec_index(struct sip_msg* msg, pv_param_p ip, int *idx, int *flags)
853
+{
854
+	pv_value_t tv;
855
+	if(ip==NULL || idx==NULL || flags==NULL)
856
+		return -1;
857
+
858
+	*idx = 0;
859
+	*flags = 0;
860
+
861
+	if(ip->pvi.type == PV_IDX_ALL) {
862
+		*flags = PV_IDX_ALL;
863
+		return 0;
864
+	}
865
+	
866
+	if(ip->pvi.type == PV_IDX_INT)
867
+	{
868
+		*idx = ip->pvi.u.ival;
869
+		return 0;
870
+	}
871
+
872
+	/* pvar */
873
+	if(pv_get_spec_value(msg, (pv_spec_p)ip->pvi.u.dval, &tv)!=0)
874
+	{
875
+		LM_ERR("cannot get index value\n");
876
+		return -1;
877
+	}
878
+	if(!(tv.flags&PV_VAL_INT))
879
+	{
880
+		LM_ERR("invalid index value\n");
881
+		return -1;
882
+	}
883
+	*idx = tv.ri;
884
+	return 0;
885
+}
886
+
705 887
 int pv_get_spec_value(struct sip_msg* msg, pv_spec_p sp, pv_value_t *value)
706 888
 {
707 889
 	int ret = 0;
... ...
@@ -718,6 +900,7 @@ int pv_get_spec_value(struct sip_msg* msg, pv_spec_p sp, pv_value_t *value)
718 900
 	ret = (*sp->getf)(msg, &(sp->pvp), value);
719 901
 	if(ret!=0)
720 902
 		return ret;
903
+		
721 904
 	if(sp->trans)
722 905
 		return tr_exec(msg, (trans_t*)sp->trans, value);
723 906
 	return ret;
... ...
@@ -834,6 +1017,23 @@ void pv_value_destroy(pv_value_t *val)
834 1017
 	memset(val, 0, sizeof(pv_value_t));
835 1018
 }
836 1019
 
1020
+#define PV_PRINT_BUF_SIZE  1024
1021
+#define PV_PRINT_BUF_NO    3
1022
+int pv_printf_s(struct sip_msg* msg, pv_elem_p list, str *s)
1023
+{
1024
+	static int buf_itr = 0;
1025
+	static char buf[PV_PRINT_BUF_NO][PV_PRINT_BUF_SIZE];
1026
+
1027
+	if (list->next==0 && list->spec.getf==0) {
1028
+		*s = list->text;
1029
+		return 0;
1030
+	} else {
1031
+		s->s = buf[buf_itr];
1032
+		s->len = PV_PRINT_BUF_SIZE;
1033
+		buf_itr = (buf_itr+1)%PV_PRINT_BUF_NO;
1034
+		return pv_printf( msg, list, s->s, &s->len);
1035
+	}
1036
+}
837 1037
 
838 1038
 /********************************************************
839 1039
  * Transformations API
... ...
@@ -860,7 +1060,7 @@ static inline char* tr_get_class(str *in, char *p, str *tclass)
860 1060
 /**
861 1061
  *
862 1062
  */
863
-static inline trans_t* tr_new()
1063
+static inline trans_t* tr_new(void)
864 1064
 {
865 1065
 	trans_t *t = NULL;
866 1066
 
... ...
@@ -965,6 +1165,14 @@ void tr_destroy(trans_t *t)
965 1165
 	memset(t, 0, sizeof(trans_t));
966 1166
 }
967 1167
 
1168
+/*!
1169
+ * \brief Exec transformation on a pseudo-variable value
1170
+ * \param msg SIP message
1171
+ * \param tr one or more transformations
1172
+ * \param val pseudo-variable value
1173
+ * \return 0 on success, -1 on error
1174
+ */
1175
+
968 1176
 int tr_exec(struct sip_msg *msg, trans_t *t, pv_value_t *v)
969 1177
 {
970 1178
 	int r;
... ...
@@ -1029,14 +1237,14 @@ typedef struct _tr_item
1029 1237
 	struct _tr_item *next;
1030 1238
 } tr_item_t, *tr_item_p;
1031 1239
 
1032
-static tr_item_t* _tr_table[PV_TABLE_SIZE];
1240
+static tr_item_t* _tr_table[TR_TABLE_SIZE];
1033 1241
 static int _tr_table_set = 0;
1034 1242
 
1035 1243
 
1036 1244
 /**
1037 1245
  *
1038 1246
  */
1039
-void tr_init_table()
1247
+void tr_init_table(void)
1040 1248
 {
1041 1249
 	memset(_tr_table, 0, sizeof(tr_item_t*)*TR_TABLE_SIZE);
1042 1250
 	_tr_table_set = 1;
... ...
@@ -1066,9 +1274,10 @@ int tr_table_add(tr_export_t *e)
1066 1274
 	}
1067 1275
 
1068 1276
 	found = 0;
1069
-	trid = get_hash1_raw(e->tclass.s, e->tclass.len);
1277
+	// trid = get_hash1_raw(e->tclass.s, e->tclass.len);
1278
+	trid = core_hash(&e->tclass, 0, 0);
1070 1279
 
1071
-	tri = _tr_table[trid%PV_TABLE_SIZE];
1280
+	tri = _tr_table[trid%TR_TABLE_SIZE];
1072 1281
 	while(tri)
1073 1282
 	{
1074 1283
 		if(tri->trid > trid)
... ...
@@ -1101,10 +1310,12 @@ int tr_table_add(tr_export_t *e)
1101 1310
 	memcpy(&(trn->tre), e, sizeof(tr_export_t));
1102 1311
 	trn->trid = trid;
1103 1312
 
1313
+	//LM_DBG("TR class [%.*s] added to entry [%d]\n", e->tclass.len,
1314
+	//					e->tclass.s, trid%TR_TABLE_SIZE);
1104 1315
 	if(trj==0)
1105 1316
 	{
1106
-		trn->next = _tr_table[trid%PV_TABLE_SIZE];
1107
-		_tr_table[trid%PV_TABLE_SIZE] = trn;
1317
+		trn->next = _tr_table[trid%TR_TABLE_SIZE];
1318
+		_tr_table[trid%TR_TABLE_SIZE] = trn;
1108 1319
 		goto done;
1109 1320
 	}
1110 1321
 	trn->next = trj->next;
... ...
@@ -1172,7 +1383,8 @@ tr_export_t* tr_lookup_class(str *tclass)
1172 1383
 	}
1173 1384
 
1174 1385
 	/* search in TR table */
1175
-	trid = get_hash1_raw(tclass->s, tclass->len);
1386
+	// trid = get_hash1_raw(tclass->s, tclass->len);
1387
+	trid = core_hash(tclass, 0, 0);
1176 1388
 	tri = _tr_table[trid%TR_TABLE_SIZE];
1177 1389
 	while(tri)
1178 1390
 	{
... ...
@@ -1190,3 +1402,8 @@ tr_export_t* tr_lookup_class(str *tclass)
1190 1402
 	return NULL;
1191 1403
 }
1192 1404
 
1405
+void pv_api_destroy(void)
1406
+{
1407
+	/* free PV and TR hash tables */
1408
+	return;
1409
+}
... ...
@@ -57,6 +57,7 @@
57 57
 
58 58
 #define PV_NAME_INTSTR	0
59 59
 #define PV_NAME_PVAR	1
60
+#define PV_NAME_OTHER	2
60 61
 
61 62
 #define PV_IDX_INT	0
62 63
 #define PV_IDX_PVAR	1
... ...
@@ -76,7 +77,7 @@ enum _pv_type {
76 77
 	PVT_RURI,             PVT_RURI_USERNAME,     PVT_RURI_DOMAIN,
77 78
 	PVT_DSTURI,           PVT_COLOR,             PVT_BRANCH,
78 79
 	PVT_FROM,             PVT_TO,                PVT_OURI,
79
-	PVT_SCRIPTVAR,        PVT_MSG_BODY,
80
+	PVT_SCRIPTVAR,        PVT_MSG_BODY,          PVT_CONTEXT,
80 81
 	PVT_OTHER,            PVT_EXTRA /* keep it last */
81 82
 };
82 83
 
... ...
@@ -164,7 +165,6 @@ typedef struct _pv_elem
164 165
 
165 166
 char* pv_parse_spec(str *in, pv_spec_p sp);
166 167
 int pv_get_spec_value(struct sip_msg* msg, pv_spec_p sp, pv_value_t *value);
167
-int pv_print_spec(struct sip_msg* msg, pv_spec_p sp, char *buf, int *len);
168 168
 int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len);
169 169
 int pv_elem_free_all(pv_elem_p log);
170 170
 void pv_value_destroy(pv_value_t *val);
... ...
@@ -175,8 +175,10 @@ int pv_get_avp_name(struct sip_msg* msg, pv_param_p ip, int_str *avp_name,
175 175
 		unsigned short *name_type);
176 176
 int pv_get_spec_name(struct sip_msg* msg, pv_param_p ip, pv_value_t *name);
177 177
 int pv_parse_format(str *in, pv_elem_p *el);
178
+int pv_parse_index(pv_spec_p sp, str *in);
178 179
 int pv_init_iname(pv_spec_p sp, int param);
179 180
 int pv_printf_s(struct sip_msg* msg, pv_elem_p list, str *s);
181
+void pv_api_destroy(void);
180 182
 
181 183
 typedef struct _pvname_list {
182 184
 	pv_spec_t sname;
... ...
@@ -194,10 +196,7 @@ int register_pvars_mod(char *mod_name, pv_export_t *items);
194 196
 int pv_free_extra_list(void);
195 197
 
196 198
 /*! \brief PV helper functions */
197
-int pv_parse_index(pv_spec_p sp, str *in);
198
-
199 199
 int pv_get_null(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
200
-int pv_update_time(struct sip_msg *msg, time_t *t);
201 200
 
202 201
 int pv_get_uintval(struct sip_msg *msg, pv_param_t *param,
203 202
 		pv_value_t *res, unsigned int uival);
... ...
@@ -221,7 +220,7 @@ int pv_get_intstrval(struct sip_msg *msg, pv_param_t *param,
221 220
 #define TR_PARAM_MARKER		','
222 221
 
223 222
 enum _tr_param_type { TR_PARAM_NONE=0, TR_PARAM_STRING, TR_PARAM_NUMBER,
224
-	TR_PARAM_SPEC };
223
+	TR_PARAM_SPEC, TR_PARAM_SUBST, TR_PARAM_OTHER };
225 224
 
226 225
 typedef struct _tr_param {
227 226
 	int type;
... ...
@@ -253,6 +252,9 @@ typedef struct _tr_export {
253 252
 char* tr_lookup(str *in, trans_t **tr);
254 253
 tr_export_t* tr_lookup_class(str *tclass);
255 254
 int tr_exec(struct sip_msg *msg, trans_t *t, pv_value_t *v);
255
+void tr_param_free(tr_param_t *tp);
256
+
257
+int register_trans_mod(char *mod_name, tr_export_t *items);
256 258
 
257 259
 #endif
258 260