/* * 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__*/