int _cfgt_get_obj_avp_vals(str name, sr_xavp_t *xavp, srjson_doc_t *jdoc, srjson_t **jobj) { sr_xavp_t *avp = NULL; srjson_t *jobjt = NULL; *jobj = srjson_CreateArray(jdoc); if(*jobj==NULL) { LM_ERR("cannot create json object\n"); return -1; } avp = xavp; while(avp!=NULL&&!STR_EQ(avp->name,name)) { avp = avp->next; } while(avp!=NULL) { _cfgt_get_obj_xavp_val(avp, jdoc, &jobjt); srjson_AddItemToArray(jdoc, *jobj, jobjt); jobjt = NULL; avp = xavp_get_next(avp); } return 0; }
/* Create Arrays: */ srjson_t *srjson_CreateIntArray(srjson_doc_t *doc, int *numbers, int count) { int i; srjson_t *n = 0, *p = 0, *a = srjson_CreateArray(doc); for (i = 0; a && i < count; i++) { n = srjson_CreateNumber(doc, numbers[i]); if (!i) a->child = n; else suffix_object(p, n); p = n; } return a; }
srjson_t *srjson_CreateStringArray(srjson_doc_t *doc, const char **strings, int count) { int i; srjson_t *n = 0, *p = 0, *a = srjson_CreateArray(doc); for (i = 0; a && i < count; i++) { n = srjson_CreateString(doc, strings[i]); if (!i) a->child = n; else suffix_object(p, n); p = n; } return a; }
int _cfgt_get_array_avp_vals(struct sip_msg *msg, pv_param_t *param, srjson_doc_t *jdoc, srjson_t **jobj, str *item_name) { struct usr_avp *avp; unsigned short name_type; int_str avp_name; int_str avp_value; struct search_state state; srjson_t *jobjt; memset(&state, 0, sizeof(struct search_state)); if(pv_get_avp_name(msg, param, &avp_name, &name_type)!=0) { LM_ERR("invalid name\n"); return -1; } *jobj = srjson_CreateArray(jdoc); if(*jobj==NULL) { LM_ERR("cannot create json object\n"); return -1; } if ((avp=search_first_avp(name_type, avp_name, &avp_value, &state))==0) { goto ok; } do { if(avp->flags & AVP_VAL_STR) { jobjt = srjson_CreateStr(jdoc, avp_value.s.s, avp_value.s.len); if(jobjt==NULL) { LM_ERR("cannot create json object\n"); return -1; } } else { jobjt = srjson_CreateNumber(jdoc, avp_value.n); if(jobjt==NULL) { LM_ERR("cannot create json object\n"); return -1; } } srjson_AddItemToArray(jdoc, *jobj, jobjt); } while ((avp=search_next_avp(&state, &avp_value))!=0); ok: item_name->s = avp_name.s.s; item_name->len = avp_name.s.len; return 0; }
/** Implementation of rpc_add function required by the management API. * * This function will be called when an RPC management function calls * rpc->add to add a parameter to the jsonrpc reply being generated. */ static int jsonrpc_add(jsonrpc_ctx_t* ctx, char* fmt, ...) { srjson_t *nj = NULL; void **void_ptr; va_list ap; jsonrpc_delayed_reply_ctx_init(ctx); va_start(ap, fmt); while(*fmt) { if (*fmt == '{' || *fmt == '[') { void_ptr = va_arg(ap, void**); if (*fmt == '{') { nj = srjson_CreateObject(ctx->jrpl); } else { nj = srjson_CreateArray(ctx->jrpl); } *void_ptr = nj; } else {
int _cfgt_get_obj_xavp_vals(struct sip_msg *msg, pv_param_t *param, srjson_doc_t *jdoc, srjson_t **jobjr, str *item_name) { pv_xavp_name_t *xname = (pv_xavp_name_t*)param->pvn.u.dname; sr_xavp_t *xavp = NULL; sr_xavp_t *avp = NULL; srjson_t *jobj = NULL; srjson_t *jobjt = NULL; struct str_list *keys; struct str_list *k; *jobjr = srjson_CreateArray(jdoc); if(*jobjr==NULL) { LM_ERR("cannot create json object\n"); return -1; } item_name->s = xname->name.s; item_name->len = xname->name.len; xavp = xavp_get_by_index(&xname->name, 0, NULL); if(xavp==NULL) { return 0; /* empty */ } do { if(xavp->val.type==SR_XTYPE_XAVP) { avp = xavp->val.v.xavp; jobj = srjson_CreateObject(jdoc); if(jobj==NULL) { LM_ERR("cannot create json object\n"); return -1; } keys = xavp_get_list_key_names(xavp); if(keys!=NULL) { do { _cfgt_get_obj_avp_vals(keys->s, avp, jdoc, &jobjt); srjson_AddStrItemToObject(jdoc, jobj, keys->s.s, keys->s.len, jobjt); k = keys; keys = keys->next; pkg_free(k); jobjt = NULL; }while(keys!=NULL); } } if(jobj!=NULL) { srjson_AddItemToArray(jdoc, *jobjr, jobj); jobj = NULL; } }while((xavp = xavp_get_next(xavp))!=0); 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 *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; }