int dbg_dump_json(struct sip_msg* msg, unsigned int mask, int level) { char *output = NULL; srjson_doc_t jdoc; srjson_InitDoc(&jdoc, NULL); if(jdoc.root==NULL) { jdoc.root = srjson_CreateObject(&jdoc); if(jdoc.root==NULL) { LM_ERR("cannot create json root\n"); goto error; } } if(dbg_get_json(msg, mask, &jdoc, jdoc.root)<0) goto error; output = srjson_PrintUnformatted(&jdoc, jdoc.root); if(output==NULL) { LM_ERR("cannot print json doc\n"); srjson_DestroyDoc(&jdoc); } LOG(level, "%s\n", output); jdoc.free_fn(output); srjson_DestroyDoc(&jdoc); return 0; error: srjson_DestroyDoc(&jdoc); return -1; }
int usrloc_dmq_send_contact(ucontact_t* ptr, str aor, int action, dmq_node_t* node) { srjson_doc_t jdoc; srjson_InitDoc(&jdoc, NULL); int flags; jdoc.root = srjson_CreateObject(&jdoc); if(jdoc.root==NULL) { LM_ERR("cannot create json root\n"); goto error; } flags = ptr->flags; flags &= ~FL_RPL; srjson_AddNumberToObject(&jdoc, jdoc.root, "action", action); srjson_AddStrToObject(&jdoc, jdoc.root, "aor", aor.s, aor.len); srjson_AddStrToObject(&jdoc, jdoc.root, "ruid", ptr->ruid.s, ptr->ruid.len); srjson_AddStrToObject(&jdoc, jdoc.root, "c", ptr->c.s, ptr->c.len); srjson_AddStrToObject(&jdoc, jdoc.root, "received", ptr->received.s, ptr->received.len); srjson_AddStrToObject(&jdoc, jdoc.root, "path", ptr->path.s, ptr->path.len); srjson_AddStrToObject(&jdoc, jdoc.root, "callid", ptr->callid.s, ptr->callid.len); srjson_AddStrToObject(&jdoc, jdoc.root, "user_agent", ptr->user_agent.s, ptr->user_agent.len); srjson_AddStrToObject(&jdoc, jdoc.root, "instance", ptr->instance.s, ptr->instance.len); srjson_AddNumberToObject(&jdoc, jdoc.root, "expires", ptr->expires); srjson_AddNumberToObject(&jdoc, jdoc.root, "cseq", ptr->cseq); srjson_AddNumberToObject(&jdoc, jdoc.root, "flags", flags); srjson_AddNumberToObject(&jdoc, jdoc.root, "cflags", ptr->cflags); srjson_AddNumberToObject(&jdoc, jdoc.root, "q", ptr->q); srjson_AddNumberToObject(&jdoc, jdoc.root, "last_modified", ptr->last_modified); srjson_AddNumberToObject(&jdoc, jdoc.root, "methods", ptr->methods); srjson_AddNumberToObject(&jdoc, jdoc.root, "reg_id", ptr->reg_id); jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root); if(jdoc.buf.s==NULL) { LM_ERR("unable to serialize data\n"); goto error; } jdoc.buf.len = strlen(jdoc.buf.s); LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s); if (usrloc_dmq_send(&jdoc.buf, node)!=0) { goto error; } jdoc.free_fn(jdoc.buf.s); jdoc.buf.s = NULL; srjson_DestroyDoc(&jdoc); return 0; error: if(jdoc.buf.s!=NULL) { jdoc.free_fn(jdoc.buf.s); jdoc.buf.s = NULL; } srjson_DestroyDoc(&jdoc); return -1; }
int ht_dmq_replicate_action(ht_dmq_action_t action, str* htname, str* cname, int type, int_str* val, int mode) { srjson_doc_t jdoc; LM_DBG("replicating action to dmq peers...\n"); srjson_InitDoc(&jdoc, NULL); jdoc.root = srjson_CreateObject(&jdoc); if(jdoc.root==NULL) { LM_ERR("cannot create json root\n"); goto error; } srjson_AddNumberToObject(&jdoc, jdoc.root, "action", action); srjson_AddStrToObject(&jdoc, jdoc.root, "htname", htname->s, htname->len); if (cname!=NULL) { srjson_AddStrToObject(&jdoc, jdoc.root, "cname", cname->s, cname->len); } if (action==HT_DMQ_SET_CELL || action==HT_DMQ_SET_CELL_EXPIRE || action==HT_DMQ_RM_CELL_RE) { srjson_AddNumberToObject(&jdoc, jdoc.root, "type", type); if (type&AVP_VAL_STR) { srjson_AddStrToObject(&jdoc, jdoc.root, "strval", val->s.s, val->s.len); } else { srjson_AddNumberToObject(&jdoc, jdoc.root, "intval", val->n); } } srjson_AddNumberToObject(&jdoc, jdoc.root, "mode", mode); jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root); if(jdoc.buf.s!=NULL) { jdoc.buf.len = strlen(jdoc.buf.s); LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s); if (ht_dmq_broadcast(&jdoc.buf)!=0) { goto error; } jdoc.free_fn(jdoc.buf.s); jdoc.buf.s = NULL; } else { LM_ERR("unable to serialize data\n"); goto error; } srjson_DestroyDoc(&jdoc); return 0; error: if(jdoc.buf.s!=NULL) { jdoc.free_fn(jdoc.buf.s); jdoc.buf.s = NULL; } srjson_DestroyDoc(&jdoc); return -1; }
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; }
int usrloc_dmq_request_sync() { srjson_doc_t jdoc; if(_dmq_usrloc_sync==0) return 0; LM_DBG("requesting sync from dmq peers\n"); srjson_InitDoc(&jdoc, NULL); jdoc.root = srjson_CreateObject(&jdoc); if(jdoc.root==NULL) { LM_ERR("cannot create json root\n"); goto error; } srjson_AddNumberToObject(&jdoc, jdoc.root, "action", DMQ_SYNC); jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root); if(jdoc.buf.s==NULL) { LM_ERR("unable to serialize data\n"); goto error; } jdoc.buf.len = strlen(jdoc.buf.s); LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s); if (usrloc_dmq_send(&jdoc.buf, 0)!=0) { goto error; } jdoc.free_fn(jdoc.buf.s); jdoc.buf.s = NULL; srjson_DestroyDoc(&jdoc); return 0; error: if(jdoc.buf.s!=NULL) { jdoc.free_fn(jdoc.buf.s); jdoc.buf.s = NULL; } srjson_DestroyDoc(&jdoc); 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; }
int dlg_dmq_replicate_action(dlg_dmq_action_t action, dlg_cell_t* dlg, int needlock, dmq_node_t *node ) { srjson_doc_t jdoc, prof_jdoc; dlg_var_t *var; LM_DBG("replicating action [%d] on [%u:%u] to dmq peers\n", action, dlg->h_entry, dlg->h_id); if (action == DLG_DMQ_UPDATE) { if (!node && (dlg->iflags & DLG_IFLAG_DMQ_SYNC) && ((dlg->dflags & DLG_FLAG_CHANGED_PROF) == 0)) { LM_DBG("dlg not changed, no sync\n"); return 1; } } else if ( (dlg->iflags & DLG_IFLAG_DMQ_SYNC) == 0 ) { LM_DBG("dlg not synced, no sync\n"); return 1; } if (action == DLG_DMQ_STATE && (dlg->state != DLG_STATE_CONFIRMED && dlg->state != DLG_STATE_DELETED && dlg->state != DLG_STATE_EARLY)) { LM_DBG("not syncing state %u\n", dlg->state); return 1; } srjson_InitDoc(&jdoc, NULL); jdoc.root = srjson_CreateObject(&jdoc); if(jdoc.root==NULL) { LM_ERR("cannot create json root\n"); goto error; } if (needlock) dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); srjson_AddNumberToObject(&jdoc, jdoc.root, "action", action); srjson_AddNumberToObject(&jdoc, jdoc.root, "h_entry", dlg->h_entry); srjson_AddNumberToObject(&jdoc, jdoc.root, "h_id", dlg->h_id); switch(action) { case DLG_DMQ_UPDATE: dlg->iflags |= DLG_IFLAG_DMQ_SYNC; dlg->dflags &= ~DLG_FLAG_CHANGED_PROF; srjson_AddNumberToObject(&jdoc, jdoc.root, "init_ts", dlg->init_ts); srjson_AddStrToObject(&jdoc, jdoc.root, "callid", dlg->callid.s, dlg->callid.len); srjson_AddStrToObject(&jdoc, jdoc.root, "from_uri", dlg->from_uri.s, dlg->from_uri.len); srjson_AddStrToObject(&jdoc, jdoc.root, "to_uri", dlg->to_uri.s, dlg->to_uri.len); srjson_AddStrToObject(&jdoc, jdoc.root, "req_uri", dlg->req_uri.s, dlg->req_uri.len); srjson_AddStrToObject(&jdoc, jdoc.root, "tag1", dlg->tag[0].s, dlg->tag[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "cseq1", dlg->cseq[0].s, dlg->cseq[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "route_set1", dlg->route_set[0].s, dlg->route_set[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "contact1", dlg->contact[0].s, dlg->contact[0].len); if (dlg->vars != NULL) { srjson_t *pj = NULL; pj = srjson_CreateObject(&jdoc); for(var=dlg->vars ; var ; var=var->next) { srjson_AddStrToObject(&jdoc, pj, var->key.s, var->value.s, var->value.len); } srjson_AddItemToObject(&jdoc, jdoc.root, "vars", pj); } if (dlg->profile_links) { srjson_InitDoc(&prof_jdoc, NULL); dlg_profiles_to_json(dlg, &prof_jdoc); if(prof_jdoc.buf.s!=NULL) { LM_DBG("adding profiles: [%.*s]\n", prof_jdoc.buf.len, prof_jdoc.buf.s); srjson_AddStrToObject(&jdoc, jdoc.root, "profiles", prof_jdoc.buf.s, prof_jdoc.buf.len); prof_jdoc.free_fn(prof_jdoc.buf.s); prof_jdoc.buf.s = NULL; } srjson_DestroyDoc(&prof_jdoc); } /* intentional fallthrough */ case DLG_DMQ_STATE: srjson_AddNumberToObject(&jdoc, jdoc.root, "state", dlg->state); switch (dlg->state) { case DLG_STATE_EARLY: srjson_AddNumberToObject(&jdoc, jdoc.root, "start_ts", dlg->start_ts); srjson_AddNumberToObject(&jdoc, jdoc.root, "lifetime", dlg->lifetime); srjson_AddStrToObject(&jdoc, jdoc.root, "tag1", dlg->tag[0].s, dlg->tag[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "cseq1", dlg->cseq[0].s, dlg->cseq[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "route_set1", dlg->route_set[0].s, dlg->route_set[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "contact1", dlg->contact[0].s, dlg->contact[0].len); break; case DLG_STATE_CONFIRMED: srjson_AddNumberToObject(&jdoc, jdoc.root, "start_ts", dlg->start_ts); srjson_AddNumberToObject(&jdoc, jdoc.root, "lifetime", dlg->lifetime); srjson_AddStrToObject(&jdoc, jdoc.root, "tag1", dlg->tag[0].s, dlg->tag[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "tag2", dlg->tag[1].s, dlg->tag[1].len); srjson_AddStrToObject(&jdoc, jdoc.root, "cseq1", dlg->cseq[0].s, dlg->cseq[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "cseq2", dlg->cseq[1].s, dlg->cseq[1].len); srjson_AddStrToObject(&jdoc, jdoc.root, "route_set1", dlg->route_set[0].s, dlg->route_set[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "route_set2", dlg->route_set[1].s, dlg->route_set[1].len); srjson_AddStrToObject(&jdoc, jdoc.root, "contact1", dlg->contact[0].s, dlg->contact[0].len); srjson_AddStrToObject(&jdoc, jdoc.root, "contact2", dlg->contact[1].s, dlg->contact[1].len); break; case DLG_STATE_DELETED: //dlg->iflags &= ~DLG_IFLAG_DMQ_SYNC; break; default: LM_DBG("not syncing state %u\n", dlg->state); } break; case DLG_DMQ_RM: srjson_AddNumberToObject(&jdoc, jdoc.root, "state", dlg->state); dlg->iflags &= ~DLG_IFLAG_DMQ_SYNC; break; case DLG_DMQ_NONE: case DLG_DMQ_SYNC: break; } if (needlock) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root); if(jdoc.buf.s==NULL) { LM_ERR("unable to serialize data\n"); goto error; } jdoc.buf.len = strlen(jdoc.buf.s); LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s); if (dlg_dmq_send(&jdoc.buf, node)!=0) { goto error; } jdoc.free_fn(jdoc.buf.s); jdoc.buf.s = NULL; srjson_DestroyDoc(&jdoc); return 0; error: if(jdoc.buf.s!=NULL) { jdoc.free_fn(jdoc.buf.s); jdoc.buf.s = NULL; } srjson_DestroyDoc(&jdoc); return -1; }
/** * @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; }
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; }
/** * @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; }
int dbg_dump_json(struct sip_msg* msg, unsigned int mask, int level) { int i; pv_value_t value; pv_cache_t **_pv_cache = pv_cache_get_table(); pv_cache_t *el = NULL; srjson_doc_t jdoc; srjson_t *jobj = NULL; char *output = NULL; str item_name = STR_NULL; static char iname[128]; int result = -1; if(_pv_cache==NULL) { LM_ERR("cannot access pv_cache\n"); return -1; } memset(_dbg_xavp_dump, 0, sizeof(str*)*DBG_XAVP_DUMP_SIZE); srjson_InitDoc(&jdoc, NULL); if(jdoc.root==NULL) { jdoc.root = srjson_CreateObject(&jdoc); if(jdoc.root==NULL) { LM_ERR("cannot create json root\n"); goto error; } } for(i=0;i<PV_CACHE_SIZE;i++) { el = _pv_cache[i]; while(el) { if(!(el->spec.type==PVT_AVP|| el->spec.type==PVT_SCRIPTVAR|| el->spec.type==PVT_XAVP|| el->spec.type==PVT_OTHER)|| !((el->spec.type==PVT_AVP&&mask&DBG_DP_AVP)|| (el->spec.type==PVT_XAVP&&mask&DBG_DP_XAVP)|| (el->spec.type==PVT_SCRIPTVAR&&mask&DBG_DP_SCRIPTVAR)|| (el->spec.type==PVT_OTHER&&mask&DBG_DP_OTHER))|| (el->spec.trans!=NULL)) { el = el->next; continue; } jobj = NULL; item_name.len = 0; item_name.s = 0; iname[0] = '\0'; if(el->spec.type==PVT_AVP) { if(el->spec.pvp.pvi.type==PV_IDX_ALL|| (el->spec.pvp.pvi.type==PV_IDX_INT&&el->spec.pvp.pvi.u.ival!=0)) { el = el->next; continue; } else { if(_dbg_get_array_avp_vals(msg, &el->spec.pvp, &jdoc, &jobj, &item_name)!=0) { LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s); el = el->next; continue; } if(srjson_GetArraySize(&jdoc, jobj)==0 && !(mask&DBG_DP_NULL)) { el = el->next; continue; } snprintf(iname, 128, "$avp(%.*s)", item_name.len, item_name.s); } } else if(el->spec.type==PVT_XAVP) { if(_dbg_xavp_dump_lookup(&el->spec.pvp)!=0) { el = el->next; continue; } if(_dbg_get_obj_xavp_vals(msg, &el->spec.pvp, &jdoc, &jobj, &item_name)!=0) { LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s); el = el->next; continue; } if(srjson_GetArraySize(&jdoc, jobj)==0 && !(mask&DBG_DP_NULL)) { el = el->next; continue; } snprintf(iname, 128, "$xavp(%.*s)", item_name.len, item_name.s); } else { if(pv_get_spec_value(msg, &el->spec, &value)!=0) { LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s); el = el->next; continue; } if(value.flags&(PV_VAL_NULL|PV_VAL_EMPTY|PV_VAL_NONE)) { if(mask&DBG_DP_NULL) { jobj = srjson_CreateNull(&jdoc); } else { el = el->next; continue; } }else if(value.flags&(PV_VAL_INT)){ jobj = srjson_CreateNumber(&jdoc, value.ri); }else if(value.flags&(PV_VAL_STR)){ jobj = srjson_CreateStr(&jdoc, value.rs.s, value.rs.len); }else { LM_WARN("el->pvname[%.*s] value[%d] unhandled\n", el->pvname.len, el->pvname.s, value.flags); el = el->next; continue; } if(jobj==NULL) { LM_ERR("el->pvname[%.*s] empty json object\n", el->pvname.len, el->pvname.s); goto error; } snprintf(iname, 128, "%.*s", el->pvname.len, el->pvname.s); } if(jobj!=NULL) { srjson_AddItemToObject(&jdoc, jdoc.root, iname, jobj); } el = el->next; } } output = srjson_PrintUnformatted(&jdoc, jdoc.root); if(output==NULL) { LM_ERR("cannot print json doc\n"); goto error; } LOG(level, "%s\n", output); result = 0; error: if(output!=NULL) jdoc.free_fn(output); srjson_DestroyDoc(&jdoc); return result; }