AudioConsole/AudioConsole.X/Source/NetworkProtocol.c
2025-02-19 18:23:12 -05:00

368 lines
8.8 KiB
C
Raw Blame History

/**********************************************************************
Project: Automatic cat feeder
Date: march 19 2006
Author: Jean-Fran<61>ois Martel
Target: PIC 18F252
Compiler: Microchip mcc18
Filename: Protocol.c
File description: Communication protocol implementation.
jean-francois.martel@polymtl.ca
**********************************************************************/
#include "define.h"
#include "NetworkProtocol.h"
#include "Uart.h"
#include <string.h>
#include "MasterCtrlInterface.h"
#include "LoraNetworkInterface.h"
#include "LTENetworkInterface.h"
static char MyDeviceID = ID_SPRINKLER_DEVICE;
char mFrameData[MAX_MESSAGE_SIZE+10];
ProtocolData_t mAudioConsoleIFProtocolData;
ProtocolData_t mMasterCtrlIFData;
void ProtocolInit(int User)
{
ProtocolData_t *DataStruct;
switch(User)
{
case NETWORK_PROTOCOL_USER_AUDIO_CONSOLE_IF:
{
DataStruct = &mAudioConsoleIFProtocolData;
break;
}
case NETWORK_PROTOCOL_USER_MASTER_CTRL_IF:
{
DataStruct = &mMasterCtrlIFData;
break;
}
default:
return;
break;
}
ResetStateMachine(DataStruct);
}
void StateMachine(unsigned char Data,ProtocolData_t *ProtocolData )
{
switch(ProtocolData->State)
{
case Initialization: //Reset all pointers and data...
{
ProtocolData->DataSize = 0;
ProtocolData->BufPtr = 0;
ProtocolData->RxPtr = 0;
ProtocolData->Command = 0;
ProtocolData->CRC = 0;
ProtocolData->State = RxHeader;
break;
}
case RxHeader: //Wait for data header...
{
if(Data == FRAME_HEADER)
{
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxAdd;
ProtocolData->CRC ^= Data;
}
else
{
ProtocolData->DataSize = 0;
ResetStateMachine(ProtocolData);
}
break;
}
case RxAdd: //Sender Address.
{
ProtocolData->SenderAddress = Data;
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxID;
ProtocolData->CRC ^= Data;
break;
}
case RxID: //Sender ID
{
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxMyID;
ProtocolData->SenderID = Data;
ProtocolData->CRC ^= Data;
break;
}
case RxMyID:
{
// if(Data != MyDeviceID && Data != BROADCAST_VALUE) //Message is not for this type of device and it's not a broadcast
// {
// ResetStateMachine();
// break;
// }
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxMyAddress;
ProtocolData->CRC ^= Data;
break;
}
case RxMyAddress:
{
if(Data != MY_DEVICE_ADDRESS && Data != BROADCAST_VALUE) //Message is not for this device address and it's not a broadcast
{
ResetStateMachine(ProtocolData);
break;
}
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxFlags;
ProtocolData->CRC ^= Data;
break;
}
case RxFlags:
{
ProtocolData->Flags = Data;
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxCMD;
ProtocolData->CRC ^= Data;
break;
}
case RxCMD:
{
ProtocolData->Command = Data;
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxSize1;
ProtocolData->CRC ^= Data;
break;
}
case RxSize1: //Data size MSB
{
ProtocolData->DataSize = 0;
ProtocolData->DataSize = (unsigned int)Data;
ProtocolData->DataSize <<= 8;
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxSize2;
ProtocolData->CRC ^= Data;
break;
}
case RxSize2: //Data size
{
ProtocolData->DataSize |= (unsigned int)Data;
ProtocolData->DataSize <<= 8;
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxSize3;
ProtocolData->CRC ^= Data;
break;
}
case RxSize3: //Data size
{
ProtocolData->DataSize |= (unsigned int)Data;
ProtocolData->DataSize <<= 8;
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->State = RxSize4;
ProtocolData->CRC ^= Data;
break;
}
case RxSize4: //Data size LSB
{
ProtocolData->DataSize |= (unsigned int)Data;
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
if(ProtocolData->DataSize > MAX_MESSAGE_SIZE)
ResetStateMachine(ProtocolData);
if(ProtocolData->DataSize == 0)
ProtocolData->State = RxCRC;
else
ProtocolData->State = RxData;
ProtocolData->CRC ^= Data;
break;
}
case RxData:
{
ProtocolData->CRC ^= Data;
ProtocolData->mRxData[ProtocolData->BufPtr++] = Data;
ProtocolData->DataCtr++;
if(ProtocolData->DataCtr == ProtocolData->DataSize)
{
ProtocolData->State = RxCRC;
}
break;
}
case RxCRC:
{
if(Data != ProtocolData->CRC)
{
ResetStateMachine(ProtocolData);
// ProtocolAcknowledge(0,Command,0);
break;
}
// NewMasterMessageReceived(mRxData);
if(ProtocolData == &mAudioConsoleIFProtocolData)
{
// ExecuteLoraMasterCommand(ProtocolData->Command,ProtocolMsgDataPtr(ProtocolData),ProtocolData->DataSize);
}
else if(ProtocolData == &mMasterCtrlIFData)
{
// ExecuteLTEMasterCommand(ProtocolData->SenderID, ProtocolData->Command,ProtocolMsgDataPtr(ProtocolData),ProtocolData->DataSize);
}
ResetStateMachine(ProtocolData);
break;
}
default:
{
ResetStateMachine(ProtocolData);
break;
}
}
}
void ProtocolAnalyzeBuffer(unsigned char *Data, int size, int User)
{
int i = 0;
for(i = 0; i < size; i++)
{
ProtocolAnalyzeNewData(Data[i],User);
}
}
void ProtocolAnalyzeNewData(unsigned char Data, int User)
{
ProtocolData_t *DataStruct;
switch(User)
{
case NETWORK_PROTOCOL_USER_AUDIO_CONSOLE_IF:
{
DataStruct = &mAudioConsoleIFProtocolData;
break;
}
case NETWORK_PROTOCOL_USER_MASTER_CTRL_IF:
{
DataStruct = &mMasterCtrlIFData;
break;
}
default:
return;
break;
}
// mRxData[RxPtr] = Data;
// printf("%X",Data);
StateMachine(Data, DataStruct);
}
void ResetStateMachine(ProtocolData_t *ProtocolData)
{
ProtocolData->DataSize = 0;
ProtocolData->BufPtr = 0;
ProtocolData->RxPtr = 0;
ProtocolData->Command = 0;
ProtocolData->CRC = 0;
ProtocolData->State = RxHeader;
ProtocolData->DataCtr = 0;
ProtocolData->Flags = 0;
ProtocolData->SenderAddress = 0;
}
void ProtocolExecCmd(void)
{
// switch(Command)
// {
// case RX_GET_STATUS:
// {
// unsigned char StatusByte =0;
//// memcpy(&StatusByte, &IRRemoteStatus, sizeof(IRRemoteStatus));
//// ProtocolSendCmd(TX_DEADBOLT_STATUS,&StatusByte,sizeof(StatusByte),1,0);
//
// break;
// }
// }
}
void ProtocolAcknowledge(unsigned char Answer,unsigned char Cmd, unsigned char Data)
{
unsigned char data[2];
if(Answer == 1)
{
data[0] = PROTOCOL_ACK; //CMD
}
else
{
data[0] = PROTOCOL_NAK; //CMD
}
data[1] = Cmd;
// ProtocolSendCmd(TX_NETWORK_ACK,&data[0],2,1,0);
}
unsigned char ProtocolCalcCrc(unsigned char* Buffer,unsigned char size)
{
unsigned char CRC = 0;
unsigned char i;
for(i = 0; i < size; i++)
CRC ^= Buffer[i];
return CRC;
}
unsigned char ProtocolIsReceiving(void)
{
// if(State == RxHeader)
// return 0; // Idle...
// else
// return 1; //receiving from serial port
}
unsigned char* ProtocolGetFrame(unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags, int *FrameSize)
{
if(Size > MAX_MESSAGE_SIZE)
{
*FrameSize = 0;
return &mFrameData[FRAME_HEADER_INDEX];
}
mFrameData[FRAME_HEADER_INDEX] = FRAME_HEADER; //header
mFrameData[FRAME_SENDER_ADDRESS_INDEX] = MY_DEVICE_ADDRESS; //My Address
mFrameData[FRAME_SENDER_DEVICE_ID_INDEX] = SenderDevice; //My ID
mFrameData[FRAME_DEST_DEVICE_ID_INDEX] = DestDevice; //Destination ID
mFrameData[FRAME_DEST_ADDRESS_INDEX] = DestAddress ;//Address; //Destination Address
mFrameData[FRAME_FLAGS_INDEX] = Flags; //Flags
mFrameData[FRAME_COMMAND_INDEX] = Cmd; //Command to send
mFrameData[FRAME_SIZE1_INDEX] = (unsigned char)((Size >> 24) & 0xFF);
mFrameData[FRAME_SIZE2_INDEX] = (unsigned char)((Size >> 16) & 0xFF);
mFrameData[FRAME_SIZE3_INDEX] = (unsigned char)((Size >> 8) & 0xFF);
mFrameData[FRAME_SIZE4_INDEX] = (unsigned char)(Size & 0xFF);
memcpy((void*)&mFrameData[FRAME_DATA_INDEX],(void*)Data,Size); //Cmd data
mFrameData[Size+FRAME_DATA_INDEX] = ProtocolCalcCrc(mFrameData,Size + FRAME_DATA_INDEX); // CRC
*FrameSize = Size + FRAME_INDEX_NBR;
return &mFrameData[FRAME_HEADER_INDEX];
}
unsigned char *ProtocolMsgDataPtr(ProtocolData_t *ProtocolData)
{
return &ProtocolData->mRxData[FRAME_DATA_INDEX];
}