344 lines
14 KiB
C
344 lines
14 KiB
C
#include "LTENetworkInterface.h"
|
|
#include "NetworkProtocol.h"
|
|
#include "SIM7080GInterface.h"
|
|
#include "timer.h"
|
|
#include "ChaletPowerRelay.h"
|
|
#include "HarakiriRelay.h"
|
|
#include "BatteryMonitor.h"
|
|
#include "LedLightCtrl.h"
|
|
#include "TemperatureSensor.h"
|
|
#include "SPI_Flash.h"
|
|
#include "FlashMapping.h"
|
|
#include "LoraWatchdog.h"
|
|
#include "versionbuild.h"
|
|
#include "WiFiCtrl.h"
|
|
#include "BoardCfg.h"
|
|
|
|
int mLTENWISMState;
|
|
static const char mFirmwareVersion[15] = VERSIONNUMBER;
|
|
#define LORA_CHALET_STATUS_CUR_SENSOR_MASK 0x02
|
|
#define LORA_CHALET_STATUS_POWER_RELAY_MASK 0x01
|
|
|
|
unsigned int mLTETotalMasterNbRequests = 0;
|
|
|
|
void LTENetworkInterfaceInit()
|
|
{
|
|
ProtocolInit(NETWORK_PROTOCOL_USER_LTE);
|
|
|
|
mLTENWISMState = LTE_NWI_INIT_STATE;
|
|
}
|
|
|
|
void ExecuteLTEMasterCommand(int SenderID, int Command, unsigned char *Data, int DataSize)
|
|
{
|
|
KickLoraWatchdog();
|
|
ChaletPowerRelayKickTimer();
|
|
mLTETotalMasterNbRequests++;
|
|
LTE_MODULE_RX_LED_PIN = LED_OFF;
|
|
switch(SenderID)
|
|
{
|
|
case ID_MASTER:
|
|
{
|
|
switch(Command)
|
|
{
|
|
case CHALET_INTERFACE_ACK:
|
|
{
|
|
break;
|
|
}
|
|
case CHALET_GENERAL_STATUS_REQUEST:
|
|
{
|
|
float FloatVoltage = GetBatteryVoltage(1);
|
|
float FloatTemperature = TempSensorGetTemp();
|
|
unsigned int BattVoltage = *((int*)&FloatVoltage);
|
|
unsigned int Temperature = *((int*)&FloatTemperature);
|
|
int SolarPanelCurrent = GetSolarPanelCurrent();
|
|
int SOC = GetBatterySOC();
|
|
|
|
char GeneralStatus = 0;
|
|
char ChaletStatus[18];
|
|
|
|
if(GetChaletPowerRelayState() == CHALET_POWER_RELAY_ON_STATE)
|
|
{
|
|
GeneralStatus |= LORA_CHALET_STATUS_POWER_RELAY_MASK;
|
|
}
|
|
if(GetCurrentModuleOK() == true)
|
|
{
|
|
GeneralStatus |= LORA_CHALET_STATUS_CUR_SENSOR_MASK;
|
|
}
|
|
|
|
ChaletStatus[0] = GeneralStatus; //General Status
|
|
ChaletStatus[1] = GetWiFiSate(); //Wifi Module state
|
|
|
|
ChaletStatus[2] = (char)(BattVoltage & 0x000000FF); //Battery Voltage 1
|
|
BattVoltage >>= 8;
|
|
ChaletStatus[3] = (char)(BattVoltage & 0x000000FF); //Battery Voltage 2
|
|
BattVoltage >>= 8;
|
|
ChaletStatus[4] = (char)(BattVoltage & 0x000000FF); //Battery Voltage 3
|
|
BattVoltage >>= 8;
|
|
ChaletStatus[5] = (char)(BattVoltage & 0x000000FF); //Battery Voltage 4
|
|
|
|
ChaletStatus[6] = (char)(SolarPanelCurrent & 0x000000FF); //Solar panel Current 1
|
|
SolarPanelCurrent >>= 8;
|
|
ChaletStatus[7] = (char)(SolarPanelCurrent & 0x000000FF); //Solar panel Current 2
|
|
|
|
ChaletStatus[8] = (char)(SOC & 0x000000FF); //Battery SOC 1
|
|
SolarPanelCurrent >>= 8;
|
|
ChaletStatus[9] = (char)(SolarPanelCurrent & 0x000000FF); //Battery SOC 2
|
|
|
|
ChaletStatus[10] = (char)(Temperature & 0x000000FF); //Temperature 1
|
|
Temperature >>= 8;
|
|
ChaletStatus[11] = (char)(Temperature & 0x000000FF); //Temperature 2
|
|
Temperature >>= 8;
|
|
ChaletStatus[12] = (char)(Temperature & 0x000000FF); //BTemperature 3
|
|
Temperature >>= 8;
|
|
ChaletStatus[13] = (char)(Temperature & 0x000000FF); //Temperature 4
|
|
|
|
int tmp = mLTETotalMasterNbRequests;
|
|
ChaletStatus[14] = (char)(mLTETotalMasterNbRequests & 0x000000FF); //Total Nb Requests 1
|
|
mLTETotalMasterNbRequests >>= 8;
|
|
ChaletStatus[15] = (char)(mLTETotalMasterNbRequests & 0x000000FF); //Total Nb Requests 2
|
|
mLTETotalMasterNbRequests >>= 8;
|
|
ChaletStatus[16] = (char)(mLTETotalMasterNbRequests & 0x000000FF); //Total Nb Requests 3
|
|
mLTETotalMasterNbRequests >>= 8;
|
|
ChaletStatus[17] = (char)(mLTETotalMasterNbRequests & 0x000000FF); //Total Nb Requests 4
|
|
mLTETotalMasterNbRequests = tmp;
|
|
|
|
|
|
SendLTENetworkCommand(CHALET_GENERAL_STATUS_RESPONSE,ChaletStatus,18);
|
|
|
|
HEARTBEAT_LED_1_PIN = ~HEARTBEAT_LED_1_PIN;
|
|
|
|
break;
|
|
}
|
|
case CHALET_AC_POWER_STATE_STATUS_REQUEST:
|
|
{
|
|
char PowerStatus = GetChaletPowerRelayState();
|
|
SendLTENetworkCommand(CHALET_AC_POWER_STATE_STATUS_RESPONSE,&PowerStatus,1);
|
|
break;
|
|
}
|
|
case CHALET_AC_POWER_SET_STATE_REQUEST:
|
|
{
|
|
char response = CHALET_POWER_RELAY_UNKNOWN_STATE;
|
|
if(Data[0] == CHALET_POWER_RELAY_OFF_STATE)
|
|
{
|
|
ChaletPowerRelayTurnOff();
|
|
response = CHALET_POWER_RELAY_OFF_STATE;
|
|
}
|
|
else if(Data[0] == CHALET_POWER_RELAY_ON_STATE)
|
|
{
|
|
ChaletPowerRelayTurnOn();
|
|
response = CHALET_POWER_RELAY_ON_STATE;
|
|
}
|
|
else
|
|
{
|
|
//invalid state requested.... don't do anything
|
|
response = CHALET_POWER_RELAY_UNKNOWN_STATE;
|
|
}
|
|
|
|
SendLTENetworkCommand(CHALET_AC_POWER_SET_STATE_RESPONSE,&response,1);
|
|
|
|
break;
|
|
}
|
|
case CHALET_BATTERY_VOLTAGE_REQUEST:
|
|
{
|
|
|
|
break;
|
|
}
|
|
case CHALET_WIFI_STATUS_REQUEST:
|
|
{
|
|
char response[5];
|
|
uint32 IPAddress = GetCurIPAddress();
|
|
|
|
response[0] = GetWiFiSate(); //Wifi Module state
|
|
response[1] = IPV4_BYTE(IPAddress,0);
|
|
response[2] = IPV4_BYTE(IPAddress,1);
|
|
response[3] = IPV4_BYTE(IPAddress,2);
|
|
response[4] = IPV4_BYTE(IPAddress,3);
|
|
SendLTENetworkCommand(CHALET_WIFI_STATUS_RESPONSE,(unsigned char*)&response,5);
|
|
break;
|
|
}
|
|
case CHALET_WIFI_SET_STATE_REQUEST:
|
|
{
|
|
char response = WIFI_UNKNOWN_STATE;
|
|
if(Data[0] == 0)
|
|
{
|
|
TurnOFFWiFi();
|
|
response = 0;
|
|
}
|
|
else if(Data[0] == 1)
|
|
{
|
|
if(GetWiFiSate() != WIFI_CONNECTED_STATE)
|
|
{
|
|
InitWiFi();
|
|
response = GetWiFiSate();
|
|
}
|
|
else
|
|
{
|
|
response = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//invalid state requested.... don't do anything
|
|
response = WIFI_UNKNOWN_STATE;
|
|
}
|
|
|
|
SendLTENetworkCommand(CHALET_WIFI_SET_STATE_RESPONSE,&response,1);
|
|
break;
|
|
}
|
|
case CHALET_DO_HARAKIRI_REQUEST:
|
|
{
|
|
char response;
|
|
if(Data[0] == 0xBA &&
|
|
Data[1] == 0xAD &&
|
|
Data[2] == 0xBE &&
|
|
Data[3] == 0xEF)
|
|
{
|
|
//Magic word is OK... let's suicide...
|
|
response = 0x01;
|
|
//First, send an ACK to master (this is blocking so it's OK)
|
|
SendLTENetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
|
|
HarakiriRelayTurnOff();
|
|
}
|
|
else
|
|
{
|
|
response = 0x00;
|
|
SendLTENetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
|
|
}
|
|
break;
|
|
}
|
|
case CHALET_REBOOT_CPU_REQUEST:
|
|
{
|
|
char response;
|
|
if(Data[0] == 0xBA &&
|
|
Data[1] == 0xAD &&
|
|
Data[2] == 0xCA &&
|
|
Data[3] == 0xFE)
|
|
{
|
|
//Magic word is OK... let's reboot...
|
|
response = 0x01;
|
|
//First, send an ACK to master (this is blocking so it's OK)
|
|
SendLTENetworkCommand(CHALET_REBOOT_CPU_RESPONSE,&response,1);
|
|
Sleep(100);
|
|
TurnOFFWiFi();
|
|
Sleep(100);
|
|
SoftReset();
|
|
}
|
|
else
|
|
{
|
|
response = 0x00;
|
|
SendLTENetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
|
|
}
|
|
break;
|
|
}
|
|
case CHALET_GET_STORED_WIFI_SETTINGS_REQUEST:
|
|
{
|
|
char response[140];
|
|
char WifiDataSize;
|
|
SPIFlashReadBuffer(response,11,FLASH_WIFI_IP_ADDRESS);
|
|
WifiDataSize = 11 + response[9] + response[10];
|
|
if(WifiDataSize > 140)
|
|
break;
|
|
SPIFlashReadBuffer(response,WifiDataSize,FLASH_WIFI_IP_ADDRESS);
|
|
SendLTENetworkCommand(CHALET_GET_STORED_WIFI_SETTINGS_RESPONSE,response,WifiDataSize);
|
|
break;
|
|
}
|
|
case CHALET_SET_STORED_WIFI_SETTINGS_REQUEST:
|
|
{
|
|
char response = 0;
|
|
if(SPIFlashWriteBuffer(Data,DataSize,FLASH_WIFI_IP_ADDRESS) == 1)
|
|
{
|
|
response = 1;
|
|
}
|
|
|
|
SendLTENetworkCommand(CHALET_SET_STORED_WIFI_SETTINGS_RESPONSE,&response,1);
|
|
break;
|
|
}
|
|
case CHALET_GET_FIRMWARE_VERSION_REQUEST:
|
|
{
|
|
SendLTENetworkCommand(CHALET_GET_FIRMWARE_VERSION_RESPONSE,(unsigned char*)mFirmwareVersion,15);
|
|
break;
|
|
}
|
|
case CHALET_CLEAR_COMMS_STATISTICS_REQUEST:
|
|
{
|
|
char response = 1;
|
|
mLTETotalMasterNbRequests = 0;
|
|
SendLTENetworkCommand(CHALET_CLEAR_COMMS_STATISTICS_RESPONSE,&response,1);
|
|
break;
|
|
}
|
|
case ETH_NETWK_DEVICE_INFO_REQUEST:
|
|
{
|
|
char data[2];
|
|
data[0] = ID_CHALET_DEVICE;
|
|
data[1] = MY_DEVICE_ADDRESS;
|
|
int PayloadSize;
|
|
unsigned char *response = ProtocolGetFrame(ID_MASTER,MASTER_ADDRESS,ID_ETHERNET_VIRTUAL,ETH_NETWK_DEVICE_INFO_RESPONSE, data,2,0, &PayloadSize);
|
|
LTESendDataToMaster((char*)response,PayloadSize);
|
|
|
|
break;
|
|
}
|
|
case ETH_NETWK_SET_DEVICE_INFO_ACK:
|
|
{
|
|
LTENetworInterfaceExecSM(LTE_NWI_MASTER_CONNECTED_EVENT);
|
|
break;
|
|
}
|
|
case ETH_NETWK_CONNECTION_REFUSED:
|
|
{
|
|
//TODO: reset the TCP module to retry connection???
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TickLTENetworkInterface()
|
|
{
|
|
LTENetworInterfaceExecSM(LTE_NWI_TICK_EVENT);
|
|
}
|
|
|
|
void LTENetworInterfaceExecSM(int Event)
|
|
{
|
|
switch(mLTENWISMState)
|
|
{
|
|
case LTE_NWI_INIT_STATE:
|
|
{
|
|
mLTENWISMState = LTE_NWI_CONNECT_TO_MASTER_STATE;
|
|
TimerStart(LTE_NWI_TIMER,LTE_NWI_MASTER_CONNECT_POLL_INTERVAL);
|
|
break;
|
|
}
|
|
case LTE_NWI_WAIT_FOR_LTE_STATE:
|
|
{
|
|
//Not necessary... master will init handshake on TCP connection....
|
|
break;
|
|
}
|
|
case LTE_NWI_CONNECT_TO_MASTER_STATE: //Here we wait for the master to initiate the handshake after a TCP connection
|
|
{
|
|
if(Event == LTE_NWI_MASTER_CONNECTED_EVENT)
|
|
{
|
|
mLTENWISMState = LTE_NWI_OPERATE_STATE;
|
|
}
|
|
break;
|
|
}
|
|
case LTE_NWI_OPERATE_STATE:
|
|
{
|
|
if(Event == LTE_NWI_TICK_EVENT)
|
|
{
|
|
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SendLTENetworkCommand(int Command, unsigned char *Data, unsigned int DataSize)
|
|
{
|
|
unsigned char *Payload;
|
|
unsigned int PayloadSize;
|
|
Payload = ProtocolGetFrame(ID_MASTER,MASTER_ADDRESS,ID_CHALET_DEVICE,Command,Data,DataSize,0,&PayloadSize);
|
|
LTESendDataToMaster(Payload,PayloadSize);
|
|
} |