Files
OpenCellular/firmware/host/ocmw/ocmw_core.c
2019-03-05 11:40:59 +05:30

847 lines
30 KiB
C

/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/* OC includes */
#include <logger.h>
#include <ocmw_core.h>
#include <ocmw_eth_comm.h>
#include <ocmw_uart_comm.h>
#include <ocwdg_daemon.h>
#include <postframe.h>
#include <occli_common.h>
#include <ocmw_occli_comm.h>
static int32_t loopCountPost = 0;
extern debugI2CData I2CInfo;
extern debugMDIOData MDIOInfo;
extern ethTivaClient clientInfo;
extern uint8_t mcuMsgBuf[OCMP_MSG_SIZE];
extern ocmwSchemaSendBuf *ecSendBufBkp;
int32_t responseCount = 0;
static int8_t s_paramInfoBackup[MAX_PARM_COUNT];
static int32_t s_semTimeOut;
static int32_t s_totalSubsystem = 0;
extern const Component sys_schema[];
subSystemInfo systemInfo;
extern ocwarePostResultData ocwarePostArray[TEMP_STR_BUFF_SIZE];
extern uint8_t ocwarePostArrayIndex;
int8_t alertRecord = 1;
extern int8_t alertFlag;
ocwarePostReplyCode ocmwReplyCode[] = {
/* Message Type, reply code, Description */
{OCMP_MSG_TYPE_POST, POST_DEV_NOSTATUS , "POST DEV NOSTATUS"},
{OCMP_MSG_TYPE_POST, POST_DEV_MISSING, "DEV MISSING"},
{OCMP_MSG_TYPE_POST, POST_DEV_ID_MISMATCH, "DEV ID MISMATCH"},
{OCMP_MSG_TYPE_POST, POST_DEV_FOUND, "DEV FOUND"},
{OCMP_MSG_TYPE_POST, POST_DEV_CFG_DONE, "CFG DONE"},
{OCMP_MSG_TYPE_POST, POST_DEV_NO_CFG_REQ, "NO CFG REQUIRED"},
{OCMP_MSG_TYPE_POST, POST_DEV_CFG_FAIL, "CFG FAILED"},
{OCMP_MSG_TYPE_POST, POST_DEV_FAULTY, "FAULT"},
{OCMP_MSG_TYPE_POST, POST_DEV_CRITICAL_FAULT, "CRITICAL FAULT"},
{OCMP_MSG_TYPE_POST, POST_DEV_NO_DRIVER_EXIST, "NO DRIVER EXIST"}
};
/******************************************************************************
* Function Name : ocmw_free_global_pointer
* Description : This Function used to free the memory allocated for
* global variable
* Input(s) : ptr
* Output(s) :
******************************************************************************/
void ocmw_free_global_pointer(void **ptr)
{
if(*ptr != NULL) {
free(*ptr);
*ptr = NULL;
}
return;
}
/******************************************************************************
* Function Name : ocmw_retrieve_post_results_count
* Description : This Function used to count the post structure size
* Input(s) : postResult
* Output(s) :
******************************************************************************/
char ocmw_retrieve_post_results_count (ocwarePostResults *postResult)
{
postResult->count =
sizeof(ocwarePostArray)/sizeof(ocwarePostArray[0]);
return SUCCESS;
}
/******************************************************************************
* Function Name : ocmw_retrieve_post_results
* Description : This Function used to get the post results
* Input(s) : postResult
* Output(s) :
******************************************************************************/
char ocmw_retrieve_post_results (ocwarePostResults *postResult)
{
memcpy(postResult->results, ocwarePostArray,
postResult->count * sizeof(ocwarePostResultData));
memset(ocwarePostArray,0,sizeof(ocwarePostResultData));
return SUCCESS;
}
/******************************************************************************
* Function Name : ocmw_retrieve_reply_code_desc
* Description : This Function used to get the reply code based the post
result data
* Input(s) : replyCode
* Output(s) :
******************************************************************************/
char ocmw_retrieve_reply_code_desc (ocwarePostReplyCode *replyCode)
{
int32_t postSize = 0;
int32_t sysIndex = 0;
postSize = sizeof(ocmwReplyCode)/sizeof(ocmwReplyCode[0]);
for (sysIndex = 0; sysIndex < postSize; sysIndex++) {
if ((ocmwReplyCode[sysIndex].msgtype == replyCode->msgtype) &&
(ocmwReplyCode[sysIndex].replycode == replyCode->replycode)) {
memset(replyCode->desc, 0, OCMW_POST_DESC_SIZE);
strncpy(replyCode->desc, ocmwReplyCode[sysIndex].desc,
strlen(ocmwReplyCode[sysIndex].desc));
}
}
return SUCCESS;
}
/******************************************************************************
* Function Name : ocmw_update_post_status
* Description : This Function used to update the post results
* Input(s) : subsystem, devsn, status
* Output(s) :
******************************************************************************/
char ocmw_update_post_status(uint8_t subsystem, uint8_t devsn,
uint8_t status)
{
int32_t sysIndex = 0;
for (sysIndex = 0; sysIndex < ocwarePostArrayIndex; sysIndex++) {
if ((ocwarePostArray[sysIndex].subsystem == subsystem) &&
(ocwarePostArray[sysIndex].devsn == devsn)) {
ocwarePostArray[sysIndex].status = status;
}
}
return SUCCESS;
}
/******************************************************************************
* Function Name : ocmw_init
* Description : This Function used to initialize the mware
* Input(s) :
* Output(s) :
******************************************************************************/
int32_t ocmw_init()
{
#ifdef INTERFACE_ETHERNET
pthread_t ethMsgPaserThreadId;
#else
pthread_t uartMsgPaserThreadId;
#endif
int32_t ret = 0;
ret = sem_init(&semecMsgParser, 0, 0);
if (ret != 0) {
logerr("sem_init(): semecMsgParser failed.");
return ret;
}
ret = ocwdg_init();
if (ret != 0) {
logerr("ocwdg_init() failed.");
return ret;
}
ret = sem_init(&semCliReturn, 0, 0);
if (ret != 0) {
logerr("sem_init(): semCliReturn failed.");
return ret;
}
ret = sem_init(&semCommandPost, 0, 0);
if (ret != 0) {
logerr("sem_init(): semCommandPost failed.");
return ret;
} else {
#ifdef INTERFACE_ETHERNET
/* Create the msg parser thread to parse
* the msg coming from ethernet ec to ap
*/
ret = pthread_create(&ethMsgPaserThreadId, NULL,
ocmw_thread_ethmsgparser, NULL);
if (ret != 0) {
return ret;
}
#else
/* Create the msg parser thread to parse
* the msg coming from uart ec to ap
*/
ret = pthread_create(&uartMsgPaserThreadId, NULL,
ocmw_thread_uartmsgparser, NULL);
if (ret != 0) {
logerr("pthread_create() failed.");
}
#endif /* INTERFACE_ETHERNET */
}
return ret;
}
/**************************************************************************
* Function Name : ocmw_tokenize_class_str
* Description : This Function used to extract the Subsystem,componentID, Messagetype,
* parameter and Subcomponent from the param string
* Input(s) : str
* Output(s) : msgFrame
***************************************************************************/
static int32_t ocmw_tokenize_class_str( const int8_t *str,
strMsgFrame *msgFrame, uint8_t msgtype)
{
char *token;
int32_t count = 0;
char *tempstr = (char *)malloc(PARAM_STR_MAX_BUFF_SIZE);
if(str == NULL)
return FAILED;
memset(tempstr,0,PARAM_STR_MAX_BUFF_SIZE);
memcpy(tempstr, str,PARAM_STR_MAX_BUFF_SIZE);
memset(msgFrame,0,sizeof(strMsgFrame));
token = strtok(tempstr, " .");
if (token == NULL)
return FAILED;
if (msgtype == OCMP_MSG_TYPE_COMMAND) {
if ((strcmp(token,"set") != 0) &&
((strcmp(token,"get") != 0))) {
strcpy(msgFrame->parameter, token);
while (token) {
if (count == 1) {
strcpy(msgFrame->subsystem, token);
} else if (count == 2) {
strcpy(msgFrame->component, token);
}
token = strtok(NULL, " .");
count ++;
if (token == NULL)
break;
}
if (count == 2) {
strcpy(msgFrame->component, "comp_all");
}
} else {
while (token) {
if (count == 1) {
strcpy(msgFrame->subsystem, token);
} else if (count == 2) {
strcpy(msgFrame->component, token);
} else if (count == 3) {
strcpy(msgFrame->subcomponent, token);
} else if (count == 0) {
strcpy(msgFrame->parameter, token);
}
token = strtok(NULL, " .");
count ++;
if (token == NULL)
break;
}
if (count == 2) {
strcpy(msgFrame->component, "comp_all");
}
}
} else {
strcpy(msgFrame->subsystem, token);
while (token) {
if (count == 1) {
strcpy(msgFrame->component, token);
} else if (count == 2) {
strcpy(msgFrame->msgtype, token);
} else if (count == 3) {
strcpy(msgFrame->subcomponent, token);
} else if(count == 4) {
strcpy(msgFrame->parameter, token);
}
token = strtok(NULL, " .");
count++;
}
if (count < 5) {
strcpy(msgFrame->parameter, msgFrame->subcomponent);
}
if (strncmp (msgFrame->component, "post", strlen("post")) == 0) {
strcpy(msgFrame->component, "post");
strcpy(msgFrame->msgtype, "post");
strcpy(msgFrame->parameter, msgFrame->subcomponent);
}
}
free(tempstr);
return SUCCESS;
}
/******************************************************************************
* Function Name : ocmw_fill_payload_data_for_commands
* Description : Packetize the msg payload for commands
* Input(s) :strTokenArray, msgFrame, ecMsgFrame, paramVal
* Output(s) :
******************************************************************************/
void ocmw_fill_payload_data_for_commands(char * strTokenArray[],
strMsgFrame *msgFrame, OCMPMessageFrame *ecMsgFrame, void* paramVal)
{
uint8_t pos = 0;
if (msgFrame == NULL) {
return;
}
// Handling sending data for test module
if (strncmp("testmodule", msgFrame->subsystem,
strlen(msgFrame->subsystem)) == 0 ) {
if ((strncmp(strTokenArray[1], "send", strlen("send")) == 0) ||
(strncmp(strTokenArray[1], "dial", strlen("dial")) == 0)) {
memcpy(&ecMsgFrame->message.info[0], paramVal,
MAX_PARM_COUNT);
} else {
memset(ecMsgFrame->message.info, 0, MAX_PARM_COUNT);
}
}
// Handling ethernet commands
if (strncmp("ethernet", msgFrame->subsystem,
strlen(msgFrame->subsystem)) == 0 ) {
if(strstr(strTokenArray[1], "loopBk")) {
memcpy(&ecMsgFrame->message.info[0], paramVal, sizeof(uint8_t));
} else if ((strncmp(strTokenArray[1], "en_pktGen",
strlen("en_pktGen")) == 0)) {
memcpy(&ecMsgFrame->message.info[0],
(uint16_t *)paramVal, sizeof(uint16_t));
} else if ((strncmp(strTokenArray[1], "en_tivaClient",
strlen("en_tivaClient")) == 0)) {
ecMsgFrame->message.info[pos] = (uint8_t) clientInfo.ip[0];
ecMsgFrame->message.info[pos + 1] = (uint8_t) clientInfo.ip[1];
ecMsgFrame->message.info[pos + 2] = (uint8_t) clientInfo.ip[2];
ecMsgFrame->message.info[pos + 3] = (uint8_t) clientInfo.ip[3];
ecMsgFrame->message.info[pos + 4] = (uint8_t)
(clientInfo.port & 0xff);
ecMsgFrame->message.info[pos + 5] = (uint8_t)
((clientInfo.port & 0xff00) >> 8);
ecMsgFrame->message.info[pos + 6] = (uint8_t) clientInfo.noOfRepeat;
}
}
}
/******************************************************************************
* Function Name : ocmw_msg_packetize_and_send
* Description : Packetize the msg frame before sending data to ec
* Input(s) :actionType, msgType, paramStr, interface, paramVal
* Output(s) :
******************************************************************************/
int32_t ocmw_msg_packetize_and_send(char * strTokenArray[], uint8_t action,
uint8_t msgType, const int8_t * paramStr, uint8_t interface, void* paramVal)
{
int32_t ret = 0;
int32_t paramValue = 0;
int32_t dataSize = 0;
int32_t pos = 0;
int32_t paramValLen = 0;
int32_t paramValFlag = 0;
const int8_t *tempStr = paramStr;
strMsgFrame msgFramestruct;
OCMPMessageFrame ecMsgFrame;
OCMPHeader ecMsgHeader;
OCMPMessage ecCoreMsg;
static int32_t loopCountSend = 0;
ocmwSchemaSendBuf ecSendBuf;
paramValLen = strlen((char *)paramVal);
if (!((msgType == OCMP_MSG_TYPE_COMMAND) &&
((strcmp(strTokenArray[1], "get")) ||
(strncmp(strTokenArray[1], "set", strlen("get")) == 0)))) {
if (paramValLen == 1 || paramValLen <= 5) {
logdebug ("Paramvalue is of integer type : %d\n", atoi( paramVal));
}
else {
paramValFlag = 1;
logdebug ("Paramvalue is of string type : %s \n", (char *)paramVal);
}
} else {
paramValFlag = 1;
logdebug ("Paramvalue is of string type : %s \n", (char *)paramVal);
}
if (paramStr == NULL) {
logdebug(" Paramstr is NULL \n");
return ret = FAILED;
} else {
ocmw_tokenize_class_str(tempStr,&msgFramestruct,msgType);
if (msgType == OCMP_MSG_TYPE_COMMAND) {
ret = ocmw_parse_command_msgframe(sys_schema, &msgFramestruct,
action, &ecSendBuf);
} else if (msgType == OCMP_MSG_TYPE_POST) {
strcpy((char*)s_paramInfoBackup,msgFramestruct.parameter);
ret = ocmw_parse_post_msgframe(sys_schema, &msgFramestruct,
action, &ecSendBuf);
} else {
ret = ocmw_parse_msgframe(sys_schema, &msgFramestruct, action,
&ecSendBuf);
}
if (ret < 0) {
return ret;
}
}
/* Frame the header packet for sending data to ec */
ecMsgHeader.ocmpFrameLen = 0;
ecMsgHeader.ocmpInterface = interface;
ecMsgHeader.ocmpSeqNumber = 0;
ecMsgHeader.ocmpSof = OCMP_MSG_SOF;
ecMsgHeader.ocmpTimestamp = 0;
/* Frame the Core packet for sending data to ec */
ecCoreMsg.action = ecSendBuf.actionType;
ecCoreMsg.msgtype = ecSendBuf.msgType;
ecCoreMsg.componentID = ecSendBuf.componentId;
ecCoreMsg.parameters = ecSendBuf.paramId;
ecCoreMsg.subsystem = ecSendBuf.subsystem;
/* Construct the final packet */
ecMsgFrame.header = ecMsgHeader;
ecMsgFrame.message = ecCoreMsg;
/* Populate the Core packet payload */
ecMsgFrame.message.info = (int8_t *) malloc(
sizeof(int8_t) * MAX_PARM_COUNT);
if (ecMsgFrame.message.info == NULL) {
logdebug("\n Memory allocation failed \n");
return ret = FAILED;
}
memset(ecMsgFrame.message.info, 0, MAX_PARM_COUNT);
if ((msgType == OCMP_MSG_TYPE_POST) &&
(strncmp(strTokenArray[1], "set", strlen("set"))== 0)) {
logdebug("OCMP_MSG_TYPE_POST:ENABLE:%s()\n", __func__);
}
if(strncmp(msgFramestruct.subsystem,"debug",strlen("debug")) == 0) {
if (strncmp(msgFramestruct.component,"I2C",
strlen("I2C")) == 0) {
if((strncmp(strTokenArray[1], "get", strlen("get")) == 0)) {
dataSize = 3 * sizeof (int8_t);
} else {
dataSize = sizeof(debugI2CData);
}
} else if (strncmp(msgFramestruct.component,"ethernet",
strlen("ethernet")) == 0) {
if((strncmp(strTokenArray[1], "get", strlen("get")) == 0)) {
dataSize = sizeof (uint16_t);
} else {
dataSize = sizeof(debugMDIOData);
}
} else {
if((strncmp(strTokenArray[1], "get", strlen("get")) == 0)) {
dataSize = sizeof (int8_t);
} else {
dataSize = sizeof(debugGPIOData);
}
}
paramValLen = dataSize;
} else {
dataSize = ecSendBuf.paramSize;
}
if((strncmp(strTokenArray[1], "set", strlen("set")) == 0) &&
(msgType != OCMP_MSG_TYPE_POST)) {
pos = ecSendBuf.paramPos;
if (paramValFlag == 0) {
paramValue = atoi( paramVal);
memcpy(&ecMsgFrame.message.info[pos], &paramValue, dataSize);
} else {
if (strncmp(msgFramestruct.component,"I2C",
strlen("I2C")) == 0) {
ecMsgFrame.message.info[pos] = I2CInfo.slaveAddress;
ecMsgFrame.message.info[pos + 1] =
I2CInfo.numOfBytes;
ecMsgFrame.message.info[pos + 2] =
I2CInfo.regAddress;
if (I2CInfo.numOfBytes == 1) {
ecMsgFrame.message.info[pos + 3] =
(uint8_t)I2CInfo.regValue;
} else {
ecMsgFrame.message.info[pos + 4] =
(uint8_t)(I2CInfo.regValue & 0xff);
ecMsgFrame.message.info[pos + 3] =
(uint8_t)
((I2CInfo.regValue & 0xff00) >> 8);
}
} else if (strncmp(msgFramestruct.component,"ethernet",
strlen("ethernet")) == 0) {
ecMsgFrame.message.info[pos] = (uint8_t)
(MDIOInfo.regAddress & 0xff);
ecMsgFrame.message.info[pos + 1] = (uint8_t)
((MDIOInfo.regAddress & 0xff00) >> 8);
ecMsgFrame.message.info[pos + 2] =
(uint8_t)(MDIOInfo.regValue & 0xff);
ecMsgFrame.message.info[pos + 3] =
(uint8_t)
((MDIOInfo.regValue & 0xff00) >> 8);
} else {
memcpy(&ecMsgFrame.message.info[pos], (char *) paramVal,
paramValLen);
}
}
}
if((strncmp(strTokenArray[1], "get", strlen("get")) == 0) &&
(ecMsgFrame.message.subsystem == DEBUG_SUBSYSTEM_NBR)) {
pos = ecSendBuf.paramPos;
memcpy(&ecMsgFrame.message.info[pos], (char *) paramVal,
paramValLen);
}
//Fill payload data for commands
ocmw_fill_payload_data_for_commands(&strTokenArray[0], &msgFramestruct,
&ecMsgFrame, paramVal);
if (!((msgType == OCMP_MSG_TYPE_POST) &&
(strncmp(strTokenArray[1], "get", strlen("get")) == 0))) {
ocmw_send_msg(ecMsgFrame, interface);
}
/* Wait on the POST msgtype semaphore */
if ((msgType == OCMP_MSG_TYPE_POST) &&
((strncmp(strTokenArray[1], "get", strlen("get")) == 0))) {
ocmw_frame_subsystem_from_schema(sys_schema, &systemInfo);
s_totalSubsystem = systemInfo.totalNum;
ocmw_frame_postTable_from_schema(sys_schema);
loopCountSend = systemInfo.Info[0].number;
loopCountPost = systemInfo.Info[0].number;
while(loopCountSend < s_totalSubsystem) {
memset(&(ecMsgFrame.message.info[0]),
loopCountSend, 1);
/* Send the message to ec */
ocmw_send_msg(ecMsgFrame, interface);
loopCountSend++;
/* Waiting on the lock to be released by receiving thread */
ret = ocmw_sem_wait(&semCommandPost, OCMW_TIMED_WAIT_INDEX);
if (ret != 0) {
perror("sem_wait");
}
/*
* Logic to check if firmware has sent post data currently we
* expect only actiontype mismatch other errors can be taken care
* as required
*/
if (loopCountSend != loopCountPost) {
logerr("POST: Error : Actiontype mismatch in message from FW");
free(ecMsgFrame.message.info);
return FAILED;
}
}
loopCountPost = systemInfo.Info[0].number;
loopCountSend = systemInfo.Info[0].number;
}
free(ecMsgFrame.message.info);
/* Semaphore wait function call */
ret = ocmw_sem_wait(&semCliReturn, OCMW_TIMED_WAIT_INDEX);
if (ret == FAILED) {
logdebug("Message is not received from EC: releasing the lock \n");
return ret;
}
if (responseCount == 0) {
ret = FAILED;
} else {
ret = 0;
responseCount = 0;
}
logdebug(" \n Semaphore released : %s() \n", __func__);
return ret;
}
/******************************************************************************
* Function Name : ocmw_thread_uartmsgparser
* Description : Thread to parse the data coming from EC to AP
* through uart communication
* Input(s) : pthreadData
* Output(s) :
******************************************************************************/
void * ocmw_thread_uartmsgparser(void *pthreadData)
{
while (1) {
/* Waiting on the semecMsgParser to be released by uart */
sem_wait(&semecMsgParser);
ocmw_ec_msgparser();
}
}
/******************************************************************************
* Function Name : ocmw_thread_ethmsgparser
* Description : Thread to parse the data coming from EC to AP
* through ethernet communication
* Input(s) : pthreadData
* Output(s) :
******************************************************************************/
void * ocmw_thread_ethmsgparser(void *pthreadData)
{
int8_t ethRecvBuf[OCMP_MSG_SIZE] = {0};
logdebug("Ethernet task created \n");
while (1) {
memset(ethRecvBuf, 0, sizeof(ethRecvBuf));
ocmw_recv_eth_msgfrom_ec(ethRecvBuf, sizeof(ethRecvBuf),OCMW_EC_DEV);
ocmw_ec_msgparser();
}
}
/******************************************************************************
* Function Name : ocmw_ec_msgparser
* Description : parse the data coming from EC to AP
* Input(s) :
* Output(s) :
******************************************************************************/
void ocmw_ec_msgparser(void)
{
uint8_t msgType = 0;
uint8_t actionType = 0;
uint8_t subsystemPost = 0;
uint8_t devsn = 0;
uint8_t status = 0;
uint8_t indexCount = 0;
uint16_t paramInfo = 0;
int32_t ret = 0;
int32_t sendPktNonpayloadSize = 0;
sMsgParam dmsgFrameParam;
OCMPMessageFrame ecReceivedMsg;
alertRecord = 1;
sendPktNonpayloadSize = (sizeof(OCMPMessage) - sizeof(void *)
+ sizeof(OCMPHeader));
ecReceivedMsg.message.info = (void *) malloc(
sizeof(char) * MAX_PARM_COUNT);
if (ecReceivedMsg.message.info == NULL) {
logerr("Memory allocation failed for "
"ecReceivedMsg.message.info \n");
return;
}
/* parse the data packet */
memcpy((void *) &ecReceivedMsg, (void *) mcuMsgBuf, sendPktNonpayloadSize);
memcpy(ecReceivedMsg.message.info, &mcuMsgBuf[sendPktNonpayloadSize],
MAX_PARM_COUNT);
msgType = ecReceivedMsg.message.msgtype;
actionType = ecReceivedMsg.message.action;
paramInfo = ecReceivedMsg.message.parameters;
printf("Received from ec :\n");
for (indexCount = 0; indexCount < OCMP_MSG_SIZE; indexCount++) {
printf("0x%x ", mcuMsgBuf[indexCount]);
}
printf("\n");
/*
* Alerts handling
*/
if ((msgType == OCMP_MSG_TYPE_ALERT) || (alertFlag > 0)) {
ocmw_handle_alert_msg(sys_schema, &ecReceivedMsg, &alertRecord);
responseCount++;
ocmw_free_global_pointer((void**)&ecSendBufBkp);
return;
}
/* In case of timeout, return from the thread
* without processing the data to avoid sync issue.
*/
if (s_semTimeOut) {
s_semTimeOut = 0;
ocmw_free_global_pointer((void**)&ecSendBufBkp);
return;
}
if ((msgType == OCMP_MSG_TYPE_POST) &&
strcmp((char*)s_paramInfoBackup,"set") == 0) {
if (actionType == OCMP_AXN_TYPE_REPLY) {
responseCount++;
}
/* Release the lock on which cli is waiting */
ocmw_free_global_pointer((void**)&ecSendBufBkp);
sem_post(&semCliReturn);
return;
}
/* Release the lock on the POST msgtype semaphore */
if (msgType == OCMP_MSG_TYPE_POST) {
if (actionType != OCMP_AXN_TYPE_REPLY) {
ocmw_free_global_pointer((void**)&ecSendBufBkp);
ret = sem_post(&semCommandPost);
if (ret != 0) {
perror("sem_wait");
}
return;
}
for (; loopCountPost < s_totalSubsystem;) {
/* Waiting on the lock to be released by receiving thread */
for (indexCount = 0; indexCount < paramInfo; indexCount++) {
subsystemPost = ecReceivedMsg.message.info[indexCount
* POST_MAIN_PAYLOAD_SIZE
+ POST_MAIN_PAYLOAD_SUBSYSTEM_OFFSET];
devsn = ecReceivedMsg.message.info[indexCount
* POST_MAIN_PAYLOAD_SIZE
+ POST_MAIN_PAYLOAD_DEVSN_OFFSET];
status = ecReceivedMsg.message.info[indexCount
* POST_MAIN_PAYLOAD_SIZE
+ POST_MAIN_PAYLOAD_STATUS_OFFSET];
ret = ocmw_update_post_status(subsystemPost, devsn, status);
}
loopCountPost++;
ret = sem_post(&semCommandPost);
if (ret != 0) {
perror("sem_wait");
}
if (loopCountPost < s_totalSubsystem) {
/* Do Nothing */
} else {
/* Release the lock on which watchdog thread is waiting */
responseCount++;
ocmw_free_global_pointer((void**)&ecSendBufBkp);
sem_post(&semCliReturn);
}
return;
}
}
memset(&dmsgFrameParam, 0, sizeof(sMsgParam));
ocmw_deserialization_msgframe(sys_schema, &dmsgFrameParam, &ecReceivedMsg);
/* Released the lock so that cli is released from the lock */
if (ecReceivedMsg.message.info) {
free(ecReceivedMsg.message.info);
}
sem_post(&semCliReturn);
}
/******************************************************************************
* Function Name : ocmw_send_msg
* Description : Send the message from ap to ec via uart/usb/ethernet.
* Input(s) : ecMsgFrame, interface
* Output(s) :
******************************************************************************/
int32_t ocmw_send_msg(OCMPMessageFrame ecMsgFrame, uint8_t interface)
{
int32_t ret = 0;
int32_t sentDev = OCMW_EC_DEV;
#ifdef INTERFACE_STUB_EC
int8_t ethRecvBuf[OCMP_MSG_SIZE];
#endif
switch (interface) {
case OCMP_COMM_IFACE_UART:
case OCMP_COMM_IFACE_USB:
/* Send the packetize data to ec through uart*/
ret = ocmw_send_uart_msg_to_ec((uint8_t *) &ecMsgFrame,
OCMP_MSG_SIZE);
break;
case OCMP_COMM_IFACE_ETHERNET:
sentDev = OCMW_EC_DEV;
#ifdef INTERFACE_STUB_EC
sentDev = OCMW_EC_STUB_DEV;
#else
sentDev = OCMW_EC_DEV;
#endif
/* Send the packetize data to ec through ethernet*/
ret = ocmw_send_eth_msgto_ec((int8_t *) &ecMsgFrame,
OCMP_MSG_SIZE, sentDev);
#ifdef INTERFACE_STUB_EC
if (alertFlag > 0) {
while (1) {
memset(ethRecvBuf, 0, sizeof(ethRecvBuf));
ocmw_recv_eth_msgfrom_ec(ethRecvBuf,
sizeof(ethRecvBuf), OCMW_EC_STUB_DEV);
ocmw_ec_msgparser();
if (alertRecord == 0) {
break;
}
}
} else {
memset(ethRecvBuf, 0, sizeof(ethRecvBuf));
ocmw_recv_eth_msgfrom_ec(ethRecvBuf, sizeof(ethRecvBuf), OCMW_EC_STUB_DEV);
ocmw_ec_msgparser();
}
#endif
break;
case OCMP_COMM_IFACE_SBD:
break;
default:
break;
}
if (ret != 0) {
logerr("ocmw_send_msg() failed \n");
}
return ret;
}
/******************************************************************************
* Function Name : ocmw_sem_wait
* Description : semaphore wait function to wait either for infinite time
* or for timeout period.
* Input(s) : semId, semWaitType
* Output(s) :
******************************************************************************/
int32_t ocmw_sem_wait(sem_t *semId, int32_t semWaitType)
{
int32_t ret = 0;
struct timespec timeSpecObj;
if (semId == NULL) {
logerr("Invalid semId \n");
ret = FAILED;
return ret;
}
if (semWaitType == OCMW_BUSY_WAIT_INDEX) {
/* Waiting on the lock to be released by receiving thread */
ret = ocmw_sem_wait_nointr(semId);
if (ret != 0) {
perror("sem_wait");
}
} else if (semWaitType == OCMW_TIMED_WAIT_INDEX) {
ret = clock_gettime(CLOCK_REALTIME, &timeSpecObj);
if (ret != 0) {
perror("clock_gettime");
}
timeSpecObj.tv_sec += OCMW_SEM_WAIT_TIME;
timeSpecObj.tv_nsec += 0;
ret = ocmw_sem_timedwait_nointr(semId, &timeSpecObj);
if (ret != 0) {
if (errno == ETIMEDOUT) {
logdebug("sem_timedwait() timed out\n");
} else {
perror("sem_timedwait");
}
logdebug("Message is not received from EC: releasing the lock \n");
s_semTimeOut = 1;
}
} else {
printf("Invalid param \n");
}
return ret;
}