Hi Steffen,
Consider also the following steps in building your host application using THCI:
1. Start from generic function for UART communcation :
- serial_send_data (uint8_t *pBuffer, uint16_t bufferLen) - to send data via UART interface
- serial_receive_data(uint8_t *pBuffer, uint16_t bufferLen) - to receive data via UART interface
2. define some internal structures:
/* Format of packets exchanged between the external client and THCI. */
typedef struct clientPacketHdr_tag
{
uint8_t startMarker;
uint8_t opGroup;
uint8_t opCode;
uint8_t len[2]; /* Actual length of payload[] */
} clientPacketHdr_t;
typedef struct clientPacketStructured_tag
{
clientPacketHdr_t header;
uint8_t payload[gTHCIMaxPayload_c];
uint8_t checksum;
} clientPacketStructured_t;
/* defines the working packet type */
typedef union clientPacket_tag
{
uint8_t raw[sizeof(clientPacketStructured_t)]; /* The entire packet as unformatted data. */
clientPacketStructured_t structured; /* The packet as header + payload. */
} clientPacket_t;
/* define command status */
typedef enum{
eFsciSuccess_c = 0x00,
...
eFsciTooBig_c = 0xFE,
eFsciError_c = 0xFF /* General catch all error. */
} fsci_Status_t;
#define gTHCIMaxPayload_c 512
3. define THCI handlers:
/* function used to check if the received packet is valid or not */
fsci_packetStatus_t THCI_CheckPacket( clientPacket_t *pData, uint16_t bytes )
{
uint8_t checksum = 0;
uint16_t len;
if((!pData) ||
(pData->raw[0] != gFsciStartMarker_c))
{
return ePacketInvalid_c;
}
if ( bytes < sizeof(clientPacketHdr_t) )
{
return ePacketToShort_c; /* Too short to be valid. */
}
if ( bytes >= sizeof(clientPacket_t) )
{
return eFramingError_c;
}
/* The packet's len field does not count the STX, the opcode group, the */
/* opcode, the len field, or the checksum. */
len = pData->structured.header.len[0] + (pData->structured.header.len[1]<<8);
/* If the length appears to be too long, it might be because the external */
/* client is sending a packet that is too long, or it might be that we're */
/* out of sync with the external client. Assume we're out of sync. */
if ( len > sizeof(pData->structured.payload) )
{
return eFramingError_c;
}
if ( bytes < len + sizeof(clientPacketHdr_t) + sizeof(checksum) )
{
return ePacketToShort_c;
}
/* If the length looks right, make sure that the checksum is correct. */
if( bytes == len + sizeof(clientPacketHdr_t) + sizeof(checksum) )
{
checksum = THCI_ComputeChecksum(pData->raw+1, len + sizeof(clientPacketHdr_t)-1);
if( checksum == pData->structured.payload[len] )
{
return ePacketValid_c;
}
}
return eFramingError_c;
}
/* function used to manage request/response commands */
void THCI_ProcessRxPkt (clientPacket_t* pPacket)
{
fsci_Status_t status;
if(!pPacket){
return;
}
/* Process only FSCI confirms */
if( pPacket->structured.header.opGroup == gFSCI_CnfOpcodeGroup_c )
{
/* receive a confirm for a request.
* At this moment the requests are send from RadioUpgrade module */
//TBD add your handler here
switch(pPacket->structured.header.opCode)
{
case ...
default:
break;
}
}
else if(pPacket->structured.header.opGroup == gFSCI_ReqOpcodeGroup_c)
{
/* receive a request */
//TBD - add your handler here
switch(pPacket->structured.header.opCode)
{
case ...
default:
break;
}
}
}
/* function used to send formatted packets */
void THCI_TransmitFormatedPacket( clientPacket_t *pPacket )
{
uint32_t size;
uint8_t checksum;
uint16_t packetLen = pPacket->structured.header.len[0] + (pPacket->structured.header.len[1]<<8);
pPacket->structured.header.startMarker = gFsciStartMarker_c;
size = sizeof(clientPacketHdr_t) + packetLen + 1 /* CRC */;
/* Compute Checksum */
checksum = THCI_ComputeChecksum( pPacket->raw+1, size - 2);
pPacket->structured.payload[packetLen] = checksum;
/* send message to the serial interface */
serial_send_data(pPacket->raw, size);
}
/* compute checksum */
static uint8_t THCI_ComputeChecksum( uint8_t *pBuffer, uint16_t size )
{
uint16_t index;
uint8_t checksum = 0;
for ( index = 0; index < size; index++ )
{
checksum ^= pBuffer[index];
}
return checksum;
}
4. Update serial receive function to handle THCI packets
void serial_receive_data(uint8_t *pBuffer, uint16_t bufferLen)
{
...
if(THCI_CheckPacket((clientPacket_t *)buffer, bufferLen) == ePacketValid_c)
{
/* THCI Packet received */
THCI_ProcessRxPkt((clientPacket_t *)rx_buf->buf);
}
...
}
Let me know if you need more details,
Ovidiu