Files
mkrtos-real/mkrtos_user/lib/sys_svr/src/ns_cli.c
2025-03-03 00:29:18 +08:00

202 lines
4.9 KiB
C

#include "u_rpc.h"
#include "u_rpc_svr.h"
#include "ns_types.h"
#include "rpc_prot.h"
#include "u_env.h"
#include "u_prot.h"
#include "u_hd_man.h"
#include "u_path.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define NS_CLI_CACHE_NR 8 //!< 一个客户端最多可以请求8个服务
typedef struct ns_cli_entry
{
char path[NS_NODE_NAME_LEN];
obj_handler_t hd;
} ns_cli_entry_t;
typedef struct ns_cli_cache
{
ns_cli_entry_t cache[NS_CLI_CACHE_NR];
} ns_cli_cache_t;
static ns_cli_cache_t ns_cli_cache;
/**
* @brief TODO:加锁
*
* @param path
* @param split_pos
* @return obj_handler_t
*/
static obj_handler_t find_hd(const char *path, int *split_pos)
{
int i = 0;
int empty = -1;
for (i = 0; i < NS_CLI_CACHE_NR; i++)
{
if (ns_cli_cache.cache[i].path[0] != 0)
{
char *new_str = strstr(path, ns_cli_cache.cache[i].path);
if (new_str && (new_str == path))
{
if (split_pos)
{
*split_pos = (int)(strlen(ns_cli_cache.cache[i].path));
}
return ns_cli_cache.cache[i].hd;
}
}
}
return HANDLER_INVALID;
}
static bool_t reg_hd(const char *path, obj_handler_t hd, int split_inx)
{
int i = 0;
int empty = -1;
for (i = 0; i < NS_CLI_CACHE_NR; i++)
{
if (ns_cli_cache.cache[i].path[0] == 0)
{
strncpy(ns_cli_cache.cache[i].path, path, split_inx);
ns_cli_cache.cache[i].path[split_inx] = 0;
ns_cli_cache.cache[i].hd = hd;
return TRUE;
}
}
return FALSE;
}
static void del_hd(obj_handler_t hd)
{
int i = 0;
int empty = -1;
for (i = 0; i < NS_CLI_CACHE_NR; i++)
{
if (ns_cli_cache.cache[i].path[0] != 0 && ns_cli_cache.cache[i].hd == hd)
{
ns_cli_cache.cache[i].path[0] = 0;
ns_cli_cache.cache[i].hd = 0;
}
}
}
RPC_GENERATION_CALL3(ns_t, NS_PROT, NS_REGISTER_OP, register,
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, type)
RPC_GENERATION_CALL2(ns_t, NS_PROT, NS_QUERY_OP, query,
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_INOUT, RPC_TYPE_BUF, cli_hd)
int ns_register(const char *path, obj_handler_t svr_hd, int flags)
{
assert(path);
rpc_ref_array_uint32_t_uint8_t_32_t rpc_path = {
.data = (uint8_t *)path,
.len = strlen(path) + 1,
};
rpc_obj_handler_t_t rpc_svr_hd = {
.data = svr_hd,
};
rpc_int_t rpc_type = {
.data = flags,
};
msg_tag_t tag = ns_t_register_call(u_get_global_env()->ns_hd, &rpc_path, &rpc_svr_hd, &rpc_type);
return msg_tag_get_val(tag);
}
int ns_query(const char *path, obj_handler_t *svr_hd, int flags)
{
int inx = 0;
assert(path);
assert(svr_hd);
if (u_is_root_path(path))
{
// 根路径直接返回服务路径就行了
*svr_hd = u_get_global_env()->ns_hd;
return 0;
}
obj_handler_t newfd;
newfd = find_hd(path, &inx);
if (newfd != HANDLER_INVALID)
{
msg_tag_t tag;
tag = task_obj_valid(TASK_THIS, newfd, NULL);
if (msg_tag_get_val(tag) < 0 || msg_tag_get_val(tag) == 0)
{
// 从缓存中删除
del_hd(newfd);
goto next;
}
*svr_hd = newfd;
return inx;
}
next:
newfd = handler_alloc();
if (newfd == HANDLER_INVALID)
{
return -ENOENT;
}
rpc_ref_array_uint32_t_uint8_t_32_t rpc_path = {
.data = (uint8_t *)path,
.len = strlen(path) + 1,
};
rpc_obj_handler_t_t rpc_svr_hd = {
.data = newfd,
.del_map_flags = VPAGE_FLAGS_MAP,
};
msg_tag_t tag = ns_t_query_call(u_get_global_env()->ns_hd, &rpc_path, &rpc_svr_hd);
if (msg_tag_get_val(tag) < 0)
{
handler_free(newfd);
return msg_tag_get_val(tag);
}
#if 0
if (flags & 0x1)
{
if (msg_tag_get_val(tag) != strlen(path))
{
// printf("ns query don't find svr obj.\n");
handler_free_umap(newfd);
return -ENOENT;
}
}
#endif
if (reg_hd(path, newfd, msg_tag_get_val(tag)) == FALSE)
{
printf("The client service cache is full.\n");
handler_free_umap(newfd);
return -ENOMEM;
}
*svr_hd = newfd;
return msg_tag_get_val(tag);
}
int ns_query_svr(const char *path, obj_handler_t *svr_hd, int flags)
{
int ret;
ret = ns_query(path, svr_hd, flags);
if (ret < 0)
{
return ret;
}
if (ret != strlen(path))
{
return -ENOENT;
}
return 0;
}