int xavp_params_explode(str *params, str *xname) { param_t* params_list = NULL; param_hooks_t phooks; param_t *pit=NULL; str s; sr_xavp_t *xavp=NULL; sr_xval_t xval; if(params==NULL || xname==NULL || params->s==NULL || xname->s==NULL || params->len<=0 || xname->len<=0) { LM_ERR("invalid parameters\n"); return -1; } s.s = params->s; s.len = params->len; if(s.s[s.len-1]==';') s.len--; if (parse_params(&s, CLASS_ANY, &phooks, ¶ms_list)<0) { LM_DBG("invalid formatted values [%.*s]\n", params->len, params->s); return -1; } if(params_list==NULL) { return -1; } for (pit = params_list; pit; pit=pit->next) { memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = pit->body; if(xavp_add_value(&pit->name, &xval, &xavp)==NULL) { free_params(params_list); xavp_destroy_list(&xavp); return -1; } } free_params(params_list); /* add main xavp in root list */ memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; xval.v.xavp = xavp; if(xavp_add_value(xname, &xval, NULL)==NULL) { xavp_destroy_list(&xavp); return -1; } return 0; }
sr_xavp_t *xavp_add_xavp_value(str *rname, str *name, sr_xval_t *val, sr_xavp_t **list) { sr_xavp_t *ravp=0; sr_xavp_t *cavp=0; sr_xval_t rval; cavp = xavp_new_value(name, val); if (cavp==NULL) return NULL; memset(&rval, 0, sizeof(sr_xval_t)); rval.type = SR_XTYPE_XAVP; rval.v.xavp = cavp; ravp = xavp_new_value(rname, &rval); if (ravp==NULL) { xavp_destroy_list(&cavp); return NULL; } /* Prepend new value to the list */ if(list) { ravp->next = *list; *list = ravp; } else { ravp->next = *_xavp_list_crt; *_xavp_list_crt = ravp; } return ravp; }
void xavp_reset_list(void) { assert(_xavp_list_crt!=0 ); if (_xavp_list_crt!=&_xavp_list_head) _xavp_list_crt=&_xavp_list_head; xavp_destroy_list(_xavp_list_crt); }
void xavp_free(sr_xavp_t *xa) { if(xa->val.type == SR_XTYPE_DATA) { if(xa->val.v.data!=NULL && xa->val.v.data->pfree!=NULL) { xa->val.v.data->pfree(xa->val.v.data->p, xavp_shm_free); shm_free(xa->val.v.data); } } else if(xa->val.type == SR_XTYPE_XAVP) { xavp_destroy_list(&xa->val.v.xavp); } shm_free(xa); }
int rtjson_init_routes(sip_msg_t *msg, str *rdoc) { sr_xavp_t *xavp=NULL; str xname; sr_xval_t xval; srjson_doc_t tdoc; srjson_InitDoc(&tdoc, NULL); tdoc.root = srjson_Parse(&tdoc, rdoc->s); if(tdoc.root == NULL) { LM_ERR("invalid json doc [[%s]]\n", rdoc->s); srjson_DestroyDoc(&tdoc); return -1; } /* basic validation */ srjson_DestroyDoc(&tdoc); memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_INT; xval.v.i = 0; xname.s = "idx"; xname.len = 3; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = *rdoc; xname.s = "json"; xname.len = 4; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; xval.v.xavp = xavp; if(xavp_add_value(&_rtjson_xavp_name, &xval, NULL)==NULL) { goto error; } return 0; error: if(xavp) xavp_destroy_list(&xavp); return -1; }
/*! \brief * add xavp with details of the record (ruid, ...) */ int xavp_rcd_helper(ucontact_t* ptr) { sr_xavp_t **xavp=NULL; sr_xavp_t *list=NULL; sr_xavp_t *new_xavp=NULL; str xname_ruid = {"ruid", 4}; str xname_received = { "received", 8}; str xname_contact = { "contact", 7}; str xname_expires = {"expires", 7}; sr_xval_t xval; if(ptr==NULL) return -1; if(reg_xavp_rcd.s==NULL || reg_xavp_rcd.len<=0) return 0; list = xavp_get(®_xavp_rcd, NULL); xavp = list ? &list->val.v.xavp : &new_xavp; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = ptr->ruid; xavp_add_value(&xname_ruid, &xval, xavp); if(ptr->received.len > 0) { memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = ptr->received; xavp_add_value(&xname_received, &xval, xavp); } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = ptr->c; xavp_add_value(&xname_contact, &xval, xavp); memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_INT; xval.v.i = (int) (ptr->expires - time(0)); xavp_add_value(&xname_expires, &xval, xavp); if(list==NULL) { /* no reg_xavp_rcd xavp in root list - add it */ xval.type = SR_XTYPE_XAVP; xval.v.xavp = *xavp; if(xavp_add_value(®_xavp_rcd, &xval, NULL)==NULL) { LM_ERR("cannot add ruid xavp to root list\n"); xavp_destroy_list(xavp); } } return 0; }
int rtjson_init_routes(sip_msg_t *msg, str *rdoc) { srjson_Hooks jhooks; srjson_doc_t *tdoc = NULL; sr_data_t *xdata = NULL; rtjson_data_t *rdata = NULL; sr_xavp_t *xavp=NULL; str xname; sr_xval_t xval; memset(&jhooks, 0, sizeof(srjson_Hooks)); jhooks.malloc_fn = rtjson_malloc; jhooks.free_fn = rtjson_free; tdoc = srjson_NewDoc(&jhooks); if(tdoc==NULL) { LM_ERR("no more shm\n"); return -1; } tdoc->root = srjson_Parse(tdoc, rdoc->s); if(tdoc->root == NULL) { LM_ERR("invalid json doc [[%s]]\n", rdoc->s); srjson_DeleteDoc(tdoc); return -1; } xdata = shm_malloc(sizeof(sr_data_t)); if(xdata==NULL) { LM_ERR("no more shm\n"); srjson_DeleteDoc(tdoc); return -1; } memset(xdata, 0, sizeof(sr_data_t)); rdata = shm_malloc(sizeof(rtjson_data_t)); if(rdata==NULL) { LM_ERR("no more shm\n"); srjson_DeleteDoc(tdoc); shm_free(xdata); return -1; } memset(rdata, 0, sizeof(rtjson_data_t)); rdata->jdoc = tdoc; xdata->p = rdata; xdata->pfree = rtjson_data_free; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = *rdoc; xname.s = "json"; xname.len = 4; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_DATA; xval.v.data = xdata; xname.s = "data"; xname.len = 4; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } /* reset pointers - they are linked inside xavp now */ tdoc = NULL; xdata = NULL; rdata = NULL; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; xval.v.xavp = xavp; if(xavp_add_value(&_rtjson_xavp_name, &xval, NULL)==NULL) { goto error; } return 0; error: if(xavp) xavp_destroy_list(&xavp); if(rdata) shm_free(rdata); if(xdata) shm_free(xdata); if(tdoc) srjson_DeleteDoc(tdoc); return -1; }
int registered4(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag, int match_action_flag) { str uri, aor; urecord_t* r; ucontact_t* ptr; int res; str match_callid = {0,0}; str match_received = {0,0}; str match_contact = {0,0}; sr_xavp_t *vavp = NULL; if(_uri!=NULL) { uri = *_uri; } else { if(IS_SIP_REPLY(_m)) { if (parse_to_header(_m) < 0) { LM_ERR("failed to prepare the message\n"); return -1; } uri = get_to(_m)->uri; } else { if (_m->new_uri.s) uri = _m->new_uri; else uri = _m->first_line.u.request.uri; } } if (extract_aor(&uri, &aor, NULL) < 0) { LM_ERR("failed to extract address of record\n"); return -1; } ul.lock_udomain(_d, &aor); res = ul.get_urecord(_d, &aor, &r); if (res < 0) { ul.unlock_udomain(_d, &aor); LM_ERR("failed to query usrloc\n"); return -1; } if (res == 0) { LM_DBG("searching with match flags (%d,%d)\n", match_flag, match_action_flag); if(reg_xavp_cfg.s!=NULL) { if((match_flag & 1) && (vavp = xavp_get_child_with_sval(®_xavp_cfg, &match_callid_name)) != NULL && vavp->val.v.s.len > 0) { match_callid = vavp->val.v.s; LM_DBG("matching with callid %.*s\n", match_callid.len, match_callid.s); } if((match_flag & 2) && (vavp = xavp_get_child_with_sval(®_xavp_cfg, &match_received_name)) != NULL && vavp->val.v.s.len > 0) { match_received = vavp->val.v.s; LM_DBG("matching with received %.*s\n", match_received.len, match_received.s); } if((match_flag & 4) && (vavp = xavp_get_child_with_sval(®_xavp_cfg, &match_contact_name)) != NULL && vavp->val.v.s.len > 0) { match_contact = vavp->val.v.s; LM_DBG("matching with contact %.*s\n", match_contact.len, match_contact.s); } } for (ptr = r->contacts; ptr; ptr = ptr->next) { if(!VALID_CONTACT(ptr, act_time)) continue; if (match_callid.s && /* optionally enforce tighter matching w/ Call-ID */ match_callid.len > 0 && (match_callid.len != ptr->callid.len || memcmp(match_callid.s, ptr->callid.s, match_callid.len))) continue; if (match_received.s && /* optionally enforce tighter matching w/ ip:port */ match_received.len > 0 && (match_received.len != ptr->received.len || memcmp(match_received.s, ptr->received.s, match_received.len))) continue; if (match_contact.s && /* optionally enforce tighter matching w/ Contact */ match_contact.len > 0 && (match_contact.len != ptr->c.len || memcmp(match_contact.s, ptr->c.s, match_contact.len))) continue; if(!(match_action_flag & 2)) { xavp_rcd_helper(ptr); } if((ptr->xavp!=NULL) && (match_action_flag & 1)) { sr_xavp_t *xavp = xavp_clone_level_nodata(ptr->xavp); if(xavp_add(xavp, NULL)<0) { LM_ERR("error adding xavp for %.*s after successful match\n", aor.len, ZSW(aor.s)); xavp_destroy_list(&xavp); } } ul.release_urecord(r); ul.unlock_udomain(_d, &aor); LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s)); return 1; } } ul.unlock_udomain(_d, &aor); LM_DBG("'%.*s' not found in usrloc\n", aor.len, ZSW(aor.s)); return -1; }
/** * clone the xavp without values that are custom data * - only one list level is cloned, other sublists are ignored */ sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold) { sr_xavp_t *xnew = NULL; sr_xavp_t *navp = NULL; sr_xavp_t *oavp = NULL; sr_xavp_t *pavp = NULL; if(xold == NULL) { return NULL; } if(xold->val.type==SR_XTYPE_DATA) { LM_INFO("xavp value type is 'data' - ignoring in clone\n"); return NULL; } xnew = xavp_new_value(&xold->name, &xold->val); if(xnew==NULL) { LM_ERR("cannot create cloned root xavp\n"); return NULL; } LM_DBG("cloned root xavp [%.*s]\n", xold->name.len, xold->name.s); if(xold->val.type!=SR_XTYPE_XAVP) { return xnew; } xnew->val.v.xavp = NULL; oavp = xold->val.v.xavp; while(oavp) { if(oavp->val.type!=SR_XTYPE_DATA && oavp->val.type!=SR_XTYPE_XAVP) { navp = xavp_new_value(&oavp->name, &oavp->val); if(navp==NULL) { LM_ERR("cannot create cloned embedded xavp\n"); if(xnew->val.v.xavp == NULL) { shm_free(xnew); return NULL; } else { xavp_destroy_list(&navp); return NULL; } } LM_DBG("cloned inner xavp [%.*s]\n", oavp->name.len, oavp->name.s); if(xnew->val.v.xavp == NULL) { /* link to val in head xavp */ xnew->val.v.xavp = navp; } else { /* link to prev xavp in the list */ pavp->next = navp; } pavp = navp; } oavp = oavp->next; } if(xnew->val.v.xavp == NULL) { shm_free(xnew); return NULL; } return xnew; }