blob: 7e4d01251a7073a3a834e2acd7c642fc75a255aa [file] [log] [blame]
/*******************************************************************************
* °æÈ¨ËùÓÐ (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 <assert.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 "nvserver.h"
#include "nv_typedef.h"
#include <message.h>
#include "sc_rpc.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*******************************************************************************
* ³£Á¿¶¨Òå *
*******************************************************************************/
/*******************************************************************************
* ºê¶¨Òå *
*******************************************************************************/
#define RPC_RPMSG_DEV "/dev/rpmsg8"
/*******************************************************************************
* Êý¾ÝÀàÐͶ¨Òå *
*******************************************************************************/
/*******************************************************************************
* ¾Ö²¿º¯ÊýÉùÃ÷ *
*******************************************************************************/
/*******************************************************************************
* ¾Ö²¿¾²Ì¬±äÁ¿¶¨Òå *
*******************************************************************************/
/*******************************************************************************
* È«¾Ö±äÁ¿¶¨Òå *
*******************************************************************************/
static int g_rpc_fd = -1;
static unsigned int g_msgRcvCnt = 0;
static unsigned int g_msgRcvErrCnt = 0;
static unsigned int g_msgSndCnt = 0;
static unsigned int g_msgSndErrCnt = 0;
/*******************************************************************************
* ¾Ö²¿º¯ÊýʵÏÖ *
*******************************************************************************/
/*******************************************************************************
* ¹¦ÄÜÃèÊö: analyMsg
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) msgrecv:½ÓÊÕÏûÏ¢
* (´«³ö²ÎÊý) msgsnd:·¢ËÍÏûÏ¢
* ·µ »Ø Öµ: 0±íʾ³É¹¦
* ÆäËü˵Ã÷: void
*******************************************************************************/
static void analyMsg(T_NV_MSG_INFO *msgrecv, T_NV_MSG_RESULT *msgsnd, T_sc_rpc_msg *rpc_data, T_sc_rpc_msg *rpc_data2)
{
unsigned int timeout = 10;
int send_once_flag = 0;
int ret;
rpc_data->header.msg_type = RPC_MSG_TYPE_REQUEST;
rpc_data->header.func_id = RPC_FUNC_ID_NV;
rpc_data->header.data_len = sizeof(T_NV_MSG_INFO) - NV_MAX_FILE_LEN - NV_MAX_KEY_LEN - NV_MAX_VAL_LEN;
rpc_data->header.file_len = strlen(msgrecv->file) + 1;
rpc_data->header.data_len += rpc_data->header.file_len;
memcpy(rpc_data->data, msgrecv, rpc_data->header.data_len);
rpc_data->header.key_len = strlen(msgrecv->key) + 1;
memcpy(rpc_data->data+rpc_data->header.data_len, msgrecv->key, rpc_data->header.key_len);
rpc_data->header.data_len += rpc_data->header.key_len;
rpc_data->header.value_len = strlen(msgrecv->value);
if (rpc_data->header.value_len > 0)
{
rpc_data->header.value_len += 1;
memcpy(rpc_data->data+rpc_data->header.data_len, msgrecv->value, rpc_data->header.value_len);
rpc_data->header.data_len += rpc_data->header.value_len;
}
do
{
if (send_once_flag == 0)
{
ret = sc_rpc_send(g_rpc_fd, rpc_data, 0);
if (ret == 0)
{
send_once_flag = 1; // send success
}
else
{
assert(0); // send fail
}
}
ret = sc_rpc_recv(g_rpc_fd, rpc_data2, timeout);
if (ret == 0)
{
break; // recv success and break
}
} while (1); //µÈ´ýÍê³É
if (rpc_data2->header.msg_type != RPC_MSG_TYPE_REPLY)
assert(0);
memcpy(msgsnd, rpc_data2->data, rpc_data2->header.data_len);
}
static int nv_rpc_wait_ready(int fd)
{
T_sc_rpc_header *rpc_data;
unsigned int timeout = 100; // ms
rpc_data = malloc(sizeof(T_sc_rpc_header));
if (rpc_data == NULL)
return -1;
while(1)
{
rpc_data->msg_type = RPC_MSG_TYPE_READY;
if (write(fd, rpc_data, sizeof(T_sc_rpc_header)) == sizeof(T_sc_rpc_header))
break;
else
usleep(timeout * 1000);
}
free(rpc_data);
return 0;
}
/*******************************************************************************
* È«¾Öº¯ÊýʵÏÖ *
*******************************************************************************/
/*******************************************************************************
* ¹¦ÄÜÃèÊö: main
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) void
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: void
* ÆäËü˵Ã÷: void
*******************************************************************************/
int nvserver_main(int argc, char *argv[])
{
int msgId = 0;
T_NV_MSG_INFO rcvBuf;
T_NV_MSG_RESULT sndBuf;
struct msqid_ds msgInfo;
T_sc_rpc_msg *rpc_data;
T_sc_rpc_msg *rpc_data2;
long pid_backup; /* app-libnvram pid backup */
prctl(PR_SET_NAME, "nvserver_rpc", 0, 0, 0);
memset(&msgInfo, 0, sizeof(msgInfo));
g_rpc_fd = sc_rpc_open(RPC_RPMSG_DEV);
msgId = msgget(MODULE_ID_NV, IPC_CREAT | 0600);
if (-1 == msgId)
{
printf("nvserver error: msgget msgId fail, errno = %d\n", errno);
return -1;
}
if (-1 != msgctl(msgId, IPC_STAT, &msgInfo))
{
msgInfo.msg_qbytes = 262144; // 256k
if (-1 == msgctl(msgId, IPC_SET, &msgInfo))
{
printf("nvserver error: msgctl msgId fail, errno = %d\n", errno);
}
}
rpc_data = malloc(sizeof(T_sc_rpc_msg));
if (rpc_data == NULL)
{
perror("[error]nvrpc malloc error\n");
return -2;
}
rpc_data2 = malloc(sizeof(T_sc_rpc_msg));
if (rpc_data2 == NULL)
{
perror("[error]nvrpc malloc2 error\n");
free(rpc_data);
return -3;
}
if (nv_rpc_wait_ready(g_rpc_fd) < 0)
{
assert(0);
}
sc_rpc_clear(g_rpc_fd);
printf("apnv and nv-rpc-daemon are ready both.");
// ÏûÏ¢½»»¥
while (1)
{
memset(&rcvBuf, 0, sizeof(rcvBuf));
memset(&sndBuf, 0, sizeof(sndBuf));
if (g_msgRcvCnt != g_msgSndCnt)
{
printf("[nvserver_rpc]Rcv:%u Snd:%u RcvErr:%u SndErr:%u\n", g_msgRcvCnt, g_msgSndCnt, g_msgRcvErrCnt, g_msgSndErrCnt);
assert(0);
}
if (-1 == msgrcv(msgId, &rcvBuf, sizeof(T_NV_MSG_INFO) - sizeof(long), MSG_TYPE_NV, 0))
{
g_msgRcvErrCnt++;
printf("nvserver error: nvserver msgrcv fail, errno = %d!\n", errno);
continue;
}
//printf("apnv nvserver_rpc msgrcv pid:%d\n", rcvBuf.pid);
pid_backup = rcvBuf.pid;
g_msgRcvCnt++; /* msgrcv success count */
analyMsg(&rcvBuf, &sndBuf, rpc_data, rpc_data2);
//printf("apnv nvserver_rpc msgsnd pid:%d, backup:%d\n", sndBuf.msgType, pid_backup);
if (-1 == msgsnd(msgId, &sndBuf, sizeof(T_NV_MSG_RESULT) - sizeof(long), 0))
{
g_msgSndErrCnt++;
printf("nvserver error: nvserver msgsnd fail, errno = %d!\n", errno);
continue;
}
g_msgSndCnt++; /* msgsnd success count */
if (sndBuf.msgType != pid_backup)
{
assert(0);
}
}
free(rpc_data);
free(rpc_data2);
return (0);
}
#ifdef __cplusplus
}
#endif