* commit 'origin/daniel/pv':
fix add/lookup pv name
fix pv&t lookup due to signness
pv api updates
- list of PVs types syncronized with Kamailio
Conflicts:
pvapi.c
... | ... |
@@ -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 |
+#define core_hash(in, a, b) get_hash1_raw((in)->s, (in)->len) |
|
41 | 42 |
|
42 | 43 |
#define PV_TABLE_SIZE 16 |
43 |
-#define TR_TABLE_SIZE 2 |
|
44 |
+#define TR_TABLE_SIZE 4 |
|
44 | 45 |
|
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 |
{ |
... | ... |
@@ -61,7 +61,7 @@ static int _pv_table_set = 0; |
61 | 61 |
/** |
62 | 62 |
* |
63 | 63 |
*/ |
64 |
-void pv_init_table() |
|
64 |
+void pv_init_table(void) |
|
65 | 65 |
{ |
66 | 66 |
memset(_pv_table, 0, sizeof(pv_item_t*)*PV_TABLE_SIZE); |
67 | 67 |
_pv_table_set = 1; |
... | ... |
@@ -89,7 +89,7 @@ int pv_table_add(pv_export_t *e) |
89 | 89 |
pv_item_t *pvj = NULL; |
90 | 90 |
pv_item_t *pvn = NULL; |
91 | 91 |
int found; |
92 |
- int pvid; |
|
92 |
+ unsigned int pvid; |
|
93 | 93 |
|
94 | 94 |
if(e==NULL || e->name.s==NULL || e->getf==NULL || e->type==PVT_NONE) |
95 | 95 |
{ |
... | ... |
@@ -112,20 +112,18 @@ int pv_table_add(pv_export_t *e) |
112 | 112 |
return -1; |
113 | 113 |
} |
114 | 114 |
found = 0; |
115 |
- pvid = get_hash1_raw(in->s, in->len); |
|
115 |
+ //pvid = get_hash1_raw(in->s, in->len); |
|
116 |
+ pvid = core_hash(in, 0, 0); |
|
116 | 117 |
|
117 | 118 |
pvi = _pv_table[pvid%PV_TABLE_SIZE]; |
118 | 119 |
while(pvi) |
119 | 120 |
{ |
120 | 121 |
if(pvi->pvid > pvid) |
121 | 122 |
break; |
122 |
- if(pvi->pve.name.len > in->len) |
|
123 |
- break; |
|
124 | 123 |
if(pvi->pve.name.len==in->len) |
125 | 124 |
{ |
126 | 125 |
found = strncmp(pvi->pve.name.s, in->s, in->len); |
127 |
- if(found>0) |
|
128 |
- break; |
|
126 |
+ |
|
129 | 127 |
if(found==0) |
130 | 128 |
{ |
131 | 129 |
LM_ERR("pvar [%.*s] already exists\n", in->len, in->s); |
... | ... |
@@ -239,7 +237,7 @@ int pv_get_sintval(struct sip_msg *msg, pv_param_t *param, |
239 | 237 |
if(res==NULL) |
240 | 238 |
return -1; |
241 | 239 |
|
242 |
- ch = int2str(sival, &l); |
|
240 |
+ ch = sint2str(sival, &l); |
|
243 | 241 |
res->rs.s = ch; |
244 | 242 |
res->rs.len = l; |
245 | 243 |
|
... | ... |
@@ -326,14 +324,13 @@ pv_export_t* pv_lookup_spec_name(str *pvname, pv_spec_p e) |
326 | 324 |
} |
327 | 325 |
|
328 | 326 |
/* search in PV table */ |
329 |
- pvid = get_hash1_raw(pvname->s, pvname->len); |
|
327 |
+ // pvid = get_hash1_raw(pvname->s, pvname->len); |
|
328 |
+ pvid = core_hash(pvname, 0, 0); |
|
330 | 329 |
pvi = _pv_table[pvid%PV_TABLE_SIZE]; |
331 | 330 |
while(pvi) |
332 | 331 |
{ |
333 | 332 |
if(pvi->pvid > pvid) |
334 | 333 |
break; |
335 |
- if(pvi->pve.name.len > pvname->len) |
|
336 |
- break; |
|
337 | 334 |
|
338 | 335 |
if(pvi->pvid==pvid && pvi->pve.name.len==pvname->len |
339 | 336 |
&& memcmp(pvi->pve.name.s, pvname->s, pvname->len)==0) |
... | ... |
@@ -352,6 +349,71 @@ pv_export_t* pv_lookup_spec_name(str *pvname, pv_spec_p e) |
352 | 349 |
return NULL; |
353 | 350 |
} |
354 | 351 |
|
352 |
+int pv_parse_index(pv_spec_p sp, str *in) |
|
353 |
+{ |
|
354 |
+ char *p; |
|
355 |
+ char *s; |
|
356 |
+ int sign; |
|
357 |
+ pv_spec_p nsp = 0; |
|
358 |
+ |
|
359 |
+ if(in==NULL || in->s==NULL || sp==NULL) |
|
360 |
+ return -1; |
|
361 |
+ p = in->s; |
|
362 |
+ if(*p==PV_MARKER) |
|
363 |
+ { |
|
364 |
+ nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t)); |
|
365 |
+ if(nsp==NULL) |
|
366 |
+ { |
|
367 |
+ LM_ERR("no more memory\n"); |
|
368 |
+ return -1; |
|
369 |
+ } |
|
370 |
+ s = pv_parse_spec(in, nsp); |
|
371 |
+ if(s==NULL) |
|
372 |
+ { |
|
373 |
+ LM_ERR("invalid index [%.*s]\n", in->len, in->s); |
|
374 |
+ pv_spec_free(nsp); |
|
375 |
+ return -1; |
|
376 |
+ } |
|
377 |
+ sp->pvp.pvi.type = PV_IDX_PVAR; |
|
378 |
+ sp->pvp.pvi.u.dval = (void*)nsp; |
|
379 |
+ return 0; |
|
380 |
+ } |
|
381 |
+ if(*p=='*' && in->len==1) |
|
382 |
+ { |
|
383 |
+ sp->pvp.pvi.type = PV_IDX_ALL; |
|
384 |
+ return 0; |
|
385 |
+ } |
|
386 |
+ sign = 1; |
|
387 |
+ if(*p=='-') |
|
388 |
+ { |
|
389 |
+ sign = -1; |
|
390 |
+ p++; |
|
391 |
+ } |
|
392 |
+ sp->pvp.pvi.u.ival = 0; |
|
393 |
+ while(p<in->s+in->len && *p>='0' && *p<='9') |
|
394 |
+ { |
|
395 |
+ sp->pvp.pvi.u.ival = sp->pvp.pvi.u.ival * 10 + *p - '0'; |
|
396 |
+ p++; |
|
397 |
+ } |
|
398 |
+ if(p!=in->s+in->len) |
|
399 |
+ { |
|
400 |
+ LM_ERR("invalid index [%.*s]\n", in->len, in->s); |
|
401 |
+ return -1; |
|
402 |
+ } |
|
403 |
+ sp->pvp.pvi.u.ival *= sign; |
|
404 |
+ sp->pvp.pvi.type = PV_IDX_INT; |
|
405 |
+ return 0; |
|
406 |
+} |
|
407 |
+ |
|
408 |
+int pv_init_iname(pv_spec_p sp, int param) |
|
409 |
+{ |
|
410 |
+ if(sp==NULL) |
|
411 |
+ return -1; |
|
412 |
+ sp->pvp.pvn.type = PV_NAME_INTSTR; |
|
413 |
+ sp->pvp.pvn.u.isname.name.n = param; |
|
414 |
+ return 0; |
|
415 |
+} |
|
416 |
+ |
|
355 | 417 |
char* pv_parse_spec2(str *in, pv_spec_p e, int silent) |
356 | 418 |
{ |
357 | 419 |
char *p; |
... | ... |
@@ -721,6 +783,122 @@ error: |
721 | 783 |
return -1; |
722 | 784 |
} |
723 | 785 |
|
786 |
+int pv_get_spec_name(struct sip_msg* msg, pv_param_p ip, pv_value_t *name) |
|
787 |
+{ |
|
788 |
+ if(msg==NULL || ip==NULL || name==NULL) |
|
789 |
+ return -1; |
|
790 |
+ memset(name, 0, sizeof(pv_value_t)); |
|
791 |
+ |
|
792 |
+ if(ip->pvn.type==PV_NAME_INTSTR) |
|
793 |
+ { |
|
794 |
+ if(ip->pvn.u.isname.type&AVP_NAME_STR) |
|
795 |
+ { |
|
796 |
+ name->rs = ip->pvn.u.isname.name.s; |
|
797 |
+ name->flags = PV_VAL_STR; |
|
798 |
+ } else { |
|
799 |
+ name->ri = ip->pvn.u.isname.name.n; |
|
800 |
+ name->flags = PV_VAL_INT|PV_TYPE_INT; |
|
801 |
+ } |
|
802 |
+ return 0; |
|
803 |
+ } else if(ip->pvn.type==PV_NAME_INTSTR) { |
|
804 |
+ /* pvar */ |
|
805 |
+ if(pv_get_spec_value(msg, (pv_spec_p)(ip->pvn.u.dname), name)!=0) |
|
806 |
+ { |
|
807 |
+ LM_ERR("cannot get name value\n"); |
|
808 |
+ return -1; |
|
809 |
+ } |
|
810 |
+ if(name->flags&PV_VAL_NULL || name->flags&PV_VAL_EMPTY) |
|
811 |
+ { |
|
812 |
+ LM_ERR("null or empty name\n"); |
|
813 |
+ return -1; |
|
814 |
+ } |
|
815 |
+ return 0; |
|
816 |
+ } |
|
817 |
+ LM_ERR("name type is PV_NAME_OTHER - cannot resolve\n"); |
|
818 |
+ return -1; |
|
819 |
+} |
|
820 |
+ |
|
821 |
+int pv_get_avp_name(struct sip_msg* msg, pv_param_p ip, int_str *avp_name, |
|
822 |
+ unsigned short *name_type) |
|
823 |
+{ |
|
824 |
+ pv_value_t tv; |
|
825 |
+ if(ip==NULL || avp_name==NULL || name_type==NULL) |
|
826 |
+ return -1; |
|
827 |
+ memset(avp_name, 0, sizeof(int_str)); |
|
828 |
+ *name_type = 0; |
|
829 |
+ |
|
830 |
+ if(ip->pvn.type==PV_NAME_INTSTR) |
|
831 |
+ { |
|
832 |
+ *name_type = ip->pvn.u.isname.type; |
|
833 |
+ if(ip->pvn.u.isname.type&AVP_NAME_STR) |
|
834 |
+ { |
|
835 |
+ avp_name->s = ip->pvn.u.isname.name.s; |
|
836 |
+ *name_type |= AVP_NAME_STR; |
|
837 |
+ } else { |
|
838 |
+ avp_name->n = ip->pvn.u.isname.name.n; |
|
839 |
+ /* *name_type &= AVP_SCRIPT_MASK; */ |
|
840 |
+ *name_type = 0; |
|
841 |
+ } |
|
842 |
+ return 0; |
|
843 |
+ } |
|
844 |
+ /* pvar */ |
|
845 |
+ if(pv_get_spec_value(msg, (pv_spec_p)(ip->pvn.u.dname), &tv)!=0) |
|
846 |
+ { |
|
847 |
+ LM_ERR("cannot get avp value\n"); |
|
848 |
+ return -1; |
|
849 |
+ } |
|
850 |
+ if(tv.flags&PV_VAL_NULL || tv.flags&PV_VAL_EMPTY) |
|
851 |
+ { |
|
852 |
+ LM_ERR("null or empty name\n"); |
|
853 |
+ return -1; |
|
854 |
+ } |
|
855 |
+ |
|
856 |
+ if((tv.flags&PV_TYPE_INT) && (tv.flags&PV_VAL_INT)) |
|
857 |
+ { |
|
858 |
+ avp_name->n = tv.ri; |
|
859 |
+ } else { |
|
860 |
+ avp_name->s = tv.rs; |
|
861 |
+ *name_type = AVP_NAME_STR; |
|
862 |
+ } |
|
863 |
+ return 0; |
|
864 |
+} |
|
865 |
+ |
|
866 |
+ |
|
867 |
+int pv_get_spec_index(struct sip_msg* msg, pv_param_p ip, int *idx, int *flags) |
|
868 |
+{ |
|
869 |
+ pv_value_t tv; |
|
870 |
+ if(ip==NULL || idx==NULL || flags==NULL) |
|
871 |
+ return -1; |
|
872 |
+ |
|
873 |
+ *idx = 0; |
|
874 |
+ *flags = 0; |
|
875 |
+ |
|
876 |
+ if(ip->pvi.type == PV_IDX_ALL) { |
|
877 |
+ *flags = PV_IDX_ALL; |
|
878 |
+ return 0; |
|
879 |
+ } |
|
880 |
+ |
|
881 |
+ if(ip->pvi.type == PV_IDX_INT) |
|
882 |
+ { |
|
883 |
+ *idx = ip->pvi.u.ival; |
|
884 |
+ return 0; |
|
885 |
+ } |
|
886 |
+ |
|
887 |
+ /* pvar */ |
|
888 |
+ if(pv_get_spec_value(msg, (pv_spec_p)ip->pvi.u.dval, &tv)!=0) |
|
889 |
+ { |
|
890 |
+ LM_ERR("cannot get index value\n"); |
|
891 |
+ return -1; |
|
892 |
+ } |
|
893 |
+ if(!(tv.flags&PV_VAL_INT)) |
|
894 |
+ { |
|
895 |
+ LM_ERR("invalid index value\n"); |
|
896 |
+ return -1; |
|
897 |
+ } |
|
898 |
+ *idx = tv.ri; |
|
899 |
+ return 0; |
|
900 |
+} |
|
901 |
+ |
|
724 | 902 |
int pv_get_spec_value(struct sip_msg* msg, pv_spec_p sp, pv_value_t *value) |
725 | 903 |
{ |
726 | 904 |
int ret = 0; |
... | ... |
@@ -737,6 +915,7 @@ int pv_get_spec_value(struct sip_msg* msg, pv_spec_p sp, pv_value_t *value) |
737 | 915 |
ret = (*sp->getf)(msg, &(sp->pvp), value); |
738 | 916 |
if(ret!=0) |
739 | 917 |
return ret; |
918 |
+ |
|
740 | 919 |
if(sp->trans) |
741 | 920 |
return tr_exec(msg, (trans_t*)sp->trans, value); |
742 | 921 |
return ret; |
... | ... |
@@ -814,6 +993,73 @@ done: |
814 | 993 |
return 0; |
815 | 994 |
} |
816 | 995 |
|
996 |
+/** |
|
997 |
+ * |
|
998 |
+ */ |
|
999 |
+pvname_list_t* parse_pvname_list(str *in, unsigned int type) |
|
1000 |
+{ |
|
1001 |
+ pvname_list_t* head = NULL; |
|
1002 |
+ pvname_list_t* al = NULL; |
|
1003 |
+ pvname_list_t* last = NULL; |
|
1004 |
+ char *p; |
|
1005 |
+ pv_spec_t spec; |
|
1006 |
+ str s; |
|
1007 |
+ |
|
1008 |
+ if(in==NULL || in->s==NULL) |
|
1009 |
+ { |
|
1010 |
+ LM_ERR("bad parameters\n"); |
|
1011 |
+ return NULL; |
|
1012 |
+ } |
|
1013 |
+ |
|
1014 |
+ p = in->s; |
|
1015 |
+ while(is_in_str(p, in)) |
|
1016 |
+ { |
|
1017 |
+ while(is_in_str(p, in) && (*p==' '||*p=='\t'||*p==','||*p==';')) |
|
1018 |
+ p++; |
|
1019 |
+ if(!is_in_str(p, in)) |
|
1020 |
+ { |
|
1021 |
+ if(head==NULL) |
|
1022 |
+ LM_ERR("wrong item name list [%.*s]\n", in->len, in->s); |
|
1023 |
+ return head; |
|
1024 |
+ } |
|
1025 |
+ s.s=p; |
|
1026 |
+ s.len = in->s+in->len-p; |
|
1027 |
+ p = pv_parse_spec(&s, &spec); |
|
1028 |
+ if(p==NULL || (type && spec.type!=type)) |
|
1029 |
+ { |
|
1030 |
+ LM_ERR("wrong item name list [%.*s]!\n", in->len, in->s); |
|
1031 |
+ goto error; |
|
1032 |
+ } |
|
1033 |
+ al = (pvname_list_t*)pkg_malloc(sizeof(pvname_list_t)); |
|
1034 |
+ if(al==NULL) |
|
1035 |
+ { |
|
1036 |
+ LM_ERR("no more memory!\n"); |
|
1037 |
+ goto error; |
|
1038 |
+ } |
|
1039 |
+ memset(al, 0, sizeof(pvname_list_t)); |
|
1040 |
+ memcpy(&al->sname, &spec, sizeof(pv_spec_t)); |
|
1041 |
+ |
|
1042 |
+ if(last==NULL) |
|
1043 |
+ { |
|
1044 |
+ head = al; |
|
1045 |
+ last = al; |
|
1046 |
+ } else { |
|
1047 |
+ last->next = al; |
|
1048 |
+ last = al; |
|
1049 |
+ } |
|
1050 |
+ } |
|
1051 |
+ |
|
1052 |
+ return head; |
|
1053 |
+ |
|
1054 |
+error: |
|
1055 |
+ while(head) |
|
1056 |
+ { |
|
1057 |
+ al = head; |
|
1058 |
+ head=head->next; |
|
1059 |
+ pkg_free(al); |
|
1060 |
+ } |
|
1061 |
+ return NULL; |
|
1062 |
+} |
|
817 | 1063 |
|
818 | 1064 |
/** |
819 | 1065 |
* |
... | ... |
@@ -853,6 +1099,23 @@ void pv_value_destroy(pv_value_t *val) |
853 | 1099 |
memset(val, 0, sizeof(pv_value_t)); |
854 | 1100 |
} |
855 | 1101 |
|
1102 |
+#define PV_PRINT_BUF_SIZE 1024 |
|
1103 |
+#define PV_PRINT_BUF_NO 3 |
|
1104 |
+int pv_printf_s(struct sip_msg* msg, pv_elem_p list, str *s) |
|
1105 |
+{ |
|
1106 |
+ static int buf_itr = 0; |
|
1107 |
+ static char buf[PV_PRINT_BUF_NO][PV_PRINT_BUF_SIZE]; |
|
1108 |
+ |
|
1109 |
+ if (list->next==0 && list->spec.getf==0) { |
|
1110 |
+ *s = list->text; |
|
1111 |
+ return 0; |
|
1112 |
+ } else { |
|
1113 |
+ s->s = buf[buf_itr]; |
|
1114 |
+ s->len = PV_PRINT_BUF_SIZE; |
|
1115 |
+ buf_itr = (buf_itr+1)%PV_PRINT_BUF_NO; |
|
1116 |
+ return pv_printf( msg, list, s->s, &s->len); |
|
1117 |
+ } |
|
1118 |
+} |
|
856 | 1119 |
|
857 | 1120 |
/******************************************************** |
858 | 1121 |
* Transformations API |
... | ... |
@@ -879,7 +1142,7 @@ static inline char* tr_get_class(str *in, char *p, str *tclass) |
879 | 1142 |
/** |
880 | 1143 |
* |
881 | 1144 |
*/ |
882 |
-static inline trans_t* tr_new() |
|
1145 |
+static inline trans_t* tr_new(void) |
|
883 | 1146 |
{ |
884 | 1147 |
trans_t *t = NULL; |
885 | 1148 |
|
... | ... |
@@ -984,6 +1247,14 @@ void tr_destroy(trans_t *t) |
984 | 1247 |
memset(t, 0, sizeof(trans_t)); |
985 | 1248 |
} |
986 | 1249 |
|
1250 |
+/*! |
|
1251 |
+ * \brief Exec transformation on a pseudo-variable value |
|
1252 |
+ * \param msg SIP message |
|
1253 |
+ * \param tr one or more transformations |
|
1254 |
+ * \param val pseudo-variable value |
|
1255 |
+ * \return 0 on success, -1 on error |
|
1256 |
+ */ |
|
1257 |
+ |
|
987 | 1258 |
int tr_exec(struct sip_msg *msg, trans_t *t, pv_value_t *v) |
988 | 1259 |
{ |
989 | 1260 |
int r; |
... | ... |
@@ -1048,14 +1319,14 @@ typedef struct _tr_item |
1048 | 1319 |
struct _tr_item *next; |
1049 | 1320 |
} tr_item_t, *tr_item_p; |
1050 | 1321 |
|
1051 |
-static tr_item_t* _tr_table[PV_TABLE_SIZE]; |
|
1322 |
+static tr_item_t* _tr_table[TR_TABLE_SIZE]; |
|
1052 | 1323 |
static int _tr_table_set = 0; |
1053 | 1324 |
|
1054 | 1325 |
|
1055 | 1326 |
/** |
1056 | 1327 |
* |
1057 | 1328 |
*/ |
1058 |
-void tr_init_table() |
|
1329 |
+void tr_init_table(void) |
|
1059 | 1330 |
{ |
1060 | 1331 |
memset(_tr_table, 0, sizeof(tr_item_t*)*TR_TABLE_SIZE); |
1061 | 1332 |
_tr_table_set = 1; |
... | ... |
@@ -1070,7 +1341,7 @@ int tr_table_add(tr_export_t *e) |
1070 | 1341 |
tr_item_t *trj = NULL; |
1071 | 1342 |
tr_item_t *trn = NULL; |
1072 | 1343 |
int found; |
1073 |
- int trid; |
|
1344 |
+ unsigned int trid; |
|
1074 | 1345 |
|
1075 | 1346 |
if(e==NULL || e->tclass.s==NULL) |
1076 | 1347 |
{ |
... | ... |
@@ -1085,9 +1356,10 @@ int tr_table_add(tr_export_t *e) |
1085 | 1356 |
} |
1086 | 1357 |
|
1087 | 1358 |
found = 0; |
1088 |
- trid = get_hash1_raw(e->tclass.s, e->tclass.len); |
|
1359 |
+ // trid = get_hash1_raw(e->tclass.s, e->tclass.len); |
|
1360 |
+ trid = core_hash(&e->tclass, 0, 0); |
|
1089 | 1361 |
|
1090 |
- tri = _tr_table[trid%PV_TABLE_SIZE]; |
|
1362 |
+ tri = _tr_table[trid%TR_TABLE_SIZE]; |
|
1091 | 1363 |
while(tri) |
1092 | 1364 |
{ |
1093 | 1365 |
if(tri->trid > trid) |
... | ... |
@@ -1120,10 +1392,12 @@ int tr_table_add(tr_export_t *e) |
1120 | 1392 |
memcpy(&(trn->tre), e, sizeof(tr_export_t)); |
1121 | 1393 |
trn->trid = trid; |
1122 | 1394 |
|
1395 |
+ //LM_DBG("TR class [%.*s] added to entry [%d]\n", e->tclass.len, |
|
1396 |
+ // e->tclass.s, trid%TR_TABLE_SIZE); |
|
1123 | 1397 |
if(trj==0) |
1124 | 1398 |
{ |
1125 |
- trn->next = _tr_table[trid%PV_TABLE_SIZE]; |
|
1126 |
- _tr_table[trid%PV_TABLE_SIZE] = trn; |
|
1399 |
+ trn->next = _tr_table[trid%TR_TABLE_SIZE]; |
|
1400 |
+ _tr_table[trid%TR_TABLE_SIZE] = trn; |
|
1127 | 1401 |
goto done; |
1128 | 1402 |
} |
1129 | 1403 |
trn->next = trj->next; |
... | ... |
@@ -1191,7 +1465,8 @@ tr_export_t* tr_lookup_class(str *tclass) |
1191 | 1465 |
} |
1192 | 1466 |
|
1193 | 1467 |
/* search in TR table */ |
1194 |
- trid = get_hash1_raw(tclass->s, tclass->len); |
|
1468 |
+ // trid = get_hash1_raw(tclass->s, tclass->len); |
|
1469 |
+ trid = core_hash(tclass, 0, 0); |
|
1195 | 1470 |
tri = _tr_table[trid%TR_TABLE_SIZE]; |
1196 | 1471 |
while(tri) |
1197 | 1472 |
{ |
... | ... |
@@ -1209,3 +1484,8 @@ tr_export_t* tr_lookup_class(str *tclass) |
1209 | 1484 |
return NULL; |
1210 | 1485 |
} |
1211 | 1486 |
|
1487 |
+void pv_api_destroy(void) |
|
1488 |
+{ |
|
1489 |
+ /* free PV and TR hash tables */ |
|
1490 |
+ return; |
|
1491 |
+} |
... | ... |
@@ -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 |
... | ... |
@@ -72,7 +73,11 @@ |
72 | 73 |
|
73 | 74 |
enum _pv_type { |
74 | 75 |
PVT_NONE=0, PVT_EMPTY, PVT_NULL, |
75 |
- PVT_MARKER, PVT_AVP, PVT_COLOR, |
|
76 |
+ PVT_MARKER, PVT_AVP, PVT_HDR, |
|
77 |
+ PVT_RURI, PVT_RURI_USERNAME, PVT_RURI_DOMAIN, |
|
78 |
+ PVT_DSTURI, PVT_COLOR, PVT_BRANCH, |
|
79 |
+ PVT_FROM, PVT_TO, PVT_OURI, |
|
80 |
+ PVT_SCRIPTVAR, PVT_MSG_BODY, PVT_CONTEXT, |
|
76 | 81 |
PVT_OTHER, PVT_EXTRA /* keep it last */ |
77 | 82 |
}; |
78 | 83 |
|
... | ... |
@@ -161,7 +166,6 @@ typedef struct _pv_elem |
161 | 166 |
char* pv_parse_spec2(str *in, pv_spec_p sp, int silent); |
162 | 167 |
#define pv_parse_spec(in, sp) pv_parse_spec2((in), (sp), 0) |
163 | 168 |
int pv_get_spec_value(struct sip_msg* msg, pv_spec_p sp, pv_value_t *value); |
164 |
-int pv_print_spec(struct sip_msg* msg, pv_spec_p sp, char *buf, int *len); |
|
165 | 169 |
int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len); |
166 | 170 |
int pv_elem_free_all(pv_elem_p log); |
167 | 171 |
void pv_value_destroy(pv_value_t *val); |
... | ... |
@@ -172,8 +176,10 @@ int pv_get_avp_name(struct sip_msg* msg, pv_param_p ip, int_str *avp_name, |
172 | 176 |
unsigned short *name_type); |
173 | 177 |
int pv_get_spec_name(struct sip_msg* msg, pv_param_p ip, pv_value_t *name); |
174 | 178 |
int pv_parse_format(str *in, pv_elem_p *el); |
179 |
+int pv_parse_index(pv_spec_p sp, str *in); |
|
175 | 180 |
int pv_init_iname(pv_spec_p sp, int param); |
176 | 181 |
int pv_printf_s(struct sip_msg* msg, pv_elem_p list, str *s); |
182 |
+void pv_api_destroy(void); |
|
177 | 183 |
|
178 | 184 |
typedef struct _pvname_list { |
179 | 185 |
pv_spec_t sname; |
... | ... |
@@ -191,10 +197,7 @@ int register_pvars_mod(char *mod_name, pv_export_t *items); |
191 | 197 |
int pv_free_extra_list(void); |
192 | 198 |
|
193 | 199 |
/*! \brief PV helper functions */ |
194 |
-int pv_parse_index(pv_spec_p sp, str *in); |
|
195 |
- |
|
196 | 200 |
int pv_get_null(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); |
197 |
-int pv_update_time(struct sip_msg *msg, time_t *t); |
|
198 | 201 |
|
199 | 202 |
int pv_get_uintval(struct sip_msg *msg, pv_param_t *param, |
200 | 203 |
pv_value_t *res, unsigned int uival); |
... | ... |
@@ -218,7 +221,7 @@ int pv_get_intstrval(struct sip_msg *msg, pv_param_t *param, |
218 | 221 |
#define TR_PARAM_MARKER ',' |
219 | 222 |
|
220 | 223 |
enum _tr_param_type { TR_PARAM_NONE=0, TR_PARAM_STRING, TR_PARAM_NUMBER, |
221 |
- TR_PARAM_SPEC }; |
|
224 |
+ TR_PARAM_SPEC, TR_PARAM_SUBST, TR_PARAM_OTHER }; |
|
222 | 225 |
|
223 | 226 |
typedef struct _tr_param { |
224 | 227 |
int type; |
... | ... |
@@ -250,6 +253,9 @@ typedef struct _tr_export { |
250 | 253 |
char* tr_lookup(str *in, trans_t **tr); |
251 | 254 |
tr_export_t* tr_lookup_class(str *tclass); |
252 | 255 |
int tr_exec(struct sip_msg *msg, trans_t *t, pv_value_t *v); |
256 |
+void tr_param_free(tr_param_t *tp); |
|
257 |
+ |
|
258 |
+int register_trans_mod(char *mod_name, tr_export_t *items); |
|
253 | 259 |
|
254 | 260 |
#endif |
255 | 261 |
|
... | ... |
@@ -299,6 +299,27 @@ static inline char* int2str(unsigned int l, int* len) |
299 | 299 |
return &r[i+1]; |
300 | 300 |
} |
301 | 301 |
|
302 |
+/* Signed INTeger-TO-STRing: convers a long to a string |
|
303 |
+ * returns a pointer to a static buffer containing l in asciiz & sets len */ |
|
304 |
+static inline char* sint2str(long l, int* len) |
|
305 |
+{ |
|
306 |
+ int sign; |
|
307 |
+ char *p; |
|
308 |
+ |
|
309 |
+ sign = 0; |
|
310 |
+ if(l<0) { |
|
311 |
+ sign = 1; |
|
312 |
+ l = -l; |
|
313 |
+ } |
|
314 |
+ p = int2str((unsigned long)l, len); |
|
315 |
+ if(sign) { |
|
316 |
+ *(--p) = '-'; |
|
317 |
+ if (len) (*len)++; |
|
318 |
+ } |
|
319 |
+ return p; |
|
320 |
+} |
|
321 |
+ |
|
322 |
+ |
|
302 | 323 |
|
303 | 324 |
|
304 | 325 |
#define USHORT2SBUF_MAX_LEN 5 /* 65535*/ |