/*
|
* Copyright (c) 2021 Rockchip Corporation
|
*
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* you may not use this file except in compliance with the License.
|
* You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
* limitations under the License.
|
*
|
*/
|
|
#ifndef __RK_AIQ_USER_API2_HELPER_H__
|
#define __RK_AIQ_USER_API2_HELPER_H__
|
|
#include "rk_aiq_user_api_sysctl.h"
|
|
typedef enum __RkAiqUapiOpMode {
|
RKAIQUAPI_OPMODE_SET = 0,
|
RKAIQUAPI_OPMODE_GET,
|
} RkAiqUapiOpMode_t;
|
|
#define RKAIQ_UAPI_NAME_MAX_LEN 64
|
#define JSON_PATCH_PATH "path"
|
#define JSON_PATCH_VALUE "value"
|
|
#define UAPIRPC_DEBUG
|
|
#define __RKAIQUAPI_SET(api_name, type_name) \
|
inline int __rkaiq_uapi_##api_name##_set(void *ctx, void *data) { \
|
rk_aiq_sys_ctx_t *__ctx = (rk_aiq_sys_ctx_t *)ctx; \
|
type_name *__data = (type_name *)data; \
|
return rkaiq_uapi_##api_name##_set(__ctx, __data); \
|
}
|
|
#define __RKAIQUAPI_GET(api_name, type_name) \
|
inline int __rkaiq_uapi_##api_name##_get(void *ctx, void *data) { \
|
rk_aiq_sys_ctx_t *__ctx = (rk_aiq_sys_ctx_t *)ctx; \
|
type_name *__data = (type_name *)data; \
|
return rkaiq_uapi_##api_name##_get(__ctx, __data); \
|
}
|
|
#define __RKAIQUAPI_CALLER(type_name) \
|
inline int __rkaiq_uapi_##type_name##_call( \
|
void *desc, void *sys_ctx, cJSON *cmd_js, cJSON **ret_js, int mode) { \
|
RkAiqUapiDesc_t *uapi_desc = (RkAiqUapiDesc_t *)desc; \
|
rk_aiq_sys_ctx_t *aiq_ctx = (rk_aiq_sys_ctx_t *)sys_ctx; \
|
j2s_ctx ctx; \
|
int ret = -1; \
|
j2s_init(&ctx); \
|
ctx.format_json = false; \
|
ctx.manage_data = false; \
|
type_name real_obj; \
|
\
|
if (mode == RKAIQUAPI_OPMODE_SET) { \
|
/* Get old json then apply change */ \
|
cJSON *old_json = NULL; \
|
ret = __rkaiq_uapi_##type_name##_call(desc, sys_ctx, cmd_js, &old_json, \
|
RKAIQUAPI_OPMODE_GET); \
|
if (ret || !old_json) { \
|
XCAM_LOG_ERROR("sysctl for %s readback failed.", #type_name); \
|
return -1; \
|
} \
|
ret = cJSONUtils_ApplyPatches(old_json, cmd_js); \
|
if (0 != ret) { \
|
XCAM_LOG_ERROR("%s apply patch failed %d!", __func__, ret); \
|
return -1; \
|
} \
|
printf("[UAPI RPC] patched json:\n%s\n", cJSON_Print(old_json)); \
|
memset(&real_obj, 0, sizeof(type_name)); \
|
ret = j2s_json_to_struct(&ctx, old_json, #type_name, &real_obj); \
|
j2s_deinit(&ctx); \
|
if (ret) { \
|
return -1; \
|
} \
|
if (!uapi_desc->arg_set) { \
|
return -1; \
|
} \
|
return uapi_desc->arg_set(aiq_ctx, &real_obj); \
|
} else if (mode == RKAIQUAPI_OPMODE_GET) { \
|
if (!uapi_desc->arg_get) { \
|
return -1; \
|
} \
|
uapi_desc->arg_get(aiq_ctx, &real_obj); \
|
*ret_js = j2s_struct_to_json(&ctx, #type_name, &real_obj); \
|
j2s_deinit(&ctx); \
|
if (!*ret_js) { \
|
XCAM_LOG_ERROR("create %s failed.", #type_name); \
|
return -1; \
|
} \
|
printf("[UAPI RPC] readback json:\n%s\n", cJSON_Print(*ret_js)); \
|
} \
|
return 0; \
|
}
|
|
#define __RKAIQUAPI_SET_FUNC(api_name, type_name) __rkaiq_uapi_##api_name##_set
|
#define __RKAIQUAPI_GET_FUNC(api_name, type_name) __rkaiq_uapi_##api_name##_get
|
#define __RKAIQUAPI_FUNC_CAST(__api) (RkAiqUapi)(__api)
|
|
typedef int (*RkAiqUapi)(void *, void *);
|
typedef int (*RkAiqUapiCaller)(void *, void *, void *, void **, int);
|
|
typedef struct __RkAiqUapiDesc {
|
char arg_path[RKAIQ_UAPI_NAME_MAX_LEN];
|
char arg_type[RKAIQ_UAPI_NAME_MAX_LEN];
|
RkAiqUapi arg_set;
|
RkAiqUapi arg_get;
|
RkAiqUapiCaller uapi_caller;
|
} RkAiqUapiDesc_t;
|
|
#ifdef __cplusplus
|
|
#define __RKAIQUAPI_DESC_DEF(__arg_path, __arg_type, __arg_set, __arg_get) \
|
{ \
|
__arg_path, #__arg_type, (RkAiqUapi)__arg_set, (RkAiqUapi)__arg_get, \
|
(RkAiqUapiCaller)__rkaiq_uapi_##__arg_type##_call, \
|
}
|
|
#else
|
|
#define __RKAIQUAPI_DESC_DEF(__arg_path, __arg_type, __arg_set, __arg_get) \
|
{ \
|
.arg_path = {__arg_path}, .arg_type = {#__arg_type}, \
|
.arg_set = (RkAiqUapi)__arg_set, .arg_get = (RkAiqUapi)__arg_get, \
|
.uapi_caller = (RkAiqUapiCaller)__rkaiq_uapi_##__arg_type##_call, \
|
}
|
|
#endif
|
|
#define __RKAIQUAPI_SET_WRAPPER(func, type_name) \
|
int func##2(const rk_aiq_sys_ctx_t *sys_ctx, const type_name *ptr) { \
|
return func(sys_ctx, *ptr); \
|
}
|
|
#define __RKAIQUAPI_SET_WRAPPER_NAME(func) func##2
|
|
int rkaiq_uapi_unified_ctl(rk_aiq_sys_ctx_t *sys_ctx, const char *js_str,
|
char **ret_str, int op_mode);
|
|
#endif /*__RK_AIQ_USER_API2_HELPER_H__*/
|