|
@@ -25,7 +25,6 @@
|
|
|
* @note The packetType, payloadLength and payload have to be preset!
|
|
|
*
|
|
|
* @param[in, out] transportLayer transport layer instance to work on
|
|
|
- * @param[in] packetType type of packet to send
|
|
|
* @param[in] packet packet to send
|
|
|
* @return errorcode
|
|
|
*/
|
|
@@ -39,8 +38,8 @@ static shellmatta_retCode_t shellmatta_transport_send(shellmatta_transport_layer
|
|
|
/** -# fill header */
|
|
|
header->startOfHeader = SHELLMATTA_TRANSPORT_START_OF_HEADER;
|
|
|
header->protocolVersion = SHELLMATTA_TRANSPORT_PROTOCOL_VERSION;
|
|
|
- header->source = 0;
|
|
|
- header->destination = 0;
|
|
|
+ header->source = transportLayer->address;
|
|
|
+ header->destination = SHELLMATTA_TRANSPORT_MASTER_ADDRESS;
|
|
|
header->sequenceH2S = transportLayer->sequenceH2S;
|
|
|
header->sequenceS2H = ++transportLayer->sequenceS2H;
|
|
|
|
|
@@ -58,6 +57,49 @@ static shellmatta_retCode_t shellmatta_transport_send(shellmatta_transport_layer
|
|
|
header->payloadLength);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief check a search packet and return if our UUID is in the search range
|
|
|
+ * @param[in, out] transportLayer transport layer instance to work on
|
|
|
+ * @param[in] packet search packet
|
|
|
+ * @return true - UUID in passed range
|
|
|
+ */
|
|
|
+static bool shellmatta_transport_search(shellmatta_transport_layer_t *transportLayer,
|
|
|
+ shellmatta_transport_packet_t *packet)
|
|
|
+{
|
|
|
+ bool match = true;
|
|
|
+ bool sure = false;
|
|
|
+ uint32_t i;
|
|
|
+ uint8_t *uuid1;
|
|
|
+ uint8_t *uuid2;
|
|
|
+
|
|
|
+ uuid1 = (uint8_t *)&packet->payload[0u];
|
|
|
+ uuid2 = (uint8_t *)&packet->payload[SHELLMATTA_TRANPORT_UUID_LENGTH];
|
|
|
+
|
|
|
+ /** -# compare UUID with range */
|
|
|
+ for(i = 0u; i < (SHELLMATTA_TRANPORT_UUID_LENGTH - 1u); i ++)
|
|
|
+ {
|
|
|
+ /** -# stop match if we are outside of the range with the current digit */
|
|
|
+ if((transportLayer->uuid[i] < uuid1[i]) || (transportLayer->uuid[i] > uuid2[i]))
|
|
|
+ {
|
|
|
+ match = false;
|
|
|
+ }
|
|
|
+ /** -# stop comparison when we are definitely in the range (lower than the top limit and inside) */
|
|
|
+ else if(transportLayer->uuid[i] < uuid2[i])
|
|
|
+ {
|
|
|
+ sure = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** -# explicitly check lowest digit - this is not inclusive to the lower limit */
|
|
|
+ if((false == sure) && ((transportLayer->uuid[i] <= uuid1[i]) || (transportLayer->uuid[i] > uuid2[i])))
|
|
|
+ {
|
|
|
+ match = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return match;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* @brief Initializes the transportLayerInst
|
|
|
* @param[in, out] transportLayer transport layer instance to work on
|
|
@@ -69,6 +111,7 @@ shellmatta_retCode_t shellmatta_transport_init( shellmatta_transport_layer_t
|
|
|
{
|
|
|
/** -# clear instance and store write function */
|
|
|
memset(transportLayer, 0u, sizeof(shellmatta_transport_layer_t));
|
|
|
+ transportLayer->hostBufferSize = SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH;
|
|
|
transportLayer->writeFct = writeFct;
|
|
|
|
|
|
return SHELLMATTA_OK;
|
|
@@ -79,12 +122,14 @@ shellmatta_retCode_t shellmatta_transport_init( shellmatta_transport_layer_t
|
|
|
* @param[in, out] handle shellmatta handle of the instance
|
|
|
* @param[in] mandatory enforce using the transport layer
|
|
|
* @param[in] disableAutoFlush enforce manual flushing of the output packet
|
|
|
+ * @param[in] uuid UUID for multidrop search (default NULL)
|
|
|
* @param[in] customCrcFct use a custom crc generation (default NULL)
|
|
|
* @return errorcode
|
|
|
*/
|
|
|
shellmatta_retCode_t shellmatta_transport_configure(shellmatta_handle_t handle,
|
|
|
bool mandatory,
|
|
|
bool disableAutoFlush,
|
|
|
+ uint8_t uuid[SHELLMATTA_TRANPORT_UUID_LENGTH],
|
|
|
shellmatta_transport_crc_t customCrcFct)
|
|
|
{
|
|
|
shellmatta_retCode_t ret = SHELLMATTA_OK;
|
|
@@ -105,6 +150,11 @@ shellmatta_retCode_t shellmatta_transport_configure(shellmatta_handle_t
|
|
|
{
|
|
|
transportLayer->active = true;
|
|
|
}
|
|
|
+
|
|
|
+ if(NULL != uuid)
|
|
|
+ {
|
|
|
+ (void)memcpy(transportLayer->uuid, uuid, SHELLMATTA_TRANPORT_UUID_LENGTH);
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -174,8 +224,8 @@ shellmatta_retCode_t shellmatta_transport_process(shellmatta_transport_layer_t
|
|
|
case SHELLMATTA_TRANSPORT_STATE_WAIT:
|
|
|
/** -# if start of header is found, continue transport layer fsm */
|
|
|
/** -# respect suspendedOptional when there is no active session */
|
|
|
- if ((SHELLMATTA_TRANSPORT_START_OF_HEADER == byte) &&
|
|
|
- !((false == transportLayer->active) && (true == transportLayer->suspendOptional)))
|
|
|
+ if((SHELLMATTA_TRANSPORT_START_OF_HEADER == byte) &&
|
|
|
+ !((false == transportLayer->active) && (true == transportLayer->suspendOptional)))
|
|
|
{
|
|
|
memset(&transportLayer->inPacket, 0, sizeof(transportLayer->inPacket));
|
|
|
transportLayer->headerIndex = 1u;
|
|
@@ -208,10 +258,16 @@ shellmatta_retCode_t shellmatta_transport_process(shellmatta_transport_layer_t
|
|
|
rawPacket[transportLayer->headerIndex] = byte;
|
|
|
transportLayer->headerIndex ++;
|
|
|
|
|
|
- if (transportLayer->headerIndex == SHELLMATTA_TRANSPORT_LENGTH_HEADER)
|
|
|
+ if(transportLayer->headerIndex == SHELLMATTA_TRANSPORT_LENGTH_HEADER)
|
|
|
{
|
|
|
- //TODO check for errors in header data
|
|
|
- if (0u != header->payloadLength)
|
|
|
+ /** -# check protocol version and addressing*/
|
|
|
+ if((SHELLMATTA_TRANSPORT_PROTOCOL_VERSION != header->protocolVersion) ||
|
|
|
+ ((SHELLMATTA_TRANSPORT_BROADCAST_ADDRESS != header->destination) &&
|
|
|
+ (transportLayer->address != header->destination)))
|
|
|
+ {
|
|
|
+ transportLayer->state = SHELLMATTA_TRANSPORT_STATE_WAIT;
|
|
|
+ }
|
|
|
+ else if(0u != header->payloadLength)
|
|
|
{
|
|
|
transportLayer->state = SHELLMATTA_TRANSPORT_STATE_GET_PAYLOAD;
|
|
|
}
|
|
@@ -263,36 +319,81 @@ shellmatta_retCode_t shellmatta_transport_process(shellmatta_transport_layer_t
|
|
|
*length = header->payloadLength;
|
|
|
ret = SHELLMATTA_OK;
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case SHELLMATTA_TRANSPORT_PACKET_SEQ_CNT_REQUEST:
|
|
|
- /** -# send out packet with no payload */
|
|
|
- intPacket.header.packetType = SHELLMATTA_TRANSPORT_PACKET_SEQ_CNT_RESPOND;
|
|
|
- intPacket.header.payloadLength = 0u;
|
|
|
- (void)shellmatta_transport_send(transportLayer, (shellmatta_transport_packet_t *)&intPacket);
|
|
|
+ if(transportLayer->inPacket.header.payloadLength == 0u)
|
|
|
+ {
|
|
|
+ /** -# send out packet with no payload */
|
|
|
+ intPacket.header.packetType = SHELLMATTA_TRANSPORT_PACKET_SEQ_CNT_RESPOND;
|
|
|
+ intPacket.header.payloadLength = 0u;
|
|
|
+ (void)shellmatta_transport_send(transportLayer, (shellmatta_transport_packet_t *)&intPacket);
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case SHELLMATTA_TRANSPORT_PACKET_SEQ_CNT_RESPOND:
|
|
|
/** -# ignore #SHELLMATTA_TRANSPORT_PACKET_SEQ_CNT_RESPOND - nothing to do */
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case SHELLMATTA_TRANSPORT_PACKET_MAX_BUFFERSIZE_REQUEST:
|
|
|
- /** @todo implement */
|
|
|
+
|
|
|
+ if(transportLayer->inPacket.header.payloadLength == 1u)
|
|
|
+ {
|
|
|
+ /** -# store the hosts buffersize */
|
|
|
+ transportLayer->hostBufferSize = (uint8_t)transportLayer->inPacket.payload[0];
|
|
|
+
|
|
|
+ /** -# respont with our own buffer size */
|
|
|
+ intPacket.header.packetType = SHELLMATTA_TRANSPORT_PACKET_MAX_BUFFERSIZE_RESPOND;
|
|
|
+ intPacket.header.payloadLength = 1u;
|
|
|
+ intPacket.payload[0] = SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH;
|
|
|
+ (void)shellmatta_transport_send(transportLayer, (shellmatta_transport_packet_t *)&intPacket);
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case SHELLMATTA_TRANSPORT_PACKET_MAX_BUFFERSIZE_RESPOND:
|
|
|
/** -# ignore #SHELLMATTA_TRANSPORT_PACKET_MAX_BUFFERSIZE_RESPOND - nothing to do */
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case SHELLMATTA_TRANSPORT_PACKET_SEARCH_DEVICE_REQUEST:
|
|
|
- /** @todo implement */
|
|
|
+ /** -# check if our own uuid is inside the passed range */
|
|
|
+ if((transportLayer->inPacket.header.payloadLength == SHELLMATTA_TRANPORT_UUID_LENGTH * 2u) &&
|
|
|
+ (true == shellmatta_transport_search(transportLayer, &transportLayer->inPacket)))
|
|
|
+ {
|
|
|
+ intPacket.header.packetType = SHELLMATTA_TRANSPORT_PACKET_SEARCH_DEVICE_RESPOND;
|
|
|
+ intPacket.header.payloadLength = SHELLMATTA_TRANPORT_UUID_LENGTH;
|
|
|
+ (void)memcpy(intPacket.payload, transportLayer->uuid, SHELLMATTA_TRANPORT_UUID_LENGTH);
|
|
|
+ (void)shellmatta_transport_send(transportLayer, (shellmatta_transport_packet_t *)&intPacket);
|
|
|
+ }
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
case SHELLMATTA_TRANSPORT_PACKET_SEARCH_DEVICE_RESPOND:
|
|
|
/** -# ignore #SHELLMATTA_TRANSPORT_PACKET_SEARCH_DEVICE_RESPOND - nothing to do */
|
|
|
break;
|
|
|
|
|
|
case SHELLMATTA_TRANSPORT_PACKET_SET_ADDRESS_REQUEST:
|
|
|
- /** @todo implement */
|
|
|
+
|
|
|
+ /** -# use the passed address if the passed UUID matches our own */
|
|
|
+ if((transportLayer->inPacket.header.payloadLength == SHELLMATTA_TRANPORT_UUID_LENGTH + 1u) &&
|
|
|
+ 0 == memcmp(transportLayer->uuid,
|
|
|
+ transportLayer->inPacket.payload,
|
|
|
+ SHELLMATTA_TRANPORT_UUID_LENGTH))
|
|
|
+ {
|
|
|
+ transportLayer->address = transportLayer->inPacket.payload[SHELLMATTA_TRANPORT_UUID_LENGTH];
|
|
|
+ if(SHELLMATTA_TRANSPORT_MASTER_ADDRESS == transportLayer->address)
|
|
|
+ {
|
|
|
+ transportLayer->address = 0u;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /** -# respond to the address set command */
|
|
|
+ intPacket.header.packetType = SHELLMATTA_TRANSPORT_PACKET_SET_ADDRESS_RESPOND;
|
|
|
+ intPacket.header.payloadLength = SHELLMATTA_TRANPORT_UUID_LENGTH;
|
|
|
+ (void)memcpy(intPacket.payload, transportLayer->uuid, SHELLMATTA_TRANPORT_UUID_LENGTH);
|
|
|
+ (void)shellmatta_transport_send(transportLayer,
|
|
|
+ (shellmatta_transport_packet_t *)&intPacket);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
break;
|
|
|
|
|
|
case SHELLMATTA_TRANSPORT_PACKET_SET_ADDRESS_RESPOND:
|
|
@@ -300,8 +401,7 @@ shellmatta_retCode_t shellmatta_transport_process(shellmatta_transport_layer_t
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
- /** -# undo sequence counter increment on wrong packet type */
|
|
|
- transportLayer->sequenceH2S--;
|
|
|
+ /** -# ignore unknown packets */
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -315,7 +415,7 @@ shellmatta_retCode_t shellmatta_transport_process(shellmatta_transport_layer_t
|
|
|
transportLayer->state = SHELLMATTA_TRANSPORT_STATE_WAIT;
|
|
|
}
|
|
|
break;
|
|
|
-
|
|
|
+
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
@@ -325,13 +425,13 @@ shellmatta_retCode_t shellmatta_transport_process(shellmatta_transport_layer_t
|
|
|
|
|
|
/**
|
|
|
* @brief Wrapper function for the write-function of shellmatta handle
|
|
|
- *
|
|
|
+ *
|
|
|
* This function is used to transmit data with the tranport layer protocol.\n
|
|
|
* The input data is copied into a new array along with the header and crc32.\n
|
|
|
* The resulting buffer is the forwarded to the original write function.\n
|
|
|
- *
|
|
|
+ *
|
|
|
* @note If length of data exceeds #UINT8_MAX, data is sent in multiple packets.\n
|
|
|
- *
|
|
|
+ *
|
|
|
* @param[in, out] transportLayer transport layer instance to work on
|
|
|
* @param[in] data pointer to input data to process
|
|
|
* @param[in] length length of data to process
|
|
@@ -359,9 +459,9 @@ shellmatta_retCode_t shellmatta_transport_write(shellmatta_transport_layer_t *tr
|
|
|
|
|
|
/* compute length of next payload split */
|
|
|
restOfPayload = (outPayloadLength - processedLength);
|
|
|
- if (restOfPayload > (SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH - piledUpPayload))
|
|
|
+ if (restOfPayload > (transportLayer->hostBufferSize - piledUpPayload))
|
|
|
{
|
|
|
- splitLength = SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH - piledUpPayload;
|
|
|
+ splitLength = transportLayer->hostBufferSize - piledUpPayload;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -372,7 +472,7 @@ shellmatta_retCode_t shellmatta_transport_write(shellmatta_transport_layer_t *tr
|
|
|
header->payloadLength += splitLength;
|
|
|
processedLength += splitLength;
|
|
|
|
|
|
- if(header->payloadLength >= SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH)
|
|
|
+ if(header->payloadLength >= transportLayer->hostBufferSize)
|
|
|
{
|
|
|
/** -# packet is full - send */
|
|
|
header->packetType = SHELLMATTA_TRANSPORT_PACKET_DATA;
|
|
@@ -386,7 +486,7 @@ shellmatta_retCode_t shellmatta_transport_write(shellmatta_transport_layer_t *tr
|
|
|
|
|
|
/**
|
|
|
* @brief Send out piled up payload
|
|
|
- *
|
|
|
+ *
|
|
|
* @param[in, out] handle shellmatta handle of the instance
|
|
|
* @return errorcode
|
|
|
*/
|