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 ht dmq callback */ int dlg_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* node) { int content_length; str body; dlg_cell_t *dlg; int unref = 0; int ret; srjson_doc_t jdoc, prof_jdoc; srjson_t *it = NULL; dlg_dmq_action_t action = DLG_DMQ_NONE; dlg_iuid_t iuid; str profiles = {0, 0}, callid = {0, 0}, tag1 = {0,0}, tag2 = {0,0}, contact1 = {0,0}, contact2 = {0,0}, k={0,0}, v={0,0}; str cseq1 = {0,0}, cseq2 = {0,0}, route_set1 = {0,0}, route_set2 = {0,0}, from_uri = {0,0}, to_uri = {0,0}, req_uri = {0,0}; unsigned int init_ts = 0, start_ts = 0, lifetime = 0; unsigned int state = 1; srjson_t *vj; /* received dmq message */ LM_DBG("dmq message received\n"); if(!msg->content_length) { LM_ERR("no content length header found\n"); goto invalid2; } content_length = get_content_length(msg); if(!content_length) { LM_DBG("content length is 0\n"); goto invalid2; } body.s = get_body(msg); body.len = content_length; if (!body.s) { LM_ERR("unable to get body\n"); goto error; } /* parse body */ LM_DBG("body: %.*s\n", body.len, body.s); srjson_InitDoc(&jdoc, NULL); jdoc.buf = body; if(jdoc.root == NULL) { jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s); if(jdoc.root == NULL) { LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s); goto invalid; } } for(it=jdoc.root->child; it; it = it->next) { if ((it->string == NULL) || (strcmp(it->string, "vars")==0)) continue; LM_DBG("found field: %s\n", it->string); if (strcmp(it->string, "action")==0) { action = SRJSON_GET_UINT(it); } else if (strcmp(it->string, "h_entry")==0) { iuid.h_entry = SRJSON_GET_UINT(it); } else if (strcmp(it->string, "h_id")==0) { iuid.h_id = SRJSON_GET_UINT(it); } else if (strcmp(it->string, "init_ts")==0) { init_ts = SRJSON_GET_UINT(it); } else if (strcmp(it->string, "start_ts")==0) { start_ts = SRJSON_GET_UINT(it); } else if (strcmp(it->string, "state")==0) { state = SRJSON_GET_UINT(it); } else if (strcmp(it->string, "lifetime")==0) { lifetime = SRJSON_GET_UINT(it); } else if (strcmp(it->string, "callid")==0) { callid.s = it->valuestring; callid.len = strlen(callid.s); } else if (strcmp(it->string, "profiles")==0) { profiles.s = it->valuestring; profiles.len = strlen(profiles.s); } else if (strcmp(it->string, "tag1")==0) { tag1.s = it->valuestring; tag1.len = strlen(tag1.s); } else if (strcmp(it->string, "tag2")==0) { tag2.s = it->valuestring; tag2.len = strlen(tag2.s); } else if (strcmp(it->string, "cseq1")==0) { cseq1.s = it->valuestring; cseq1.len = strlen(cseq1.s); } else if (strcmp(it->string, "cseq2")==0) { cseq2.s = it->valuestring; cseq2.len = strlen(cseq2.s); } else if (strcmp(it->string, "route_set1")==0) { route_set1.s = it->valuestring; route_set1.len = strlen(route_set1.s); } else if (strcmp(it->string, "route_set2")==0) { route_set2.s = it->valuestring; route_set2.len = strlen(route_set2.s); } else if (strcmp(it->string, "contact1")==0) { contact1.s = it->valuestring; contact1.len = strlen(contact1.s); } else if (strcmp(it->string, "contact2")==0) { contact2.s = it->valuestring; contact2.len = strlen(contact2.s); } else if (strcmp(it->string, "from_uri")==0) { from_uri.s = it->valuestring; from_uri.len = strlen(from_uri.s); } else if (strcmp(it->string, "to_uri")==0) { to_uri.s = it->valuestring; to_uri.len = strlen(to_uri.s); } else if (strcmp(it->string, "req_uri")==0) { req_uri.s = it->valuestring; req_uri.len = strlen(req_uri.s); } else { LM_ERR("unrecognized field in json object\n"); } } dlg = dlg_get_by_iuid(&iuid); if (dlg) { LM_DBG("found dialog [%u:%u] at %p\n", iuid.h_entry, iuid.h_id, dlg); unref++; } switch(action) { case DLG_DMQ_UPDATE: LM_DBG("Updating dlg [%u:%u] with callid [%.*s]\n", iuid.h_entry, iuid.h_id, callid.len, callid.s); if (!dlg) { dlg = build_new_dlg(&callid, &from_uri, &to_uri, &tag1, &req_uri); if (!dlg) { LM_ERR("failed to build new dialog\n"); goto error; } if(dlg->h_entry != iuid.h_entry){ LM_ERR("inconsistent hash data from peer: " "make sure all Kamailio's use the same hash size\n"); shm_free(dlg); goto error; } /* link the dialog */ link_dlg(dlg, 0, 0); dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0); /* override generated h_id */ dlg->h_id = iuid.h_id; /* prevent DB sync */ dlg->dflags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED); dlg->iflags |= DLG_IFLAG_DMQ_SYNC; } else { /* remove existing profiles */ if (dlg->profile_links!=NULL) { destroy_linkers(dlg->profile_links); dlg->profile_links = NULL; } } dlg->init_ts = init_ts; dlg->start_ts = start_ts; vj = srjson_GetObjectItem(&jdoc, jdoc.root, "vars"); if(vj!=NULL) { for(it=vj->child; it; it = it->next) { k.s = it->string; k.len = strlen(k.s); v.s = it->valuestring; v.len = strlen(v.s); set_dlg_variable(dlg, &k, &v); } } /* add profiles */ if(profiles.s!=NULL) { srjson_InitDoc(&prof_jdoc, NULL); prof_jdoc.buf = profiles; dlg_json_to_profiles(dlg, &prof_jdoc); srjson_DestroyDoc(&prof_jdoc); } if (state == dlg->state) { break; } /* intentional fallthrough */ case DLG_DMQ_STATE: if (!dlg) { LM_ERR("dialog [%u:%u] not found\n", iuid.h_entry, iuid.h_id); goto error; } if (state < dlg->state) { LM_NOTICE("Ignoring backwards state change on dlg [%u:%u]" " with callid [%.*s] from state [%u] to state [%u]\n", iuid.h_entry, iuid.h_id, dlg->callid.len, dlg->callid.s, dlg->state, state); break; } LM_DBG("State update dlg [%u:%u] with callid [%.*s] from state [%u]" " to state [%u]\n", iuid.h_entry, iuid.h_id, dlg->callid.len, dlg->callid.s, dlg->state, state); switch (state) { case DLG_STATE_EARLY: dlg->start_ts = start_ts; dlg->lifetime = lifetime; dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0); break; case DLG_STATE_CONFIRMED: dlg->start_ts = start_ts; dlg->lifetime = lifetime; dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0); dlg_set_leg_info(dlg, &tag2, &route_set2, &contact2, &cseq2, 1); if (insert_dlg_timer( &dlg->tl, dlg->lifetime ) != 0) { LM_CRIT("Unable to insert dlg timer %p [%u:%u]\n", dlg, dlg->h_entry, dlg->h_id); } else { /* dialog pointer inserted in timer list */ dlg_ref(dlg, 1); } break; case DLG_STATE_DELETED: if (dlg->state == DLG_STATE_CONFIRMED) { ret = remove_dialog_timer(&dlg->tl); if (ret == 0) { /* one extra unref due to removal from timer list */ unref++; } else if (ret < 0) { LM_CRIT("unable to unlink the timer on dlg %p [%u:%u]\n", dlg, dlg->h_entry, dlg->h_id); } } /* prevent DB sync */ dlg->dflags |= DLG_FLAG_NEW; /* keep dialog around for a bit, to prevent out-of-order * syncs to reestablish the dlg */ dlg->init_ts = time(NULL); break; default: LM_ERR("unhandled state update to state %u\n", state); dlg_unref(dlg, unref); goto error; } dlg->state = state; break; case DLG_DMQ_RM: if (!dlg) { LM_DBG("dialog [%u:%u] not found\n", iuid.h_entry, iuid.h_id); goto error; } LM_DBG("Removed dlg [%u:%u] with callid [%.*s] int state [%u]\n", iuid.h_entry, iuid.h_id, dlg->callid.len, dlg->callid.s, dlg->state); if (dlg->state==DLG_STATE_CONFIRMED || dlg->state==DLG_STATE_EARLY) { ret = remove_dialog_timer(&dlg->tl); if (ret == 0) { /* one extra unref due to removal from timer list */ unref++; } else if (ret < 0) { LM_CRIT("unable to unlink the timer on dlg %p [%u:%u]\n", dlg, dlg->h_entry, dlg->h_id); } } /* prevent DB sync */ dlg->dflags |= DLG_FLAG_NEW; unref++; break; case DLG_DMQ_SYNC: dmq_send_all_dlgs(0); break; case DLG_DMQ_NONE: break; } if (dlg && unref) dlg_unref(dlg, unref); srjson_DestroyDoc(&jdoc); resp->reason = dmq_200_rpl; resp->resp_code = 200; return 0; invalid: srjson_DestroyDoc(&jdoc); invalid2: resp->reason = dmq_400_rpl; resp->resp_code = 400; return 0; error: srjson_DestroyDoc(&jdoc); resp->reason = dmq_500_rpl; resp->resp_code = 500; return 0; }
/** * json de-serialization of dialog profiles */ int dlg_json_to_profiles(dlg_cell_t *dlg, srjson_doc_t *jdoc) { srjson_t *aj = NULL; srjson_t *it = NULL; srjson_t *jt = NULL; dlg_profile_table_t *profile; str name; str val; str puid; time_t expires; int flags; if(dlg==NULL || jdoc==NULL || jdoc->buf.s==NULL) return -1; if(jdoc->root == NULL) { jdoc->root = srjson_Parse(jdoc, jdoc->buf.s); if(jdoc->root == NULL) { LM_ERR("invalid json doc [[%s]]\n", jdoc->buf.s); return -1; } } aj = srjson_GetObjectItem(jdoc, jdoc->root, "profiles"); if(aj!=NULL) { for(it=aj->child; it; it = it->next) { name.s = val.s = puid.s = NULL; expires = 0; flags = 0; for(jt = it->child; jt; jt = jt->next) { if(strcmp(jt->string, "name")==0) { name.s = jt->valuestring; name.len = strlen(name.s); } else if(strcmp(jt->string, "value")==0) { val.s = jt->valuestring; val.len = strlen(val.s); } else if(strcmp(jt->string, "puid")==0) { puid.s = jt->valuestring; puid.len = strlen(puid.s); } else if(strcmp(jt->string, "expires")==0) { expires = (time_t)SRJSON_GET_ULONG(jt); } else if(strcmp(jt->string, "flags")==0) { flags = SRJSON_GET_UINT(jt); } } if(name.s==NULL) continue; profile = search_dlg_profile(&name); if(profile==NULL) { LM_ERR("profile [%.*s] not found\n", name.len, name.s); continue; } if(val.s!=NULL) { if(profile->has_value) { if(dlg_add_profile(dlg, &val, profile, &puid, expires, flags) < 0) LM_ERR("dynamic profile cannot be added, ignore!\n"); else LM_DBG("dynamic profile added [%s : %s]\n", name.s, val.s); } } else { if(!profile->has_value) { if(dlg_add_profile(dlg, NULL, profile, &puid, expires, flags) < 0) LM_ERR("static profile cannot be added, ignore!\n"); else LM_DBG("static profile added [%s]\n", name.s); } } } } return 0; }
/** * @brief ht dmq callback */ int usrloc_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* node) { int content_length; str body; srjson_doc_t jdoc; srjson_t *it = NULL; static ucontact_info_t ci; int action, expires, cseq, flags, cflags, q, last_modified, methods, reg_id; str aor, ruid, c, received, path, callid, user_agent, instance; parse_from_header(msg); body = ((struct to_body*)msg->from->parsed)->uri; LM_DBG("dmq message received from %.*s\n", body.len, body.s); if(!msg->content_length) { LM_ERR("no content length header found\n"); goto invalid; } content_length = get_content_length(msg); if(!content_length) { LM_DBG("content length is 0\n"); goto invalid; } body.s = get_body(msg); body.len = content_length; if (!body.s) { LM_ERR("unable to get body\n"); goto error; } srjson_InitDoc(&jdoc, NULL); jdoc.buf = body; if(jdoc.root == NULL) { jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s); if(jdoc.root == NULL) { LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s); goto invalid; } } for(it=jdoc.root->child; it; it = it->next) { if (it->string == NULL) continue; if (strcmp(it->string, "action")==0) { action = it->valueint; } else if (strcmp(it->string, "aor")==0) { aor.s = it->valuestring; aor.len = strlen(aor.s); } else if (strcmp(it->string, "ruid")==0) { ruid.s = it->valuestring; ruid.len = strlen(ruid.s); } else if (strcmp(it->string, "c")==0) { c.s = it->valuestring; c.len = strlen(c.s); } else if (strcmp(it->string, "received")==0) { received.s = it->valuestring; received.len = strlen(received.s); } else if (strcmp(it->string, "path")==0) { path.s = it->valuestring; path.len = strlen(path.s); } else if (strcmp(it->string, "callid")==0) { callid.s = it->valuestring; callid.len = strlen(callid.s); } else if (strcmp(it->string, "user_agent")==0) { user_agent.s = it->valuestring; user_agent.len = strlen(user_agent.s); } else if (strcmp(it->string, "instance")==0) { instance.s = it->valuestring; instance.len = strlen(instance.s); } else if (strcmp(it->string, "expires")==0) { // expires = it->valueint; } else if (strcmp(it->string, "cseq")==0) { cseq = it->valueint; } else if (strcmp(it->string, "flags")==0) { flags = it->valueint; } else if (strcmp(it->string, "cflags")==0) { cflags = it->valueint; } else if (strcmp(it->string, "q")==0) { q = it->valueint; } else if (strcmp(it->string, "last_modified")==0) { last_modified = it->valueint; } else if (strcmp(it->string, "methods")==0) { methods = it->valueint; } else if (strcmp(it->string, "reg_id")==0) { reg_id = it->valueint; } else { LM_ERR("unrecognized field in json object\n"); } } memset( &ci, 0, sizeof(ucontact_info_t)); ci.ruid = ruid; ci.c = &c; ci.received = received; ci.path = &path; ci.expires = expires; ci.q = q; ci.callid = &callid; ci.cseq = cseq; ci.flags = flags; ci.flags |= FL_RPL; ci.cflags = cflags; ci.user_agent = &user_agent; ci.methods = methods; ci.instance = instance; ci.reg_id = reg_id; ci.tcpconn_id = -1; ci.last_modified = last_modified; switch(action) { case DMQ_UPDATE: LM_DBG("Received DMQ_UPDATE. Update contact info...\n"); add_contact(aor, &ci); break; case DMQ_RM: LM_DBG("Received DMQ_RM. Delete contact info...\n"); delete_contact(aor, &ci); break; case DMQ_SYNC: LM_DBG("Received DMQ_SYNC. Sending all contacts...\n"); usrloc_get_all_ucontact(node); break; case DMQ_NONE: LM_DBG("Received DMQ_NONE. Not used...\n"); break; default: goto invalid; } srjson_DestroyDoc(&jdoc); resp->reason = dmq_200_rpl; resp->resp_code = 200; return 0; invalid: srjson_DestroyDoc(&jdoc); resp->reason = dmq_400_rpl; resp->resp_code = 400; return 0; error: srjson_DestroyDoc(&jdoc); resp->reason = dmq_500_rpl; resp->resp_code = 500; return 0; }
/** * json de-serialization of dialog profiles */ int dlg_json_to_profiles(dlg_cell_t *dlg, srjson_doc_t *jdoc) { srjson_t *sj = NULL; srjson_t *dj = NULL; srjson_t *it = NULL; dlg_profile_table_t *profile; str name; str val; if(dlg==NULL || jdoc==NULL || jdoc->buf.s==NULL) return -1; if(jdoc->root == NULL) { jdoc->root = srjson_Parse(jdoc, jdoc->buf.s); if(jdoc->root == NULL) { LM_ERR("invalid json doc [[%s]]\n", jdoc->buf.s); return -1; } } dj = srjson_GetObjectItem(jdoc, jdoc->root, "dprofiles"); sj = srjson_GetObjectItem(jdoc, jdoc->root, "sprofiles"); if(dj!=NULL) { for(it=dj->child; it; it = it->next) { name.s = it->string; name.len = strlen(name.s); val.s = it->valuestring; val.len = strlen(val.s); profile = search_dlg_profile(&name); if(profile==NULL) { LM_ERR("profile [%.*s] not found\n", name.len, name.s); continue; } if(profile->has_value) { if(dlg_add_profile(dlg, &val, profile) < 0) LM_ERR("dynamic profile cannot be added, ignore!\n"); else LM_DBG("dynamic profile added [%s : %s]\n", name.s, val.s); } } } if(sj!=NULL) { for(it=sj->child; it; it = it->next) { name.s = it->valuestring; name.len = strlen(name.s); profile = search_dlg_profile(&name); if(profile==NULL) { LM_ERR("profile [%.*s] not found\n", name.len, name.s); continue; } if(!profile->has_value) { if(dlg_add_profile(dlg, NULL, profile) < 0) LM_ERR("static profile cannot be added, ignore!\n"); else LM_DBG("static profile added [%s]\n", name.s); } } } return 0; }
int rtjson_update_branch(sip_msg_t *msg) { sr_xavp_t *javp = NULL; sr_xavp_t *iavp = NULL; srjson_doc_t tdoc; srjson_t *tj = NULL; srjson_t *nj = NULL; str val; str xname; int i; xname.s = "json"; xname.len = 4; javp = xavp_get_child_with_sval(&_rtjson_xavp_name, &xname); if(javp==NULL || javp->val.v.s.len<=0) { LM_WARN("no json for routing\n"); return -1; } xname.s = "idx"; xname.len = 3; iavp = xavp_get_child_with_ival(&_rtjson_xavp_name, &xname); if(iavp==NULL) { LM_WARN("no idx for routing\n"); return -1; } if(iavp->val.v.i<=0) { LM_WARN("invalid branch idx for routing\n"); return -1; } srjson_InitDoc(&tdoc, NULL); tdoc.root = srjson_Parse(&tdoc, javp->val.v.s.s); if(tdoc.root == NULL) { LM_ERR("invalid json doc [[%s]]\n", javp->val.v.s.s); srjson_DestroyDoc(&tdoc); return -1; } nj = srjson_GetObjectItem(&tdoc, tdoc.root, "routing"); if(nj==NULL || nj->valuestring==NULL) { LM_ERR("missing or invalid routing field\n"); goto error; } val.s = nj->valuestring; val.len = strlen(val.s); if(val.len!=6 || strncmp(val.s, "serial", 6)!=0) { LM_DBG("not serial routing [%.*s]\n", val.len, val.s); goto error; } tj = srjson_GetObjectItem(&tdoc, tdoc.root, "routes"); if(tj==NULL || tj->type!=srjson_Array || tj->child==NULL) { LM_ERR("missing or invalid routes field\n"); goto error; } nj = tj->child; i = 0; /* stop at number of branches - 1 */ while(nj && i<iavp->val.v.i-1) { nj = nj->next; i++; } if(nj==NULL) goto error; if(rtjson_prepare_branch(msg, &tdoc, nj)<0) goto error; srjson_DestroyDoc(&tdoc); return 0; error: srjson_DestroyDoc(&tdoc); return -1; }
int rtjson_push_routes(sip_msg_t *msg) { sr_xavp_t *javp = NULL; sr_xavp_t *iavp = NULL; srjson_doc_t tdoc; srjson_t *nj = NULL; str val; str xname; int ret; xname.s = "json"; xname.len = 4; javp = xavp_get_child_with_sval(&_rtjson_xavp_name, &xname); if(javp==NULL || javp->val.v.s.len<=0) { LM_WARN("no json for routing\n"); return -1; } xname.s = "idx"; xname.len = 3; iavp = xavp_get_child_with_ival(&_rtjson_xavp_name, &xname); if(iavp==NULL) { LM_WARN("no idx for routing\n"); return -1; } srjson_InitDoc(&tdoc, NULL); tdoc.root = srjson_Parse(&tdoc, javp->val.v.s.s); if(tdoc.root == NULL) { LM_ERR("invalid json doc [[%s]]\n", javp->val.v.s.s); srjson_DestroyDoc(&tdoc); return -1; } nj = srjson_GetObjectItem(&tdoc, tdoc.root, "routing"); if(nj==NULL || nj->valuestring==NULL) { LM_ERR("missing or invalid routing field\n"); goto error; } val.s = nj->valuestring; val.len = strlen(val.s); if(val.len==6 && strncmp(val.s, "serial", 6)==0) { LM_DBG("supported routing [%.*s]\n", val.len, val.s); ret = rtjson_init_serial(msg, &tdoc, iavp); } else if(val.len==8 && strncmp(val.s, "parallel", 8)==0) { LM_DBG("supported routing [%.*s]\n", val.len, val.s); ret = rtjson_init_parallel(msg, &tdoc, iavp); } else { LM_ERR("unsupported routing [%.*s]\n", val.len, val.s); goto error; } srjson_DestroyDoc(&tdoc); return ret; error: srjson_DestroyDoc(&tdoc); return -1; }
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; }
/** * @brief ht dmq callback */ int ht_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* dmq_node) { int content_length; str body; ht_dmq_action_t action = HT_DMQ_NONE; str htname, cname; int type = 0, mode = 0; int_str val; srjson_doc_t jdoc; srjson_t *it = NULL; /* received dmq message */ LM_DBG("dmq message received\n"); if(!msg->content_length) { LM_ERR("no content length header found\n"); goto invalid; } content_length = get_content_length(msg); if(!content_length) { LM_DBG("content length is 0\n"); goto invalid; } body.s = get_body(msg); body.len = content_length; if (!body.s) { LM_ERR("unable to get body\n"); goto error; } /* parse body */ LM_DBG("body: %.*s\n", body.len, body.s); srjson_InitDoc(&jdoc, NULL); jdoc.buf = body; if(jdoc.root == NULL) { jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s); if(jdoc.root == NULL) { LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s); goto invalid; } } for(it=jdoc.root->child; it; it = it->next) { LM_DBG("found field: %s\n", it->string); if (strcmp(it->string, "action")==0) { action = it->valueint; } else if (strcmp(it->string, "htname")==0) { htname.s = it->valuestring; htname.len = strlen(htname.s); } else if (strcmp(it->string, "cname")==0) { cname.s = it->valuestring; cname.len = strlen(cname.s); } else if (strcmp(it->string, "type")==0) { type = it->valueint; } else if (strcmp(it->string, "strval")==0) { val.s.s = it->valuestring; val.s.len = strlen(val.s.s); } else if (strcmp(it->string, "intval")==0) { val.n = it->valueint; } else if (strcmp(it->string, "mode")==0) { mode = it->valueint; } else { LM_ERR("unrecognized field in json object\n"); goto invalid; } } if (ht_dmq_replay_action(action, &htname, &cname, type, &val, mode)!=0) { LM_ERR("failed to replay action\n"); goto error; } srjson_DestroyDoc(&jdoc); resp->reason = dmq_200_rpl; resp->resp_code = 200; return 0; invalid: srjson_DestroyDoc(&jdoc); resp->reason = dmq_400_rpl; resp->resp_code = 400; return 0; error: srjson_DestroyDoc(&jdoc); resp->reason = dmq_500_rpl; resp->resp_code = 500; return 0; }