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; }
int cfgt_get_json(struct sip_msg* msg, unsigned int mask, srjson_doc_t *jdoc, srjson_t *head) { int i; pv_value_t value; pv_cache_t **_pv_cache = pv_cache_get_table(); pv_cache_t *el = NULL; srjson_t *jobj = NULL; str item_name = STR_NULL; static char iname[128]; if(_pv_cache==NULL) { LM_ERR("cannot access pv_cache\n"); return -1; } if(jdoc==NULL){ LM_ERR("jdoc is null\n"); return -1; } if(head==NULL){ LM_ERR("head is null\n"); return -1; } memset(_cfgt_xavp_dump, 0, sizeof(str*)*CFGT_XAVP_DUMP_SIZE); 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&CFGT_DP_AVP)|| (el->spec.type==PVT_XAVP&&mask&CFGT_DP_XAVP)|| (el->spec.type==PVT_SCRIPTVAR&&mask&CFGT_DP_SCRIPTVAR)|| (el->spec.type==PVT_OTHER&&mask&CFGT_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(_cfgt_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&CFGT_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(_cfgt_xavp_dump_lookup(&el->spec.pvp)!=0) { el = el->next; continue; } if(_cfgt_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&CFGT_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&CFGT_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, head, iname, jobj); } el = el->next; } } return 0; error: srjson_Delete(jdoc, head); return -1; }
/** * json serialization of dialog profiles */ int dlg_profiles_to_json(dlg_cell_t *dlg, srjson_doc_t *jdoc) { dlg_profile_link_t *l; srjson_t *aj = NULL; srjson_t *pj = NULL; LM_DBG("serializing profiles for dlg[%u:%u]\n", dlg->h_entry, dlg->h_id); if(dlg==NULL || dlg->profile_links==NULL) return -1; LM_DBG("start of serializing profiles for dlg[%u:%u]\n", dlg->h_entry, dlg->h_id); for (l = dlg->profile_links ; l ; l=l->next) { if(aj==NULL) { aj = srjson_CreateArray(jdoc); if(aj==NULL) { LM_ERR("cannot create json profiles array object\n"); goto error; } } pj = srjson_CreateObject(jdoc); if(pj==NULL) { LM_ERR("cannot create json dynamic profiles obj\n"); goto error; } srjson_AddStrStrToObject(jdoc, pj, "name", 4, l->profile->name.s, l->profile->name.len); if(l->profile->has_value) { srjson_AddStrStrToObject(jdoc, pj, "value", 5, l->hash_linker.value.s, l->hash_linker.value.len); } if(l->hash_linker.puid[0]!='\0') srjson_AddStringToObject(jdoc, pj, "puid", l->hash_linker.puid); if(l->hash_linker.expires!=0) srjson_AddNumberToObject(jdoc, pj, "expires", l->hash_linker.expires); if(l->hash_linker.flags!=0) srjson_AddNumberToObject(jdoc, pj, "flags", l->hash_linker.flags); srjson_AddItemToArray(jdoc, aj, pj); } if(jdoc->root==NULL) { jdoc->root = srjson_CreateObject(jdoc); if(jdoc->root==NULL) { LM_ERR("cannot create json root\n"); goto error; } } if(aj!=NULL) srjson_AddItemToObject(jdoc, jdoc->root, "profiles", aj); if(jdoc->buf.s != NULL) { jdoc->free_fn(jdoc->buf.s); jdoc->buf.s = NULL; jdoc->buf.len = 0; } jdoc->buf.s = srjson_PrintUnformatted(jdoc, jdoc->root); if(jdoc->buf.s!=NULL) { jdoc->buf.len = strlen(jdoc->buf.s); LM_DBG("serialized profiles for dlg[%u:%u] = [[%.*s]]\n", dlg->h_entry, dlg->h_id, jdoc->buf.len, jdoc->buf.s); return 0; } return -1; error: srjson_Delete(jdoc, aj); return -1; }
/** Implementation of rpc_send function required by the management API. * * This is the function that will be called whenever a management function * asks the management interface to send the reply to the client. * The SIP/HTTP reply sent to * the client will be always 200 OK, if an error ocurred on the server then it * will be indicated in the html document in body. * * @param ctx A pointer to the context structure of the jsonrpc request that * generated the reply. * @return 1 if the reply was already sent, 0 on success, a negative number on * error */ static int jsonrpc_send(jsonrpc_ctx_t* ctx) { srjson_t *nj = NULL; int i; str rbuf; if (ctx->reply_sent) return 1; ctx->reply_sent = 1; if(ctx->error_code != 0) { /* fault handling */ nj = srjson_CreateObject(ctx->jrpl); if(nj!=NULL) { srjson_AddNumberToObject(ctx->jrpl, nj, "code", ctx->error_code); for(i=0; _jsonrpc_error_table[i].code!=0 && _jsonrpc_error_table[i].code!=ctx->error_code; i++); if(_jsonrpc_error_table[i].code!=0) { srjson_AddStrStrToObject(ctx->jrpl, nj, "message", 7, _jsonrpc_error_table[i].text.s, _jsonrpc_error_table[i].text.len); } else { srjson_AddStrStrToObject(ctx->jrpl, nj, "message", 7, "Unexpected Error", 16); } srjson_AddItemToObject(ctx->jrpl, ctx->jrpl->root, "error", nj); } } else { nj = srjson_GetObjectItem(ctx->jrpl, ctx->jrpl->root, "result"); if(nj==NULL) { if (!ctx->rpl_node) { if(ctx->flags & RET_ARRAY) { ctx->rpl_node = srjson_CreateArray(ctx->jrpl); } else { ctx->rpl_node = srjson_CreateObject(ctx->jrpl); } if(ctx->rpl_node == 0) { LM_ERR("failed to create the root array node\n"); } } srjson_AddItemToObject(ctx->jrpl, ctx->jrpl->root, "result", ctx->rpl_node); ctx->rpl_node = 0; } } nj = srjson_GetObjectItem(ctx->jreq, ctx->jreq->root, "id"); if(nj!=NULL) { if(nj->valuestring!=NULL) { srjson_AddStrStrToObject(ctx->jrpl, ctx->jrpl->root, "id", 2, nj->valuestring, strlen(nj->valuestring)); } else { srjson_AddNumberToObject(ctx->jrpl, ctx->jrpl->root, "id", nj->valuedouble); } } if(jsonrpc_pretty_format==0) { rbuf.s = srjson_PrintUnformatted(ctx->jrpl, ctx->jrpl->root); } else { rbuf.s = srjson_Print(ctx->jrpl, ctx->jrpl->root); } if(rbuf.s!=NULL) { rbuf.len = strlen(rbuf.s); } if (rbuf.s!=NULL) { LM_DBG("sending response with body: %p - %d %.*s\n", ctx->msg, ctx->http_code, ctx->http_text.len, ctx->http_text.s); if(ctx->msg) { xhttp_api.reply(ctx->msg, ctx->http_code, &ctx->http_text, &JSONRPC_CONTENT_TYPE_HTML, &rbuf); } else { jsonrpc_set_plain_reply(ctx->http_code, &ctx->http_text, &rbuf, ctx->jrpl->free_fn); rbuf.s=NULL; } } else { LM_DBG("sending response without body: %p - %d %.*s\n", ctx->msg, ctx->http_code, ctx->http_text.len, ctx->http_text.s); if(ctx->msg) { xhttp_api.reply(ctx->msg, ctx->http_code, &ctx->http_text, NULL, NULL); } else { jsonrpc_set_plain_reply(ctx->http_code, &ctx->http_text, NULL, ctx->jrpl->free_fn); } } if (rbuf.s!=NULL) { ctx->jrpl->free_fn(rbuf.s); } return 0; }
/** * json serialization of dialog profiles */ int dlg_profiles_to_json(dlg_cell_t *dlg, srjson_doc_t *jdoc) { dlg_profile_link_t *l; srjson_t *sj = NULL; srjson_t *dj = NULL; LM_DBG("serializing profiles for dlg[%u:%u]\n", dlg->h_entry, dlg->h_id); if(dlg==NULL || dlg->profile_links==NULL) return -1; LM_DBG("start of serializing profiles for dlg[%u:%u]\n", dlg->h_entry, dlg->h_id); for (l = dlg->profile_links ; l ; l=l->next) { if(l->profile->has_value) { if(dj==NULL) { dj = srjson_CreateObject(jdoc); if(dj==NULL) { LM_ERR("cannot create json dynamic profiles obj\n"); goto error; } } srjson_AddStrStrToObject(jdoc, dj, l->profile->name.s, l->profile->name.len, l->hash_linker.value.s, l->hash_linker.value.len); } else { if(sj==NULL) { sj = srjson_CreateArray(jdoc); if(sj==NULL) { LM_ERR("cannot create json static profiles obj\n"); goto error; } } srjson_AddItemToArray(jdoc, sj, srjson_CreateStr(jdoc, l->profile->name.s, l->profile->name.len)); } } if(jdoc->root==NULL) { jdoc->root = srjson_CreateObject(jdoc); if(jdoc->root==NULL) { LM_ERR("cannot create json root\n"); goto error; } } if(dj!=NULL) srjson_AddItemToObject(jdoc, jdoc->root, "dprofiles", dj); if(sj!=NULL) srjson_AddItemToObject(jdoc, jdoc->root, "sprofiles", sj); if(jdoc->buf.s != NULL) { jdoc->free_fn(jdoc->buf.s); jdoc->buf.s = NULL; jdoc->buf.len = 0; } jdoc->buf.s = srjson_PrintUnformatted(jdoc, jdoc->root); if(jdoc->buf.s!=NULL) { jdoc->buf.len = strlen(jdoc->buf.s); LM_DBG("serialized profiles for dlg[%u:%u] = [[%.*s]]\n", dlg->h_entry, dlg->h_id, jdoc->buf.len, jdoc->buf.s); return 0; } return -1; error: srjson_Delete(jdoc, dj); srjson_Delete(jdoc, sj); return -1; }
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; }
void srjson_AddItemReferenceToObject(srjson_doc_t *doc, srjson_t *object, const char *string, srjson_t *item) { srjson_AddItemToObject(doc, object, string, create_reference(doc, item)); }