123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- /**
- * @file shellmatta_transport.c
- * @brief transport layer functions of shellmatta
- * @author Simon Fischer <fischer.simon.1991@gmail.com>
- */
- #include "shellmatta_transport.h"
- #include "shellmatta_crc.h"
- #include <string.h>
- /* init global variables */
- uint8_t protocolVersion = 0u;
- shellmatta_transport_packet_t packetType = 0u;
- uint8_t payloadLength = 0u;
- uint8_t source = 0u;
- uint8_t destination = 0u;
- uint32_t crc32 = 0u;
- uint8_t payloadCounter = 0u;
- uint8_t crcCounter = 0u;
- uint32_t packetSequenceCounter_h2s = 0u;
- uint32_t packetSequenceCounter_s2h = 0u;
- shellmatta_transport_layer_t transportLayerInst = {
- 0,
- 0,
- STATE_GET_SOH,
- false,
- false,
- false,
- NULL
- };
- char payloadBuffer[SHELLMATTA_PAYLOAD_MAXLENGTH + 1];
- shellmatta_retCode_t shellmatta_init_transport_inst()
- {
- transportLayerInst.h2s_sequenceCnt = 0;
- transportLayerInst.s2h_sequenceCnt = 0;
- transportLayerInst.state = STATE_GET_SOH;
- transportLayerInst.mandatory = false;
- transportLayerInst.active = false;
- transportLayerInst.continueStep = false;
- memset(payloadBuffer, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1);
- return SHELLMATTA_OK;
- }
- shellmatta_retCode_t shellmatta_reset_transport()
- {
- transportLayerInst.state = STATE_GET_SOH;
- protocolVersion = 0u;
- packetType = 0u;
- payloadLength = 0u;
- source = 0u;
- destination = 0u;
- crc32 = 0u;
- payloadCounter = 0u;
- crcCounter = 0u;
- transportLayerInst.active = false;
- memset(payloadBuffer, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1);
- return SHELLMATTA_OK;
- }
- shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
- {
- switch (transportLayerInst.state)
- {
- case STATE_GET_SOH:
- if (SHELLMATTA_START_OF_HEADER == *data)
- {
- transportLayerInst.state = STATE_GET_PROTOCOL_VERSION;
- transportLayerInst.active = true;
- }
- else
- {
- transportLayerInst.state = STATE_MANUAL_INPUT;
- transportLayerInst.active = false;
- }
- break;
- case STATE_MANUAL_INPUT:
- break;
- case STATE_GET_PROTOCOL_VERSION:
- transportLayerInst.state = STATE_GET_PACKET_TYPE;
- break;
- case STATE_GET_PACKET_TYPE:
- transportLayerInst.state = STATE_GET_PAYLOAD_LENGTH;
- break;
- case STATE_GET_PAYLOAD_LENGTH:
- transportLayerInst.state = STATE_GET_SOURCE;
- break;
- case STATE_GET_SOURCE:
- transportLayerInst.state = STATE_GET_DESTINATION;
- break;
- case STATE_GET_DESTINATION:
- transportLayerInst.state = STATE_GET_H2S_SEQUENCE_CNT;
- break;
- case STATE_GET_H2S_SEQUENCE_CNT:
- transportLayerInst.state = STATE_GET_S2H_SEQUENCE_CNT;
- break;
- case STATE_GET_S2H_SEQUENCE_CNT:
- transportLayerInst.state = STATE_GET_PAYLOAD;
- break;
- case STATE_GET_PAYLOAD:
- if ( (payloadLength <= payloadCounter)
- && (true == transportLayerInst.active))
- {
- transportLayerInst.state = STATE_GET_CRC;
- }
- break;
- case STATE_GET_CRC:
- if (SHELLMATTA_LENGTH_CRC <= crcCounter)
- {
- char data[SHELLMATTA_PAYLOAD_MAXLENGTH + 1 + SHELLMATTA_HEADER_LENGTH];
- memset(data, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1 + SHELLMATTA_HEADER_LENGTH);
- data[0] = SHELLMATTA_START_OF_HEADER;
- data[1] = protocolVersion;
- data[2] = packetType;
- data[3] = payloadLength;
- data[4] = source;
- data[5] = destination;
- data[6] = transportLayerInst.h2s_sequenceCnt;
- data[7] = transportLayerInst.s2h_sequenceCnt;
- strncat(&data[8], payloadBuffer, payloadLength);
- uint32_t refCrc;
- refCrc = crc32Calc(data, SHELLMATTA_HEADER_LENGTH + payloadLength);
- if (crc32 == refCrc)
- {
- /* crc is correct */
- switch (packetType)
- {
- case PACKET_DATA:
- transportLayerInst.state = STATE_PROCESS_PAYLOAD;
- transportLayerInst.h2s_sequenceCnt++;
- break;
-
- case PACKET_SEQ_CNT_REQUEST:
- transportLayerInst.h2s_sequenceCnt++;
- break;
- case PACKET_SEQ_CNT_RESPOND:
- transportLayerInst.h2s_sequenceCnt++;
- break;
-
- case PACKET_MAX_BUFFERSIZE_REQUEST:
- transportLayerInst.h2s_sequenceCnt++;
- break;
- case PACKET_MAX_BUFFERSIZE_RESPOND:
- transportLayerInst.h2s_sequenceCnt++;
- break;
-
- case PACKET_SEARCH_DEVICE_REQUEST:
- transportLayerInst.h2s_sequenceCnt++;
- break;
-
- case PACKET_SEARCH_DEVICE_RESPOND:
- transportLayerInst.h2s_sequenceCnt++;
- break;
- case PACKET_SET_ADDRESS_REQUEST:
- transportLayerInst.h2s_sequenceCnt++;
- break;
- case PACKET_SET_ADDRESS_RESPOND:
- transportLayerInst.h2s_sequenceCnt++;
- break;
- /* should not happen */
- default:
- break;
- }
- break;
- }
- else
- {
- /* crc is incorrect */
- return SHELLMATTA_ERROR;
- }
- }
- break;
- case STATE_PROCESS_PAYLOAD:
- transportLayerInst.state = STATE_GET_SOH;
- protocolVersion = 0u;
- packetType = 0u;
- payloadLength = 0u;
- source = 0u;
- destination = 0u;
- crc32 = 0u;
- payloadCounter = 0u;
- crcCounter = 0u;
- transportLayerInst.active = false;
- memset(payloadBuffer, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1);
- break;
-
- default:
- break;
- }
- return SHELLMATTA_OK;
- }
- shellmatta_retCode_t shellmatta_write_transport(const char* data, uint32_t length)
- {
- uint8_t outputBuffer[ SHELLMATTA_HEADER_LENGTH + /* length of header */
- SHELLMATTA_PAYLOAD_MAXLENGTH + 1 + /* max length of payload */
- SHELLMATTA_LENGTH_CRC]; /* length of crc */
-
- uint8_t outPayloadLength = length + SHELLMATTA_HEADER_LENGTH + SHELLMATTA_LENGTH_CRC;
- outputBuffer[0] = SHELLMATTA_START_OF_HEADER;
- outputBuffer[1] = 0x01u;
- outputBuffer[2] = 0x00u;
- outputBuffer[3] = length;
- outputBuffer[4] = 0x01u;
- outputBuffer[5] = 0x00u;
- outputBuffer[6] = transportLayerInst.h2s_sequenceCnt;
- outputBuffer[7] = ++transportLayerInst.s2h_sequenceCnt;
- memcpy(&outputBuffer[8], data, length);
- uint32_t outCrc = crc32Calc((char*) outputBuffer, SHELLMATTA_HEADER_LENGTH + length);
- outputBuffer[length + SHELLMATTA_HEADER_LENGTH + 0] = (uint8_t)(outCrc >> 0);
- outputBuffer[length + SHELLMATTA_HEADER_LENGTH + 1] = (uint8_t)(outCrc >> 8);
- outputBuffer[length + SHELLMATTA_HEADER_LENGTH + 2] = (uint8_t)(outCrc >> 16);
- outputBuffer[length + SHELLMATTA_HEADER_LENGTH + 3] = (uint8_t)(outCrc >> 24);
- shellmatta_retCode_t ret = transportLayerInst.originalWrite((char*) outputBuffer, outPayloadLength);
- return ret;
- }
|