Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r8642cf765f2248b0bb2c2ef5598687e4feea0967 -rb0d1521cd365dbc9efb79a2774ed3360e3d450e9 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 8642cf765f2248b0bb2c2ef5598687e4feea0967) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision b0d1521cd365dbc9efb79a2774ed3360e3d450e9) @@ -99,92 +99,92 @@ static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); -static BOOL sendUIResponseMsg( MSG_ID_T msgID, BOOL accepted, U32 reason ); +static BOOL sendUIResponseMsg( MSG_ID_T msgID, UI_RESPONSE_PAYLOAD_T *uiResponse ); + +/*********************************************************************//** + * @brief + * The serializeMessage function serializes a given message into a given + * array of bytes. A sequence # is added to the message here and the ACK + * bit of the sequence # is set if ACK is required per parameter. A sync byte + * is inserted at the beginning of the message and an 8-bit CRC is appended to + * the end of the message. The message is queued for transmission in the given buffer. + * @details Inputs: none + * @details Outputs: given data array populated with serialized message data and queued for transmit. + * @param msg message to serialize + * @param buffer outgoing buffer that message should be queued in + * @param ackReq is an acknowledgement from receiver required? + * @return size (in bytes) of serialized message populated in given data array. + *************************************************************************/ +U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) +{ + BOOL result = FALSE; + BOOL error = FALSE; + U32 msgSize = 0; + U32 sizeMod, sizePad; + U32 i; + U08 crc; + U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data + + // prefix data with message sync byte + data[ msgSize++ ] = MESSAGE_SYNC_BYTE; + + // set sequence # and ACK bit (unless this is an ACK to a received message) + if ( msg.hdr.msgID != MSG_ID_ACK_MESSAGE_THAT_REQUIRES_ACK ) + { + // thread protect next sequence # access & increment + _disable_IRQ(); + msg.hdr.seqNo = nextSeqNo; + nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); + _enable_IRQ(); + if ( TRUE == ackReq ) + { + msg.hdr.seqNo *= -1; + } + } + + // calculate message CRC + crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); + + // serialize message header data + memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); + msgSize += sizeof( MESSAGE_HEADER_T ); + + // serialize message payload (only used bytes per payloadLen field) + memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); + msgSize += msg.hdr.payloadLen; + + // add 8-bit CRC + data[ msgSize++ ] = crc; + + // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) + sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; + sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); + for ( i = 0; i < sizePad; i++ ) + { + data[ msgSize++ ] = 0; + } + + // if ACK required, add to pending ACK list + if ( TRUE == ackReq ) + { + if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) + { + error = TRUE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) + } + } + + if ( FALSE == error ) + { + // add serialized message data to appropriate out-going comm buffer + result = addToCommBuffer( buffer, data, msgSize ); + } + + return result; +} /*********************************************************************//** * @brief - * The serializeMessage function serializes a given message into a given - * array of bytes. A sequence # is added to the message here and the ACK - * bit of the sequence # is set if ACK is required per parameter. A sync byte - * is inserted at the beginning of the message and an 8-bit CRC is appended to - * the end of the message. The message is queued for transmission in the given buffer. - * @details Inputs: none - * @details Outputs: given data array populated with serialized message data and queued for transmit. - * @param msg message to serialize - * @param buffer outgoing buffer that message should be queued in - * @param ackReq is an acknowledgement from receiver required? - * @return size (in bytes) of serialized message populated in given data array. - *************************************************************************/ -U32 serializeMessage( MESSAGE_T msg, COMM_BUFFER_T buffer, BOOL ackReq ) -{ - BOOL result = FALSE; - BOOL error = FALSE; - U32 msgSize = 0; - U32 sizeMod, sizePad; - U32 i; - U08 crc; - U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data - - // prefix data with message sync byte - data[ msgSize++ ] = MESSAGE_SYNC_BYTE; - - // set sequence # and ACK bit (unless this is an ACK to a received message) - if ( msg.hdr.msgID != MSG_ID_ACK_MESSAGE_THAT_REQUIRES_ACK ) - { - // thread protect next sequence # access & increment - _disable_IRQ(); - msg.hdr.seqNo = nextSeqNo; - nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); - _enable_IRQ(); - if ( TRUE == ackReq ) - { - msg.hdr.seqNo *= -1; - } - } - - // calculate message CRC - crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); - - // serialize message header data - memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); - msgSize += sizeof( MESSAGE_HEADER_T ); - - // serialize message payload (only used bytes per payloadLen field) - memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); - msgSize += msg.hdr.payloadLen; - - // add 8-bit CRC - data[ msgSize++ ] = crc; - - // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) - sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; - sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); - for ( i = 0; i < sizePad; i++ ) - { - data[ msgSize++ ] = 0; - } - - // if ACK required, add to pending ACK list - if ( TRUE == ackReq ) - { - if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) - { - error = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) - } - } - - if ( FALSE == error ) - { - // add serialized message data to appropriate out-going comm buffer - result = addToCommBuffer( buffer, data, msgSize ); - } - - return result; -} - -/*********************************************************************//** - * @brief * The sendACKMsg function constructs and queues for transmit an ACK message * for a given received message. * @details Inputs: none @@ -247,18 +247,18 @@ * @details Inputs: none * @details Outputs: response message constructed and queued for transmit. * @param msgID ID of handled message that we are responding to - * @param accepted T/F - request accepted? - * @param reason reason code if rejected + * @param ui response pointer to the UI response payload * @return TRUE if response message successfully queued for transmit, FALSE if not *************************************************************************/ -static BOOL sendUIResponseMsg( MSG_ID_T msgID, BOOL accepted, U32 reason ) +static BOOL sendUIResponseMsg( MSG_ID_T msgID, UI_RESPONSE_PAYLOAD_T *uiResponse ) { BOOL result; MESSAGE_T msg; UI_RESPONSE_PAYLOAD_T cmd; - cmd.accepted = accepted; - cmd.rejectionReason = reason; + cmd.fwValue = uiResponse->fwValue; + cmd.accepted = uiResponse->accepted; + cmd.rejectionReason = uiResponse->rejectionReason; // Create a message record blankMessage( &msg ); @@ -557,8 +557,14 @@ *************************************************************************/ void handleDGSerialNumberRequest( void ) { + typedef struct + { + U08 topLevelSN[ MAX_TOP_LEVEL_SN_CHARS ]; + } LOCAL_TOP_SN_T; MESSAGE_T msg; DG_SYSTEM_RECORD_T system; + U08 i; + LOCAL_TOP_SN_T localTopLevelSN; // Get the system's record. There are no arrays of system to check and also, raise no alarm since the system record // has been already checked in POST @@ -573,8 +579,15 @@ // Add 1 byte for null terminator msg.hdr.payloadLen = MAX_TOP_LEVEL_SN_CHARS + 1; + for ( i = 0; i < MAX_TOP_LEVEL_SN_CHARS; i++ ) + { + // NOTE: A local variable was created to avoid system.topLevelSN in the messages list + // NOTE: For loop was used instead of memory copy to ensure it is not parsed in the messages list script + localTopLevelSN.topLevelSN[ i ] = system.topLevelSN[ i ]; + } + // Fill message payload - memcpy( payloadPtr, &system.topLevelSN, sizeof( U08 ) * MAX_TOP_LEVEL_SN_CHARS ); + memcpy( payloadPtr, &localTopLevelSN, sizeof( LOCAL_TOP_SN_T ) ); payloadPtr += MAX_TOP_LEVEL_SN_CHARS; *payloadPtr = 0; @@ -608,10 +621,12 @@ if ( 0 == message->hdr.payloadLen ) { - memcpy( payloadPtr, &service.lastServiceEpochDate, sizeof( U32 ) ); + U32 lastServiceEpochDate = service.lastServiceEpochDate; + U32 serviceIntervalSeconds = ( 0 == service.lastServiceEpochDate ? 0 : service.serviceIntervalSeconds ); + + memcpy( payloadPtr, &lastServiceEpochDate, sizeof( U32 ) ); payloadPtr += sizeof( U32 ); - service.serviceIntervalSeconds = ( 0 == service.lastServiceEpochDate ? 0 : service.serviceIntervalSeconds ); - memcpy( payloadPtr, &service.serviceIntervalSeconds, sizeof( U32 ) ); + memcpy( payloadPtr, &serviceIntervalSeconds, sizeof( U32 ) ); } // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer @@ -1770,13 +1785,13 @@ *************************************************************************/ void handleSetROOnlyMode( MESSAGE_T* message ) { + UI_RESPONSE_PAYLOAD_T uiResponse; + BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_DG_RO_ONLY_MODE_INVALID_PAYLOAD_LENGTH; BOOL accepted = FALSE; if ( message->hdr.payloadLen == sizeof(U32) ) { - BOOL result; - rejReason = REQUEST_REJECT_REASON_NONE; memcpy( &result, message->payload, sizeof(BOOL) ); @@ -1795,17 +1810,23 @@ break; default: + result = isROOnlyModeEnabled(); rejReason = REQUEST_REJECT_REASON_DG_RO_ONLY_MODE_DG_BUSY; break; } } else { + result = isROOnlyModeEnabled(); rejReason = REQUEST_REJECT_REASON_DG_RO_ONLY_MODE_INVALID_PARAMETER; } } - sendUIResponseMsg( MSG_ID_DG_RO_ONLY_MODE_STATUS_RESPONSE, accepted, rejReason ); + uiResponse.accepted = accepted; + uiResponse.rejectionReason = rejReason; + uiResponse.fwValue = (U32)result; + + sendUIResponseMsg( MSG_ID_DG_RO_ONLY_MODE_STATUS_RESPONSE, &uiResponse ); } /*********************************************************************//** @@ -4953,8 +4974,9 @@ *************************************************************************/ void handleDGROStatusRequest( MESSAGE_T* message ) { + UI_RESPONSE_PAYLOAD_T uiResponse; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; - BOOL roMode = FALSE; + BOOL roMode = FALSE; if ( 0 == message->hdr.payloadLen ) { @@ -4964,7 +4986,12 @@ { rejReason = REQUEST_REJECT_REASON_DG_RO_ONLY_MODE_INVALID_PAYLOAD_LENGTH; } - sendUIResponseMsg( MSG_ID_DG_RO_ONLY_MODE_STATUS_RESPONSE, roMode, rejReason ); + + uiResponse.accepted = roMode; + uiResponse.rejectionReason = rejReason; + uiResponse.fwValue = (U32)roMode; + + sendUIResponseMsg( MSG_ID_DG_RO_ONLY_MODE_STATUS_RESPONSE, &uiResponse ); } /*********************************************************************//**