2 * Copyright (C) 2001-2003 FhG Fokus
4 * This file is part of SIP-Router, a free SIP server.
6 * SIP-Router is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version
11 * SIP-Router is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * \brief SIP-router core :: PV API specification
31 #include <sys/types.h>
35 #include "mem/shm_mem.h"
43 #define PV_TABLE_SIZE 32 /*!< pseudo-variables table size */
44 #define PV_CACHE_SIZE 32 /*!< pseudo-variables table size */
45 #define TR_TABLE_SIZE 16 /*!< transformations table size */
48 void tr_destroy(trans_t *t);
49 void tr_free(trans_t *t);
51 typedef struct _pv_item
55 struct _pv_item *next;
56 } pv_item_t, *pv_item_p;
58 static pv_item_t* _pv_table[PV_TABLE_SIZE];
59 static int _pv_table_set = 0;
61 typedef struct _pv_cache
66 struct _pv_cache *next;
69 static pv_cache_t* _pv_cache[PV_CACHE_SIZE];
70 static int _pv_cache_set = 0;
75 void pv_init_table(void)
77 memset(_pv_table, 0, sizeof(pv_item_t*)*PV_TABLE_SIZE);
84 void pv_init_cache(void)
86 memset(_pv_cache, 0, sizeof(pv_cache_t*)*PV_CACHE_SIZE);
92 * @brief Check if a char is valid according to the PV syntax
93 * @param c checked char
94 * @return 1 if char is valid, 0 if not valid
96 static int is_pv_valid_char(char c)
98 if((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z')
99 || (c=='_') || (c=='.') || (c=='?') /* ser $? */)
107 int pv_locate_name(str *in)
112 if(in==NULL || in->s==NULL || in->len<2)
114 LM_ERR("bad parameters\n");
118 if(in->s[0]!=PV_MARKER)
120 LM_ERR("missing pv marker [%.*s]\n", in->len, in->s);
124 if(in->s[1]==PV_LNBRACKET)
126 /* name with parenthesis: $(...) */
128 for(i=2; i<in->len; i++)
130 if(in->s[i]==PV_LNBRACKET)
132 else if(in->s[i]==PV_RNBRACKET)
137 /* non-closing name parenthesis */
138 LM_ERR("non-closing name parenthesis [%.*s]\n",in->len,in->s);
142 /* name without parenthesis: $xyz(...) */
143 for(i=1; i<in->len; i++)
145 if(!is_pv_valid_char(in->s[i]))
147 if(in->s[i]==PV_LNBRACKET)
149 /* inner-name parenthesis */
161 for( ; i<in->len; i++)
163 if(in->s[i]==PV_LNBRACKET)
165 else if(in->s[i]==PV_RNBRACKET)
170 /* non-closing inner-name parenthesis */
171 LM_ERR("non-closing inner-name parenthesis [%.*s]\n",in->len,in->s);
178 int pv_table_add(pv_export_t *e)
182 pv_item_t *pvi = NULL;
183 pv_item_t *pvj = NULL;
184 pv_item_t *pvn = NULL;
188 if(e==NULL || e->name.s==NULL || e->getf==NULL || e->type==PVT_NONE)
190 LM_ERR("invalid parameters\n");
196 LM_DBG("PV table not initialized, doing it now\n");
201 while(is_in_str(p,in) && is_pv_valid_char(*p))
205 LM_ERR("invalid char [%c] in [%.*s]\n", *p, in->len, in->s);
209 //pvid = get_hash1_raw(in->s, in->len);
210 pvid = get_hash1_raw(in->s, in->len);
212 pvi = _pv_table[pvid%PV_TABLE_SIZE];
217 if(pvi->pve.name.len==in->len)
219 found = strncmp(pvi->pve.name.s, in->s, in->len);
223 LM_ERR("pvar [%.*s] already exists\n", in->len, in->s);
231 pvn = (pv_item_t*)pkg_malloc(sizeof(pv_item_t));
234 LM_ERR("no more memory\n");
237 memset(pvn, 0, sizeof(pv_item_t));
238 memcpy(&(pvn->pve), e, sizeof(pv_export_t));
243 pvn->next = _pv_table[pvid%PV_TABLE_SIZE];
244 _pv_table[pvid%PV_TABLE_SIZE] = pvn;
247 pvn->next = pvj->next;
257 pv_spec_t* pv_cache_add(str *name)
265 LM_DBG("PV cache not initialized, doing it now\n");
268 pvid = get_hash1_raw(name->s, name->len);
269 pvn = (pv_cache_t*)pkg_malloc(sizeof(pv_cache_t) + name->len + 1);
272 LM_ERR("no more memory\n");
275 memset(pvn, 0, sizeof(pv_item_t) + name->len + 1);
276 p = pv_parse_spec(name, &pvn->spec);
283 pvn->pvname.len = name->len;
284 pvn->pvname.s = (char*)pvn + sizeof(pv_cache_t);
285 memcpy(pvn->pvname.s, name->s, name->len);
287 pvn->next = _pv_cache[pvid%PV_CACHE_SIZE];
288 _pv_cache[pvid%PV_CACHE_SIZE] = pvn;
290 LM_DBG("pvar [%.*s] added in cache\n", name->len, name->s);
297 pv_spec_t* pv_cache_lookup(str *name)
306 pvid = get_hash1_raw(name->s, name->len);
307 pvi = _pv_cache[pvid%PV_CACHE_SIZE];
310 if(pvi->pvid == pvid) {
311 if(pvi->pvname.len==name->len)
313 found = strncmp(pvi->pvname.s, name->s, name->len);
317 LM_DBG("pvar [%.*s] found in cache\n",
331 pv_spec_t* pv_cache_get(str *name)
336 if(name->s==NULL || name->len==0)
338 LM_ERR("invalid parameters\n");
343 tname.len = pv_locate_name(name);
348 pvs = pv_cache_lookup(&tname);
353 return pv_cache_add(&tname);
359 int register_pvars_mod(char *mod_name, pv_export_t *items)
367 for ( i=0 ; items[i].name.s ; i++ ) {
368 ret = pv_table_add(&items[i]);
370 LM_ERR("failed to register pseudo-variable <%.*s> for module %s\n",
371 items[i].name.len, items[i].name.s, mod_name);
380 int pv_table_free(void)
386 for(i=0; i<PV_TABLE_SIZE; i++)
396 memset(_pv_table, 0, sizeof(pv_item_t*)*PV_TABLE_SIZE);
402 /********** helper functions ********/
404 * convert unsigned int to pv_value_t
406 int pv_get_uintval(struct sip_msg *msg, pv_param_t *param,
407 pv_value_t *res, unsigned int uival)
415 ch = int2str(uival, &l);
419 res->ri = (int)uival;
420 res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT;
425 * convert signed int to pv_value_t
427 int pv_get_sintval(struct sip_msg *msg, pv_param_t *param,
428 pv_value_t *res, int sival)
436 ch = sint2str(sival, &l);
441 res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT;
446 * convert str to pv_value_t
448 int pv_get_strval(struct sip_msg *msg, pv_param_t *param,
449 pv_value_t *res, str *sval)
455 res->flags = PV_VAL_STR;
460 * convert str-int to pv_value_t (type is str)
462 int pv_get_strintval(struct sip_msg *msg, pv_param_t *param,
463 pv_value_t *res, str *sval, int ival)
470 res->flags = PV_VAL_STR|PV_VAL_INT;
475 * convert int-str to pv_value_t (type is int)
477 int pv_get_intstrval(struct sip_msg *msg, pv_param_t *param,
478 pv_value_t *res, int ival, str *sval)
485 res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT;
489 /*** ============================= ***/
490 static str pv_str_marker = { PV_MARKER_STR, 1 };
491 static int pv_get_marker(struct sip_msg *msg, pv_param_t *param,
494 return pv_get_strintval(msg, param, res, &pv_str_marker,
495 (int)pv_str_marker.s[0]);
498 static str pv_str_empty = { "", 0 };
499 static str pv_str_null = { "<null>", 6 };
500 int pv_get_null(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
505 res->rs = pv_str_empty;
507 res->flags = PV_VAL_NULL;
514 pv_export_t* pv_lookup_spec_name(str *pvname, pv_spec_p e)
519 if(pvname==0 || e==0)
521 LM_ERR("bad parameters\n");
525 /* search in PV table */
526 // pvid = get_hash1_raw(pvname->s, pvname->len);
527 pvid = get_hash1_raw(pvname->s, pvname->len);
528 pvi = _pv_table[pvid%PV_TABLE_SIZE];
534 if(pvi->pvid==pvid && pvi->pve.name.len==pvname->len
535 && memcmp(pvi->pve.name.s, pvname->s, pvname->len)==0)
537 /*LM_DBG("found [%.*s] [%d]\n", pvname->len, pvname->s,
538 _pv_names_table[i].type);*/
539 /* copy data from table to spec */
540 e->type = pvi->pve.type;
541 e->getf = pvi->pve.getf;
542 e->setf = pvi->pve.setf;
554 int pv_parse_index(pv_spec_p sp, str *in)
561 if(in==NULL || in->s==NULL || sp==NULL)
566 nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t));
569 LM_ERR("no more memory\n");
572 s = pv_parse_spec(in, nsp);
575 LM_ERR("invalid index [%.*s]\n", in->len, in->s);
579 sp->pvp.pvi.type = PV_IDX_PVAR;
580 sp->pvp.pvi.u.dval = (void*)nsp;
583 if(*p=='*' && in->len==1)
585 sp->pvp.pvi.type = PV_IDX_ALL;
594 sp->pvp.pvi.u.ival = 0;
595 while(p<in->s+in->len && *p>='0' && *p<='9')
597 sp->pvp.pvi.u.ival = sp->pvp.pvi.u.ival * 10 + *p - '0';
602 LM_ERR("invalid index [%.*s]\n", in->len, in->s);
605 sp->pvp.pvi.u.ival *= sign;
606 sp->pvp.pvi.type = PV_IDX_INT;
613 int pv_init_iname(pv_spec_p sp, int param)
617 sp->pvp.pvn.type = PV_NAME_INTSTR;
618 sp->pvp.pvn.u.isname.name.n = param;
625 char* pv_parse_spec2(str *in, pv_spec_p e, int silent)
632 pv_export_t *pte = NULL;
635 if(in==NULL || in->s==NULL || e==NULL || *in->s!=PV_MARKER)
637 if (!silent) LM_ERR("bad parameters\n");
641 /* LM_DBG("***** input [%.*s] (%d)\n", in->len, in->s, in->len); */
644 memset(e, 0, sizeof(pv_spec_t));
653 if(*p == PV_MARKER) {
661 e->getf = pv_get_marker;
662 e->type = PVT_MARKER;
666 while(is_in_str(p,in) && is_pv_valid_char(*p))
668 pvname.len = p - pvname.s;
672 { /* full pv name ended here*/
674 } else if(*p==PV_LNBRACKET) {
677 } else if(*p==PV_LIBRACKET) {
680 } else if(*p==TR_LBRACKET) {
685 LM_ERR("invalid char '%c' in [%.*s] (%d)\n",
686 *p, in->len, in->s, pvstate);
690 if(!is_in_str(p, in)) {
693 } else if(*p==PV_LNBRACKET) {
697 /* still in input str, but end of PV */
698 /* p is increased at the end, so decrement here */
705 if((pte = pv_lookup_spec_name(&pvname, e))==NULL)
708 LM_ERR("error searching pvar \"%.*s\"\n", pvname.len, pvname.s);
711 if(pte->parse_name!=NULL && pvstate!=2 && pvstate!=5)
714 LM_ERR("pvar \"%.*s\" expects an inner name\n",
715 pvname.len, pvname.s);
718 if(pvstate==2 || pvstate==5)
720 if(pte->parse_name==NULL)
723 LM_ERR("pvar \"%.*s\" does not get name param\n",
724 pvname.len, pvname.s);
729 while(is_in_str(p, in))
737 if(*p == PV_LNBRACKET)
742 if(!is_in_str(p, in))
748 LM_ERR("pvar \"%.*s\" does not get empty name param\n",
749 pvname.len, pvname.s);
753 if(pte->parse_name(e, &s)!=0)
756 LM_ERR("pvar \"%.*s\" has an invalid name param [%.*s]\n",
757 pvname.len, pvname.s, s.len, s.s);
764 { /* full pv name ended here*/
766 } else if(*p==PV_LIBRACKET) {
769 } else if(*p==TR_LBRACKET) {
774 LM_ERR("invalid char '%c' in [%.*s] (%d)\n",
775 *p, in->len, in->s, pvstate);
780 { /* full pv name ended here*/
785 LM_ERR("invalid char '%c' in [%.*s] (%d)\n",
786 *p, in->len, in->s, pvstate);
794 if(pte->parse_index==NULL)
797 LM_ERR("pvar \"%.*s\" does not get index param\n",
798 pvname.len, pvname.s);
803 while(is_in_str(p, in))
811 if(*p == PV_LIBRACKET)
815 if(!is_in_str(p, in))
821 LM_ERR("pvar \"%.*s\" does not get empty index param\n",
822 pvname.len, pvname.s);
826 if(pte->parse_index(e, &s)!=0)
829 LM_ERR("pvar \"%.*s\" has an invalid index param [%.*s]\n",
830 pvname.len, pvname.s, s.len, s.s);
835 { /* full pv name ended here*/
837 } else if(*p==TR_LBRACKET) {
842 LM_ERR("invalid char '%c' in [%.*s] (%d)\n",
843 *p, in->len, in->s, pvstate);
852 while(is_in_str(p, in))
858 /* yet another transformation */
860 while(is_in_str(p, in) && (*p==' ' || *p=='\t')) p++;
862 if(!is_in_str(p, in) || *p != TR_LBRACKET)
870 if(*p == TR_LBRACKET)
874 if(!is_in_str(p, in))
880 LM_ERR("pvar \"%.*s\" does not get empty index param\n",
881 pvname.len, pvname.s);
886 p = tr_lookup(&s, &tr);
890 LM_ERR("bad tr in pvar name \"%.*s\"\n", pvname.len, pvname.s);
896 LM_ERR("bad pvar name \"%.*s\" (%c)!\n", in->len, in->s, *p);
899 e->trans = (void*)tr;
904 if(pte!=NULL && pte->init_param)
905 pte->init_param(e, pte->iparam);
911 LM_ERR("wrong char [%c/%d] in [%.*s] at [%d (%d)]\n", *p, (int)*p,
912 in->len, in->s, (int)(p-in->s), pvstate);
915 LM_ERR("invalid parsing in [%.*s] at (%d)\n",
916 in->len, in->s, pvstate);
920 } /* end: pv_parse_spec */
925 int pv_parse_format(str *in, pv_elem_p *el)
932 if(in==NULL || in->s==NULL || el==NULL)
935 /*LM_DBG("parsing [%.*s]\n", in->len, in->s);*/
939 *el = pkg_malloc(sizeof(pv_elem_t));
942 memset(*el, 0, sizeof(pv_elem_t));
951 while(is_in_str(p,in))
954 e = pkg_malloc(sizeof(pv_elem_t));
957 memset(e, 0, sizeof(pv_elem_t));
965 while(is_in_str(p,in) && *p!=PV_MARKER)
967 e->text.len = p - e->text.s;
969 if(*p == '\0' || !is_in_str(p,in))
972 s.len = in->s+in->len-p;
973 p0 = pv_parse_spec(&s, &e->spec);
981 /*LM_DBG("format parsed OK: [%d] items\n", n);*/
989 pv_elem_free_all(*el);
997 int pv_get_spec_name(struct sip_msg* msg, pv_param_p ip, pv_value_t *name)
999 if(msg==NULL || ip==NULL || name==NULL)
1001 memset(name, 0, sizeof(pv_value_t));
1003 if(ip->pvn.type==PV_NAME_INTSTR)
1005 if(ip->pvn.u.isname.type&AVP_NAME_STR)
1007 name->rs = ip->pvn.u.isname.name.s;
1008 name->flags = PV_VAL_STR;
1010 name->ri = ip->pvn.u.isname.name.n;
1011 name->flags = PV_VAL_INT|PV_TYPE_INT;
1014 } else if(ip->pvn.type==PV_NAME_PVAR) {
1016 if(pv_get_spec_value(msg, (pv_spec_p)(ip->pvn.u.dname), name)!=0)
1018 LM_ERR("cannot get name value\n");
1021 if(name->flags&PV_VAL_NULL || name->flags&PV_VAL_EMPTY)
1023 LM_ERR("null or empty name\n");
1028 LM_ERR("name type is PV_NAME_OTHER - cannot resolve\n");
1034 * @return 0 on success, -1 on error
1036 int pv_parse_avp_name(pv_spec_p sp, str *in)
1042 if(in==NULL || in->s==NULL || sp==NULL)
1047 nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t));
1050 LM_ERR("no more memory\n");
1053 s = pv_parse_spec(in, nsp);
1056 LM_ERR("invalid name [%.*s]\n", in->len, in->s);
1060 //LM_ERR("dynamic name [%.*s]\n", in->len, in->s);
1061 //pv_print_spec(nsp);
1062 sp->pvp.pvn.type = PV_NAME_PVAR;
1063 sp->pvp.pvn.u.dname = (void*)nsp;
1066 /*LM_DBG("static name [%.*s]\n", in->len, in->s);*/
1067 if(km_parse_avp_spec(in, &sp->pvp.pvn.u.isname.type,
1068 &sp->pvp.pvn.u.isname.name)!=0)
1070 LM_ERR("bad avp name [%.*s]\n", in->len, in->s);
1073 sp->pvp.pvn.type = PV_NAME_INTSTR;
1078 * fill avp name details (id and type)
1079 * @return 0 on success, -1 on error
1081 int pv_get_avp_name(struct sip_msg* msg, pv_param_p ip, int_str *avp_name,
1082 unsigned short *name_type)
1085 if(ip==NULL || avp_name==NULL || name_type==NULL)
1087 memset(avp_name, 0, sizeof(int_str));
1090 if(ip->pvn.type==PV_NAME_INTSTR)
1092 *name_type = ip->pvn.u.isname.type;
1093 if(ip->pvn.u.isname.type&AVP_NAME_STR)
1095 avp_name->s = ip->pvn.u.isname.name.s;
1096 *name_type |= AVP_NAME_STR;
1098 avp_name->n = ip->pvn.u.isname.name.n;
1099 /* *name_type &= AVP_SCRIPT_MASK; */
1105 if(pv_get_spec_value(msg, (pv_spec_p)(ip->pvn.u.dname), &tv)!=0)
1107 LM_ERR("cannot get avp value\n");
1110 if(tv.flags&PV_VAL_NULL || tv.flags&PV_VAL_EMPTY)
1112 LM_ERR("null or empty name\n");
1116 if((tv.flags&PV_TYPE_INT) && (tv.flags&PV_VAL_INT))
1118 avp_name->n = tv.ri;
1120 avp_name->s = tv.rs;
1121 *name_type = AVP_NAME_STR;
1129 int pv_get_spec_index(struct sip_msg* msg, pv_param_p ip, int *idx, int *flags)
1132 if(ip==NULL || idx==NULL || flags==NULL)
1138 if(ip->pvi.type == PV_IDX_ALL) {
1139 *flags = PV_IDX_ALL;
1143 if(ip->pvi.type == PV_IDX_INT)
1145 *idx = ip->pvi.u.ival;
1150 if(pv_get_spec_value(msg, (pv_spec_p)ip->pvi.u.dval, &tv)!=0)
1152 LM_ERR("cannot get index value\n");
1155 if(!(tv.flags&PV_VAL_INT))
1157 LM_ERR("invalid index value\n");
1167 int pv_get_spec_value(struct sip_msg* msg, pv_spec_p sp, pv_value_t *value)
1171 if(msg==NULL || sp==NULL || sp->getf==NULL || value==NULL
1172 || sp->type==PVT_NONE)
1174 LM_ERR("bad parameters\n");
1178 memset(value, 0, sizeof(pv_value_t));
1180 ret = (*sp->getf)(msg, &(sp->pvp), value);
1185 return tr_exec(msg, (trans_t*)sp->trans, value);
1192 int pv_set_spec_value(struct sip_msg* msg, pv_spec_p sp, int op,
1195 if(sp==NULL || !pv_is_w(sp))
1196 return 0; /* no op */
1197 if(pv_alter_context(sp) && is_route_type(LOCAL_ROUTE))
1198 return 0; /* no op */
1199 return sp->setf(msg, &sp->pvp, op, value);
1205 int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len)
1212 if(msg==NULL || list==NULL || buf==NULL || len==NULL)
1222 for (it=list; it; it=it->next)
1225 if(it->text.s && it->text.len>0)
1227 if(n+it->text.len < *len)
1229 memcpy(cur, it->text.s, it->text.len);
1231 cur += it->text.len;
1233 LM_ERR("no more space for text [%d]\n", it->text.len);
1237 /* put the value of the specifier */
1238 if(it->spec.type!=PVT_NONE
1239 && pv_get_spec_value(msg, &(it->spec), &tok)==0)
1241 if(tok.flags&PV_VAL_NULL)
1242 tok.rs = pv_str_null;
1243 if(n+tok.rs.len < *len)
1247 memcpy(cur, tok.rs.s, tok.rs.len);
1252 LM_ERR("no more space for spec value\n");
1261 LM_ERR("buffer overflow -- increase the buffer size...\n");
1266 LM_DBG("final buffer length %d\n", n);
1276 pvname_list_t* parse_pvname_list(str *in, unsigned int type)
1278 pvname_list_t* head = NULL;
1279 pvname_list_t* al = NULL;
1280 pvname_list_t* last = NULL;
1285 if(in==NULL || in->s==NULL)
1287 LM_ERR("bad parameters\n");
1292 while(is_in_str(p, in))
1294 while(is_in_str(p, in) && (*p==' '||*p=='\t'||*p==','||*p==';'||*p=='\n'))
1296 if(!is_in_str(p, in))
1299 LM_ERR("parse error in name list [%.*s]\n", in->len, in->s);
1303 s.len = in->s + in->len - p;
1304 p = pv_parse_spec(&s, &spec);
1307 LM_ERR("parse error in item [%.*s]\n", s.len, s.s);
1310 if(type && spec.type!=type)
1312 LM_ERR("wrong type for item [%.*s]\n", (int)(p-s.s), s.s);
1315 al = (pvname_list_t*)pkg_malloc(sizeof(pvname_list_t));
1318 LM_ERR("no more memory!\n");
1321 memset(al, 0, sizeof(pvname_list_t));
1322 memcpy(&al->sname, &spec, sizeof(pv_spec_t));
1348 /** destroy the content of pv_spec_t structure.
1350 void pv_spec_destroy(pv_spec_t *spec)
1353 /* free name if it is PV */
1354 if(spec->pvp.pvn.nfree)
1355 spec->pvp.pvn.nfree((void*)(&spec->pvp.pvn));
1357 tr_free((trans_t*)spec->trans);
1360 /** free the pv_spec_t structure.
1362 void pv_spec_free(pv_spec_t *spec)
1365 pv_spec_destroy(spec);
1372 int pv_elem_free_all(pv_elem_p log)
1387 void pv_value_destroy(pv_value_t *val)
1390 if(val->flags&PV_VAL_PKG) pkg_free(val->rs.s);
1391 if(val->flags&PV_VAL_SHM) shm_free(val->rs.s);
1392 memset(val, 0, sizeof(pv_value_t));
1395 int pv_printf_s(struct sip_msg* msg, pv_elem_p list, str *s)
1397 s->s = pv_get_buffer();
1398 s->len = pv_get_buffer_size();
1399 return pv_printf( msg, list, s->s, &s->len);
1402 /********************************************************
1403 * Transformations API
1404 ********************************************************/
1409 static inline char* tr_get_class(str *in, char *p, str *tclass)
1412 while(is_in_str(p, in) && *p!=TR_CLASS_MARKER) p++;
1413 if(*p!=TR_CLASS_MARKER || tclass->s == p)
1415 LM_ERR("invalid transformation: %.*s (%c)!\n", in->len, in->s, *p);
1418 tclass->len = p - tclass->s;
1427 static inline trans_t* tr_new(void)
1431 t = (trans_t*)pkg_malloc(sizeof(trans_t));
1434 LM_ERR("no more private memory\n");
1437 memset(t, 0, sizeof(trans_t));
1441 char* tr_lookup(str *in, trans_t **tr)
1446 tr_export_t *te = NULL;
1451 if(in==NULL || in->s==NULL || tr==NULL)
1456 while(is_in_str(p, in) && (*p==' ' || *p=='\t' || *p=='\n')) p++;
1457 if(*p != TR_LBRACKET)
1461 if((t = tr_new())==NULL) return NULL;
1463 if(t0==NULL) *tr = t;
1467 /* find transformation class */
1468 p = tr_get_class(in, p, &tclass);
1469 if(p==NULL) goto error;
1471 /* locate transformation */
1472 te = tr_lookup_class(&tclass);
1475 LM_ERR("unknown transformation: [%.*s] in [%.*s]\n",
1476 tclass.len, tclass.s, in->len, in->s);
1480 s.s = p; s.len = in->s + in->len - p;
1481 p0 = te->tparse(&s, t);
1486 if(*p != TR_RBRACKET)
1488 LM_ERR("invalid transformation: %.*s | %c !!\n", in->len,
1494 if(!is_in_str(p, in))
1500 LM_ERR("error parsing [%.*s]\n", in->len, in->s);
1513 * \brief Destroy transformation including eventual parameter
1514 * \param t transformation
1516 void tr_destroy(trans_t *t)
1529 memset(t, 0, sizeof(trans_t));
1533 * \brief Exec transformation on a pseudo-variable value
1534 * \param msg SIP message
1535 * \param t one or more transformations
1536 * \param v pseudo-variable value
1537 * \return 0 on success, -1 on error
1539 int tr_exec(struct sip_msg *msg, trans_t *t, pv_value_t *v)
1544 if(t==NULL || v==NULL)
1546 LM_DBG("invalid parameters\n");
1550 for(i = t; i!=NULL; i=i->next)
1552 r = (*i->trf)(msg, i->params, i->subtype, v);
1560 * \brief Free allocated memory of transformation list
1561 * \param t transformation list
1563 void tr_free(trans_t *t)
1578 * \brief Free transformation parameter list
1579 * \param tp transformation list
1581 void tr_param_free(tr_param_t *tp)
1585 if(tp==NULL) return;
1590 if(tp0->type==TR_PARAM_SPEC)
1591 pv_spec_free((pv_spec_t*)tp0->v.data);
1596 typedef struct _tr_item
1600 struct _tr_item *next;
1601 } tr_item_t, *tr_item_p;
1603 static tr_item_t* _tr_table[TR_TABLE_SIZE];
1604 static int _tr_table_set = 0;
1610 void tr_init_table(void)
1612 memset(_tr_table, 0, sizeof(tr_item_t*)*TR_TABLE_SIZE);
1619 int tr_table_add(tr_export_t *e)
1621 tr_item_t *tri = NULL;
1622 tr_item_t *trj = NULL;
1623 tr_item_t *trn = NULL;
1627 if(e==NULL || e->tclass.s==NULL)
1629 LM_ERR("invalid parameters\n");
1633 if(_tr_table_set==0)
1635 LM_DBG("TR table not initialized, doing it now\n");
1640 // trid = get_hash1_raw(e->tclass.s, e->tclass.len);
1641 trid = get_hash1_raw(e->tclass.s, e->tclass.len);
1643 tri = _tr_table[trid%TR_TABLE_SIZE];
1646 if(tri->tre.tclass.len==e->tclass.len)
1648 found = strncmp(tri->tre.tclass.s, e->tclass.s, e->tclass.len);
1651 LM_ERR("TR class [%.*s] already exists\n", e->tclass.len,
1660 trn = (tr_item_t*)pkg_malloc(sizeof(tr_item_t));
1663 LM_ERR("no more memory\n");
1666 memset(trn, 0, sizeof(tr_item_t));
1667 memcpy(&(trn->tre), e, sizeof(tr_export_t));
1670 //LM_DBG("TR class [%.*s] added to entry [%d]\n", e->tclass.len,
1671 // e->tclass.s, trid%TR_TABLE_SIZE);
1674 trn->next = _tr_table[trid%TR_TABLE_SIZE];
1675 _tr_table[trid%TR_TABLE_SIZE] = trn;
1678 trn->next = trj->next;
1688 int register_trans_mod(char *mod_name, tr_export_t *items)
1696 for ( i=0 ; items[i].tclass.s ; i++ ) {
1697 ret = tr_table_add(&items[i]);
1699 LM_ERR("failed to register pseudo-variable <%.*s> for module %s\n",
1700 items[i].tclass.len, items[i].tclass.s, mod_name);
1709 int tr_table_free(void)
1715 for(i=0; i<TR_TABLE_SIZE; i++)
1725 memset(_tr_table, 0, sizeof(tr_item_t*)*TR_TABLE_SIZE);
1734 tr_export_t* tr_lookup_class(str *tclass)
1739 if(tclass==0 || tclass->s==0)
1741 LM_ERR("bad parameters\n");
1745 /* search in TR table */
1746 // trid = get_hash1_raw(tclass->s, tclass->len);
1747 trid = get_hash1_raw(tclass->s, tclass->len);
1748 tri = _tr_table[trid%TR_TABLE_SIZE];
1751 if(tri->trid==trid && tri->tre.tclass.len==tclass->len
1752 && memcmp(tri->tre.tclass.s, tclass->s, tclass->len)==0)
1761 /********************************************************
1762 * core PVs, initialization and destroy APIs
1763 ********************************************************/
1765 static pv_export_t _core_pvs[] = {
1766 {{"null", (sizeof("null")-1)}, /* */
1767 PVT_NULL, pv_get_null, 0,
1770 { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
1773 /** init pv api (optional).
1774 * @return 0 on success, -1 on error
1776 int pv_init_api(void)
1780 if(pv_init_buffer()<0)
1782 if(register_pvars_mod("core", _core_pvs)<0)
1788 /** destroy pv api. */
1789 void pv_destroy_api(void)
1791 /* free PV and TR hash tables */
1794 pv_destroy_buffer();
1799 * - buffer to print PVs
1801 static char **_pv_print_buffer = NULL;
1802 #define PV_DEFAULT_PRINT_BUFFER_SIZE 1024
1803 static int _pv_print_buffer_size = PV_DEFAULT_PRINT_BUFFER_SIZE;
1804 /* 6 mod params + 4 direct usage from mods */
1805 #define PV_DEFAULT_PRINT_BUFFER_SLOTS 10
1806 static int _pv_print_buffer_slots = PV_DEFAULT_PRINT_BUFFER_SLOTS;
1807 static int _pv_print_buffer_index = 0;
1812 int pv_init_buffer(void)
1816 /* already initialized ?!? */
1817 if(_pv_print_buffer!=NULL)
1821 (char**)pkg_malloc(_pv_print_buffer_slots*sizeof(char*));
1822 if(_pv_print_buffer==NULL)
1824 LM_ERR("cannot init PV print buffer slots\n");
1827 memset(_pv_print_buffer, 0, _pv_print_buffer_slots*sizeof(char*));
1828 for(i=0; i<_pv_print_buffer_slots; i++)
1830 _pv_print_buffer[i] =
1831 (char*)pkg_malloc(_pv_print_buffer_size*sizeof(char));
1832 if(_pv_print_buffer[i]==NULL)
1834 LM_ERR("cannot init PV print buffer slot[%d]\n", i);
1838 LM_DBG("PV print buffer initialized to [%d][%d]\n",
1839 _pv_print_buffer_slots, _pv_print_buffer_size);
1846 void pv_destroy_buffer(void)
1850 if(_pv_print_buffer==NULL)
1852 for(i=0; i<_pv_print_buffer_slots; i++)
1854 if(_pv_print_buffer[i]!=NULL)
1855 pkg_free(_pv_print_buffer[i]);
1857 pkg_free(_pv_print_buffer);
1858 _pv_print_buffer = NULL;
1864 int pv_reinit_buffer(void)
1866 if(_pv_print_buffer_size==PV_DEFAULT_PRINT_BUFFER_SIZE
1867 && _pv_print_buffer_slots==PV_DEFAULT_PRINT_BUFFER_SLOTS)
1869 pv_destroy_buffer();
1870 return pv_init_buffer();
1876 char* pv_get_buffer(void)
1880 p = _pv_print_buffer[_pv_print_buffer_index];
1881 _pv_print_buffer_index = (_pv_print_buffer_index+1)%_pv_print_buffer_slots;
1889 int pv_get_buffer_size(void)
1891 return _pv_print_buffer_size;
1897 int pv_get_buffer_slots(void)
1899 return _pv_print_buffer_slots;
1905 void pv_set_buffer_size(int n)
1907 _pv_print_buffer_size = n;
1908 if(_pv_print_buffer_size<=0)
1909 _pv_print_buffer_size = PV_DEFAULT_PRINT_BUFFER_SIZE;
1915 void pv_set_buffer_slots(int n)
1917 _pv_print_buffer_slots = n;
1918 if(_pv_print_buffer_slots<=0)
1919 _pv_print_buffer_slots = PV_DEFAULT_PRINT_BUFFER_SLOTS;