#include <stdio.h>
#include “chm_default.h”
#include “ubus_test.h”
#include “chm_dbg.h”
#include “chm_ubus.h”
extern struct ubus_context *ctx;
extern struct blob_buf b;
enum
{
TEST_CHANNEL,
__TEST_MAX
};
static void leak_mem()
{
/* 故意分配内存但不释放 - 内存泄漏 */
int *leak_memory = malloc(1024 * sizeof(int));
if (leak_memory)
{
// 写入数据避免编译器优化
for (int i = 0; i < 1024; i++)
{
leak_memory[i] = i;
}
}
}
static void null_pointer()
{
// 故意创建空指针并解引用 - 空指针访问
int *null_pointer = NULL; *null_pointer = 0xDEADBEEF; // 触发SIGSEGV
}
// 用于消息解析,指明key为channel字符串的时候,它的值是一个INT32类型的值,可以单纯的理解为"channel" : 20
static const struct blobmsg_policy test_policy[__TEST_MAX] = {
[TEST_CHANNEL] = {.name = “channel”, .type = BLOBMSG_TYPE_INT32}};
// 方法函数
static int32 test_problem_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int32 ret = ERROR;
int32 test_channel;
struct blob_attr *tb[__TEST_MAX]; // 根据policy从解析出blobmsg blobmsg在blob_attr的data区 /* blobmsg用于二进制对象网络序列化。嵌套在blob数据结构(blob_attr)的data区。 因此形成:blob_buff <- blob_attr -< blobmsg,blob_buff可存储管理多个blob_attr,每个blob_attr又可存储管理一个blogmsg。且可存储在线性数据区,不需要链表指针。 blobmsg_policy用于解析和缓存blobmsg列表,一般声明为一个静态数组,用于指导消息解析。 blobmsg默认使用id为table。array类似C语言的数组,table类似C的结构。 */ blobmsg_parse(test_policy, __TEST_MAX, tb, blob_data(msg), blob_len(msg)); /* 这里是一系列函数,因为上面的.type = BLOBMSG_TYPE_INT32 所以这里用blobmsg_get_u32来解析 */ if (tb[TEST_CHANNEL] != NULL) { test_channel = blobmsg_get_u32(tb[TEST_CHANNEL]); if (0 == test_channel) { /* 触发内存泄漏 */ leak_mem(); ret = 0; } else if (1 == test_channel) { /* 访问空指针 */ null_pointer(); ret = 1; } // ret = notify_cloud_connect_status(connect_status); } // 因为blob_buff // blob_buf一般声明为本地静态变量,id一般使用0(BLOBMSG_TYPE_UNSPEC)来初始化。 blob_buf_init(&b, 0); // 将ret的值添加到buf中,然后调用发送函数 blobmsg_add_u32(&b, "result", ret); // ubus发送函数,执行完成方法调用后发送响应 ubus_send_reply(ctx, req, b.head); return 0;
}
static struct ubus_method test_leakmem_methods[] =
{
/* 触发通知 */
UBUS_METHOD(“test_problem”, test_problem_handler, test_policy),
};
static struct ubus_object_type test_ubus_obj_type = UBUS_OBJECT_TYPE(“leakmem_test”, test_leakmem_methods);
static struct ubus_object test_ubus_obj =
{
.name = “leakmem_test”,
.type = &test_ubus_obj_type,
.methods = test_leakmem_methods,
.n_methods = ARRAY_SIZE(test_leakmem_methods),
};
/******************************************************************************
函数名称: test_ubus_init
函数描述: 初始化ubus处理模块,注册ubus对象
输 入: path: unix socket path
输 出: N/A
返 回 值: -1: 失败。该函数正常情况下不会返回
******************************************************************************/
CHM_STATUS test_ubus_init()
{
int32 ret = CHM_STATUS_OK;
ret = ubus_add_object(ctx, &test_ubus_obj);
if (ret)
{
CHM_DPRINTF(MSG_FATAL, “ubus problem test add obj failed\n”);
return CHM_STATUS_ERROR;
}
return CHM_STATUS_OK;
}
这是一个测试模块注册的ubus程序,此外我需要用TDCP接口调用上面的ubus方法,应该是可以用ubus_simple_call函数去调用ubus方法,/******************************************************************************
函数名称: ubus_simple_call
函数描述: 调用无需传参的ubus方法
输 入: module: 模块名
method: 方法名
输 出: err_code: 错误码
返 回 值:
******************************************************************************/
int ubus_simple_call(const char *module, const char *method, const char msg, int err_code)
下面是我的TDCP接口的代码,我需要写一下S32 test_leakmem_problem(DS_HANDLE_CONTEXT context, JSON_OBJPTR param)这个函数,你学习别人的函数实现,帮我重新写一下这个函数的内容,我的题目是这样的3. 该进程实现ubus方法,根据传入参数触发内存泄漏及访问空指针问题4. 在dsd中添加接口,可用postman通过TDCP接口调用上述ubus 方法
帮我重新写一下函数代码,完成上面的要求,注意不要用ubus_cal函数,学习一些test_leakmem_problem里面的ubus_simple_call函数逻辑来完成题目要求,并告知我请求的json串格式和我回应的json串格式应该是怎样的:
/ 处理IPC osd多语言字符,生成字库文件并上传给ipc /
S32 do_multi_language_osd_process(DS_HANDLE_CONTEXT context, JSON_OBJPTR param)
{
S32 ret = SLP_ENONE;
int chn_id;
int port;
int retry_count = 2;
int err_code;
const char osd_str = NULL;
const char upload_uri = NULL;
const char stok = NULL;
const char ip = NULL;
char http_port[PORT_STR_LEN] = {0};
char recv_buf[RECV_BUF_SIZE] = {0};
char stok_buf[STOK_BUF_SIZE] = {0};
char upload_uri_decode[HTTP_URL_MAX_SIZE] = {0};
JSON_OBJPTR json_header = NULL;
JSON_OBJPTR resp_obj = NULL;
if (!context || !param || !jso_is_obj(param))
{
DSD_LOG(DSD_LOG_ERROR, “Invalid params.”);
ret = SLP_EINVARG;
goto finish;
}
jso_obj_get_int(param, “chn_id”, &chn_id);
jso_obj_get_int(param, “http_port”, &port);
osd_str = jso_obj_get_string_origin(param, “osd_str”);
upload_uri = jso_obj_get_string_origin(param, “url”);
stok = jso_obj_get_string_origin(param, “stok”);
ip = jso_obj_get_string_origin(param, “ip”);
if (!osd_str || !upload_uri || !stok || !ip)
{
ret = SLP_EINVARG;
goto finish;
}
strcpy(stok_buf, stok);
ret = generate_ttf_file(osd_str);
if (ret < 0)
{
goto finish;
}
DSD_LOG(DSD_LOG_ERROR, “chn:%d, %s, %d”, chn_id, osd_str, ret);
if (chn_id < 0 || !osd_str || !upload_uri || !stok)
{
DSD_LOG(DSD_LOG_ERROR, “Invalid params.”);
ret = SLP_EINVARG;
goto finish;
}
snprintf(http_port, sizeof(http_port), “%d”, port);
uh_urldecode(upload_uri_decode, sizeof(upload_uri_decode), upload_uri, strlen(upload_uri));
DSD_LOG(DSD_LOG_DEBUG, “upload_uri_decode : %s”, upload_uri_decode);
retry:
//上传文件
memset(recv_buf, 0, RECV_BUF_SIZE);
ret = https_mutipartform_post_upload_file(ip, http_port, stok_buf, URL_WITH_STOK, upload_uri_decode, (char *)NEW_OSD_FILE_PATH, recv_buf);
DSD_LOG(DSD_LOG_DEBUG, "http_mutipartform_post_upload_file recv_buf: %s, ret = %d", recv_buf, ret); resp_obj = json_tokener_parse(recv_buf); if (NULL == resp_obj || is_error(resp_obj)) { DSD_LOG(DSD_LOG_ERROR, "parse json data failed"); resp_obj = NULL; ret = ECPARSEJSON; goto finish; } err_code = json_object_get_int(json_object_object_get(resp_obj, "error_code")); if (err_code == SLP_EUNAUTH && retry_count-- > 0) { get_new_token(context, chn_id + 1, stok_buf); goto retry; } if (NULL != context->res_obj) { jso_free_obj(context->res_obj); context->res_obj = NULL; } context->res_obj = resp_obj;
finish:
if (NULL == context->res_obj) { context->res_obj = jso_new_obj(); } return ret;
}
S32 check_ip_conflict(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param)
{
UBUS_CONN *conn = NULL;
UBUS_CALL_ATTR attr = {0};
JSON_OBJPTR result = NULL;
int ret = 0;
int error_code;
int i;
JSON_OBJPTR code_list = NULL;
JSON_OBJPTR temp = NULL;
JSON_OBJPTR ret_list = NULL;
if (!context || !param || (FALSE == jso_is_obj(param))) { DSD_LOG(DSD_LOG_ERROR, "Invalid params."); return SLP_EINVARG; } conn = ubus_create_connection(); if (NULL == conn) { goto finish; } if (ERROR == jso_to_string(param, context->buffer, context->buf_len)) { DSD_LOG(DSD_LOG_ERROR, "jso_to_string error."); ret = NVR_UBUS_CONN_ERR; goto finish; } attr.module = "chm_dev_manager"; attr.method = "chm_ubus_check_ip_conflict"; attr.msg = context->buffer; if (NULL != context->res_obj) { jso_free_obj(context->res_obj); context->res_obj = NULL; context->res_obj = jso_new_obj(); } ret = ubus_call(conn, &attr, &result); if (ret < 0) { DSD_LOG(DSD_LOG_ERROR, "ubus call error."); ret = EPROCESSERR; goto finish; } if (FALSE == jso_is_obj(result)) { DSD_LOG(DSD_LOG_ERROR, "result is not a json object."); ret = EPROCESSERR; goto finish; } code_list = jso_obj_get(result, "result"); if (FALSE == jso_is_array(code_list)) { DSD_LOG(DSD_LOG_ERROR, "result is not a json array."); ret = NVR_CHM_UNK_ERR; goto finish; } ret_list = jso_new_array(); for (i = 0; i < jso_array_length(code_list); i++) { temp = jso_array_get_idx(code_list, i); error_code = json_object_get_int(temp); if (error_code < MAP_TABLE_LEN && error_code >= 0) { jso_array_add(ret_list, json_object_new_int(MAP_TABLE[error_code])); } else { jso_array_add(ret_list, json_object_new_int(NVR_CHM_UNK_ERR)); } } jso_obj_add(context->res_obj, "result", ret_list);
finish:
if (NULL != conn)
{
ubus_close_connection(conn);
}
jso_free_obj(result); return SLP_ENONE;
}
S32 test_leakmem_problem(DS_HANDLE_CONTEXT *context, JSON_OBJPTR param)
{
const char *action = NULL;
JSON_OBJPTR channels = NULL;
JSON_OBJPTR jso_channel = NULL;
S32 err_code = 0;
U8 params[MAX_JSON_STR_LEN] = {0};
U8 channel_param[MAX_JSON_STR_LEN] = {0};
if (!context || !jso_is_obj(param)) { return SLP_EINVARG; } action = jso_obj_get_string_origin(param, "action"); if ((NULL == action) || (0 == strlen(action))) { return SLP_EINVARG; } if (!strcmp(action, ACTION_CHANGE_UPLOAD_STATE)) { DSD_LOG(DSD_LOG_DEBUG, "!!!change upload state"); /* parse channels */ channels = jso_obj_get(param, "channel"); if (!channels || !jso_is_array(channels)) { return SLP_EINVARG; } jso_to_string(channels, channel_param, MAX_JSON_STR_LEN); if (MAX_JSON_STR_LEN <= snprintf(params, MAX_JSON_STR_LEN, "{\"channel\": %s}", channel_param)) { DSD_LOG(DSD_LOG_ERROR, "Buf not large enough!"); } DSD_LOG(DSD_LOG_DEBUG, "Msg: %s", params); if ((OK != ubus_simple_call(CLOUD_STORAGE_UBUS_OBJ, CS_METHOD_CHANGE_UPLOAD_STATE, params, &err_code)) || (SLP_ENONE != err_code)) { DSD_LOG(DSD_LOG_ERROR, "Ubus call " CLOUD_STORAGE_UBUS_OBJ " " CS_METHOD_CHANGE_UPLOAD_STATE " failed: %d.", err_code); err_code = EPROCESSERR; } else { err_code = SLP_ENONE; } } else if (!strcmp(action, ACTION_CHANGE_ENCRYPT_KEY)) { DSD_LOG(DSD_LOG_DEBUG, "!!!change encrypt key"); /* no other arguments */ if ((OK != ubus_simple_call(CLOUD_STORAGE_UBUS_OBJ, CS_METHOD_CHANGE_ENCRYPT_KEY, NULL, &err_code)) || (SLP_ENONE != err_code)) { DSD_LOG(DSD_LOG_ERROR, "Ubus call " CLOUD_STORAGE_UBUS_OBJ " " CS_METHOD_CHANGE_ENCRYPT_KEY " failed."); err_code = EPROCESSERR; } else { err_code = SLP_ENONE; } } else { DSD_LOG(DSD_LOG_ERROR, "Unsupported action: %s", action); return SLP_EINVARG; } return err_code;
}
最新发布