blob: eb1efeeff5f28661a0bbcf477e445f359092128e [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 FOTA_AB
#include "zxic_fota_ab_upgrade.h"
#endif
#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_header *rpc_data, T_sc_rpc_header *rpc_data2)
{
unsigned int timeout = 10;
int try_cnt = 0;
memset(rpc_data, 0, sizeof(T_sc_rpc_header));
memset(rpc_data2, 0, sizeof(T_sc_rpc_header));
rpc_data->msg_type = RPC_MSG_TYPE_REQUEST;
rpc_data->func_id = RPC_FUNC_ID_NV;
rpc_data->data_len = sizeof(T_NV_MSG_INFO);
memcpy(rpc_data->data, msgrecv, sizeof(T_NV_MSG_INFO));
do
{
if (try_cnt > 0)
{
sc_rpc_clear(g_rpc_fd);
}
sc_rpc_send(g_rpc_fd, rpc_data, 0);
try_cnt++;
//sleep(1);
//continue;
} while (0 != sc_rpc_recv(g_rpc_fd, rpc_data2, timeout)); //µÈ´ýÍê³É
if (rpc_data2->msg_type != RPC_MSG_TYPE_REPLY)
assert(0);
memcpy(msgsnd, rpc_data2->data, sizeof(T_NV_MSG_RESULT));
}
static int nv_rpc_wait_ready(int fd)
{
T_sc_rpc_header *rpc_data;
unsigned int timeout = 200; // ms
int write_flag = 1;
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_flag)
{
if (write(fd, rpc_data, sizeof(T_sc_rpc_header)) != 0)
write_flag = 0; // write ok and write sonly once
}
if (read(fd, rpc_data, sizeof(T_sc_rpc_header)) == 0)
{
usleep(timeout * 1000);
continue;
}
break; /* read some data mean channel ok */
}
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_header *rpc_data;
T_sc_rpc_header *rpc_data2;
long pid_backup; /* app-libnvram pid backup */
prctl(PR_SET_NAME, "nvserver", 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_header));
if (rpc_data == NULL)
{
perror("[error]nvrpc malloc error\n");
return -2;
}
rpc_data2 = malloc(sizeof(T_sc_rpc_header));
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