295abb37ee
Firmware for an autonomous wave-measurement buoy (ATmega2560-based WII5 v2 board). Reads wave motion from a Sparton AHRS-M1/M2 IMU, samples GPS and battery state, and reports back over Iridium SBD satellite telemetry. Originally developed 2012-2024. This is the first public release. Code, documentation, and field-tested operating modes (Capture, Sleep, Position, ManualTest, SelfTest, LowBattery) are licensed under Apache 2.0 — see LICENSE and NOTICE. See README.md for an overview and build instructions, CONTRIBUTING.md for how to contribute, and DEPLOYMENTS.md for the field-deployment log.
658 lines
24 KiB
C++
658 lines
24 KiB
C++
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
|
|
//
|
|
// This file is part of WII5 Buoy firmware.
|
|
// See LICENSE for full terms.
|
|
|
|
/**
|
|
* @file WII5Communications.cpp
|
|
* @brief High-level communications dispatcher: orchestrates Iridium send/receive flows.
|
|
*/
|
|
|
|
/*
|
|
|
|
TODO 2024 - This seems a little over complicated, any simplification possible
|
|
* List of results to send with current SD card???
|
|
* Status - what to send what not to?
|
|
|
|
TODO: Full testing, especially:
|
|
. Receiving multiple messages when only sending one
|
|
. New sdBlock code for loading and finding records
|
|
|
|
Communications - Really in control of Iridium
|
|
|
|
However, it may become more, startup of Weather and Voltage.
|
|
Possibly even read/write SD cared for data
|
|
|
|
When is a message sent:
|
|
* By request - e.g. sendBinModeData
|
|
* Automatically - e.g. looking for unset results
|
|
* By time - if start is called and we get to JUMP, and it has been more than 12 hours.
|
|
(this last one covers the case where something has gotten stuck - e.g. Sparton Failure and no results to post)
|
|
|
|
Template in another Mode / State machine
|
|
|
|
Simple Mode - Just send messages requested, no looking at SD
|
|
|
|
Start sending a message (don't call again until stopped)
|
|
wii5Communications.setSimpleMode();
|
|
wii5Communications.sendBinModeType(1, 0);
|
|
wii5Communications.start();
|
|
|
|
while (!wii5Communications.isRunning()) {
|
|
Wait...
|
|
|
|
|
|
Complex Mode:
|
|
Start the background processing
|
|
wii5Communications.setAutoMode();
|
|
|
|
Be very careful of SD changes, power on/off/swap
|
|
Ideally, once you start - don't turn it off.
|
|
However, this may not always be practical.
|
|
Send signalSD when an SD Card is changed.
|
|
|
|
*/
|
|
|
|
#include <Arduino.h>
|
|
#include <TimeLib.h>
|
|
#include <WII5.h>
|
|
|
|
void WII5Communications::begin() {
|
|
step = WII5COMMUNICATIONS_IDLE;
|
|
lastStep = WII5COMMUNICATIONS_END;
|
|
wait = 0;
|
|
autoMode = false;
|
|
metadataScan = false;
|
|
testMode = false;
|
|
|
|
mainBinType = 0;
|
|
metadataBlock = 0;
|
|
resultsBlock = 0;
|
|
mainRecordCount = 0;
|
|
|
|
// Clear the request
|
|
requestBinType = 0;
|
|
requestMetadataBlock = 0;
|
|
requestResultsBlock = 0;
|
|
requestRecordCount = 0;
|
|
updateStatus = false;
|
|
countSucces = 0;
|
|
countFailed = 0;
|
|
|
|
// Find Request - these should happen before other requests or auto searches
|
|
findBinType = 0;
|
|
findRecordCount = 0; // When it finds this record it will select this address and the correct Results record
|
|
|
|
// TODO 2024 - Disabled - this is unsafe. Can we make it so there is a maimum - look at other loops
|
|
disabled = false;
|
|
}
|
|
|
|
// NOTE: Call start to clear
|
|
void WII5Communications::setTESTING() { testMode = true; }
|
|
|
|
// TODO 2024 - New code to disable - must timeout !!!
|
|
bool WII5Communications::setDisabled(bool in) {
|
|
disabled = in;
|
|
if (disabled) {
|
|
step = WII5COMMUNICATIONS_DISABLED;
|
|
console.log(LOG_INFO, F("Communications: disabled on (do nothing)"));
|
|
}
|
|
else {
|
|
step = WII5COMMUNICATIONS_IDLE;
|
|
console.log(LOG_INFO, F("Communications: disabled off (move to idle)"));
|
|
}
|
|
wait = 0;
|
|
return disabled;
|
|
}
|
|
void WII5Communications::setAutoMode() { autoMode = true; }
|
|
void WII5Communications::setSimpleMode() { autoMode = false; }
|
|
bool WII5Communications::getAutoMode() { return autoMode; }
|
|
bool WII5Communications::getSimpleMode() { return !autoMode; }
|
|
|
|
void WII5Communications::signalSD() {
|
|
// Reset that we definitely want a metadata scan
|
|
metadataScan = true;
|
|
|
|
// disable existing scans - set them to 0 - as this is a new SD
|
|
sdCardId = 0;
|
|
sdStartBlock = 0;
|
|
sdCurrentBlock = 0;
|
|
|
|
// Check the mode, and put it in appropriate place.
|
|
start();
|
|
}
|
|
|
|
void WII5Communications::findRecord(uint32_t t, uint32_t rc) {
|
|
// Set a type and Record Count to find, it will override the previous
|
|
findRecordCount = rc;
|
|
findBinType = t;
|
|
}
|
|
|
|
void WII5Communications::sendText(void *buf = NULL, uint16_t bufSize = 0) {
|
|
if (buf && bufSize > 0) {
|
|
strncpy(wii5Commands.lastCommandMessage, buf, bufSize); // < 235 ? bufSize, 235);
|
|
}
|
|
uint32_t replyType = wii5BinData.setBit(0, 4);
|
|
sendBinModeType(replyType, 0, 0, 0);
|
|
setSimpleMode();
|
|
console.log(LOG_INFO, F("Communications: sendText() message=%s"), wii5Commands.lastCommandMessage);
|
|
start();
|
|
}
|
|
|
|
void WII5Communications::sendError() {
|
|
uint32_t replyType = wii5BinData.setBit(0, 3);
|
|
wii5Commands.lastCommandResult = WII5RESULTS_ERROR;
|
|
sendBinModeType(replyType, 0, 0, 0);
|
|
setSimpleMode();
|
|
console.log(LOG_INFO, F("Communications: sendError() message=%s"), wii5Commands.lastCommandMessage);
|
|
start();
|
|
}
|
|
|
|
void WII5Communications::sendBinModeType(uint32_t t, uint32_t recordCount, uint32_t mdBlock, uint32_t resultsBlock) {
|
|
updateStatus = false;
|
|
requestWait = 0;
|
|
requestBinType = t;
|
|
requestRecordCount = recordCount; // Note - this does not look up the count - uses it to check Block
|
|
// Leave this at 0 to load currecnt record count
|
|
requestMetadataBlock = mdBlock; // Leave this at zero to not load a Block
|
|
requestResultsBlock = resultsBlock; // Leave this at zero to not load a Block
|
|
}
|
|
|
|
/*
|
|
|
|
How to use this library.
|
|
|
|
setType - The BinData type to be sent
|
|
setResultsRecord - Pick and SD Card and record to read.
|
|
- Or could have a setResultsBuf
|
|
- Not sure how to choose SD card - as it may be locked by maths etc
|
|
- Not sure how to keep copy of data - 512 bytes too much
|
|
. readRecord, just before BinData.set ?
|
|
- How to deal with queues and wrong cards.
|
|
|
|
Advanced use
|
|
|
|
Instead of just a type with record etc, this library should handle
|
|
things like sending raw data.
|
|
|
|
Simple Mode
|
|
- Like used in Position. Just send message requested.
|
|
|
|
Queue Mode
|
|
- Find missing entries, not yet sent
|
|
|
|
*/
|
|
|
|
|
|
void WII5Communications::start() {
|
|
// Note: Test mode is turned to false at each start. So to enable test mode, start then setTESTING
|
|
testMode = false;
|
|
|
|
sdDone = 0;
|
|
sdTried = 0;
|
|
if (step == WII5COMMUNICATIONS_IDLE) {
|
|
step = WII5COMMUNICATIONS_PREPARE; wait = 0;
|
|
}
|
|
}
|
|
|
|
void WII5Communications::stop() {
|
|
// TODO I think we should consider a shutdown, or just use first?
|
|
if (step != WII5COMMUNICATIONS_IDLE) {
|
|
step = WII5COMMUNICATIONS_END; wait = 0;
|
|
}
|
|
}
|
|
|
|
bool WII5Communications::isRunning() {
|
|
return (step != WII5COMMUNICATIONS_IDLE);
|
|
}
|
|
|
|
void WII5Communications::loop() {
|
|
bool first = (lastStep != step);
|
|
lastStep = step;
|
|
|
|
switch (step) {
|
|
case WII5COMMUNICATIONS_DISABLED:
|
|
if (first) {
|
|
console.log(LOG_DEBUG, F("Communications: step disabled"));
|
|
}
|
|
break;
|
|
|
|
case WII5COMMUNICATIONS_IDLE:
|
|
if (first) {
|
|
if (disabled) {
|
|
step = WII5COMMUNICATIONS_DISABLED; wait = 0;
|
|
}
|
|
console.log(LOG_DEBUG, F("Communications: step idle - manual waiting for start"));
|
|
wii5Iridium.stop();
|
|
countSend = 0; // We use this to count how many in this run
|
|
}
|
|
// More than 14 hours since last messsage - send out a ping
|
|
else if (lastSuccess > ((uint32_t)14*3600000)) {
|
|
console.log(LOG_DEBUG, F("Communications: Not sent a successful message in 14 hours - send pinkg"));
|
|
sendBinModeType(1,1,0,0);
|
|
// TODO Custom text for the error/reason
|
|
lastSuccess = 0; // To stop repeating every loop
|
|
}
|
|
break;
|
|
|
|
case WII5COMMUNICATIONS_PREPARE:
|
|
step = WII5COMMUNICATIONS_IRIDIUM_START; wait = 0;
|
|
break;
|
|
|
|
case WII5COMMUNICATIONS_IRIDIUM_START:
|
|
if (first) {
|
|
console.log(LOG_DEBUG, F("Communications: step IRIDIUM_START (firmware, imei, signalQuality)"));
|
|
if (testMode) {
|
|
console.log(LOG_FATAL, F("FAKE: skipping iridium request Firmware"));
|
|
step = WII5COMMUNICATIONS_JUMP; wait = 0;
|
|
}
|
|
else {
|
|
wii5Iridium.requestFirmware();
|
|
}
|
|
binNextBit = 0; // Important to start split
|
|
binCount = 0;
|
|
}
|
|
// Waiting - we are ready to send the text
|
|
else if (wii5Iridium.waiting()) {
|
|
step = WII5COMMUNICATIONS_JUMP; wait = 0;
|
|
}
|
|
// TODO Hard coded
|
|
else if (wait > 600000) {
|
|
console.log(LOG_ERROR, F("Communications: Iridium Timed out after 600 seconds"));
|
|
step = WII5COMMUNICATIONS_JUMP; wait = 0;
|
|
}
|
|
break;
|
|
|
|
// Decide what to do
|
|
case WII5COMMUNICATIONS_JUMP:
|
|
if (first) {
|
|
}
|
|
|
|
// Already got one moving on
|
|
else if (mainBinType > 0) {
|
|
console.log(LOG_DEBUG, F("Communications: step JUMP - existing message in mainBinType"));
|
|
step = WII5COMMUNICATIONS_IRIDIUM_SEND; wait = 0;
|
|
}
|
|
|
|
// New request - set it and move on
|
|
else if (requestBinType > 0) {
|
|
console.log(LOG_DEBUG, F("Communications: step JUMP - new message in requestBiType"));
|
|
// One in the background - must clearit, so not used again
|
|
mainBinType = requestBinType;
|
|
metadataBlock = requestMetadataBlock;
|
|
resultsBlock = requestResultsBlock;
|
|
mainRecordCount = requestRecordCount;
|
|
|
|
countSucces = 0;
|
|
countFailed = 0;
|
|
|
|
// Clear the request
|
|
requestBinType = 0;
|
|
requestMetadataBlock = 0;
|
|
requestResultsBlock = 0;
|
|
requestRecordCount = 0;
|
|
step = WII5COMMUNICATIONS_IRIDIUM_SEND; wait = 0;
|
|
}
|
|
else if (autoMode) {
|
|
// TODO - autoMode - decide what to do
|
|
// Only when we have nothing else to do
|
|
step = WII5COMMUNICATIONS_SD_NEXT; wait = 0;
|
|
}
|
|
// else if (Old!) {
|
|
// TODO Send a minimum packet
|
|
// }
|
|
else {
|
|
step = WII5COMMUNICATIONS_END; wait = 0;
|
|
}
|
|
|
|
// TODO Decide on loading data from SD
|
|
// 1. requestBlock or similar manuarl request (Which SD Card?)
|
|
// 2. Auto Mode - find a record not sent and send it
|
|
|
|
break;
|
|
|
|
// SD Next - find a record
|
|
case WII5COMMUNICATIONS_SD_NEXT:
|
|
|
|
// Find out the SD Card and Block we started at - if either change, start again
|
|
|
|
// TODO - consider openging the SD Card ourselves
|
|
|
|
// No card is open.... quit
|
|
if (!sdBlock.cardIsOpen()) {
|
|
// TODO - consider opening one? - Nah - Capture mode only
|
|
console.log(LOG_DEBUG, F("Communications: card is not open - finishing"));
|
|
sdCardId = 0;
|
|
sdStartBlock = 0;
|
|
sdCurrentBlock = 0;
|
|
step = WII5COMMUNICATIONS_END; wait = 0;
|
|
}
|
|
|
|
// Nothing processed - lets get that data from the SD card
|
|
else if ( (sdCardId == 0) || (sdStartBlock == 0) ) {
|
|
console.log(LOG_DEBUG, F("Communications: new card... getting locations"));
|
|
sdCardId = sdBlock.getCardId();
|
|
sdStartBlock = sdBlock.getMetadataNext(); // 1 record past where to read
|
|
sdCurrentBlock = sdBlock.getMetadataNext(); // Current record read, starts past because never reads. Sub one first
|
|
}
|
|
|
|
// Card has changed, blank these and move on
|
|
else if ( (sdBlock.getCardId() != sdCardId) || (sdBlock.getMetadataNext() != sdStartBlock)) {
|
|
console.log(LOG_DEBUG, F("Communications: card changed ! - trying to read new card"));
|
|
console.log(LOG_DEBUG, F("Communications: OldSD=%d, NewCard=%d"), int(sdCardId), int(sdBlock.getCardId()));
|
|
console.log(LOG_DEBUG, F("Communications: OldBlock=%lu, NewBlock=%lu"), sdCurrentBlock, sdBlock.getMetadataNext());
|
|
sdCardId = 0;
|
|
sdStartBlock = 0;
|
|
sdCurrentBlock = 0;
|
|
}
|
|
|
|
// Is the next block we have to read before the start?
|
|
else if ((sdCurrentBlock - 1) < sdBlock.getMetadataFirst()) {
|
|
console.log(LOG_DEBUG, F("Communications: Read all metadata records to start"));
|
|
// Finsihed readin as far as we can.
|
|
sdCardId = 0;
|
|
sdStartBlock = 0;
|
|
sdCurrentBlock = 0;
|
|
step = WII5COMMUNICATIONS_END; wait = 0;
|
|
}
|
|
|
|
// TODO - check if we have gone back far enough - e.g. 100 records.
|
|
// TODO - FIND ! This is where we can do the find.
|
|
|
|
// Do 100 max tests
|
|
else if (sdTried > 100) {
|
|
console.log(LOG_DEBUG, F("Communications: Tried 100 records, Finishing"));
|
|
// Finsihed readin as far as we can.
|
|
sdCardId = 0;
|
|
sdStartBlock = 0;
|
|
sdCurrentBlock = 0;
|
|
|
|
step = WII5COMMUNICATIONS_END; wait = 0;
|
|
}
|
|
|
|
// Do 10 transmitts
|
|
else if (sdDone > 10) {
|
|
console.log(LOG_DEBUG, F("Communications: Done 10 transmitts. Finsihing"));
|
|
// Finsihed readin as far as we can.
|
|
sdCardId = 0;
|
|
sdStartBlock = 0;
|
|
sdCurrentBlock = 0;
|
|
step = WII5COMMUNICATIONS_END; wait = 0;
|
|
|
|
}
|
|
|
|
// Read record and use now - cos might loose it
|
|
else {
|
|
sdTried++;
|
|
sdCurrentBlock--;
|
|
console.log(LOG_DEBUG, F("Communications: reading block: %lu"), sdCurrentBlock);
|
|
if (!sdBlock.read(sdCurrentBlock)) {
|
|
console.log(LOG_FATAL, F("Communications: Error reading this block. Skipping to next"));
|
|
// TODO what next afer error?
|
|
}
|
|
else {
|
|
WII5MetaDataObject* local_metadata = (WII5MetaDataObject*)(sdBlock.metadata->data);
|
|
// TODO Print this out to test ?
|
|
if (
|
|
// Status is blank, not sent or tried
|
|
(sdBlock.metadata->status == 0)
|
|
&& (sdBlock.metadata->resultsBlockStart != 0)
|
|
&& (sdBlock.metadata->recordId != 0)
|
|
&& (sdBlock.metadata->recordId == local_metadata->recordCount)
|
|
) {
|
|
console.log(LOG_DEBUG, F("Communications: Metadata readyy, but is Result?"));
|
|
|
|
// Copy the values across, but zero if next record fails - because we loose the data
|
|
mainBinType = wii5Config.getCaptureBinaryType();
|
|
metadataBlock = sdCurrentBlock;
|
|
resultsBlock = sdBlock.metadata->resultsBlockStart;
|
|
mainRecordCount = sdBlock.metadata->recordId;
|
|
updateStatus = true;
|
|
|
|
bool badResults = false;
|
|
|
|
// Read the block
|
|
if (!sdBlock.read(resultsBlock)) {
|
|
badResults = true;
|
|
console.log(LOG_ERROR, F("Communications: Failed to read results for testing"));
|
|
}
|
|
|
|
// All records should match
|
|
else if (sdBlock.block->recordId != mainRecordCount) {
|
|
badResults = true;
|
|
console.log(LOG_ERROR, F("Communications: Results bock record ID does not match, skipping"));
|
|
}
|
|
|
|
// This is a way I know the RESULTS block has been written to
|
|
else if (sdBlock.block->status != mainRecordCount) {
|
|
badResults = true;
|
|
console.log(LOG_ERROR, F("Communications: Results status is not the record count - it isn't ready to send"));
|
|
}
|
|
|
|
if (badResults) {
|
|
// Abandon ship
|
|
console.log(LOG_FATAL, F("Communications: Error reading this block. Skipping to next"));
|
|
mainBinType = 0;
|
|
metadataBlock = 0;
|
|
resultsBlock = 0;
|
|
mainRecordCount = 0;
|
|
updateStatus = false;
|
|
}
|
|
else {
|
|
console.log(LOG_FATAL, F("Communications: Block ready to send = %lu"), resultsBlock);
|
|
step = WII5COMMUNICATIONS_IRIDIUM_SEND; wait = 0;
|
|
}
|
|
}
|
|
else {
|
|
console.log(LOG_DEBUG, F("Communications: Skipping - Status = %lu"), sdBlock.metadata->status);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// SD Load Block
|
|
case WII5COMMUNICATIONS_SD_BLOCK:
|
|
step = WII5COMMUNICATIONS_IRIDIUM_SEND; wait = 0;
|
|
break;
|
|
|
|
// SEND a message
|
|
case WII5COMMUNICATIONS_IRIDIUM_SEND:
|
|
if (first) {
|
|
console.log(LOG_DEBUG, F("Communications: step IRIDIUM_SEND"));
|
|
}
|
|
// Safety
|
|
else if (binCount > 25) {
|
|
console.log(LOG_FATAL, F("Communications: More than 25 data splits - cancelling Iridium"));
|
|
step = WII5COMMUNICATIONS_END; wait = 0;
|
|
}
|
|
|
|
// if (wii5BinData.getSplit(wii5Config.getCommunicationsBinaryType(), 300, &binNextBit, &binType)) {
|
|
else {
|
|
// NOTE: Stil hard coded iridium number
|
|
if (wii5BinData.getSplit(mainBinType, 340, &binNextBit, &binType)) {
|
|
console.log(LOG_INFO, F("Communications: Sending BinData Splitting #=%d, original type/size=%lu/%d, new type/size=%lu/%d, nextBit=%d"),
|
|
binCount,
|
|
mainBinType, wii5BinData.getSize(mainBinType),
|
|
binType, wii5BinData.getSize(binType),
|
|
int(binNextBit)
|
|
);
|
|
binCount++;
|
|
|
|
// NOTE: setData will not set data from Blocks, call the necessary after steps.
|
|
// see BinData for more information.
|
|
wii5BinData.createData(binType, wii5BinaryIridium, 340, mainRecordCount);
|
|
wii5BinData.setData(binType, wii5BinaryIridium, 340); // TODO Hard coded
|
|
|
|
// NOTE: Performance. This should be split up into steps in this state machine, card open, read metadata, etc... This will do for now
|
|
if (metadataBlock) {
|
|
if (sdBlock.read(metadataBlock)) {
|
|
console.log(LOG_INFO, F("Communications: Loaded metadata=%lu and setting Iridium data"), metadataBlock);
|
|
// TODO Consider checking metadta block wth mainRecordCount
|
|
wii5BinData.setBlockMetadata(binType, wii5BinaryIridium, 340, (WII5MetaDataObject*)sdBlock.metadata->data);
|
|
}
|
|
else {
|
|
console.log(LOG_FATAL, F("Communications: FAILED TO LOAD Load metadata=%lu"), metadataBlock);
|
|
}
|
|
}
|
|
|
|
if (resultsBlock) {
|
|
if (sdBlock.read(resultsBlock)) {
|
|
console.log(LOG_INFO, F("Communications: Loaded results=%lu"), resultsBlock);
|
|
wii5BinData.setBlockResults(binType, wii5BinaryIridium, 340, (WII5Processed*)sdBlock.block->data);
|
|
}
|
|
else {
|
|
console.log(LOG_FATAL, F("Communications: FAILED TO LOAD Load results=%lu"), resultsBlock);
|
|
}
|
|
}
|
|
|
|
wii5Iridium.setBinSize(
|
|
wii5BinData.getSize(binType)
|
|
);
|
|
|
|
// Send it !
|
|
if (testMode)
|
|
console.log(LOG_FATAL, F("FAKE: Not requestSendBinary"));
|
|
else {
|
|
wii5Iridium.requestSendBinary();
|
|
countSend++;
|
|
}
|
|
|
|
waitStatus = true; // We are waiting for the status, unlike command replies
|
|
step = WII5COMMUNICATIONS_IRIDIUM_SEND_WAIT; wait = 0;
|
|
}
|
|
|
|
// Clear them and move on
|
|
else {
|
|
console.log(LOG_DEBUG, F("Communications: Iridium send complete, moving to end"));
|
|
if (
|
|
updateStatus
|
|
&& metadataBlock
|
|
&& (countSucces > 0)
|
|
// && (countFailed < 1) - TODO add this test
|
|
) {
|
|
// TODO how about some better meaning to the number?
|
|
sdDone++;
|
|
console.log(LOG_DEBUG, F("Communications: Updating status block=%lu, record=%lu, status=1"), metadataBlock, mainRecordCount);
|
|
sdBlock.metadataUpdateStatus(metadataBlock, mainRecordCount, 1);
|
|
|
|
sdBlock.read(metadataBlock);
|
|
console.log(LOG_INFO, F("Communications: TODO Updated status and read for block = %lu, record = %lu and status = %lu"),
|
|
metadataBlock, mainRecordCount, sdBlock.metadata->status
|
|
);
|
|
}
|
|
else {
|
|
console.log(LOG_INFO, F("Communications: Message sent but status not updated - metadataBlock=%lu,countSucces=%d,update=%d"), metadataBlock, int(countSucces), int(updateStatus));
|
|
}
|
|
|
|
updateStatus = false;
|
|
binNextBit = 0; // Important to start split
|
|
binCount = 0;
|
|
mainBinType = 0;
|
|
metadataBlock = 0;
|
|
resultsBlock = 0;
|
|
step = WII5COMMUNICATIONS_JUMP; wait = 0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Wait for send and check reply
|
|
case WII5COMMUNICATIONS_IRIDIUM_SEND_WAIT:
|
|
if (first) {
|
|
console.log(LOG_DEBUG, F("Communications: step IRIDIUM_SEND_WAIT"));
|
|
if (testMode) {
|
|
console.log(LOG_FATAL, F("FAKE: Not waiting for Iridium"));
|
|
updateStatus = true;
|
|
countSucces++;
|
|
step = WII5COMMUNICATIONS_JUMP; wait = 0; first = true;
|
|
}
|
|
}
|
|
else if (wii5Iridium.waiting()) {
|
|
// Wait for status success/fail for counts. This allos us to ignore command messages
|
|
if (waitStatus) {
|
|
if (wii5Iridium.lastSend == WII5IRIDIUMSENDRESULT_OK) {
|
|
countSucces++;
|
|
lastSuccess = 0; // To stop repeating every loop
|
|
}
|
|
else
|
|
countFailed++;
|
|
waitStatus = false;
|
|
}
|
|
|
|
// TODO - check this isn't a race condition.
|
|
// Check incoming messages
|
|
if (wii5Iridium.lastReceive == WII5IRIDIUMRECEIVERESULT_OK) {
|
|
if (wii5Iridium.lastSend == WII5IRIDIUMSENDRESULT_OK)
|
|
console.log(LOG_INFO, F("Communications: (Send success) Received Iridium Data length=%d"), wii5Iridium.lastReceiveLen);
|
|
else
|
|
console.log(LOG_ERROR, F("Communications: (Send failed) Received Iridium Data length=%d"), wii5Iridium.lastReceiveLen);
|
|
wii5Commands.processBinData();
|
|
if ( (wii5Commands.lastCommandCmd != WII5COMMAND_NONE) && (wii5Commands.lastCommandResult != WII5RESULTS_UNKNOWN) ) {
|
|
console.log(LOG_ERROR, F("Communications: Sending reply command=%d, result=%d"), int(wii5Commands.lastCommandCmd), int(wii5Commands.lastCommandResult));
|
|
// Always send a result, allowing for next message too - 3 or 4 depending on lenght reply
|
|
uint32_t replyType = wii5BinData.setBit(0, 3);
|
|
wii5BinData.createData(replyType, wii5BinaryIridium, 340, 1);
|
|
wii5BinData.setData(replyType, wii5BinaryIridium, 340); // TODO Hard coded
|
|
wii5Iridium.setBinSize(wii5BinData.getSize(replyType));
|
|
wii5Iridium.requestSendBinary();
|
|
|
|
// Blank last command
|
|
wii5Commands.lastCommandCmd = WII5COMMAND_NONE;
|
|
wii5Commands.lastCommandResult = WII5RESULTS_UNKNOWN;
|
|
memset(wii5Commands.lastCommandMessage, 0, sizeof(wii5Commands.lastCommandMessage));
|
|
}
|
|
else {
|
|
// TODO Send error !
|
|
console.log(LOG_ERROR, F("Communications: Unable to reply command=%d, result=%d"), int(wii5Commands.lastCommandCmd), int(wii5Commands.lastCommandResult));
|
|
step = WII5COMMUNICATIONS_JUMP; wait = 0; first = true;
|
|
}
|
|
// No change of step - as we are sending again
|
|
}
|
|
else {
|
|
if (wii5Iridium.lastSend == WII5IRIDIUMSENDRESULT_OK)
|
|
console.log(LOG_INFO, F("Communications: (Send success) nothing received"));
|
|
else
|
|
console.log(LOG_ERROR, F("Communications: (Send failed) nothing received"));
|
|
// Check any further waiting messages - send same message again.
|
|
|
|
step = WII5COMMUNICATIONS_JUMP; wait = 0; first = true;
|
|
}
|
|
}
|
|
// TODO Configurables
|
|
else if (wait > 300000) {
|
|
console.log(LOG_ERROR, F("Communications: Iridium Timed out after 5 minutes"));
|
|
step = WII5COMMUNICATIONS_END; wait = 0;
|
|
}
|
|
|
|
break;
|
|
|
|
case WII5COMMUNICATIONS_END:
|
|
if (first) {
|
|
console.log(LOG_INFO, F("Communications: step END - checking"));
|
|
}
|
|
else if (metadataScan && (countSend < 1)) {
|
|
// Turn it off, so we don't get in here twice on no send.
|
|
metadataScan = false;
|
|
console.log(LOG_INFO, F("Communications: NO TRANSMISSIONS - Sending a default"));
|
|
uint32_t replyType = wii5BinData.setBit(1, 5);
|
|
sendBinModeType(replyType, 0, 0, 0);
|
|
setSimpleMode();
|
|
step = WII5COMMUNICATIONS_JUMP; wait = 0;
|
|
}
|
|
else {
|
|
metadataScan = false;
|
|
console.log(LOG_INFO, F("Communications: Sent %d messages"), countSend);
|
|
// Noithing left to do - lets shut it down.
|
|
wii5Iridium.stop();
|
|
step = WII5COMMUNICATIONS_IDLE; wait = 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
console.log(LOG_FATAL, F("COMMUNICATIONS: Default step... step=%d"), step);
|
|
step = WII5COMMUNICATIONS_IDLE; wait = 0;
|
|
}
|
|
}
|
|
|
|
WII5Communications wii5Communications;
|