3
0
Fork 0
xnode/xnode-satellite/XnodeSatelliteRadio.cpp
2022-11-13 01:46:38 +01:00

205 lines
6 KiB
C++

#include <XnodeSatelliteRadio.h>
const char pmRadioChipInit[] PROGMEM = MSG_RF_CHIP_INIT;
const char pmRadioChipError[] PROGMEM = MSG_RF_CHIP_ERROR;
const char pmRadioExecutePrefix[] PROGMEM = "@";//MSG_REMOTE_PREFIX; // FIXME
const char pmRadioInfoFreq[] PROGMEM = MSG_RF_INFO_FREQ;
const char pmRadioInfoNetwork[] PROGMEM = MSG_RF_INFO_NETWORK;
const char pmRadioInfoNode[] PROGMEM = MSG_RF_INFO_NODE;
const char pmRadioInfoKey[] PROGMEM = MSG_RF_INFO_KEY;
const char pmRadioEncrypt[] PROGMEM = MSG_RF_ENCRYPT;
const char pmRadioInfo[] PROGMEM = MSG_RF_INFO;
uint8_t rf_status_chip = ZERO;
uint8_t rf_status_key = ZERO;
volatile unsigned long key_fetch_timer = ZERO;
volatile unsigned long key_encrypt_timer = ZERO;
xp_super_t rf_data;
xp_msg_init_t* rf_msg_init;
xp_msg_flash_t* rf_msg_flash;
xp_msg_char_t* rf_msg_char;
RFM69 radio;
XnodeSatelliteRadio XSRadio;
void XnodeSatelliteRadio::begin() {
XSerial.printCommentLineP(pmRadioChipInit);
if (!radio.initialize(RF_FREQUENCY, XSHardware.config.node_id, RF_NETWORK_ID)) {
XSerial.printCommentLineP(pmRadioChipError);
rf_status_chip = ONE;
return;
}
key_encrypt_timer = millis() + (unsigned long) RF_KEY_ENCRYPT_TIME;
key_fetch_timer = millis() + (unsigned long) RF_KEY_FETCH_TIME;
// Print serial info
XSerial.executeCommandP(pmRadioInfo);
}
void XnodeSatelliteRadio::loop() {
if (rf_status_chip != ZERO) {
return; // no chip
}
if (key_encrypt_timer != ZERO) {
initEncryptionKey();
}
if (!radio.receiveDone()) {
return;
}
//rf_status_data = ZERO;
rf_data = *(xp_super_t*) radio.DATA;
#ifdef DEBUG_RADIO
Serial.print(F("#D rf_rx "));
Serial.print(radio.SENDERID,DEC);
Serial.print(CHAR_SPACE);
Serial.print(rf_data.msg_type,DEC);
Serial.print(CHAR_NEWLINE);
#endif
// always reply ack if requested, see sendWithRetry impl
if (radio.ACK_REQUESTED) {
#ifdef DEBUG_RADIO
Serial.println(F("#D rf_sendACK"));
#endif
radio.sendACK();
}
if (rf_data.msg_type == RF_MSG_NODE_INIT) {
handleNodeInit();
} else if (rf_data.msg_type == RF_MSG_NODE_COMMAND) {
handleNodeCommand();
}
}
void XnodeSatelliteRadio::handleNodeInit() {
rf_msg_init = (xp_msg_init_t*) rf_data.msg_data;
if (XSHardware.config.node_id != rf_msg_init->node_id) {
#ifdef DEBUG_RADIO
Serial.print(F("#D init "));
Serial.print(rf_msg_init->node_id,DEC);
Serial.print(CHAR_NEWLINE);
#endif
XSHardware.config.node_id = rf_msg_init->node_id; // allow new node_id
}
for (byte i = ZERO; i < RF_KEY_SIZE; ++i) {
XSHardware.config.rf_key[i] = rf_msg_init->rf_key[i];
}
XSystem.configSave();
key_fetch_timer = ZERO; // stop sending because we have reply
if (XSHardware.config.node_id != rf_msg_init->node_id) {
radio.initialize(RF_FREQUENCY, XSHardware.config.node_id, RF_NETWORK_ID); // re-init
}
}
void XnodeSatelliteRadio::handleNodeCommand() {
rf_msg_char = (xp_msg_char_t*) rf_data.msg_data;
XSerial.print(CHAR_NEWLINE);
XSerial.printCharP(pmRadioExecutePrefix);
//XSerial.printPromtLine();
//XSerial.processCommand(rf_msg_char->char_data);
}
void XnodeSatelliteRadio::initEncryptionKey() {
if (millis() > key_encrypt_timer) {
cmdClose(); // do once after timeout
return;
}
if (key_fetch_timer==ZERO) {
return; // we are done
}
if (millis() < key_fetch_timer) {
return; // wait until next fetch
}
key_fetch_timer = millis() + (unsigned long) RF_KEY_FETCH_TIME;
// Setup first data package for fetching key rf_keys.
rf_data.msg_type = RF_MSG_NODE_INIT;
rf_msg_init = (xp_msg_init_t*) rf_data.msg_data;
rf_msg_init->node_id = XSHardware.config.node_id; // send our id, so we fetch only once new id.
send();
}
byte XnodeSatelliteRadio::readTemperature() {
return radio.readTemperature();
}
bool XnodeSatelliteRadio::isSecure() {
return key_encrypt_timer == ZERO;
}
void XnodeSatelliteRadio::cmdClose() {
XSystem.buildReplyPValue(pmRadioEncrypt, ONE);
radio.encrypt((const char*) XSHardware.config.rf_key);
key_encrypt_timer = ZERO; // disable calling initEncrytion and this
}
void XnodeSatelliteRadio::cmdOpen() {
if (key_encrypt_timer != ZERO) {
return; // only open if it is encrypted already
}
radio.encrypt(ZERO);
key_encrypt_timer = millis() + (unsigned long) RF_KEY_ENCRYPT_TIME;
XSystem.buildReplyPValue(pmRadioEncrypt, ZERO);
}
void XnodeSatelliteRadio::send() {
//rf_tx++;
if (radio.sendWithRetry(RF_BASE_NODE_ID, (const void*) &rf_data, sizeof(xp_super_t)), 5, 100) {
// TODO make cnt
Serial.println("# send ok");
} else {
Serial.println("# ERR: send failed");
}
}
void XnodeSatelliteRadio::sendNodeData(char* data) {
rf_data.msg_type = RF_MSG_NODE_DATA;
rf_msg_char = (xp_msg_char_t*) rf_data.msg_data;
// TODO: add loop + cnt over data
strcpy(rf_msg_char->char_data, data);
send();
}
void XnodeSatelliteRadio::sendCommandP(const char* cmdName) {
if (!isSecure()) {
return; // wait until line is secure
}
char sendCommandBuff[32];
strcpy(sendCommandBuff, XUtil.UNPSTR(cmdName)); // free buffer as gets used in strcmpP again..
XSystem.executeCommand(sendCommandBuff);
sendNodeData(XSystem.replyBuffer); // print result or error
}
void XnodeSatelliteRadio::cmdInfo() {
// Print key
XSystem.buildReplyPValueByteA(pmRadioInfoKey,XSHardware.config.rf_key,RF_KEY_SIZE);
// Print radio config
XSystem.buildReplyPValue(pmRadioInfoFreq,(int) RF_FREQUENCY == RF69_433MHZ ? 433 : RF_FREQUENCY == RF69_868MHZ ? 868 : 915);
XSystem.buildReplyPValue(pmRadioInfoNetwork,(int) RF_NETWORK_ID);
XSystem.buildReplyPValue(pmRadioInfoNode,(int) XSHardware.config.node_id);
XSystem.buildReplyPValue(pmRadioEncrypt,(int) key_encrypt_timer == ZERO ? ONE : ZERO);// if timer==0 then encrypted=1
}
void XnodeSatelliteRadio::systemModuleCommandList() {
XSystem.buildReplyCommandListP(pmRadioInfo);
XSystem.buildReplyCommandListP(pmRadioEncrypt);
}
bool XnodeSatelliteRadio::systemModuleCommandExecute(char* cmd, char** args) {
if (XUtil.strcmpP(cmd, pmRadioInfo) == ZERO) {
cmdInfo();
return true;
} else if (XUtil.strcmpP(cmd, pmRadioEncrypt) == ZERO) {
if (key_encrypt_timer == ZERO) {
cmdOpen();
} else {
cmdClose();
}
return true;
}
return false;
}