| /******************************************************************************* |
| * 版权所有 (C)2023, 中兴通讯股份有限公司。 |
| * |
| * 文件名称: nvserver_rpc.c |
| * 文件标识: nvserver_rpc.c |
| * 内容摘要: nvserver转接cap的nvserver |
| * |
| * 修改日期 版本号 修改标记 修改人 修改内容 |
| * ------------------------------------------------------------------------------ |
| * 2016/06/13 V1.0 Create 刘亚南 创建 |
| * |
| *******************************************************************************/ |
| |
| /******************************************************************************* |
| * 头文件 * |
| *******************************************************************************/ |
| #include <unistd.h> |
| #include <errno.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <dirent.h> |
| #include <string.h> |
| #include <sys/file.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <sys/ipc.h> |
| #include <sys/msg.h> |
| #include <sys/ioctl.h> |
| #include <unistd.h> |
| #include "sc_rpc.h" |
| #include "zxicbasic_api.h" |
| #include "rpmsg_zx29.h" |
| |
| /******************************************************************************* |
| * 常量定义 * |
| *******************************************************************************/ |
| |
| /******************************************************************************* |
| * 宏定义 * |
| *******************************************************************************/ |
| #define RPC_CHN_MAX_BUF_LEN 18432 |
| |
| /******************************************************************************* |
| * 数据类型定义 * |
| *******************************************************************************/ |
| |
| /******************************************************************************* |
| * 局部函数声明 * |
| *******************************************************************************/ |
| |
| /******************************************************************************* |
| * 局部静态变量定义 * |
| *******************************************************************************/ |
| |
| /******************************************************************************* |
| * 全局变量定义 * |
| *******************************************************************************/ |
| |
| /******************************************************************************* |
| * 局部函数实现 * |
| *******************************************************************************/ |
| |
| /******************************************************************************* |
| * 全局函数实现 * |
| *******************************************************************************/ |
| |
| int sc_rpc_open(const char *rpmsg_dev) |
| { |
| int fd; |
| fd = open(rpmsg_dev, O_RDWR); |
| |
| if (fd < 0) |
| { |
| perror("[rpc] open device fail\n"); |
| return -1; |
| } |
| |
| if (ioctl(fd, RPMSG_CREATE_CHANNEL, RPC_CHN_MAX_BUF_LEN) < 0) |
| { |
| perror("[rpc] RPMSG_CREATE_CHANNEL error\n"); |
| return -1; |
| } |
| |
| // 发送消息时,触发中断 |
| if (ioctl(fd, RPMSG_SET_INT_FLAG, NULL) < 0) |
| { |
| perror("[rpc] RPMSG_SET_INT_FLAG error\n"); |
| return -1; |
| } |
| |
| // 阻塞的方式读 |
| if (ioctl(fd, RPMSG_CLEAR_POLL_FLAG, NULL) < 0) |
| { |
| perror("[rpc] RPMSG_CLEAR_POLL_FLAG error\n"); |
| return -1; |
| } |
| |
| return fd; |
| } |
| |
| int sc_rpc_clear(int fd) |
| { |
| char tmp_buf[1024]; |
| int ret = -1; |
| |
| if (ioctl(fd, RPMSG_SET_POLL_FLAG, NULL) < 0) |
| { |
| perror("[rpc] RPMSG_SET_POLL_FLAG error\n"); |
| return -1; |
| } |
| |
| while (1) |
| { |
| ret = safe_read(fd, tmp_buf, sizeof(tmp_buf)); |
| if (ret == 0) |
| { |
| break; /* channel clear */ |
| } |
| else |
| { |
| printf("[rpc] UNBLOCK read len = %d!\n", ret); |
| } |
| } |
| if (ioctl(fd, RPMSG_CLEAR_POLL_FLAG, NULL) < 0) |
| { |
| perror("[rpc] RPMSG_CLEAR_POLL_FLAG error\n"); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int sc_rpc_send(int fd, T_sc_rpc_msg *data, unsigned int flag) |
| { |
| ssize_t ret; |
| T_sc_rpc_header *header = (T_sc_rpc_header *)data; |
| |
| ret = full_write(fd, data, sizeof(T_sc_rpc_header) + header->data_len); |
| if (ret != sizeof(T_sc_rpc_header) + header->data_len) |
| { |
| printf("[rpc] write error, len=%d != %d!\n", ret, (int)sizeof(T_sc_rpc_header)+ header->data_len); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int sc_rpc_recv(int fd, T_sc_rpc_msg *data, unsigned int timeout) |
| { |
| #if 1 |
| fd_set readfds; |
| ssize_t len; |
| int ret; |
| struct timeval timeout_t = {timeout, 0}; |
| int errNo = 0; |
| T_sc_rpc_header *header = 0; |
| |
| FD_ZERO(&readfds); |
| FD_SET(fd, &readfds); |
| |
| //ret = select(fd + 1, &readfds, NULL, NULL, &timeout_t); |
| do { |
| ret = select(fd + 1, &readfds, NULL, NULL, &timeout_t); |
| } while (ret < 0 && errno == EINTR); |
| |
| if (ret == 0) |
| { |
| printf("[error] nvrpc select timeout!\n"); |
| return -1; |
| } |
| else if(ret < 0) |
| { |
| printf("[error] nvrpc ret:%d\n", ret); |
| return -2; |
| } |
| |
| len = safe_read(fd, data, sizeof(T_sc_rpc_msg)); |
| header = (T_sc_rpc_header *)data; |
| if (len != sizeof(T_sc_rpc_header)+ header->data_len) |
| { |
| printf("[nvrpc] read error, len=%d != %d!\n", len, (int)sizeof(T_sc_rpc_header)+ header->data_len); |
| return -3; |
| } |
| |
| return 0; |
| #else |
| ssize_t ret; |
| |
| ret = full_read(fd, data, sizeof(T_sc_rpc_header)); |
| if (ret != sizeof(T_sc_rpc_header)) |
| { |
| printf("[rpc] read error, len=%d != %d!\n", ret, (int)sizeof(T_sc_rpc_header)); |
| return -1; |
| } |
| |
| return 0; |
| #endif |
| } |
| |
| int sc_rpc_close(int fd) |
| { |
| return close(fd); |
| } |