static char *jsonrpc_build_cmd(str *method, str *params, int *id) { char *s; cJSON *param_obj; cJSON *ret_obj; char *params_buf; /* first thing - try to parse the parameters - need it NULL terminated */ params_buf = pkg_malloc(params->len + 1); if (!params_buf) { LM_ERR("cannot allocate memory for params!\n"); return NULL; } memcpy(params_buf, params->s, params->len); params_buf[params->len] = 0; param_obj = cJSON_Parse(params_buf); pkg_free(params_buf); if (!param_obj) { LM_ERR("cannot parse json param: %.*s\n", params->len, params->s); return NULL; } if (param_obj->type != cJSON_Array && param_obj->type != cJSON_Object) { LM_ERR("invalid cJSON type %d - must be array or object!\n", param_obj->type); cJSON_Delete(param_obj); return NULL; } ret_obj = cJSON_CreateObject(); if (id) cJSON_AddNumberToObject(ret_obj, "id", *id); else cJSON_AddNullToObject(ret_obj, "id"); cJSON_AddItemToObject(ret_obj, "jsonrpc", cJSON_CreateString(JSONRPC_VERSION)); cJSON_AddItemToObject(ret_obj, "method", cJSON_CreateStr(method->s, method->len)); cJSON_AddItemToObject(ret_obj, "params", param_obj); s = cJSON_PrintUnformatted(ret_obj); if (!s) LM_ERR("cannot print json object!\n"); cJSON_Delete(ret_obj); return s; }
static int push_kv_to_json(void *param, str key, void *value) { cJSON *flat_map = (cJSON *)param, *val_json; int_str_t *val = (int_str_t *)value; if (!val->is_str) val_json = cJSON_CreateNumber(val->i); else val_json = cJSON_CreateStr(val->s.s, val->s.len); if (!val_json) { LM_ERR("oom\n"); return -1; } _cJSON_AddItemToObject(flat_map, &key, val_json); return 0; }
static mi_response_t *cl_run_mi_cmd(str *cmd_name, mi_item_t *item_params_arr, str *str_params_arr, int no_params) { struct mi_cmd *cmd = NULL; mi_response_t *resp = NULL; mi_request_t req_item; mi_item_t *param_item; int i; str val; memset(&req_item, 0, sizeof req_item); req_item.req_obj = cJSON_CreateObject(); if (!req_item.req_obj) { LM_ERR("Failed to build temporary json request\n"); return NULL; } cmd = lookup_mi_cmd(cmd_name->s, cmd_name->len); if (!cmd) { resp = init_mi_error(400, MI_SSTR("Command to be run not found")); goto out; } if (cmd->flags & MI_ASYNC_RPL_FLAG) { resp = init_mi_error(400, MI_SSTR("Async commands not supported")); goto out; } if (cmd->flags & MI_NAMED_PARAMS_ONLY) { resp = init_mi_error(400, MI_SSTR("Commands requiring named params not supported")); goto out; } if (no_params) { req_item.params = cJSON_CreateArray(); if (!req_item.params) { LM_ERR("Failed to add 'params' to temporary json request\n"); goto out; } cJSON_AddItemToObject(req_item.req_obj, JSONRPC_PARAMS_S, req_item.params); } for (i = 0; i < no_params; i++) { if (item_params_arr) { if (get_mi_arr_param_string(item_params_arr, i, &val.s, &val.len) < 0) { resp = init_mi_param_error(); goto out; } } else { val.s = str_params_arr[i].s; val.len = str_params_arr[i].len; } param_item = cJSON_CreateStr(val.s, val.len); if (!param_item) { LM_ERR("Failed to create string item in temporary json request\n"); goto out; } cJSON_AddItemToArray(req_item.params, param_item); } resp = handle_mi_request(&req_item, cmd, NULL); LM_DBG("got mi response = [%p]\n", resp); out: cJSON_Delete(req_item.req_obj); return resp; }