From 7f3def442c0f724b6799d2b8f4970f2df9b085fe Mon Sep 17 00:00:00 2001 From: zhaohonghao Date: Tue, 23 Jan 2024 21:28:23 +0800 Subject: [PATCH] proxy: rpc proxy interface for hi3093 description: add rpc proxy interface for hi3093 Signed-off-by: zhaohonghao --- CMakeLists.txt | 4 + mica_demo/mica_main.c | 2 +- mica_demo/rpmsg_pty.c | 21 +- mica_demo/rpmsg_pty.h | 3 + rpmsg_rpc_demo/ethercat_cmd/ioctl_rpc.h | 50 + rpmsg_rpc_demo/ethercat_cmd/mq_master.c | 247 +++ rpmsg_rpc_demo/rpc_err.h | 11 + rpmsg_rpc_demo/rpc_helper.c | 241 +++ rpmsg_rpc_demo/rpc_internal_model.h | 1357 ++++++++++++ rpmsg_rpc_demo/rpc_server_internal.h | 60 + rpmsg_rpc_demo/rpmsg_backend.c | 2497 +++++++++++++++++++++++ rpmsg_rpc_demo/rpmsg_workers.c | 126 ++ 12 files changed, 4616 insertions(+), 3 deletions(-) create mode 100644 rpmsg_rpc_demo/ethercat_cmd/ioctl_rpc.h create mode 100644 rpmsg_rpc_demo/ethercat_cmd/mq_master.c create mode 100644 rpmsg_rpc_demo/rpc_err.h create mode 100644 rpmsg_rpc_demo/rpc_helper.c create mode 100644 rpmsg_rpc_demo/rpc_internal_model.h create mode 100644 rpmsg_rpc_demo/rpc_server_internal.h create mode 100644 rpmsg_rpc_demo/rpmsg_backend.c create mode 100644 rpmsg_rpc_demo/rpmsg_workers.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 17d7cb2..e228133 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,10 @@ elseif(DEMO_TARGET MATCHES "mica_demo") # add source file for mica_demo list(APPEND SRC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${DEMO_TARGET}/rpmsg_pty.c") list(APPEND SRC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${DEMO_TARGET}/mica_debug.c") + list(APPEND SRC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg_rpc_demo/rpc_helper.c") + list(APPEND SRC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg_rpc_demo/rpmsg_workers.c") + list(APPEND SRC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg_rpc_demo/rpmsg_backend.c") + list(APPEND SRC_FILE "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg_rpc_demo/ethercat_cmd/mq_master.c") # enable debug log if(DEFINED MICA_DEBUG_LOG) add_definitions(-DMICA_DEBUG_LOG) diff --git a/mica_demo/mica_main.c b/mica_demo/mica_main.c index 9339583..afa51ea 100644 --- a/mica_demo/mica_main.c +++ b/mica_demo/mica_main.c @@ -9,7 +9,7 @@ static struct client_os_inst client_os = { /* physical address start of shared device mem */ - .phy_shared_mem = 0x70000000, + .phy_shared_mem = 0x90000000, /* size of shared device mem */ .shared_mem_size = 0x30000, .vring_size = VRING_SIZE, diff --git a/mica_demo/rpmsg_pty.c b/mica_demo/rpmsg_pty.c index e282f5a..c269c00 100644 --- a/mica_demo/rpmsg_pty.c +++ b/mica_demo/rpmsg_pty.c @@ -13,8 +13,12 @@ #include #include +#include +#include + #include "openamp_module.h" #include "rpmsg_pty.h" +#include "../rpmsg_rpc_demo/rpc_server_internal.h" /* define the keys according to your terminfo */ #define KEY_CTRL_D 4 @@ -130,7 +134,7 @@ static void *pty_thread(void *arg) break; } - ret = rpmsg_service_send(pty_ep->ep_id, cmd, ret); + ret = rpc_server_send(pty_ep->ep_id, 0, RPMSG_RPC_OK, cmd, ret); if (ret < 0) { printf("rpmsg_service_send error %d\n", ret); ret = -1; @@ -162,8 +166,15 @@ static struct pty_ep_data *pty_service_create(const char * ep_name) goto err_free_resource_struct; } - pty_ep->ep_id = rpmsg_service_register_endpoint(ep_name, pty_endpoint_cb, + pty_ep->f = fdopen(pty_ep->fd_master, "r+"); + if (pty_ep->f == NULL) { + close(pty_ep->fd_master); + goto err_free_resource_struct; + } + + pty_ep->ep_id = rpmsg_service_register_endpoint(ep_name, rpmsg_endpoint_server_cb, pty_endpoint_unbind_cb, pty_ep); + if (pty_ep->ep_id < 0) { printf("register endpoint %s failed\n", ep_name); goto err_close_pty; @@ -205,6 +216,12 @@ int rpmsg_app_start(struct client_os_inst *client) goto err_free_uart; } + ret = rpmsg_service_init(); + if (ret != 0) { + ret = -errno; + goto err_free_console; + } + if (pthread_create(&g_rpmsg_app_resource.rpmsg_loop_thread, NULL, rpmsg_loop_thread, client) != 0) { perror("create rpmsg loop thread failed\n"); ret = -errno; diff --git a/mica_demo/rpmsg_pty.h b/mica_demo/rpmsg_pty.h index 846bf33..a5e0813 100644 --- a/mica_demo/rpmsg_pty.h +++ b/mica_demo/rpmsg_pty.h @@ -15,9 +15,12 @@ extern "C" { #endif +#define RPMSG_CONSOLE_BUFFER_SIZE 2048 + struct pty_ep_data { unsigned int ep_id; /* endpoint id */ int fd_master; /* pty master fd */ + FILE *f; pthread_t pty_thread; /* thread id */ }; diff --git a/rpmsg_rpc_demo/ethercat_cmd/ioctl_rpc.h b/rpmsg_rpc_demo/ethercat_cmd/ioctl_rpc.h new file mode 100644 index 0000000..225bf35 --- /dev/null +++ b/rpmsg_rpc_demo/ethercat_cmd/ioctl_rpc.h @@ -0,0 +1,50 @@ +#ifndef _IOCTL_RPC_H +#define _IOCTL_RPC_H + +#include + +#define IGH_IOCTL_ID 301UL +#define IGH_OPEN_ID 302UL +#define IGH_CLOSE_ID 303UL + +#define MQ_NAME_FORMATE "/mq_slave_%d" +#define MQ_MASTER_NAME "/mq_0" + +typedef struct { + unsigned long func_id; + pid_t pid; +} cmd_base_req_t; // open can just use base req + +typedef struct { + unsigned long func_id; + int ret; + int remote_errno; +} cmd_base_resp_t; // open and close can just use base resp + +typedef struct { + unsigned long func_id; + pid_t pid; + int fd; +} cmd_close_req_t; + +typedef struct { + unsigned long func_id; + pid_t pid; + int fd; + unsigned int request; + int arg_size; + char arg[]; // flexible arg +} cmd_ioctl_req_t; + +typedef struct { + unsigned long func_id; + int ret; + int remote_errno; + int arg_size; + char resv[4]; // 8字节对齐 + char arg[]; // flexible arg +} cmd_ioctl_resp_t; + +#define is_valid_cmd_func_id(func_id) ((func_id) >= IGH_IOCTL_ID && (func_id) <= IGH_CLOSE_ID) + +#endif /* _IOCTL_RPC_H */ \ No newline at end of file diff --git a/rpmsg_rpc_demo/ethercat_cmd/mq_master.c b/rpmsg_rpc_demo/ethercat_cmd/mq_master.c new file mode 100644 index 0000000..83807ad --- /dev/null +++ b/rpmsg_rpc_demo/ethercat_cmd/mq_master.c @@ -0,0 +1,247 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// #include "openamp_module.h" + +#include "ioctl_rpc.h" +#include "../rpc_server_internal.h" +#include "../rpc_internal_model.h" +#include "../../mica_demo/rpmsg_pty.h" + +int ipc_handle_cmd_ioctl(cmd_base_req_t *req, unsigned int ep_id); +int ipc_handle_cmd_open(cmd_base_req_t *req, unsigned int ep_id); +int ipc_handle_cmd_close(cmd_base_req_t *req, unsigned int ep_id); + +inline mqd_t mq_open_by_pid(pid_t pid) +{ + char respond_mq_name[64]; + sprintf(respond_mq_name, MQ_NAME_FORMATE, pid); + lprintf("mq name: %s\n", respond_mq_name); + return mq_open(respond_mq_name, O_WRONLY, 0, NULL); +} + +static int process_cmd_request(cmd_base_req_t *req, unsigned int ep_id) +{ + int ret = 0; + if (!req ) { + return -1; + } + + switch (req->func_id) { + case IGH_IOCTL_ID: + ret = ipc_handle_cmd_ioctl(req, ep_id); + break; + case IGH_OPEN_ID: + ret = ipc_handle_cmd_open(req, ep_id); + break; + case IGH_CLOSE_ID: + ret = ipc_handle_cmd_close(req, ep_id); + break; + default: + lprintf("[ERROR] invalid func_id:%lu\n", req->func_id); + ret = -1; + break; + } + return ret; +} + +static void *cmd_worker_thread(void *arg) { + struct mq_attr attr = {0}; + struct pty_ep_data *pty_ep; + pty_ep = (struct pty_ep_data *)arg; + + mqd_t mqd = mq_open(MQ_MASTER_NAME, O_CREAT | O_EXCL | O_RDONLY, S_IRUSR | S_IWUSR, NULL); + + if (mqd == -1 && errno == EEXIST) { + mq_unlink(MQ_MASTER_NAME); + lprintf("unlink and create\n"); + mqd = mq_open(MQ_MASTER_NAME, O_CREAT | O_EXCL | O_RDONLY, S_IRUSR | S_IWUSR, NULL); + } + if (mqd == -1) { + lprintf("create fail %d, %s\n", errno, strerror(errno)); + return NULL; + } + + mq_getattr(mqd, &attr); + lprintf("max msg size: %ld, max msg num: %ld\n", attr.mq_msgsize, attr.mq_maxmsg); + cmd_base_req_t *req = (cmd_base_req_t *)malloc(attr.mq_msgsize); + if (req == NULL) { + lprintf("alloc fail\n"); + goto exit_close_mq; + } + + /* wait endpoint bound */ + while(!rpmsg_service_endpoint_is_bound(pty_ep->ep_id)); + + while (1) { + req->pid = 0; + req->func_id = 0; + lprintf("wait for msg...\n"); + mq_receive(mqd, (char *)req, attr.mq_msgsize, NULL); + if (req->pid == 0 || !is_valid_cmd_func_id(req->func_id)) { + lprintf("[ERROR] pid %d, func_id %lu", req->pid, req->func_id); + // pid等于0, 或func_id不正确,未收到消息 + continue; + } + + int ret = process_cmd_request(req, pty_ep->ep_id); + if (ret >= 0) { + // 处理成功,接收下一个消息 + continue; + } + + // 处理失败,直接发送回复 + lprintf("[ERROR] process msg fail, ret:%d, %s\n", ret, strerror(errno)); + mqd_t mq_slave = mq_open_by_pid(req->pid); + if (mq_slave == -1) { + lprintf("[ERROR] open slave fail %d, %s\n", errno, strerror(errno)); + continue; + } + cmd_base_resp_t resp = {req->func_id, ret, errno}; + mq_send(mq_slave, (char *)&resp, sizeof(cmd_base_resp_t), 0); + mq_close(mq_slave); + } + + free(req); +exit_close_mq: + mq_close(mqd); + mq_unlink("/mq_0"); +} + +int cmd_workers_init(struct pty_ep_data *pty_ep) +{ + pthread_t thread; + if (pthread_create(&thread, NULL, cmd_worker_thread, (void *)pty_ep) < 0) { + printf("cmd thread create failed\n"); + return -1; + } + printf("cmd worker created\n"); + pthread_detach(thread); +} + +int rpmsg_handle_cmd_ioctl(void *data, struct rpc_instance *inst, void *priv) +{ + rpc_cmd_ioctl_req_t *req = (rpc_cmd_ioctl_req_t *)data; + int ret = 0; + (void)inst; + (void)priv; + if (!req || !inst) + return -EINVAL; + lprintf("receive ioctl reply: pid:%d, func_id:%lu, resp_func_id:%lu, size:%d\n", req->cmd_pid, req->func_id, + req->ioctl_respond.func_id, req->ioctl_respond.arg_size); + + mqd_t mq_slave = mq_open_by_pid(req->cmd_pid); + if (mq_slave == -1) { + lprintf("[ERROR] open slave fail %d, %s\n", errno, strerror(errno)); + return -1; + } + ret = mq_send(mq_slave, (char *)&req->ioctl_respond, sizeof(cmd_ioctl_resp_t) + req->ioctl_respond.arg_size, 0); + mq_close(mq_slave); + + return ret; +} + +int rpmsg_handle_cmd_base(void *data, struct rpc_instance *inst, void *priv) +{ + rpc_cmd_base_req_t *req = (rpc_cmd_base_req_t *)data; + int ret = 0; + (void)inst; + (void)priv; + if (!req || !inst) + return -EINVAL; + lprintf("receive base reply: pid:%d, func_id:%lu, resp_func_id:%lu\n", req->cmd_pid, req->func_id, + req->base_respond.func_id); + + mqd_t mq_slave = mq_open_by_pid(req->cmd_pid); + if (mq_slave == -1) { + lprintf("[ERROR] open slave fail %d, %s\n", errno, strerror(errno)); + return -1; + } + ret = mq_send(mq_slave, (char *)&req->base_respond, sizeof(cmd_base_resp_t), 0); + mq_close(mq_slave); + + return ret; +} + +int ipc_handle_cmd_ioctl(cmd_base_req_t *req, unsigned int ep_id) +{ + int ret = 0; + if (!req) { + return -EINVAL; + } + cmd_ioctl_req_t *ioctl_req = (cmd_ioctl_req_t *)req; + + lprintf("receive ioctl request: pid:%d, func_id:%lu, request:%u, arg_size:%d\n", + ioctl_req->pid, ioctl_req->func_id, ioctl_req->request, ioctl_req->arg_size); + + size_t payload_size = sizeof(cmd_ioctl_req_t) + ioctl_req->arg_size; + if (ioctl_req->arg_size == 0) { + payload_size += sizeof(void *); + } + + cmd_ioctl_req_t *rpc_ioctl_req = (cmd_ioctl_req_t *)malloc(payload_size); + if (rpc_ioctl_req == NULL) { + return -1; + } + memcpy(rpc_ioctl_req, ioctl_req, payload_size); + ret = rpc_server_send(ep_id, IGH_IOCTL_ID, RPMSG_RPC_OK, rpc_ioctl_req, payload_size); + free(rpc_ioctl_req); + return ret < 0 ? ret : 0; +} + +int ipc_handle_cmd_open(cmd_base_req_t *req, unsigned int ep_id) +{ + int ret = 0; + if (!req) { + return -EINVAL; + } + lprintf("receive open request: pid:%d, func_id:%lu\n", req->pid, req->func_id); + + size_t payload_size = sizeof(cmd_base_req_t); + + cmd_base_req_t *rpc_base_req = (cmd_base_req_t *)malloc(payload_size); + if (rpc_base_req == NULL) { + return -1; + } + memcpy(rpc_base_req, req, sizeof(cmd_base_req_t)); + + /* Transmit rpc response */ + lprintf("send open request: pid:%d, func_id:%lu, size:%lu\n", rpc_base_req->pid, + rpc_base_req->func_id, payload_size); + ret = rpc_server_send(ep_id, req->func_id, RPMSG_RPC_OK, rpc_base_req, payload_size); + free(rpc_base_req); + return ret < 0 ? ret : 0; +} + +int ipc_handle_cmd_close(cmd_base_req_t *req, unsigned int ep_id) +{ + int ret = 0; + if (!req) { + return -EINVAL; + } + lprintf("receive close request: pid:%d, func_id:%lu\n", req->pid, req->func_id); + + size_t payload_size = sizeof(cmd_close_req_t); + + cmd_close_req_t *rpc_close_req = (cmd_close_req_t *)malloc(payload_size); + if (rpc_close_req == NULL) { + return -1; + } + memcpy(rpc_close_req, req, sizeof(cmd_close_req_t)); + + /* Transmit rpc response */ + lprintf("send close request: pid:%d, func_id:%lu, fd:%d, size:%lu\n", rpc_close_req->pid, + rpc_close_req->func_id, rpc_close_req->fd, payload_size); + ret = rpc_server_send(ep_id, req->func_id, RPMSG_RPC_OK, rpc_close_req, payload_size); + free(rpc_close_req); + return ret < 0 ? ret : 0; +} diff --git a/rpmsg_rpc_demo/rpc_err.h b/rpmsg_rpc_demo/rpc_err.h new file mode 100644 index 0000000..5665f62 --- /dev/null +++ b/rpmsg_rpc_demo/rpc_err.h @@ -0,0 +1,11 @@ +#ifndef _RPC_ERR_H +#define _RPC_ERR_H + +#define RPC_EBASE 3000 +#define RPC_ENO_SLOT (RPC_EBASE + 1) +#define RPC_EOVERLONG (RPC_EBASE + 2) +#define RPC_ECORRUPTED (RPC_EBASE + 3) +#define RPC_ENEED_INIT (RPC_EBASE + 4) +#define RPC_EINVAL (RPC_EBASE + 5) +#define RPC_ENOMEM (RPC_EBASE + 6) +#endif /* _RPC_ERR_H */ \ No newline at end of file diff --git a/rpmsg_rpc_demo/rpc_helper.c b/rpmsg_rpc_demo/rpc_helper.c new file mode 100644 index 0000000..d447683 --- /dev/null +++ b/rpmsg_rpc_demo/rpc_helper.c @@ -0,0 +1,241 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "rpc_internal_model.h" +#include "rpc_err.h" + +static char *__strdup(const char *s) +{ + size_t l = strlen(s); + char *d = malloc(l+1); + if (!d) return NULL; + return memcpy(d, s, l+1); +} + +void freeaddrlist(struct addrinfo *ai) +{ + struct addrinfo *p; + + while (ai != NULL) { + p = ai; + ai = ai->ai_next; + free(p->ai_canonname); + free(p); + } +} + +int encode_addrlist(const struct addrinfo *ai, char *buf, int *buflen) +{ + int len = 0, bi = 0, cnt = 0, aclen = 0; + const struct addrinfo *p = ai; + int hlen = sizeof(iaddrinfo_t) - sizeof(int); + + if(ai == NULL || buf == NULL || buflen == NULL) { + return -RPC_EINVAL; + } + while (p != NULL) { + len += hlen + p->ai_addrlen + sizeof(int); + if (p->ai_canonname != NULL) { + len += strlen(p->ai_canonname) + 1; + } + p = p->ai_next; + } + if (len > *buflen) { + return -RPC_EOVERLONG; + } + *buflen = len; + p = ai; + while (p != NULL) { + memcpy(&buf[bi], p, hlen); + bi += hlen; + aclen = 0; + if (p->ai_canonname != NULL) { + aclen = strlen(p->ai_canonname) + 1; + } + memcpy(&buf[bi], &aclen, sizeof(int)); + bi += sizeof(int); + if (p->ai_addr != NULL && p->ai_addrlen > 0) { + memcpy(&buf[bi], p->ai_addr, p->ai_addrlen); + bi += p->ai_addrlen; + } + if (aclen > 0) { + memcpy(&buf[bi], p->ai_canonname, aclen); + bi += aclen; + } + p = p->ai_next; + cnt ++; + } + + return cnt; +} + +int decode_addrlist(const char *buf, int cnt, int buflen, struct addrinfo **out) +{ + int bi = 0, aclen = 0, ret = 0; + struct addrinfo *p = NULL, **pp = out; + int hlen = sizeof(iaddrinfo_t) - sizeof(int); + + *out = p; + for (int i = 0; i < cnt; i++) { + struct addrinfo addr; + memcpy(&addr, &buf[bi], hlen); + if (addr.ai_addrlen < 0) { + ret = -RPC_ECORRUPTED; + goto clean; + } + *pp = p = (struct addrinfo *)malloc(sizeof(struct addrinfo) + addr.ai_addrlen); + if (p == NULL) { + ret = -RPC_ENOMEM; + goto clean; + } + if (bi + hlen >= buflen) { + ret = -RPC_EOVERLONG; + goto clean; + } + memcpy(p, &buf[bi], hlen); + bi += hlen; + if (bi + sizeof(int) >= buflen) { + ret = -RPC_EOVERLONG; + goto clean; + } + memcpy(&aclen, &buf[bi], sizeof(int)); + bi += sizeof(int); + p->ai_addr = (void *)&p[1]; + if (addr.ai_addrlen > 0) { + if (bi + addr.ai_addrlen >= buflen) { + ret = -RPC_EOVERLONG; + goto clean; + } + memcpy(p->ai_addr, &buf[bi], addr.ai_addrlen); + bi += addr.ai_addrlen; + } + p->ai_canonname = NULL; + if (aclen > 0) { + if (&buf[bi] == NULL) { + ret = -RPC_ECORRUPTED; + goto clean; + } + p->ai_canonname = __strdup(&buf[bi]); + bi += aclen; + } + + p->ai_next = NULL; + pp = &(p->ai_next); + } + return 0; +clean: + freeaddrlist(*out); + return ret; +} + +int decode_hostent(struct hostent **ppht, char *src_buf, int buflen) +{ + ihostent_t ih; + int tlen, dst_idx, src_idx, i, slen; + struct hostent *pht; + char *dst_buf, **aliases, **addr; + if (ppht == NULL || src_buf == NULL || buflen < sizeof(ihostent_t)) { + return -RPC_EINVAL; + } + memcpy(&ih, src_buf, sizeof(ih)); + if (ih.h_name_idx > ih.h_aliases_idx || + ih.h_aliases_idx > ih.h_addr_list_idx) { + return -RPC_ECORRUPTED; + } + tlen = buflen + sizeof(char *) * (ih.aliaslen + ih.addrlen + 2) - + sizeof(ihostent_t) + sizeof(struct hostent); + dst_idx = sizeof(char *) * (ih.aliaslen + ih.addrlen + 2); + src_idx = sizeof(ihostent_t); + pht = (struct hostent *)malloc(tlen); + if (pht == NULL) { + return -RPC_ENOMEM; + } + dst_buf = (char *)(pht + 1); + memcpy(&dst_buf[dst_idx], &src_buf[src_idx], buflen - sizeof(ihostent_t)); + + pht->h_length = ih.h_length; + pht->h_addrtype = ih.h_addrtype; + if (ih.h_name_idx == ih.h_aliases_idx) { + pht->h_name = NULL; + } else { + pht->h_name = &dst_buf[dst_idx]; + dst_idx += ih.h_aliases_idx - ih.h_name_idx; + } + aliases = pht->h_aliases = (char **)dst_buf; + for (i = 0; i < ih.aliaslen; i++) { + aliases[i] = &dst_buf[dst_idx]; + if (aliases[i] == NULL) { + free(pht); + return -RPC_ECORRUPTED; + } + slen = strlen(aliases[i]) + 1; + dst_idx += slen; + } + aliases[i] = NULL; + addr = pht->h_addr_list = (char **)&dst_buf[sizeof(char *) * (ih.aliaslen + 1)]; + slen = pht->h_length; + for (i = 0 ; i < ih.addrlen; i++) { + addr[i] = &dst_buf[dst_idx]; + dst_idx += slen; + } + addr[i] = NULL; + *ppht = pht; + return 0; +} + +int encode_hostent(struct hostent *ht, char *buf, int buflen) +{ + int tlen = sizeof(ihostent_t), len = 0; + ihostent_t ih; + char **p; + + if (ht == NULL || buf == NULL) { + return -RPC_EINVAL; + } + ih.aliaslen = 0; + ih.addrlen = 0; + ih.h_name_idx = tlen; + ih.h_addrtype = ht->h_addrtype; + ih.h_length = ht->h_length; + if (ht->h_name != NULL) { + len = strlen(ht->h_name) + 1; + if (tlen + len >= buflen) { + return -RPC_EOVERLONG; + } + memcpy(&buf[tlen], ht->h_name, len); + tlen += len; + } + ih.h_aliases_idx = tlen; + if (ht->h_aliases != NULL) { + p = ht->h_aliases; + for (int i = 0; p[i] != NULL; i++) { + len = strlen(p[i]) + 1; + if (tlen + len >= buflen) { + return -RPC_EOVERLONG; + } + memcpy(&buf[tlen], p[i], len); + ih.aliaslen++; + tlen += len; + } + } + ih.h_addr_list_idx = tlen; + if (ht->h_addr_list != NULL) { + len = ht->h_length; + p = ht->h_addr_list; + for (int i = 0; p[i] != NULL; i++) { + if (tlen + len >= buflen) { + return -RPC_EOVERLONG; + } + memcpy(&buf[tlen], p[i], len); + ih.addrlen++; + tlen += len; + } + } + memcpy(buf, &ih, sizeof(ih)); + return tlen; +} diff --git a/rpmsg_rpc_demo/rpc_internal_model.h b/rpmsg_rpc_demo/rpc_internal_model.h new file mode 100644 index 0000000..e624ecf --- /dev/null +++ b/rpmsg_rpc_demo/rpc_internal_model.h @@ -0,0 +1,1357 @@ +#ifndef _RPC_INTERNAL_MODEL_H +#define _RPC_INTERNAL_MODEL_H +#include +#include +#include +#include +#include "ethercat_cmd/ioctl_rpc.h" + +#define OPEN_ID 1UL +#define CLOSE_ID 2UL +#define WRITE_ID 3UL +#define READ_ID 4UL +#define LSEEK_ID 5UL +#define FCNTL_ID 6UL +#define IOCTL_ID 7UL +#define UNLINK_ID 8UL +#define GETDENTS64_ID 9UL +#define FOPEN_ID 10UL +#define FCLOSE_ID 11UL +#define FREAD_ID 12UL +#define FWRITE_ID 13UL +#define FREOPEN_ID 14UL +#define FPUTS_ID 15UL +#define FGETS_ID 16UL +#define FEOF_ID 17UL +#define FPRINTF_ID 18UL +#define GETC_ID 19UL +#define FERROR_ID 20UL +#define GETC_UNLOCK_ID 21UL +#define PCLOSE_ID 22UL +#define TMPFILE_ID 23UL +#define CLEARERR_ID 24UL +#define POPEN_ID 25UL +#define UNGETC_ID 26UL +#define FSEEKO_ID 27UL +#define FTELLO_ID 28UL +#define RENAME_ID 29UL +#define REMOVE_ID 30UL +#define MKSTMP_ID 31UL +#define FSEEK_ID 32UL +#define FTELL_ID 33UL + +#define FFLUSH_ID 34UL +#define GETWC_ID 35UL +#define PUTWC_ID 36UL +#define PUTC_ID 37UL +#define UNGETWC_ID 38UL + +#define STAT_ID 39UL +#define GETCWD_ID 40UL +#define LSTAT_ID 41UL +#define FSTAT_ID 42UL + +#define NCPYWRITE_ID 43UL +#define NCPYREAD_ID 44UL +#define FDOPEN_ID 45UL +#define FILENO_ID 46UL +#define SETVBUF_ID 46UL +#define READLINK_ID 47UL +#define SYSTEM_ID 48UL + +#define ACCESS_ID 49UL +#define PIPE_ID 50UL +#define DUP2_ID 51UL +#define MKFIFO_ID 52UL +#define CHMOD_ID 53UL +#define CHDIR_ID 54UL +#define MKDIR_ID 55UL +#define RMDIR_ID 56UL +#define FSCANFX_ID 57UL + +#define FREEADDRINFO_ID 100UL +#define GETADDRINFO_ID 101UL +#define GETHOSTBYADDR_ID 102UL +#define GETHOSTBYNAME_ID 103UL +#define POLL_ID 104UL +#define GETPEERNAME_ID 105UL +#define GETHOSTNAME_ID 106UL +#define GETSOCKNAME_ID 107UL +#define GETSOCKOPT_ID 108UL +#define SELECT_ID 109UL +#define ACCEPT_ID 110UL +#define BIND_ID 111UL +#define CONNECT_ID 112UL +#define LISTEN_ID 113UL +#define RECV_ID 114UL +#define RECVFROM_ID 115UL +#define SEND_ID 116UL +#define SENDTO_ID 117UL +#define SETSOCKOPT_ID 118UL +#define SHUTDOWN_ID 119UL +#define SOCKET_ID 120UL +#define IFNAMEINDEX_ID 121UL +#define PUTCHAR_ID 122UL +#define GAISTRERROR_ID 123UL +#define ACCEPT4_ID 124UL +#define WRITEV_ID 125UL +#define PRINTF_ID 300UL + +#define MIN_ID OPEN_ID +#define MAX_ID PRINTF_ID + +#define MAX_SBUF_LEN 432 /* max socket buf len*/ +#define MAX_CBUF_LEN 416 +#define MAX_SADDR_SIZE 8 +#define MAX_STRING_LEN MAX_SBUF_LEN +#define MAX_FILE_NAME_LEN 128 +#define MAX_POLL_FDS 32 +#define MAX_PATH_LEN 1024 +#define MAX_IFNAMEINDEX_LEN 40 +#define MAX_IFNAMEINDEX_SIZE 40 +#define MAX_IOV_LEN 60 +#define MAX_IOV_SIZE 30 + +#define MAX_FILE_MODE_LEN 6 + +#ifndef MAX_FUNC_ID_LEN +#define MAX_FUNC_ID_LEN sizeof(unsigned long) +#endif + +typedef unsigned int uint32_t; + +typedef unsigned long fileHandle; + +/* RPMSG_CONSOLE_BUFFER_SIZE = 2048 + * sizeof(struct rpmsg_hdr) = 16 + * RPMSG_CONSOLE_BUFFER_SIZE - sizeof(struct rpmsg_hdr) - 1 = 2031 + * Aligning to 64 bits -> 2024UL + */ +#define PROXY_MAX_BUF_LEN 2024UL + +struct rpmsg_proxy_answer { + uint32_t id; + int32_t status; + unsigned char params[PROXY_MAX_BUF_LEN]; +}; + +typedef struct iaddrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + socklen_t ai_addrlen; + int namelen; +} iaddrinfo_t; + +typedef struct ihostent { + int h_name_idx; + int h_aliases_idx; + short aliaslen; + short addrlen; + int h_addrtype; + int h_length; + int h_addr_list_idx; +} ihostent_t; + +typedef struct rpc_resp_base { + uint32_t trace_id; + int errnum; +} rpc_resp_base_t; + +typedef struct rpc_outp_base { + int *eptr; +} rpc_outp_base_t; + +typedef struct rpc_common_resp { + rpc_resp_base_t super; + int ret; +} rpc_common_resp_t; + +typedef struct rpc_common_outp { + rpc_outp_base_t super; + int ret; +} rpc_common_outp_t; + +typedef struct rpc_fcommon_req { + unsigned long func_id; + uint32_t trace_id; + fileHandle fhandle; +} rpc_fcommon_req_t; + +typedef struct rpc_fcommon_resp { + rpc_resp_base_t super; + fileHandle fhandle; +} rpc_fcommon_resp_t; + +typedef struct rpc_fcommon_outp { + rpc_outp_base_t super; + fileHandle fhandle; +} rpc_fcommon_outp_t; + +/* common ssize_t ret*/ +typedef struct rpc_csret_resp { + rpc_resp_base_t super; + ssize_t ret; +} rpc_csret_resp_t; + +typedef struct rpc_csret_outp { + rpc_outp_base_t super; + ssize_t ret; +} rpc_csret_outp_t; + +/* open */ +typedef struct rpc_open_req { + unsigned long func_id; + uint32_t trace_id; + int flags; + uint32_t mode; + char buf[MAX_FILE_NAME_LEN]; +} rpc_open_req_t; + +typedef rpc_common_resp_t rpc_open_resp_t; + +typedef rpc_common_outp_t rpc_open_outp_t; + + +/* read */ +typedef struct rpc_read_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + uint32_t count; +} rpc_read_req_t; + +typedef struct rpc_read_resp { + rpc_resp_base_t super; + ssize_t ret; + char buf[MAX_STRING_LEN]; +} rpc_read_resp_t; + +typedef struct rpc_read_outp { + rpc_outp_base_t super; + ssize_t ret; + void *buf; +} rpc_read_outp_t; + +/* no copy read */ +typedef struct rpc_ncpyread_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + unsigned long baddr_offset; + uint32_t count; +} rpc_ncpyread_req_t; + +typedef rpc_csret_resp_t rpc_ncpyread_resp_t; + +typedef rpc_csret_outp_t rpc_ncpyread_outp_t; + +/* write */ +typedef struct rpc_write_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + uint32_t count; + char buf[MAX_STRING_LEN]; +} rpc_write_req_t; + +typedef rpc_csret_resp_t rpc_write_resp_t; + +typedef rpc_csret_outp_t rpc_write_outp_t; + +/* no copy write */ +typedef struct rpc_ncpywrite_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + uint32_t count; + unsigned long baddr_offset; +} rpc_ncpywrite_req_t; + +typedef rpc_write_resp_t rpc_ncpywrite_resp_t; + +typedef rpc_write_outp_t rpc_ncpywrite_outp_t; + +/* close */ +typedef struct rpc_close_req { + unsigned long func_id; + uint32_t trace_id; + int fd; +} rpc_close_req_t; + +typedef rpc_common_resp_t rpc_close_resp_t; + +typedef rpc_common_outp_t rpc_close_outp_t; + + +/* ioctl */ +typedef struct rpc_ioctl_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + unsigned long request; + size_t len; + char buf[MAX_STRING_LEN]; +} rpc_ioctl_req_t; + +typedef struct rpc_ioctl_resp { + rpc_resp_base_t super; + int ret; + size_t len; + char buf[MAX_STRING_LEN]; +} rpc_ioctl_resp_t; + +typedef struct rpc_ioctl_outp { + rpc_outp_base_t super; + int ret; + void *buf; +} rpc_ioctl_outp_t; + + +/* lseek */ +typedef struct rpc_lseek_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + off_t offset; + int whence; +} rpc_lseek_req_t; + +typedef struct rpc_lseek_resp { + rpc_resp_base_t super; + off_t ret; +} rpc_lseek_resp_t; + +typedef struct rpc_lseek_outp { + rpc_outp_base_t super; + off_t ret; +} rpc_lseek_outp_t; + + +/* fcntl */ +typedef struct rpc_fcntl_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + int cmd; + unsigned long arg; +} rpc_fcntl_req_t; + +typedef rpc_common_resp_t rpc_fcntl_resp_t; + +typedef rpc_common_outp_t rpc_fcntl_outp_t; + + +/* unlink */ +typedef struct rpc_unlink_req { + unsigned long func_id; + uint32_t trace_id; + char buf[MAX_FILE_NAME_LEN]; +} rpc_unlink_req_t; + +typedef rpc_common_resp_t rpc_unlink_resp_t; + +typedef rpc_common_outp_t rpc_unlink_outp_t; + +/* gethostbyaddr */ +typedef struct rpc_gethostbyaddr_req { + unsigned long func_id; + uint32_t trace_id; + socklen_t len; + int type; + char buf[MAX_SBUF_LEN]; +} rpc_gethostbyaddr_req_t; + +typedef struct rpc_gethostbyaddr_resp { + rpc_resp_base_t super; + int h_errnum; + int len; + char buf[MAX_SBUF_LEN]; +} rpc_gethostbyaddr_resp_t; + +typedef struct rpc_gethostbyaddr_outp { + rpc_outp_base_t super; + int len; + void *buf; +} rpc_gethostbyaddr_outp_t; + +/* gethostbyname */ +typedef struct rpc_gethostbyname_req { + unsigned long func_id; + uint32_t trace_id; + char buf[MAX_SBUF_LEN]; +} rpc_gethostbyname_req_t; + +typedef rpc_gethostbyaddr_resp_t rpc_gethostbyname_resp_t; + +typedef rpc_gethostbyaddr_outp_t rpc_gethostbyname_outp_t; + +/* getaddrinfo */ +typedef struct rpc_getaddrinfo_req { + unsigned long func_id; + uint32_t trace_id; + int hints_cnt; + int hints; /* hints index*/ + int node; /* node index*/ + int service; /* service index*/ + int buflen; + char buf[MAX_SBUF_LEN]; +} rpc_getaddrinfo_req_t; + +typedef struct rpc_getaddrinfo_resp { + rpc_resp_base_t super; + int h_errnum; + int ret; + int cnt; + int buflen; + char buf[MAX_SBUF_LEN]; +} rpc_getaddrinfo_resp_t; + +typedef struct rpc_getaddrinfo_outp { + rpc_outp_base_t super; + int ret; + int cnt; + void *buf; +} rpc_getaddrinfo_outp_t; + +/* getpeername */ +typedef struct rpc_getpeername_req { + unsigned long func_id; + uint32_t trace_id; + int sockfd; + socklen_t addrlen; + char addr_buf[MAX_SBUF_LEN]; +} rpc_getpeername_req_t; + +typedef struct rpc_getpeername_resp { + rpc_resp_base_t super; + int ret; + socklen_t addrlen; + char addr_buf[MAX_SBUF_LEN]; +} rpc_getpeername_resp_t; + +typedef struct rpc_getpeername_outp { + rpc_outp_base_t super; + ssize_t ret; + socklen_t *addrlen; + struct sockaddr *addr; +} rpc_getpeername_outp_t; + +/* getsockname */ +typedef rpc_getpeername_req_t rpc_getsockname_req_t; + +typedef rpc_getpeername_resp_t rpc_getsockname_resp_t; + +typedef rpc_getpeername_outp_t rpc_getsockname_outp_t; + +/* accept */ +typedef struct rpc_accept_req { + unsigned long func_id; + uint32_t trace_id; + int sockfd; + socklen_t addrlen; + char addr_buf[MAX_SBUF_LEN]; +} rpc_accept_req_t; + +typedef struct rpc_accept_resp { + rpc_resp_base_t super; + int ret; + socklen_t addrlen; + char buf[MAX_SBUF_LEN]; +} rpc_accept_resp_t; + +typedef struct rpc_accept_outp { + rpc_outp_base_t super; + ssize_t ret; + socklen_t *addrlen; + struct sockaddr *addr; +} rpc_accept_outp_t; + +/* bind */ +typedef struct rpc_bind_req { + unsigned long func_id; + uint32_t trace_id; + int sockfd; + socklen_t addrlen; + char addr_buf[MAX_SBUF_LEN]; +} rpc_bind_req_t; + +typedef rpc_common_resp_t rpc_bind_resp_t; + +typedef rpc_common_outp_t rpc_bind_outp_t; + +/* connect */ +typedef rpc_bind_req_t rpc_connect_req_t; + +typedef rpc_common_resp_t rpc_connect_resp_t; + +typedef rpc_common_outp_t rpc_connect_outp_t; + +/* listen */ +typedef struct rpc_listen_req { + unsigned long func_id; + uint32_t trace_id; + int sockfd; + int backlog; +} rpc_listen_req_t; + +typedef rpc_common_resp_t rpc_listen_resp_t; + +typedef rpc_common_outp_t rpc_listen_outp_t; + +/* recv */ +typedef struct rpc_recv_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + int flags; + size_t len; +} rpc_recv_req_t; + +typedef struct rpc_recv_resp { + rpc_resp_base_t super; + ssize_t ret; + char buf[MAX_SBUF_LEN]; +} rpc_recv_resp_t; + +typedef struct rpc_recv_outp { + rpc_outp_base_t super; + ssize_t ret; + void *buf; +} rpc_recv_outp_t; + +/* recvfrom */ +typedef struct rpc_recvfrom_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + int flags; + socklen_t addrlen; + size_t len; + char buf[MAX_SBUF_LEN]; +} rpc_recvfrom_req_t; + +typedef struct rpc_recvfrom_resp { + rpc_resp_base_t super; + socklen_t addrlen; + ssize_t ret; + struct sockaddr addr[MAX_SADDR_SIZE]; + char buf[MAX_SBUF_LEN - MAX_SADDR_SIZE * sizeof(struct sockaddr)]; +} rpc_recvfrom_resp_t; + +typedef struct rpc_recvfrom_outp { + rpc_outp_base_t super; + ssize_t ret; + void *buf; + socklen_t *addrlen; + struct sockaddr *src_addr; +} rpc_recvfrom_outp_t; + +/* send */ +typedef struct rpc_send_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + size_t len; + int flags; + char buf[MAX_SBUF_LEN]; +} rpc_send_req_t; + +typedef rpc_csret_resp_t rpc_send_resp_t; + +typedef rpc_csret_outp_t rpc_send_outp_t; + +/* sendto */ +typedef struct rpc_sendto_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + size_t len; + int flags; + socklen_t addrlen; + char buf[MAX_SBUF_LEN]; +} rpc_sendto_req_t; + +typedef rpc_csret_resp_t rpc_sendto_resp_t; + +typedef rpc_csret_outp_t rpc_sendto_outp_t; + +/* setsockopt */ +typedef struct rpc_setsockopt_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + int level; + int optname; + socklen_t optlen; + char optval[MAX_STRING_LEN]; +} rpc_setsockopt_req_t; + +typedef rpc_common_resp_t rpc_setsockopt_resp_t; + +typedef rpc_common_outp_t rpc_setsockopt_outp_t; + +/* shutdown */ +typedef struct rpc_shutdown_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + int how; +} rpc_shutdown_req_t; + +typedef rpc_common_resp_t rpc_shutdown_resp_t; + +typedef rpc_common_outp_t rpc_shutdown_outp_t; + +/* socket */ +typedef struct rpc_socket_req { + unsigned long func_id; + uint32_t trace_id; + int domain; + int type; + int protocol; +} rpc_socket_req_t; + +typedef rpc_common_resp_t rpc_socket_resp_t; + +typedef rpc_common_outp_t rpc_socket_outp_t; + +/* poll */ +typedef struct rpc_poll_req { + unsigned long func_id; /* 8 */ + uint32_t trace_id; /* 4 */ + int timeout; /* 4 */ + struct pollfd fds[MAX_POLL_FDS]; /* 8 * MAX_POLL_FDS*/ + nfds_t nfds; /* 8 */ +} rpc_poll_req_t; + +typedef struct rpc_poll_resp { + rpc_resp_base_t super; + int ret; + struct pollfd fds[MAX_POLL_FDS]; +} rpc_poll_resp_t; + +typedef struct rpc_poll_outp { + rpc_outp_base_t super; + int ret; + int fdsNum; + struct pollfd* fds; +} rpc_poll_outp_t; + +/* select */ +typedef struct rpc_select_req { + unsigned long func_id; /* 8 */ + uint32_t trace_id; /* 4 */ + int nfds; /* 4 */ + fd_set readfds; /* 128 */ + fd_set writefds; /* 128 */ + fd_set exceptfds; /* 128 */ + struct timeval timeout; /* 16 */ + char is_readfds_not_null; + char is_writefds_not_null; + char is_exceptfds_not_null; + char is_timeout_not_null; +} rpc_select_req_t; + +typedef struct rpc_select_resp { + rpc_resp_base_t super; + fd_set readfds; /* 128 */ + fd_set writefds; /* 128 */ + fd_set exceptfds; /* 128 */ + struct timeval timeout; /* 16 */ + int ret; +} rpc_select_resp_t; + +typedef struct rpc_select_outp { + rpc_outp_base_t super; + int ret; + fd_set *readfds; + fd_set *writefds; + fd_set *exceptfds; + struct timeval *timeout; +} rpc_select_outp_t; + +/* gethostname */ +typedef struct rpc_gethostname_req { + unsigned long func_id; + uint32_t trace_id; + size_t len; +} rpc_gethostname_req_t; + +typedef struct rpc_gethostname_resp { + rpc_resp_base_t super; + int ret; + int len; + char name[MAX_STRING_LEN]; +} rpc_gethostname_resp_t; + +typedef struct rpc_gethostname_outp { + rpc_outp_base_t super; + int ret; + char* name; + size_t len; +} rpc_gethostname_outp_t; + +/* getsockopt*/ +typedef struct rpc_getsockopt_req { + unsigned long func_id; + uint32_t trace_id; + int sockfd; + socklen_t optlen; + int level; + int optname; +} rpc_getsockopt_req_t; + +typedef struct rpc_getsockopt_resp { + rpc_resp_base_t super; + int ret; + socklen_t optlen; + char optval[MAX_STRING_LEN]; +} rpc_getsockopt_resp_t; + +typedef struct rpc_getsockopt_outp { + rpc_outp_base_t super; + int ret; + void* optval; + socklen_t* optlen; +} rpc_getsockopt_outp_t; + +/* printf */ +typedef struct rpc_printf_req { + unsigned long func_id; + int len; + char buf[MAX_STRING_LEN]; +} rpc_printf_req_t; + +/* getdents64*/ +typedef struct rpc_getdents64_req { + unsigned long func_id; + uint32_t trace_id; + int count; + long pos; + int fd; +} rpc_getdents64_req_t; + +typedef struct rpc_getdents64_resp { + rpc_resp_base_t super; + long pos; + int ret; + char buf[MAX_STRING_LEN]; +} rpc_getdents64_resp_t; + +typedef struct rpc_getdents64_outp { + rpc_outp_base_t super; + long pos; + char *buf; + int bufsize; + int ret; +} rpc_getdents64_outp_t; +/* ethercat ioctl */ +typedef struct rpc_cmd_ioctl_req { + unsigned long func_id; + pid_t cmd_pid; + char resv[4]; // 8字节对齐 + cmd_ioctl_resp_t ioctl_respond; +} rpc_cmd_ioctl_req_t; // actually for respond + +/* ethercat open or close */ +typedef struct rpc_cmd_base_req { + unsigned long func_id; + pid_t cmd_pid; + char resv[4]; // 8字节对齐 + cmd_base_resp_t base_respond; +} rpc_cmd_base_req_t; // actually for respond +/* fopen */ +typedef struct rpc_fopen_req { + unsigned long func_id; + uint32_t trace_id; + char filename[MAX_FILE_NAME_LEN]; + char mode[MAX_FILE_MODE_LEN]; +} rpc_fopen_req_t; + +/* fclose */ +typedef rpc_fcommon_req_t rpc_fclose_req_t; + +/* fread */ +typedef struct rpc_fread_req { + unsigned long func_id; + uint32_t trace_id; + size_t size; + size_t count; + fileHandle fhandle; +} rpc_fread_req_t; + +typedef struct rpc_fread_resp { + rpc_resp_base_t super; + size_t ret; + char buf[MAX_STRING_LEN]; +} rpc_fread_resp_t; + +typedef struct rpc_fread_outp { + rpc_outp_base_t super; + size_t ret; + size_t totalSize; + void *buf; +} rpc_fread_outp_t; + +/* fwrite */ +typedef struct rpc_fwrite_req { + unsigned long func_id; + uint32_t trace_id; + size_t size; + size_t count; + fileHandle fhandle; + char buf[MAX_STRING_LEN]; +} rpc_fwrite_req_t; + +typedef struct rpc_fwrite_resp { + rpc_resp_base_t super; + size_t ret; +} rpc_fwrite_resp_t; + +typedef struct rpc_fwrite_outp { + rpc_outp_base_t super; + size_t ret; +} rpc_fwrite_outp_t; + +/* freopen */ +typedef struct rpc_freopen_req { + unsigned long func_id; + uint32_t trace_id; + char filename[MAX_FILE_NAME_LEN]; + char mode[MAX_FILE_MODE_LEN]; + fileHandle fhandle; +} rpc_freopen_req_t; + +/* fputs */ +typedef struct rpc_fputs_req { + unsigned long func_id; + uint32_t trace_id; + fileHandle fhandle; + char str[MAX_STRING_LEN]; +} rpc_fputs_req_t; + +/* fgets */ +typedef struct rpc_fgets_req { + unsigned long func_id; + uint32_t trace_id; + fileHandle fhandle; + int size; +} rpc_fgets_req_t; + +typedef struct rpc_fgets_resp { + rpc_resp_base_t super; + int isEof; + char str[MAX_STRING_LEN]; +} rpc_fgets_resp_t; + +typedef struct rpc_fgets_outp { + rpc_outp_base_t super; + char *str; + int size; + int isEof; +} rpc_fgets_outp_t; + +/* fflush */ +typedef rpc_fcommon_req_t rpc_fflush_req_t; + +typedef rpc_common_resp_t rpc_fflush_resp_t; + +typedef rpc_common_outp_t rpc_fflush_outp_t; + +/* feof */ +typedef rpc_fcommon_req_t rpc_feof_req_t; + +/* fprintf */ +typedef struct rpc_fprintf_req { + unsigned long func_id; + fileHandle fhandle; + int len; + char buf[MAX_STRING_LEN]; +} rpc_fprintf_req_t; + +/* getc */ +typedef rpc_fcommon_req_t rpc_getc_req_t; + +/* ferror */ +typedef rpc_fcommon_req_t rpc_ferror_req_t; + +/* flockfile */ +typedef struct rpc_flockfile_req { + unsigned long func_id; + fileHandle fhandle; +} rpc_flockfile_req_t; + +/* funlockfile */ +typedef struct rpc_funlockfile_req { + unsigned long func_id; + fileHandle fhandle; +} rpc_funlockfile_req_t; + +/* getc_unlocked */ +typedef rpc_fcommon_req_t rpc_getc_unlocked_req_t; + +/* pclose */ +typedef rpc_fcommon_req_t rpc_pclose_req_t; + +/* tmpfile */ +typedef struct rpc_tmpfile_req { + unsigned long func_id; + uint32_t trace_id; +} rpc_tmpfile_req_t; + +/* clearerr */ +typedef struct rpc_clearerr_req { + unsigned long func_id; + fileHandle fhandle; +} rpc_clearerr_req_t; + +/* popen */ +typedef struct rpc_popen_req { + unsigned long func_id; + uint32_t trace_id; + char cmd[MAX_FILE_NAME_LEN]; + char mode[MAX_FILE_MODE_LEN]; +} rpc_popen_req_t; + +/* ungetc */ +typedef struct rpc_ungetc_req { + unsigned long func_id; + uint32_t trace_id; + int c; + fileHandle fhandle; +} rpc_ungetc_req_t; + +typedef rpc_common_resp_t rpc_ungetc_resp_t; + +typedef rpc_common_outp_t rpc_ungetc_outp_t; + +/* fseeko */ +typedef struct rpc_fseeko_req { + unsigned long func_id; + uint32_t trace_id; + fileHandle fhandle; + long offset; + int whence; +} rpc_fseeko_req_t; + +/* ftello */ +typedef rpc_fcommon_req_t rpc_ftello_req_t; + +typedef struct rpc_ftello_resp { + rpc_resp_base_t super; + long ret; +} rpc_ftello_resp_t; + +typedef struct rpc_ftello_outp { + rpc_outp_base_t super; + long ret; +} rpc_ftello_outp_t; + +/* rename */ +typedef struct rpc_rename_req { + unsigned long func_id; + uint32_t trace_id; + char old[MAX_FILE_NAME_LEN]; + char new[MAX_FILE_NAME_LEN]; +} rpc_rename_req_t; + +/* remove */ +typedef struct rpc_remove_req { + unsigned long func_id; + uint32_t trace_id; + char path[MAX_FILE_NAME_LEN]; +} rpc_remove_req_t; + +/* mkstemp */ +typedef struct rpc_mkstemp_req { + unsigned long func_id; + uint32_t trace_id; + char tmp[MAX_FILE_NAME_LEN]; +} rpc_mkstemp_req_t; + +/* getwc */ +typedef rpc_fflush_req_t rpc_getwc_req_t; + +typedef struct rpc_getwc_resp { + rpc_resp_base_t super; + wint_t ret; +} rpc_getwc_resp_t; + +typedef struct rpc_getwc_outp { + rpc_outp_base_t super; + wint_t ret; +} rpc_getwc_outp_t; + +/* putwc */ +typedef struct rpc_putwc_req { + unsigned long func_id; + uint32_t trace_id; + wchar_t wc; + fileHandle fhandle; +} rpc_putwc_req_t; + +typedef rpc_getwc_resp_t rpc_putwc_resp_t; + +typedef rpc_getwc_outp_t rpc_putwc_outp_t; + +/* ungetwc */ +typedef struct rpc_ungetwc_req { + unsigned long func_id; + uint32_t trace_id; + wint_t wc; + fileHandle fhandle; +} rpc_ungetwc_req_t; + +typedef rpc_getwc_resp_t rpc_ungetwc_resp_t; + +typedef rpc_getwc_outp_t rpc_ungetwc_outp_t; + +/* putc */ +typedef rpc_ungetc_req_t rpc_putc_req_t; + +typedef rpc_common_resp_t rpc_putc_resp_t; + +typedef rpc_common_outp_t rpc_putc_outp_t; + +/* stat */ +typedef struct rpc_stat_req { + unsigned long func_id; + uint32_t trace_id; + char path[MAX_PATH_LEN]; +} rpc_stat_req_t; + +typedef struct rpc_stat_resp { + rpc_resp_base_t super; + int ret; + + unsigned long st_dev; + unsigned long st_ino; + unsigned long st_nlink; + + unsigned st_mode; + unsigned st_uid; + unsigned st_gid; + unsigned long st_rdev; + long st_size; + long st_blksize; + long st_blocks; + + long st_atime_sec; + long st_atime_nsec; + long st_mtime_sec; + long st_mtime_nsec; + long st_ctime_sec; + long st_ctime_nsec; +} rpc_stat_resp_t; + +typedef struct rpc_stat_outp { + rpc_outp_base_t super; + int ret; + struct stat *statbuf; +} rpc_stat_outp_t; + +/* getcwd */ +typedef struct rpc_getcwd_req { + unsigned long func_id; + uint32_t trace_id; + size_t size; +} rpc_getcwd_req_t; + +typedef struct rpc_getcwd_resp { + rpc_resp_base_t super; + int isNull; + char buf[MAX_PATH_LEN]; +} rpc_getcwd_resp_t; + +typedef struct rpc_getcwd_outp { + rpc_outp_base_t super; + char *buf; + size_t size; +} rpc_getcwd_outp_t; + +/* fileno */ +typedef rpc_fcommon_req_t rpc_fileno_req_t; + +typedef rpc_common_resp_t rpc_fileno_resp_t; + +typedef rpc_common_outp_t rpc_fileno_outp_t; + +/* fdopen */ +typedef struct rpc_fdopen_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + char mode[MAX_FILE_MODE_LEN]; +} rpc_fdopen_req_t; + +typedef rpc_fcommon_resp_t rpc_fdopen_resp_t; + +typedef rpc_fcommon_outp_t rpc_fdopen_outp_t; + +/* fstat */ +typedef struct rpc_fstat_req { + unsigned long func_id; + uint32_t trace_id; + int fd; +} rpc_fstat_req_t; + +typedef rpc_stat_resp_t rpc_fstat_resp_t; + +typedef rpc_stat_outp_t rpc_fstat_outp_t; + +/* setvbuf */ +typedef struct rpc_setvbuf_req { + unsigned long func_id; + uint32_t trace_id; + fileHandle fhandle; +} rpc_setvbuf_req_t; + +typedef rpc_common_resp_t rpc_setvbuf_resp_t; + +typedef rpc_common_outp_t rpc_setvbuf_outp_t; + +/* system */ +typedef rpc_unlink_req_t rpc_system_req_t; + +typedef rpc_common_resp_t rpc_system_resp_t; + +typedef rpc_common_outp_t rpc_system_outp_t; + +/* readlink */ +typedef struct rpc_readlink_req { + unsigned long func_id; + uint32_t trace_id; + size_t bufsiz; + char pathname[MAX_STRING_LEN]; +} rpc_readlink_req_t; + +typedef struct rpc_readlink_resp { + rpc_resp_base_t super; + ssize_t ret; + char buf[MAX_STRING_LEN]; +} rpc_readlink_resp_t; + +typedef struct rpc_readlink_outp { + rpc_outp_base_t super; + size_t bufsiz; + ssize_t ret; + void *buf; +} rpc_readlink_outp_t; + +/* access */ +typedef struct rpc_access_req { + unsigned long func_id; + uint32_t trace_id; + int mode; + char pathname[MAX_STRING_LEN]; +} rpc_access_req_t; + +typedef rpc_common_resp_t rpc_access_resp_t; + +typedef rpc_common_outp_t rpc_access_outp_t; + +/* dup2 */ +typedef struct rpc_dup2_req { + unsigned long func_id; + uint32_t trace_id; + int oldfd; + int newfd; +} rpc_dup2_req_t; + +typedef rpc_common_resp_t rpc_dup2_resp_t; + +typedef rpc_common_outp_t rpc_dup2_outp_t; + +/* mkfifo */ +typedef rpc_access_req_t rpc_mkfifo_req_t; + +typedef rpc_common_resp_t rpc_mkfifo_resp_t; + +typedef rpc_common_outp_t rpc_mkfifo_outp_t; + +/* chmod */ +typedef struct rpc_chmod_req { + unsigned long func_id; + uint32_t trace_id; + int mode; + char pathname[MAX_STRING_LEN]; +} rpc_chmod_req_t; + +typedef rpc_common_resp_t rpc_chmod_resp_t; + +typedef rpc_common_outp_t rpc_chmod_outp_t; + +/* chdir */ +typedef rpc_unlink_req_t rpc_chdir_req_t; + +typedef rpc_common_resp_t rpc_chdir_resp_t; + +typedef rpc_common_outp_t rpc_chdir_outp_t; + +/* mkdir */ +typedef struct rpc_mkdir_req { + unsigned long func_id; + uint32_t trace_id; + int mode; + char pathname[MAX_STRING_LEN]; +} rpc_mkdir_req_t; + +typedef rpc_common_resp_t rpc_mkdir_resp_t; + +typedef rpc_common_outp_t rpc_mkdir_outp_t; + +/* rmdir */ +typedef rpc_unlink_req_t rpc_rmdir_req_t; + +typedef rpc_common_resp_t rpc_rmdir_resp_t; + +typedef rpc_common_outp_t rpc_rmdir_outp_t; + +/* pipe */ +typedef struct rpc_pipe_req { + unsigned long func_id; + uint32_t trace_id; +} rpc_pipe_req_t; + +typedef struct rpc_pipe_resp { + rpc_resp_base_t super; + ssize_t ret; + int fd[2]; +} rpc_pipe_resp_t; + +typedef struct rpc_pipe_outp { + rpc_outp_base_t super; + ssize_t ret; + int fd[2]; +} rpc_pipe_outp_t; + +/* fscanf only one %llx */ +typedef struct rpc_fscanfx_req { + unsigned long func_id; + uint32_t trace_id; + char fmt[MAX_FILE_NAME_LEN]; + fileHandle fhandle; +} rpc_fscanfx_req_t; + +typedef struct rpc_fscanfx_resp { + rpc_resp_base_t super; + ssize_t ret; + uint64_t data; +} rpc_fscanfx_resp_t; + +typedef struct rpc_fscanx_outp { + rpc_outp_base_t super; + ssize_t ret; + uint64_t data; +} rpc_fscanfx_outp_t; + +typedef struct nameindex { + unsigned int if_index; + char if_name[MAX_IFNAMEINDEX_LEN]; +} t_nameindex; + +/* if_nameindex */ +typedef struct rpc_if_nameindex_req{ + unsigned long func_id; + uint32_t trace_id; +} rpc_if_nameindex_req_t; + +typedef struct rpc_if_nameindex_resp { + rpc_resp_base_t super; + ssize_t ret; + int cnt; + t_nameindex if_index[MAX_IFNAMEINDEX_SIZE]; +} rpc_if_nameindex_resp_t; + +typedef struct rpc_if_nameindex_outp { + rpc_outp_base_t super; + ssize_t ret; + int cnt; + struct if_nameindex *if_index; +} rpc_if_nameindex_outp_t; + +/* putchar */ +typedef struct rpc_putchar_req{ + unsigned long func_id; + uint32_t trace_id; + int ch; +} rpc_putchar_req_t; + +typedef struct rpc_putchar_resp { + rpc_resp_base_t super; + int ret; +} rpc_putchar_resp_t; + +typedef struct rpc_putchar_outp { + rpc_outp_base_t super; + int ret; +} rpc_putchar_outp_t; + +/* gai_strerror */ +typedef struct rpc_gai_strerror_req{ + unsigned long func_id; + uint32_t trace_id; + int error; +} rpc_gai_strerror_req_t; + +typedef struct rpc_gai_strerror_resp { + rpc_resp_base_t super; + int isNull; + char buf[MAX_STRING_LEN]; +} rpc_gai_strerror_resp_t; + +typedef struct rpc_gai_strerror_outp { + rpc_outp_base_t super; + char *buf; +} rpc_gai_strerror_outp_t; + +/* accept4 */ +typedef struct rpc_accept4_req { + unsigned long func_id; + uint32_t trace_id; + int sockfd; + int flags; + socklen_t addrlen; + char addr_buf[MAX_SBUF_LEN]; // MAX_SBUF_LEN / sizeof(struct sockaddr) +} rpc_accept4_req_t; + +typedef struct rpc_accept4_resp { + rpc_resp_base_t super; + int ret; + socklen_t addrlen; + char buf[MAX_SBUF_LEN]; +} rpc_accept4_resp_t; + +typedef struct rpc_accept4_outp { + rpc_outp_base_t super; + ssize_t ret; + socklen_t *addrlen; + struct sockaddr *addr; +} rpc_accept4_outp_t; + +/* writev */ +typedef struct iovbuf { + size_t len; + char iov[MAX_IOV_LEN]; +} rpc_iovbuf; + +typedef struct rpc_writev_req { + unsigned long func_id; + uint32_t trace_id; + int fd; + int iovcnt; + rpc_iovbuf buf[MAX_IOV_SIZE]; +} rpc_writev_req_t; + +typedef struct rpc_writev_resp { + rpc_resp_base_t super; + ssize_t ret; +} rpc_writev_resp_t; + +typedef struct rpc_writev_outp { + rpc_outp_base_t super; + ssize_t ret; +} rpc_writev_outp_t; +#endif /* _RPC_INTERNAL_MODEL_H */ diff --git a/rpmsg_rpc_demo/rpc_server_internal.h b/rpmsg_rpc_demo/rpc_server_internal.h new file mode 100644 index 0000000..b4ea305 --- /dev/null +++ b/rpmsg_rpc_demo/rpc_server_internal.h @@ -0,0 +1,60 @@ +#ifndef _RPC_SERVER_INTERNAL_H +#define _RPC_SERVER_INTERNAL_H + +#include +#include +#include "../mica_demo/rpmsg_pty.h" + +#define WORKERS 5 +#define MAX_QUEUE_SIZE 256 + +struct rpc_instance; +typedef int (*rpc_cb_t)(void *params, struct rpc_instance *inst, void *priv); + +struct rpc_service { + uint32_t id; + rpc_cb_t cb_function; +}; + +struct rpc_instance { + const struct rpc_service *services; /* service table */ + unsigned int n_services; /* number of services */ +}; + +typedef struct { + unsigned char *data; + const struct rpc_service *service; + struct rpc_instance *inst; + void *priv; +} req_t; + +typedef struct { + req_t *q[MAX_QUEUE_SIZE]; + int head; + int tail; + int size; + pthread_mutex_t lock; + pthread_cond_t cond; +} rpc_queue_t; + +extern void enqueue_req(req_t *req); + +extern req_t *build_req(unsigned char *data, const struct rpc_service *service, + struct rpc_instance *inst, void *priv); + +extern int workers_init(); +extern int cmd_workers_init(struct pty_ep_data *pty_ep); + +extern int rpmsg_service_init(); +extern int lprintf(const char *fmt, ...); + +extern void freeaddrlist(struct addrinfo *ai); +extern int encode_addrlist(const struct addrinfo *ai, char *buf, int *buflen); +extern int decode_addrlist(const char *buf, int cnt, int buflen, struct addrinfo **out); +extern int decode_hostent(struct hostent **ppht, char *src_buf, int buflen); +extern int encode_hostent(struct hostent *ht, char *buf, int buflen); + +int rpc_server_send(unsigned int ept_id, uint32_t rpc_id, int status, void *request_param, size_t param_size); +int rpmsg_endpoint_server_cb(struct rpmsg_endpoint *, void *, size_t, uint32_t, void *); + +#endif /* _RPC_SERVER_INTERNAL_H */ \ No newline at end of file diff --git a/rpmsg_rpc_demo/rpmsg_backend.c b/rpmsg_rpc_demo/rpmsg_backend.c new file mode 100644 index 0000000..05d0be5 --- /dev/null +++ b/rpmsg_rpc_demo/rpmsg_backend.c @@ -0,0 +1,2497 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "rpc_internal_model.h" +#include "rpc_server_internal.h" +#include "rpmsg_rpc_service.h" +#include "rpmsg_endpoint.h" +#include "rpc_err.h" +#include "../mica_demo/rpmsg_pty.h" + +#define DEFINE_VARS(name) \ + void *req_ptr = data; \ + rpc_##name##_req_t *req = req_ptr; \ + rpc_##name##_resp_t resp; \ + size_t payload_size = sizeof(resp); \ + int ret; + +#ifdef MULTI_WORKERS +#define CLEANUP(data) free(data) +#else +#define CLEANUP(data) +#endif + +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) + +#define ADDR 0xFF +#define DEST_ADDR 0xFE + +static struct rpmsg_endpoint g_ept; + +int rpc_server_send(unsigned int ept_id, uint32_t rpc_id, int status, void *request_param, size_t param_size) +{ + struct rpmsg_proxy_answer msg; + + if (param_size > PROXY_MAX_BUF_LEN) + return -EINVAL; + + msg.id = rpc_id; + msg.status = status; + memcpy(msg.params, request_param, param_size); + return rpmsg_service_send(ept_id, &msg, MAX_FUNC_ID_LEN + param_size); +} + +static int rpmsg_handle_open(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_read(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_write(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_close(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_lseek(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fcntl(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_ioctl(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_unlink(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getdents64(void *data, struct rpc_instance *inst, void *priv); + +static int rpmsg_handle_freeaddrinfo(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getaddrinfo(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_gethostbyaddr(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_gethostbyname(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_poll(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getpeername(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_gethostname(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getsockname(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getsockopt(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_select(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_accept(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_bind(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_connect(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_listen(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_recv(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_recvfrom(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_send(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_sendto(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_setsockopt(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_shutdown(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_socket(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_printf(void *data, struct rpc_instance *inst, void *priv); +int rpmsg_handle_cmd_ioctl(void *data, struct rpc_instance *inst, void *priv); +int rpmsg_handle_cmd_base(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fopen(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fclose(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fread(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fwrite(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_freopen(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fputs(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fgets(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_feof(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fprintf(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getc(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_ferror(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getc_unlocked(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_pclose(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_tmpfile(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_clearerr(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_popen(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_ungetc(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fseeko(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_ftello(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fseek(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_ftell(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_rename(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_remove(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_mkstemp(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fflush(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getwc(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_putwc(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_putc(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_ungetwc(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_stat(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_lstat(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_getcwd(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fstat(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fdopen(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fileno(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_setvbuf(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_system(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_readlink(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_access(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_dup2(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_mkfifo(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_chmod(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_chdir(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_mkdir(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_rmdir(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_pipe(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_fscanfx(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_ifnameindex(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_putchar(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_gaistrerror(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_accept4(void *data, struct rpc_instance *inst, void *priv); +static int rpmsg_handle_writev(void *data, struct rpc_instance *inst, void *priv); + +/* Service table */ +static struct rpc_instance service_inst; +static struct rpc_service service_table[] = { + {OPEN_ID, &rpmsg_handle_open}, + {READ_ID, &rpmsg_handle_read}, + {WRITE_ID, &rpmsg_handle_write}, + {CLOSE_ID, &rpmsg_handle_close}, + {LSEEK_ID, &rpmsg_handle_lseek}, + {FCNTL_ID, &rpmsg_handle_fcntl}, + {IOCTL_ID, &rpmsg_handle_ioctl}, + {UNLINK_ID, &rpmsg_handle_unlink}, + {GETDENTS64_ID, &rpmsg_handle_getdents64}, + {FREEADDRINFO_ID, &rpmsg_handle_freeaddrinfo}, + {GETADDRINFO_ID, &rpmsg_handle_getaddrinfo}, + {GETHOSTBYADDR_ID, &rpmsg_handle_gethostbyaddr}, + {GETHOSTBYNAME_ID, &rpmsg_handle_gethostbyname}, + {POLL_ID, &rpmsg_handle_poll}, + {GETPEERNAME_ID, &rpmsg_handle_getpeername}, + {GETHOSTNAME_ID, &rpmsg_handle_gethostname}, + {GETSOCKNAME_ID, &rpmsg_handle_getsockname}, + {GETSOCKOPT_ID, &rpmsg_handle_getsockopt}, + {SELECT_ID, &rpmsg_handle_select}, + {ACCEPT_ID, &rpmsg_handle_accept}, + {BIND_ID, &rpmsg_handle_bind}, + {CONNECT_ID, &rpmsg_handle_connect}, + {LISTEN_ID, &rpmsg_handle_listen}, + {RECV_ID, &rpmsg_handle_recv}, + {RECVFROM_ID, &rpmsg_handle_recvfrom}, + {SEND_ID, &rpmsg_handle_send}, + {SENDTO_ID, &rpmsg_handle_sendto}, + {SETSOCKOPT_ID, &rpmsg_handle_setsockopt}, + {SHUTDOWN_ID, &rpmsg_handle_shutdown}, + {SOCKET_ID, &rpmsg_handle_socket}, + {FOPEN_ID, &rpmsg_handle_fopen}, + {FCLOSE_ID, &rpmsg_handle_fclose}, + {FREAD_ID, &rpmsg_handle_fread}, + {FWRITE_ID, &rpmsg_handle_fwrite}, + {FREOPEN_ID, &rpmsg_handle_freopen}, + {FPUTS_ID, &rpmsg_handle_fputs}, + {FGETS_ID, &rpmsg_handle_fgets}, + {FEOF_ID, &rpmsg_handle_feof}, + {FPRINTF_ID, &rpmsg_handle_fprintf}, + {GETC_ID, &rpmsg_handle_getc}, + {FERROR_ID, &rpmsg_handle_ferror}, + {GETC_UNLOCK_ID, &rpmsg_handle_getc_unlocked}, + {PCLOSE_ID, &rpmsg_handle_pclose}, + {TMPFILE_ID, &rpmsg_handle_tmpfile}, + {CLEARERR_ID, &rpmsg_handle_clearerr}, + {POPEN_ID, &rpmsg_handle_popen}, + {UNGETC_ID, &rpmsg_handle_ungetc}, + {FSEEKO_ID, &rpmsg_handle_fseeko}, + {FTELLO_ID, &rpmsg_handle_ftello}, + {FSEEK_ID, &rpmsg_handle_fseek}, + {FTELL_ID, &rpmsg_handle_ftell}, + {RENAME_ID, &rpmsg_handle_rename}, + {REMOVE_ID, &rpmsg_handle_remove}, + {MKSTMP_ID, &rpmsg_handle_mkstemp}, + {STAT_ID, &rpmsg_handle_stat}, + {LSTAT_ID, &rpmsg_handle_lstat}, + {GETCWD_ID, &rpmsg_handle_getcwd}, + {PRINTF_ID, &rpmsg_handle_printf}, + {IGH_IOCTL_ID, &rpmsg_handle_cmd_ioctl}, + {IGH_OPEN_ID, &rpmsg_handle_cmd_base}, + {IGH_CLOSE_ID, &rpmsg_handle_cmd_base}, + {FFLUSH_ID, &rpmsg_handle_fflush}, + {GETWC_ID, &rpmsg_handle_getwc}, + {PUTWC_ID, &rpmsg_handle_putwc}, + {PUTC_ID, &rpmsg_handle_putc}, + {UNGETWC_ID, &rpmsg_handle_ungetwc}, + {FSTAT_ID, &rpmsg_handle_fstat}, + {FDOPEN_ID, &rpmsg_handle_fdopen}, + {FILENO_ID, &rpmsg_handle_fileno}, + {SETVBUF_ID, &rpmsg_handle_setvbuf}, + {SYSTEM_ID, &rpmsg_handle_system}, + {READLINK_ID, &rpmsg_handle_readlink}, + {ACCESS_ID, &rpmsg_handle_access}, + {DUP2_ID, &rpmsg_handle_dup2}, + {MKFIFO_ID, &rpmsg_handle_mkfifo}, + {CHMOD_ID, &rpmsg_handle_chmod}, + {CHDIR_ID, &rpmsg_handle_chdir}, + {MKDIR_ID, &rpmsg_handle_mkdir}, + {RMDIR_ID, &rpmsg_handle_rmdir}, + {PIPE_ID, &rpmsg_handle_pipe}, + {FSCANFX_ID, &rpmsg_handle_fscanfx}, + {IFNAMEINDEX_ID, &rpmsg_handle_ifnameindex}, + {PUTCHAR_ID, &rpmsg_handle_putchar}, + {GAISTRERROR_ID, &rpmsg_handle_gaistrerror}, + {ACCEPT4_ID, &rpmsg_handle_accept4}, + {WRITEV_ID, &rpmsg_handle_writev}, +}; + +#define LOG_PATH "/tmp/accesslog" +#define WBUF_LEN 0x200 + +static int lfd; + +static int __lprintf(const char *fmt, va_list list) +{ + int len; + char buf[WBUF_LEN] = {0}; + + len = vsnprintf(buf, WBUF_LEN, fmt, list); + if (len < 0) { + return len; + } + return write(lfd, buf, len); +} + +int lprintf(const char *fmt, ...) +{ + va_list list; + int count; + + va_start(list, fmt); + count = __lprintf(fmt, list); + va_end(list); + return count; +} + +static void dump(char *buf, int len) +{ + for(int i = 0; i < len; i++) { + lprintf("%x ", buf[i]); + } + lprintf("\n"); +} + +static void lerror(int ret, int errnum) +{ + if (ret < 0) { + lprintf("errstr:%s\n", strerror(errnum)); + } +} + +static inline void set_rsp_base(rpc_resp_base_t *base, uint32_t trace_id) +{ + base->trace_id = trace_id; + base->errnum = errno; + errno = 0; +} + +static int rpmsg_init_rpc_server(struct rpc_instance *inst, + const struct rpc_service *services, int len) +{ + int ret = 0; + + /* parameter check */ + if (inst == NULL || services == NULL || len == 0) { + return -1; + } + + inst->services = services; + inst->n_services = len; + + if (ret < 0) { + lprintf("Creating endpoint %s failed with error %d", RPMSG_RPC_SERVICE_NAME, ret); + return ret; + } + return ret; +} + +static const struct rpc_service *find_service(struct rpc_instance *inst, + unsigned int id) +{ + const struct rpc_service *service; + + for (unsigned int i = 0; i < inst->n_services; i++) { + service = &inst->services[i]; + + if (service->id == id) { + return service; + } + } + return NULL; +} + +int rpmsg_endpoint_server_cb(struct rpmsg_endpoint *ept, void *data, + size_t len, + uint32_t src, void *priv) +{ +#ifdef MULTI_WORKERS + unsigned char *buf; +#else + unsigned char buf[RPMSG_CONSOLE_BUFFER_SIZE]; +#endif + unsigned long id; + struct rpc_instance *inst; + (void)src; + + lprintf("ccb: src %x, len %lu\n", src, len); + + inst = &service_inst; + id = *(unsigned long *)data; + lprintf("fun_id:%d\n", id); + if (len > RPMSG_CONSOLE_BUFFER_SIZE) { + lprintf("overlong data\n"); + rpc_server_send((((struct pty_ep_data *)priv)->ep_id), id, RPC_EOVERLONG, NULL, 0); + return -EINVAL; + } +#ifdef MULTI_WORKERS + buf = malloc(len * sizeof(unsigned char)); + if (buf == NULL) { + rpc_server_send((((struct pty_ep_data *)priv)->ep_id), id, RPC_ENOMEM, NULL, 0); + return RPMSG_ERR_NO_MEM; + } +#endif + memcpy(buf, data, len); + + const struct rpc_service *service = find_service(inst, id); + if (service) { +#ifdef MULTI_WORKERS + enqueue_req(build_req(buf, service, inst, priv)); +#else + if (service->cb_function(buf, inst, priv)) { + /* In this case, the client proactively detects a timeout + failure and we do not send a response for the failure. + */ + lprintf("Service failed at rpc id: %u\r\n", id); + } +#endif + } else { + lprintf("Handling remote procedure call errors: rpc id %u\r\n", id); + rpc_server_send((((struct pty_ep_data *)priv)->ep_id), id, RPMSG_RPC_INVALID_ID, NULL, 0); + } + return RPMSG_SUCCESS; +} + +int rpmsg_service_init() +{ + int ret; + unsigned int n_services = sizeof(service_table)/ sizeof(struct rpmsg_rpc_service); + + lfd = open(LOG_PATH, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR); + if (lfd < 0) { + lfd = STDOUT_FILENO; + } + + lprintf("number of services: %d, %p\n", n_services, service_table); + ret = rpmsg_init_rpc_server(&service_inst, service_table, n_services); +#ifdef MULTI_WORKERS + workers_init(); +#endif + return ret; +} + +void terminate_rpc_app(void) +{ + lprintf("Destroying endpoint.\r\n"); +} +#define STDFILE_BASE 1 + +static inline FILE *handle2file(uintptr_t fhandle, void *priv) +{ + if (fhandle == STDOUT_FILENO + STDFILE_BASE || + fhandle == STDIN_FILENO + STDFILE_BASE || + fhandle == STDERR_FILENO + STDFILE_BASE) { + return ((struct pty_ep_data *)priv)->f; + } + return (FILE *)fhandle; +} + +static int is_pty_fd(uintptr_t fhandle) +{ + return (fhandle == STDOUT_FILENO + STDFILE_BASE || + fhandle == STDIN_FILENO + STDFILE_BASE || + fhandle == STDERR_FILENO + STDFILE_BASE); +} + +static inline int file2fd(FILE *f) +{ + if (f == NULL) { + return -1; + } + return f->_fileno; +} + +static int rpmsg_handle_open(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(open) + char *buf; + int fd; + + if (!req || !inst) + return -EINVAL; + buf = req->buf; + lprintf("==open(%s)\n", buf); + /* Open remote fd */ + fd = open(buf, req->flags, req->mode); + lprintf("==open ret:%d\n", fd); + lerror(fd, errno); + /* Construct rpc response */ + resp.ret = fd; + set_rsp_base(&resp.super, req->trace_id); + /* Transmit rpc response */ + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), OPEN_ID, RPMSG_RPC_OK, &resp, + payload_size); + lprintf("==open send rsp:%d, %d\n", resp.ret, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_close(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(close) + + if (!req || !inst) + return -EINVAL; + lprintf("==close(%d)\n", req->fd); + /* Close remote fd */ + ret = close(req->fd); + lprintf("==close ret(%d)\n", ret); + lerror(ret, errno); + /* Construct rpc response */ + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + /* Transmit rpc response */ + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), CLOSE_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==close send rsp:%d, %d\n", req->fd, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_read(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(read) + ssize_t sret; + + if (!req || !inst) + return -EINVAL; + lprintf("==read(%d, %d)\n", req->fd, req->count); + if (req->fd == 0) { + sret = MAX_STRING_LEN; + /* Perform read from fd for large size since this is a + * STD/I request + */ + sret = read(req->fd, resp.buf, sret); + } else { + /* Perform read from fd */ + sret = read(req->fd, resp.buf, req->count); + } + lprintf("==read ret %ld\n", sret); + lerror((int)sret, errno); + /* Construct rpc response */ + resp.ret = sret; + set_rsp_base(&resp.super, req->trace_id); + + payload_size -= sizeof(resp.buf); + if (sret > 0) { + payload_size += sret; + } + + /* Transmit rpc response */ + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), READ_ID, RPMSG_RPC_OK, &resp, + payload_size); + lprintf("==read send rsp:%d, %d\n", req->fd, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_write(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(write) + ssize_t sret; + + if (!req || !inst) + return -EINVAL; + lprintf("==write(%d, %d)\n", req->fd, req->count); + /* Write to remote fd */ + sret = write(req->fd, req->buf, req->count); + lprintf("==write ret:%ld\n", sret); + lerror((int)sret, errno); + /* Construct rpc response */ + resp.ret = sret; + set_rsp_base(&resp.super, req->trace_id); + + /* Transmit rpc response */ + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), WRITE_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==write send rsp:%d, %d\n", req->fd, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_lseek(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(lseek) + off_t off; + + if (!req || !inst) + return -EINVAL; + lprintf("==lseek(%d, %ld, %d)\n", req->fd, req->offset, req->whence); + off = lseek(req->fd, req->offset, req->whence); + lprintf("==lseek ret:%ld\n", off); + lerror((int)off, errno); + resp.ret = off; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), LSEEK_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==lseek send rsp:%d,%d\n", req->fd, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fcntl(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(fcntl) + + if (!req || !inst) + return -EINVAL; + lprintf("==fcntl(%d, %d, %lu)\n", req->fd, req->cmd, req->arg); + ret = fcntl(req->fd, req->cmd, req->arg); + lprintf("==fcntl ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FCNTL_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==fcntl send rsp:%d, %d\n", req->fd, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_ioctl(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(ioctl) + + if (!req || !inst) + return -EINVAL; + lprintf("==ioctl(%d, %ld)\n", req->fd, req->request); + ret = ioctl(req->fd, req->request, req->buf); + lprintf("==ioctl ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + resp.len = req->len; + set_rsp_base(&resp.super, req->trace_id); + payload_size -= sizeof(req->buf); + if (req->len > 0) { + memcpy(resp.buf, req->buf, req->len); + payload_size += req->len; + } + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), IOCTL_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==ioctl send rsp:%d,%d\n", req->fd, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_unlink(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(unlink) + + if (!req || !inst) + return -EINVAL; + + lprintf("==unlink(%s)\n", req->buf); + ret = unlink(req->buf); + lprintf("==unlink ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), IOCTL_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==unlink send rsp:%s,%d\n", req->buf,ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_freeaddrinfo(void *data, struct rpc_instance *inst, void *priv) +{ + (void)data; + (void)inst; + lprintf("UNUSED\n"); + return 0; +} + +static int rpmsg_handle_getaddrinfo(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(getaddrinfo) + char *node = NULL, *service = NULL; + struct addrinfo *hints = NULL, *res = NULL; + + if (!req || !inst || req->node >= req->buflen || req->service >= req->buflen) + return -EINVAL; + + if (req->hints_cnt > 0) { + ret = decode_addrlist(req->buf, req->hints_cnt, sizeof(req->buf), &hints); + if (ret < 0) { + lprintf("==getaddrinfo decode failed(%d)\n", ret); + goto response; + } + } + if (req->service > req->node) { + node = &req->buf[req->node]; + } + if (req->buflen > req->service) { + service = &req->buf[req->service]; + } + lprintf("==getaddrinfo(%s, %s)\n", node, service); + ret = getaddrinfo(node, service, hints, &res); + lprintf("==getaddrinfo ret:%d\n", ret); + if (ret < 0) { + goto response; + } + lerror(ret, errno); + resp.cnt = 0; + resp.buflen = sizeof(resp.buf); + payload_size -= sizeof(resp.buf); + + if (res != NULL) { + resp.cnt = encode_addrlist(res, resp.buf, &resp.buflen); + payload_size += resp.buflen; + } else { + resp.cnt = 0; + resp.buflen = 0; + } + +response: + if (res != NULL) { + freeaddrinfo(res); + } + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETADDRINFO_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==getaddrinfo send rsp:%d,%d\n", payload_size, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +/* paddr: print the IP address in a standard decimal dotted format */ +static void paddr(unsigned char *a) +{ + lprintf("%d.%d.%d.%d\n", a[0], a[1], a[2], a[3]); +} + +static void print_host(struct hostent *hp) +{ + int i; + + if (hp == NULL) { + return; + } + lprintf("name:%s, %d\n", hp->h_name, hp->h_length); + for (i = 0; hp->h_addr_list[i] != 0; i++) { + paddr((unsigned char*) hp->h_addr_list[i]); + } + for (i = 0; hp->h_aliases[i] != 0; i++) { + lprintf("alias:%s\n", hp->h_aliases[i]); + } +} + +static int rpmsg_handle_gethostbyaddr(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(gethostbyaddr) + struct hostent *ht; + if (!req || !inst) + return -EINVAL; + + lprintf("==gethostbyaddr(%d, %d)\n", req->len, req->type); + ht = gethostbyaddr(req->buf, req->len, req->type); + lprintf("==gethostbyaddr ret:%p\n", ht); + if (ht == NULL) { + lprintf("errstr:%s\n", strerror(errno)); + } + payload_size -= sizeof(resp.buf); + set_rsp_base(&resp.super, req->trace_id); + print_host(ht); + if (ht == NULL) { + resp.len = 0; + goto response; + } + resp.len = encode_hostent(ht, resp.buf, sizeof(resp.buf)); + if (resp.len >= 0) { + payload_size += resp.len; + } +response: + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETHOSTBYADDR_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==gethostbyaddr send rsp, %d, %d\n", ret, resp.len); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_gethostbyname(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(gethostbyname) + struct hostent *ht; + if (!req || !inst) + return -EINVAL; + + lprintf("==gethostbyname(%s)\n", req->buf); + ht = gethostbyname(req->buf); + lprintf("==gethostbyname ret:%p\n", ht); + if (ht == NULL) { + lprintf("errstr:%s\n", strerror(errno)); + } + payload_size -= sizeof(resp.buf); + set_rsp_base(&resp.super, req->trace_id); + print_host(ht); + + if (ht == NULL) { + resp.len = 0; + goto response; + } + resp.len = encode_hostent(ht, resp.buf, sizeof(resp.buf)); + if (resp.len >= 0) { + payload_size += resp.len; + } +response: + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETHOSTBYNAME_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==gethostbyname send rsp, %d, %d\n", ret, resp.len); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_getpeername(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(getpeername) + + if (!req || !inst) + return -EINVAL; + + lprintf("==getpeername(%d, %d)\n", req->sockfd, req->addrlen); + ret = getpeername(req->sockfd, (struct sockaddr *)req->addr_buf, + (socklen_t *)&req->addrlen); + lprintf("==getpeername ret:%d\n", ret); + lerror(ret, errno); + + payload_size -= sizeof(resp.addr_buf); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + if (req->addrlen > 0) { + payload_size += req->addrlen; + memcpy(resp.addr_buf, req->addr_buf, req->addrlen); + } + resp.addrlen = req->addrlen; + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETPEERNAME_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==getpeername send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_getsockname(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(getsockname) + + if (!req || !inst) + return -EINVAL; + + lprintf("==getsockname(%d, %d)\n", req->sockfd, req->addrlen); + ret = getsockname(req->sockfd, (struct sockaddr *)req->addr_buf, + (socklen_t *)&req->addrlen); + lprintf("==getsockname ret:%d\n", ret); + lerror(ret, errno); + payload_size -= sizeof(resp.addr_buf); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + if (req->addrlen > 0) { + payload_size += req->addrlen; + memcpy(resp.addr_buf, req->addr_buf, req->addrlen); + } + resp.addrlen = req->addrlen; + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETSOCKNAME_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==getsockname send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_accept(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(accept) + + if (!req || !inst) + return -EINVAL; + + lprintf("==accept(%d, %d)\n", req->sockfd, req->addrlen); + if (req->addrlen > 0) { + ret = accept(req->sockfd, (struct sockaddr *)req->addr_buf, &req->addrlen); + } else { + ret = accept(req->sockfd, NULL, NULL); + } + lprintf("==accept ret:%d, addrlen:%d\n", ret, req->addrlen); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + resp.addrlen = req->addrlen; + payload_size -= sizeof(resp.addrlen); + + if (req->addrlen > 0) { + memcpy(resp.buf, req->addr_buf, req->addrlen); + payload_size += req->addrlen; + } + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), ACCEPT_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==accept send rsp,%d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_bind(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(bind) + + if (!req || !inst) + return -EINVAL; + + lprintf("==bind(%d, %d)\n", req->sockfd, req->addrlen); + ret = bind(req->sockfd, (struct sockaddr *)req->addr_buf, req->addrlen); + lprintf("==bind ret:%d, addrlen:%d\n", ret, req->addrlen); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), BIND_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==bind send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_connect(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(connect) + + if (!req || !inst) + return -EINVAL; + + lprintf("==connect(%d, %d)\n", req->sockfd, req->addrlen); + ret = connect(req->sockfd, (struct sockaddr *)req->addr_buf, req->addrlen); + lprintf("==connect ret:%d, addrlen:%d\n", ret, req->addrlen); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), CONNECT_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==connect send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} +static int rpmsg_handle_listen(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(listen) + + if (!req || !inst) + return -EINVAL; + + lprintf("==listen(%d, %d)\n", req->sockfd, req->backlog); + ret = listen(req->sockfd, req->backlog); + lprintf("==listen ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), LISTEN_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==listen send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_recv(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(recv) + ssize_t sret; + + if (!req || !inst) + return -EINVAL; + + lprintf("==recv(%d, %lu, %d)\n", req->fd, req->len, req->flags); + sret = recv(req->fd, resp.buf, req->len, req->flags); + lprintf("==recv ret:%ld\n", sret); + lerror(ret, errno); + payload_size -= sizeof(resp.buf); + resp.ret = sret; + set_rsp_base(&resp.super, req->trace_id); + if (sret > 0) { + payload_size += sret; + } + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), RECV_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==recv send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_recvfrom(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(recvfrom) + ssize_t sret; + int len; + + if (!req || !inst) + return -EINVAL; + + lprintf("==recvfrom(%d, %lu, %d)\n", req->fd, req->len, req->flags); + len = MIN(sizeof(resp.buf), req->len); + sret = recvfrom(req->fd, resp.buf, len, req->flags, (struct sockaddr *)req->buf, + (socklen_t *)&req->addrlen); + lprintf("==recvfrom ret:%ld\n", sret); + lerror(ret, errno); + resp.ret = sret; + set_rsp_base(&resp.super, req->trace_id); + resp.addrlen = req->addrlen; + payload_size -= sizeof(resp.buf); + if (req->addrlen > sizeof(resp.addr)) { + resp.ret = -RPC_EOVERLONG; + lprintf("==recvfrom addr overflow:%d, %d\n", req->addrlen, sizeof(resp.addr)); + goto response; + } + if (req->addrlen > 0) { + memcpy(resp.addr, req->buf, req->addrlen); + } + + if (sret > 0) { + payload_size += sret; + } +response: + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), RECVFROM_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==recv send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_send(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(send) + ssize_t sret; + + if (!req || !inst) + return -EINVAL; + + lprintf("==send(%d, %lu, %d)\n", req->fd, req->len, req->flags); + sret = send(req->fd, req->buf, req->len, req->flags); + lprintf("==send ret:%ld\n", sret); + lerror(ret, errno); + resp.ret = sret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), SEND_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==send send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_sendto(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(sendto) + ssize_t sret; + + if (!req || !inst) + return -EINVAL; + + lprintf("==sendto(%d, %lu, %d, %d)\n", req->fd, req->len, req->flags, req->addrlen); + sret = sendto(req->fd, &req->buf[req->addrlen], req->len, req->flags, + (struct sockaddr *)req->buf, req->addrlen); + lprintf("==sendto ret:%ld\n", sret); + lerror(ret, errno); + resp.ret = sret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), SENDTO_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==sendto send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_setsockopt(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(setsockopt) + + if (!req || !inst) + return -EINVAL; + + lprintf("==setsockopt(%d, %d, %d, %d)\n", req->fd, req->level, req->optname, + req->optlen); + ret = setsockopt(req->fd, req->level, req->optname, req->optval, req->optlen); + lprintf("==setsockopt ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), SETSOCKOPT_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==setsockopt send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_shutdown(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(shutdown) + + if (!req || !inst) + return -EINVAL; + + lprintf("==shutdown(%d, %d)\n", req->fd, req->how); + ret = shutdown(req->fd, req->how); + lprintf("==shutdown ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), SHUTDOWN_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==shutdown send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_socket(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(socket) + + if (!req || !inst) + return -EINVAL; + + lprintf("==socket(%d, %d, %d)\n", req->domain, req->type, req->protocol); + ret = socket(req->domain, req->type, req->protocol); + lprintf("==socket ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), SOCKET_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==socket send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + + +static int rpmsg_handle_poll(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(poll) + + if (!req || !inst) + return -EINVAL; + + lprintf("==poll(%d,%d,%d,%ld,%d)\n", req->fds[0].fd, req->fds[0].events, + req->fds[0].revents, req->nfds, req->timeout); + ret = poll(req->fds, req->nfds, req->timeout); + lprintf("==poll ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + memcpy(resp.fds, req->fds, sizeof(struct pollfd) * req->nfds); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), POLL_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==poll send rsp:(%d,%d,%d)\n", resp.fds[0].fd, resp.fds[0].revents, ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; + +} + +static int rpmsg_handle_select(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(select) + + if (!req || !inst) + return -EINVAL; + + lprintf("\n==select(%d,%d,%d,%d,%d,%ld,%ld)\n", req->nfds, (int)req->is_readfds_not_null, + (int)req->is_writefds_not_null, (int)req->is_exceptfds_not_null, (int)req->is_timeout_not_null, + req->timeout.tv_sec, req->timeout.tv_usec); + + fd_set *readfds = NULL; + fd_set *writefds = NULL; + fd_set *exceptfds = NULL; + struct timeval *timeout = NULL; + if (req->is_readfds_not_null) { + readfds = &(req->readfds); + } + if (req->is_writefds_not_null) { + writefds = &(req->writefds); + } + if (req->is_exceptfds_not_null) { + exceptfds = &(req->exceptfds); + } + if (req->is_timeout_not_null) { + timeout = &(req->timeout); + } + ret = select(req->nfds, readfds, writefds, exceptfds, timeout); + lprintf("==select ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + memcpy(&(resp.readfds), &(req->readfds), sizeof(fd_set)); + memcpy(&(resp.writefds), &(req->writefds), sizeof(fd_set)); + memcpy(&(resp.exceptfds), &(req->exceptfds), sizeof(fd_set)); + memcpy(&(resp.timeout), &(req->timeout), sizeof(struct timeval)); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), SELECT_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==select send rsp:%d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_gethostname(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(gethostname) + + if (!req || !inst) + return -EINVAL; + + lprintf("==gethostname(%lu)\n", (unsigned long)req->len); + if (req->len > MAX_STRING_LEN) { + req->len = MAX_STRING_LEN; + } + + ret = gethostname(resp.name, req->len); + lprintf("==gethostname ret:%d\n", ret); + lerror(ret, errno); + payload_size -= sizeof(resp.name); + resp.len = 0; + if (!ret) { + resp.len = strlen(resp.name) + 1; + payload_size += resp.len; + } + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETHOSTNAME_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==gethostname send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_getsockopt(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(getsockopt) + + if (!req || !inst) + return -EINVAL; + + lprintf("==getsockopt(%d, %d, %d)\n", req->sockfd, req->level, + req->optname); + + ret = getsockopt(req->sockfd, req->level, req->optname, &resp.optval, &req->optlen); + payload_size -= sizeof(resp.optval); + if (resp.optlen > sizeof(resp.optval)) { + ret = -RPC_EOVERLONG; + } else { + payload_size += req->optlen; + } + lprintf("==getsockopt(%d)\n", ret); + lerror(ret, errno); + resp.ret = ret; + resp.optlen = req->optlen; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETSOCKOPT_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==getsockopt send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +int pty_write(void *data, size_t len, void *priv); + +static int rpmsg_handle_printf(void *data, struct rpc_instance *inst, void *priv) +{ + rpc_printf_req_t *req = (rpc_printf_req_t *)data; + int ret = 0; + + if (!req || !inst) + return -EINVAL; + + ret = pty_write(req->buf, MIN(sizeof(req->buf), req->len), priv); + lprintf("==printf(%d), ret(%d)\n", req->len, ret); + + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_getdents64(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(getdents64) + off_t off = 0; + + if (!req || !inst) + return -EINVAL; + int buflen = MIN(req->count, sizeof(resp.buf)); + payload_size -= sizeof(resp.buf); + lprintf("==getdents64 fd:%d, pos:%ld\n", req->fd, req->pos); + if (req->pos != -1) { + off = lseek(req->fd, req->pos, SEEK_SET); + } + if (off < 0) { + resp.ret = -1; + lprintf("==getdents64 seek fail fd:%d, ret:%ld\n", req->fd, off); + } else { + ret = syscall(SYS_getdents64, req->fd, resp.buf, buflen); + lprintf("==getdents64 fd:%d, ret:%d\n", req->fd, ret); + if (ret > 0) { + payload_size += ret; + } + resp.ret = ret; + } + lerror(resp.ret, errno); + set_rsp_base(&resp.super, req->trace_id); + resp.pos = lseek(req->fd, 0, SEEK_CUR); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETDENTS64_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==getdents64 send rsp(%d), new pos: %ld\n", ret, resp.pos); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fopen(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fopen_req_t *req = data; + rpc_fcommon_resp_t resp = {0}; + + lprintf("==fopen(%s, %s)\n", req->filename, req->mode); + FILE *fd = fopen(req->filename, req->mode); + lprintf("==fopen %s.\n", (fd == 0 ? "fail" : "success")); + + resp.fhandle = (fileHandle)fd; + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FOPEN_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==fopen send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fclose(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fclose_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==fclose(0x%x)\n", req->fhandle); + int ret = fclose(f); + lprintf("==fclose ret(%d)\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FCLOSE_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==fclose send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fread(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fread_req_t *req = data; + rpc_fread_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==fread(0x%x, %u, %u)\n", req->fhandle, req->size, req->count); + size_t sz = fread(resp.buf, req->size, req->count, f); + lprintf("==fread ret(%u)\n", sz); + size_t payload_size = sizeof(resp) - sizeof(resp.buf) + sz; + resp.ret = sz; + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FREAD_ID, RPMSG_RPC_OK, &resp, payload_size); + lprintf("==fread send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fwrite(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fwrite_req_t *req = data; + rpc_fwrite_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==fwrite(0x%x, %u, %u)\n", req->fhandle, req->size, req->count); + size_t sz = fwrite(req->buf, req->size, req->count, f); + lprintf("==fwrite ret(%u)\n", sz); + + resp.ret = sz; + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FWRITE_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==fwrite send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_freopen(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_freopen_req_t *req = data; + rpc_fcommon_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==freopen(%s, %s)\n", req->filename, req->mode); + FILE *fd = freopen(req->filename, req->mode, f); + lprintf("==freopen %s.\n", (fd == 0 ? "fail" : "success")); + + resp.fhandle = (fileHandle)fd; + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FREOPEN_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==freopen send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fputs(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fputs_req_t *req = data; + rpc_common_resp_t resp = {0}; + + FILE *f = handle2file(req->fhandle, priv); + lprintf("==fputs(0x%x)\n", req->fhandle); + int ret = fputs(req->str, f); + lprintf("==fputs ret(%d)\n", ret); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FPUTS_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==fputs send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fgets(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fgets_req_t *req = data; + rpc_fgets_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==fgets(0x%x)\n", req->fhandle); + char *retStr = fgets(resp.str, req->size, f); + lprintf("==fgets ret(%s)\n", (retStr == NULL ? "end" : "continue")); + + resp.isEof = (retStr == NULL ? 1 : 0); + lprintf("==fgets isEof %d\n", resp.isEof); + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FGETS_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==fgets send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_feof(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_feof_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==feof(0x%x)\n", req->fhandle); + int ret = feof(f); + lprintf("==feof ret(%d)\n", ret); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FEOF_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==feof send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fprintf(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fprintf_req_t *req = (rpc_fprintf_req_t *)data; + int ret = 0; + + if (is_pty_fd(req->fhandle)) { + ret = pty_write(req->buf, MIN(sizeof(req->buf), req->len), priv); + lprintf("==fprintf printf(%d), ret(%d)\n", req->len, ret); + } else { + ret = fwrite(req->buf, sizeof(char), req->len, (FILE *)req->fhandle); + lprintf("==fprintf(%d), ret(%d)\n", req->len, ret); + } + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_getc(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_getc_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==getc(0x%x)\n", req->fhandle); + int ret = getc(f); + lprintf("==getc ret(%d)\n", ret); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETC_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==getc send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_ferror(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_ferror_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==ferror(0x%x)\n", req->fhandle); + int ret = ferror(f); + lprintf("==ferror ret(%d)\n", ret); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FERROR_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==ferror send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_getc_unlocked(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_getc_unlocked_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==getc_unlocked(0x%x)\n", req->fhandle); + int ret = getc_unlocked(f); + lprintf("==getc_unlocked ret(%d)\n", ret); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETC_UNLOCK_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==getc_unlocked send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_pclose(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_pclose_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==pclose(0x%x)\n", req->fhandle); + int ret = pclose(f); + lprintf("==pclose ret(%d)\n", ret); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), PCLOSE_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==pclose send rsp:0x%x, %d\n", req->fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_tmpfile(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_tmpfile_req_t *req = data; + rpc_fcommon_resp_t resp = {0}; + + lprintf("==tmpfile\n"); + FILE *f = tmpfile(); + + resp.fhandle = (fileHandle)f; + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), TMPFILE_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==tmpfile send rsp:0x%x, %d\n", resp.fhandle, ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_clearerr(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_clearerr_req_t *req = data; + FILE *f = handle2file(req->fhandle, priv); + lprintf("==clearerr(0x%x)\n", req->fhandle); + clearerr(f); + + CLEANUP(data); + return 0; +} + +static int rpmsg_handle_popen(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_popen_req_t *req = data; + rpc_fcommon_resp_t resp = {0}; + + lprintf("==popen(%s, %s)\n", req->cmd, req->mode); + FILE *fd = popen(req->cmd, req->mode); + lprintf("==popen %s, fd: 0x%x.\n", (fd == 0 ? "fail" : "success"), fd); + + resp.fhandle = (fileHandle)fd; + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), POPEN_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==popen send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_ungetc(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_ungetc_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==ungetc(%d)\n", req->c); + resp.ret = ungetc(req->c, f); + lprintf("==ungetc %d.\n", resp.ret); + + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), UNGETC_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==ungetc send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; + +} + +static int rpmsg_handle_fseeko(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fseeko_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==fseeko(%ld, %d)\n", req->offset, req->whence); + resp.ret = fseeko(f, req->offset, req->whence); + lprintf("==fseeko %d.\n", resp.ret); + + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FSEEKO_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==fseeko send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_ftello(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_ftello_req_t *req = data; + rpc_ftello_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==ftello\n"); + resp.ret = ftello(f); + lprintf("==ftello %d.\n", resp.ret); + + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FTELLO_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==ftello send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fseek(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_fseeko_req_t *req = data; + rpc_common_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==fseek(%ld, %d)\n", req->offset, req->whence); + resp.ret = fseek(f, req->offset, req->whence); + lprintf("==fseek %d.\n", resp.ret); + + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FSEEK_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==fseek send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_ftell(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_ftello_req_t *req = data; + rpc_ftello_resp_t resp = {0}; + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==ftello\n"); + resp.ret = ftello(f); + lprintf("==ftello %d.\n", resp.ret); + + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FTELL_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==ftello send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_rename(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_rename_req_t *req = data; + rpc_common_resp_t resp = {0}; + + lprintf("==rename(%s, %s)\n", req->old, req->new); + resp.ret = rename(req->old, req->new); + lprintf("==rename %d.\n", resp.ret); + + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), RENAME_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==rename send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_remove(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_remove_req_t *req = data; + rpc_common_resp_t resp = {0}; + + lprintf("==remove(%s, %s)\n", req->path); + resp.ret = remove(req->path); + lprintf("==remove %d.\n", resp.ret); + + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), REMOVE_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==remove send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_mkstemp(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + rpc_mkstemp_req_t *req = data; + rpc_common_resp_t resp = {0}; + + lprintf("==mkstemp(%s)\n", req->tmp); + resp.ret = mkstemp(req->tmp); + lprintf("==mkstemp %d.\n", resp.ret); + + set_rsp_base(&resp.super, req->trace_id); + int ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), MKSTMP_ID, RPMSG_RPC_OK, &resp, sizeof(resp)); + lprintf("==mkstemp send rsp:%d\n", ret); + + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fflush(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(fflush) + + if (!req || !inst) + return -EINVAL; + + FILE *f = handle2file(req->fhandle, priv); + lprintf("==fflush(fileno: %d)\n", file2fd(f)); + + ret = fflush(f); + + lprintf("==fflush(%d)\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FFLUSH_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==fflush send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_getwc(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(getwc) + + if (!req || !inst) + return -EINVAL; + + FILE *f = handle2file(req->fhandle, priv); + lprintf("==getwc(fileno: %d)\n", file2fd(f)); + wint_t wret = getwc(f); + lprintf("==getwc(%d)\n", wret); + + resp.ret = wret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETWC_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==getwc send rsp(%d)\n", wret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_putwc(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(putwc) + + if (!req || !inst) + return -EINVAL; + + FILE *f = handle2file(req->fhandle, priv); + lprintf("==putwc(%d, fileno: %d)\n", req->wc, file2fd(f)); + wint_t wret = putwc(req->wc, f); + lprintf("==putwc(%d)\n", wret); + + resp.ret = wret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), PUTWC_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==putwc send rsp(%d)\n", wret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_putc(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(putc) + + if (!req || !inst) + return -EINVAL; + + FILE *f = handle2file(req->fhandle, priv); + lprintf("==putc(%d, fileno: %d)\n", req->c, file2fd(f)); + ret = putc(req->c, f); + lprintf("==putc(%d)\n", ret); + + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), PUTC_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==putc send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_ungetwc(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(ungetwc) + + if (!req || !inst) + return -EINVAL; + + FILE *f = handle2file(req->fhandle, priv); + lprintf("==ungetwc(%d, fileno: %d)\n", req->wc, file2fd(f)); + wint_t wret = ungetwc(req->wc, f); + lprintf("==ungetwc(%d)\n", wret); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), UNGETWC_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==ungetwc send rsp(%d)\n", wret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static inline void set_stat_buff(rpc_stat_resp_t *resp, struct stat *statbuff) +{ + resp->st_dev = statbuff->st_dev; + resp->st_ino = statbuff->st_ino; + resp->st_nlink = statbuff->st_nlink; + resp->st_mode = statbuff->st_mode; + resp->st_uid = statbuff->st_uid; + resp->st_gid = statbuff->st_gid; + resp->st_rdev = statbuff->st_rdev; + resp->st_size = statbuff->st_size; + resp->st_blksize = statbuff->st_blksize; + resp->st_blocks = statbuff->st_blocks; + + resp->st_atime_sec = statbuff->st_atim.tv_sec; + resp->st_atime_nsec = statbuff->st_atim.tv_nsec; + resp->st_mtime_sec = statbuff->st_mtim.tv_sec; + resp->st_mtime_nsec = statbuff->st_mtim.tv_nsec; + resp->st_ctime_sec = statbuff->st_ctim.tv_sec; + resp->st_ctime_nsec = statbuff->st_ctim.tv_nsec; +} + +static int rpmsg_handle_stat(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(stat) + + if (!req || !inst) + return -EINVAL; + + struct stat statbuff = {0}; + lprintf("==stat(%s)\n", req->path); + ret = stat(req->path, &statbuff); + lprintf("==stat(%d)\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_stat_buff(&resp, &statbuff); + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), STAT_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==stat send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_lstat(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(stat) + + if (!req || !inst) + return -EINVAL; + + struct stat statbuff = {0}; + lprintf("==lstat(%s)\n", req->path); + ret = lstat(req->path, &statbuff); + lprintf("==lstat(%d)\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_stat_buff(&resp, &statbuff); + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), LSTAT_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==lstat send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_getcwd(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(getcwd) + + if (!req || !inst || req->size > sizeof(resp.buf)) + return -EINVAL; + + lprintf("==getcwd(%ld)\n", req->size); + char *buf = getcwd(resp.buf, req->size); + if (buf != NULL) { + lprintf("==getcwd(%s)\n", resp.buf); + resp.isNull = 0; + } else { + lprintf("==getcwd(NULL) %s\n", strerror(errno)); + resp.isNull = 1; + } + set_rsp_base(&resp.super, req->trace_id); + payload_size = payload_size - sizeof(resp.buf) + req->size; + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GETCWD_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==getcwd send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fstat(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(fstat) + + if (!req || !inst) + return -EINVAL; + + struct stat statbuff = {0}; + lprintf("==fstat(%d)\n", req->fd); + ret = fstat(req->fd, &statbuff); + lprintf("==fstat(%d)\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_stat_buff(&resp, &statbuff); + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FSTAT_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==fstat send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fdopen(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(fdopen) + + if (!req || !inst) + return -EINVAL; + + lprintf("==fdopen(%d)\n", req->fd); + FILE *f = fdopen(req->fd, req->mode); + lprintf("==fstat(%p)\n", f); + if (f == NULL) { + lprintf("errstr:%s\n", strerror(errno)); + } + + resp.fhandle = (fileHandle)f; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FDOPEN_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==fdopen send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fileno(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(fileno) + + if (!req || !inst) + return -EINVAL; + + lprintf("==fileno(0x%lx)\n", req->fhandle); + ret = fileno((FILE *)req->fhandle); + lprintf("==fileno(%d)\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FILENO_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==fileno send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_setvbuf(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(setvbuf) + + if (!req || !inst) + return -EINVAL; + + lprintf("==setvbuf(0x%lx) [_IONBF]\n", req->fhandle); + + // only support unbuffered mode + ret = setvbuf((FILE *)req->fhandle, NULL, _IONBF, 0); + lprintf("==setvbuf(%d)\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), SETVBUF_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==setvbuf send rsp(%d)\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_readlink(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(readlink) + + if (!req || !inst) + return -EINVAL; + + lprintf("==readlink(%s, %lu)\n",req->pathname, req->bufsiz); + ssize_t sret = readlink(req->pathname, resp.buf, MIN(sizeof(resp.buf), req->bufsiz)); + lprintf("==readlink ret:%ld\n", sret); + lerror((int)sret, errno); + + resp.ret = sret; + set_rsp_base(&resp.super, req->trace_id); + payload_size -= sizeof(resp.buf); + if (sret > 0) { + payload_size += sret; + } + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), READLINK_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==readlink send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_system(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(system) + + if (!req || !inst) + return -EINVAL; + + lprintf("==system(%s)\n", req->buf); + ret = system(req->buf); + lprintf("==system ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), SYSTEM_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==system send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_access(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(access) + + if (!req || !inst) + return -EINVAL; + + lprintf("==access(%s,%d)\n", req->pathname, req->mode); + ret = access(req->pathname, req->mode); + lprintf("==access ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), ACCESS_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==access send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_dup2(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(dup2) + + if (!req || !inst) + return -EINVAL; + + lprintf("==dup2(%d,%d)\n", req->oldfd, req->newfd); + ret = dup2(req->oldfd, req->newfd); + lprintf("==dup2 ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), DUP2_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==dup2 send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_mkfifo(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(mkfifo) + + if (!req || !inst) + return -EINVAL; + + lprintf("==mkfifo(%s,%u)\n", req->pathname, req->mode); + ret = mkfifo(req->pathname, req->mode); + lprintf("==mkfifo ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), MKFIFO_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==mkfifo send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_chmod(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(chmod) + + if (!req || !inst) + return -EINVAL; + + lprintf("==chmod(%s,%d)\n", req->pathname, req->mode); + ret = chmod(req->pathname, req->mode); + lprintf("==chmod ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), CHMOD_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==chmod send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_chdir(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(chdir) + + if (!req || !inst) + return -EINVAL; + + lprintf("==chdir(%s)\n", req->buf); + ret = chdir(req->buf); + lprintf("==chdir ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), CHDIR_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==chdir send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_mkdir(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(mkdir) + + if (!req || !inst) + return -EINVAL; + + lprintf("==mkdir(%s,%d)\n", req->pathname, req->mode); + ret = mkdir(req->pathname, req->mode); + lprintf("==mkdir ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), MKDIR_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==mkdir send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_rmdir(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(rmdir) + + if (!req || !inst) + return -EINVAL; + + lprintf("==rmdir(%s)\n", req->buf); + ret = rmdir(req->buf); + lprintf("==rmdir ret:%d\n", ret); + lerror(ret, errno); + + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), RMDIR_ID, RPMSG_RPC_OK, + &resp, payload_size); + + lprintf("==rmdir send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_pipe(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(pipe) + + if (!req || !inst) + return -EINVAL; + + lprintf("==pipe\n"); + ret = pipe(resp.fd); + lprintf("==pipe ret:%d fd[2]:%d %d\n", ret, resp.fd[0], resp.fd[1]); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), PIPE_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==pipe send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_fscanfx(void *data, struct rpc_instance *inst, void *priv) +{ + if (data == NULL || inst == NULL || priv == NULL) { + return -EINVAL; + } + + int ret; + rpc_fscanfx_req_t *req = data; + rpc_fscanfx_resp_t resp = {0}; + size_t payload_size = sizeof(resp); + FILE *f = handle2file(req->fhandle, priv); + + lprintf("==fscanfx(0x%x, %s)\n", req->fhandle, req->fmt); + ret = fscanf(f, req->fmt, &(resp.data)); + lprintf("==fscanfx ret:%d data:0x%llx\n", ret, resp.data); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), FSCANFX_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==fscanfx send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_ifnameindex(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(if_nameindex) + + if (!req || !inst) + return -EINVAL; + + lprintf("==ifnameindex\n"); + struct if_nameindex *ifNameIndex = if_nameindex(); + struct if_nameindex *p; + int cnt = 0; + + if(ifNameIndex != NULL){ + for (p = ifNameIndex; ! (p->if_index == 0 && p->if_name == NULL); p++){ + resp.if_index[cnt].if_index = p->if_index; + memcpy(resp.if_index[cnt].if_name, p->if_name, strlen(p->if_name)+1); + cnt++; + } + } + + resp.cnt = cnt; + + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), IFNAMEINDEX_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==ifnameindex send rsp, %d\n", ret); + if_freenameindex(ifNameIndex); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_putchar(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(putchar) + + if (!req || !inst) + return -EINVAL; + + lprintf("==putchar\n"); + ret = putchar(req->ch); + lprintf("==putchar ret:%d\n", ret); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), PUTCHAR_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==putchar send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; + +} + +static int rpmsg_handle_gaistrerror(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(gai_strerror) + + if (!req || !inst) + return -EINVAL; + + lprintf("==gaistrerror\n"); + const char *retStr = gai_strerror(req->error); + if (retStr != NULL) { + memcpy(resp.buf, retStr, strlen(retStr)+1); + lprintf("==gaistrerror(%s)\n", resp.buf); + resp.isNull = 0; + } else { + lprintf("==gaistrerror(NULL) %s\n", strerror(errno)); + resp.isNull = 1; + } + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), GAISTRERROR_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==gaistrerror send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_accept4(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(accept4) + + if (!req || !inst) + return -EINVAL; + + lprintf("==accept4(%d, %d)\n", req->sockfd, req->addrlen); + if (req->addrlen > 0) { + ret = accept4(req->sockfd, (struct sockaddr *)req->addr_buf, &req->addrlen, req->flags); + } else { + ret = accept4(req->sockfd, NULL, NULL, req->flags); + } + lprintf("==accept4 ret:%d, addrlen:%d\n", ret, req->addrlen); + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + resp.addrlen = req->addrlen; + payload_size -= sizeof(resp.addrlen); + + if (req->addrlen > 0) { + memcpy(resp.buf, req->addr_buf, req->addrlen); + payload_size += req->addrlen; + } + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), ACCEPT4_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==accept4 send rsp,%d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} + +static int rpmsg_handle_writev(void *data, struct rpc_instance *inst, void *priv) +{ + DEFINE_VARS(writev) + + if (!req || !inst) + return -EINVAL; + + lprintf("==writev\n"); + struct iovec iov[req->iovcnt]; + for(int i = 0; i < req->iovcnt; i++){ + iov[i].iov_base = (void *)malloc(sizeof(char) * MAX_IOV_SIZE); + memcpy(iov[i].iov_base,req->buf[i].iov, req->buf[i].len); + iov[i].iov_len = req->buf[i].len; + } + + ret = writev(req->fd, (const struct iovec *)&iov[0], req->iovcnt); + lprintf("==writev ret:%d\n", ret); + for(int i = 0; i < req->iovcnt; i++){ + free(iov[i].iov_base); + } + lerror(ret, errno); + resp.ret = ret; + set_rsp_base(&resp.super, req->trace_id); + + ret = rpc_server_send((((struct pty_ep_data *)priv)->ep_id), WRITEV_ID, RPMSG_RPC_OK, + &resp, payload_size); + lprintf("==writev send rsp, %d\n", ret); + CLEANUP(data); + return ret > 0 ? 0 : ret; +} diff --git a/rpmsg_rpc_demo/rpmsg_workers.c b/rpmsg_rpc_demo/rpmsg_workers.c new file mode 100644 index 0000000..2552cc3 --- /dev/null +++ b/rpmsg_rpc_demo/rpmsg_workers.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include + +#include "rpc_server_internal.h" +#include "rpmsg_rpc_service.h" + +static pthread_t pids[WORKERS]; + +static rpc_queue_t rx_q; + +static void rq_init(rpc_queue_t *rq, int size) +{ + memset(rq->q, 0, size * sizeof(req_t *)); + pthread_mutex_init(&rq->lock, NULL); + pthread_cond_init(&rq->cond, NULL); + rq->head = rq->tail = 0; + rq->size = size; +} + +static int __dequeue(rpc_queue_t *rq, req_t **ppreq) +{ + if (rq->head == rq->tail) { + *ppreq = NULL; + return -1; + } + *ppreq = rq->q[rq->head++]; + if (rq->head == rq->size) { + rq->head = 0; + } + return 0; +} + +static int __enqueue(rpc_queue_t *rq, req_t *req) +{ + if ((rq->tail + 1) % rq->size == rq->head) { + lprintf("ERROR: queue is full!\n"); + return -1; + } + rq->q[rq->tail++] = req; + if (rq->tail == rq->size) { + rq->tail = 0; + } + return 0; +} + +static int dequeue(rpc_queue_t *rq, req_t **req) +{ + int err = 0; + + (void)pthread_mutex_lock(&rq->lock); + err = __dequeue(rq, req); + if (err == -1) { + pthread_cond_wait(&rq->cond, &rq->lock); + } + (void)pthread_mutex_unlock(&rq->lock); + return err; +} + +static int enqueue(rpc_queue_t *rq, req_t *req) +{ + int err; + + (void)pthread_mutex_lock(&rq->lock); + err = __enqueue(rq, req); + if (!err) { + pthread_cond_signal(&rq->cond); + } + (void)pthread_mutex_unlock(&rq->lock); + return err; +} + +void enqueue_req(req_t *req) +{ + if (req == NULL) { + return; + } + enqueue(&rx_q, req); +} + +req_t *build_req(unsigned char *data, const struct rpc_service *service, struct rpc_instance *inst, void *priv) +{ + req_t *req = (req_t *)malloc(sizeof(req_t)); + if (req == NULL) { + return NULL; + } + req->data = data; + req->inst = inst; + req->service = service; + req->priv = priv; + return req; +} + +static void *worker_thread(void *args) { + req_t *req = NULL; + const struct rpc_service *service; + + (void)args; + while (1) { + dequeue(&rx_q, &req); + if (req == NULL) { + continue; + } + service = req->service; + if (service != NULL && service->cb_function != NULL) { + service->cb_function(req->data, req->inst, req->priv); + } + free(req); + } +} + +int workers_init() +{ + rq_init(&rx_q, MAX_QUEUE_SIZE); + for (int i = 0; i < WORKERS; i++) { + if (pthread_create(&pids[i], NULL, worker_thread, NULL) < 0) { + printf("worker thread create failed\n"); + return -1; + } + printf("worker %d created\n", i); + pthread_detach(pids[i]); + } + return 0; +} \ No newline at end of file -- Gitee