/** Initialize jsonrpc reply data structure. * * This function initializes the data structure that contains all data related * to the jsonrpc reply being created. The function must be called before any * other function that adds data to the reply. * @param ctx jsonrpc_ctx_t structure to be initialized. * @return 0 on success, a negative number on error. */ static int jsonrpc_init_reply(jsonrpc_ctx_t *ctx) { ctx->http_code = 200; ctx->http_text = JSONRPC_REASON_OK; ctx->jrpl = srjson_NewDoc(NULL); if(ctx->jrpl==NULL) { LM_ERR("Failed to init the reply json document\n"); return -1; } ctx->jrpl->root = srjson_CreateObject(ctx->jrpl); if(ctx->jrpl->root==NULL) { LM_ERR("Failed to init the reply json root node\n"); return -1; } srjson_AddStrStrToObject(ctx->jrpl, ctx->jrpl->root, "jsonrpc", 7, "2.0", 3); 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; }