/** * 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 #include #include #include #include #include #include #include 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(ðMsgPaserThreadId, 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], ¶mValue, 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; }