Skip to content
78 changes: 78 additions & 0 deletions Firmware/LoRaSerial/Commands.ino
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,15 @@ bool commandAT(const char * commandString)
systemPrintln(" ATI10 - Display radio metrics");
systemPrintln(" ATI11 - Display the system runtime");
systemPrintln(" ATI12 - Set programming complete");
systemPrintln(" ATI13 - Display the random seed");
systemPrintln(" ATI14 - Display the channel table by channel");
systemPrintln(" ATI15 - Display the channel table by frequency");

//Virtual circuit information commands
systemPrintln(" ATI30 - Return myVc value");
systemPrintln(" ATI31 - Display the VC details");
systemPrintln(" ATI32 - Dump the NVM unique ID table");
systemPrintln(" ATI33 - Display the VC states");
return true;

case ('0'): //ATI0 - Show user settable parameters
Expand Down Expand Up @@ -637,6 +641,69 @@ bool commandAT(const char * commandString)
systemWrite(*data++);
}
return true;

case ('3'): //ATI13 - Display the random seed
systemPrint("myRandSeed: ");
systemPrintln(myRandSeed);
return true;

case ('4'): //ATI14 - Display the channel table by channel
systemPrintln("Channel Table");
if (!channels)
systemPrintln(" Channel table not allocated!");
else
{
for (int index = 0; index < settings.numberOfChannels; index++)
{
systemPrint(" Channel ");
if ((index <= 9) && (settings.numberOfChannels >= 10))
systemPrint(" ");
systemPrint(index);
systemPrint(": ");
systemPrint(channels[index],3);
systemPrintln(" MHz");
}
}
return true;

case ('5'): //ATI14 - Display the channel table by frequency
systemPrintln("Channel Table by Frequency");
if (!channels)
systemPrintln(" Channel table not allocated!");
else
{
//Initialize the channel array
uint8_t chanIndex[settings.numberOfChannels];
for (int index = 0; index < settings.numberOfChannels; index++)
chanIndex[index] = index;

//Sort the channel numbers by frequency
for (int index = 0; index < (settings.numberOfChannels - 1); index++)
{
for (int x = index + 1; x < settings.numberOfChannels; x++)
{
if (channels[chanIndex[index]] > channels[chanIndex[x]])
{
uint8_t f = chanIndex[index];
chanIndex[index] = chanIndex[x];
chanIndex[x] = f;
}
}
}

//Display the frequencies
for (int index = 0; index < settings.numberOfChannels; index++)
{
systemPrint(" Channel ");
if ((chanIndex[index] <= 9) && (settings.numberOfChannels >= 10))
systemPrint(" ");
systemPrint(chanIndex[index]);
systemPrint(": ");
systemPrint(channels[chanIndex[index]],3);
systemPrintln(" MHz");
}
}
return true;
}
}
if ((commandString[2] == 'I') && (commandString[3] == '3') && (commandLength == 5))
Expand Down Expand Up @@ -769,6 +836,17 @@ bool commandAT(const char * commandString)
systemPrintln("Empty");
}
return true;

case ('3'): //ATI33 - Display the VC states
for (int vcIndex = 0; vcIndex < MAX_VC; vcIndex++)
{
systemPrint("VC ");
systemPrint(vcIndex);
systemPrint(": ");
systemPrintln(vcStateNames[virtualCircuitList[vcIndex].vcState]);
}
return true;

}
}
if ((commandString[2] == 'I') && (commandString[3] == '5') && (commandLength == 5))
Expand Down
3 changes: 3 additions & 0 deletions Firmware/LoRaSerial/LoRaSerial.ino
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ float *channels;
uint8_t channelNumber = 0;
uint32_t airSpeed;

uint16_t myRandSeed;
bool myRandBit;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

//Encryption
Expand Down
3 changes: 0 additions & 3 deletions Firmware/LoRaSerial/Radio.ino
Original file line number Diff line number Diff line change
Expand Up @@ -482,9 +482,6 @@ uint16_t calcMaxThroughput()
return (mostBytesPerSecond);
}

uint16_t myRandSeed;
bool myRandBit;

//Generate unique hop table based on radio settings
void generateHopTable()
{
Expand Down
2 changes: 1 addition & 1 deletion Firmware/LoRaSerial/Serial.ino
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void updateSerial()

//Assert RTS when there is enough space in the receive buffer
if ((!rtsAsserted) && (availableRXBytes() < (sizeof(serialReceiveBuffer) / 2))
&& (availableTXBytes() <= RTS_ON_BYTES))
&& (availableTXBytes() <= settings.rtsOnBytes))
updateRTS(true); //We're ready for more data

//Attempt to empty the serialTransmitBuffer
Expand Down
96 changes: 75 additions & 21 deletions Firmware/Tools/VcServerTest.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#define SET_PROGRAM_COMPLETE "ati12"
#define START_3_WAY_HANDSHAKE "atc"

#define DEBUG_CMD_ISSUE 0
#define DEBUG_LOCAL_COMMANDS 0
#define DEBUG_PC_CMD_ISSUE 0
#define DEBUG_PC_TO_RADIO 0
Expand Down Expand Up @@ -64,28 +65,54 @@
{ \
if (COMMAND_PENDING(queue, active)) \
{ \
if (DEBUG_CMD_ISSUE) \
{ \
if (queue == pcCommandQueue) \
printf("PC %s done\n", commandName[active]); \
else \
{ \
int vc = (&queue[0] - &virtualCircuitList[0].commandQueue[0]) \
* sizeof(QUEUE_T) / sizeof(virtualCircuitList[0]); \
printf("VC %d %s done\n", vc, commandName[active]); \
} \
} \
queue[active / QUEUE_T_BITS] &= ~(1 << (active & QUEUE_T_MASK)); \
active = CMD_LIST_SIZE; \
} \
}

#define COMMAND_ISSUE(queue, pollCount, cmd) \
{ \
/* Place the command in the queue */ \
queue[cmd / QUEUE_T_BITS] |= 1 << (cmd & QUEUE_T_MASK); \
\
/* Timeout the command processor */ \
if (!commandProcessorRunning) \
commandProcessorRunning = STALL_CHECK_COUNT; \
\
/* Remember when this command was issued */ \
if (!pollCount) \
{ \
if (timeoutCount) \
pollCount = timeoutCount; \
else \
pollCount = 1; \
} \
#define COMMAND_ISSUE(queue, pollCount, cmd) \
{ \
if (DEBUG_CMD_ISSUE) \
{ \
if (!COMMAND_PENDING(queue, cmd)) \
{ \
if (queue == pcCommandQueue) \
printf("PC %s issued\n", commandName[cmd]); \
else \
{ \
int vc = (&queue[0] - &virtualCircuitList[0].commandQueue[0]) \
* sizeof(QUEUE_T) / sizeof(virtualCircuitList[0]); \
printf("VC %d %s issued\n", vc, commandName[cmd]); \
} \
} \
} \
\
/* Place the command in the queue */ \
queue[cmd / QUEUE_T_BITS] |= 1 << (cmd & QUEUE_T_MASK); \
\
/* Timeout the command processor */ \
if (!commandProcessorRunning) \
commandProcessorRunning = STALL_CHECK_COUNT; \
\
/* Remember when this command was issued */ \
if (!pollCount) \
{ \
if (timeoutCount) \
pollCount = timeoutCount; \
else \
pollCount = 1; \
} \
}

#define COMMAND_PENDING(queue,cmd) ((queue[cmd / QUEUE_T_BITS] >> (cmd & QUEUE_T_MASK)) & 1)
Expand All @@ -102,6 +129,7 @@ typedef enum
//Connect to the remote radio
CMD_AT_CMDVC, //Select target VC
CMD_ATC, //Start the 3-way handshake

CMD_WAIT_CONNECTED, //Wait until the client is connected

//Get remote radio connection status, type and ID
Expand Down Expand Up @@ -443,6 +471,7 @@ int hostToStdout(VC_SERIAL_MESSAGE_HEADER * header, uint8_t * data, uint8_t byte
//Write this data to stdout
bytesSent = 0;
status = 0;
fflush(stdout);
while (bytesSent < bytesToSend)
{
bytesWritten = write(STDOUT, &data[bytesSent], bytesToSend - bytesSent);
Expand Down Expand Up @@ -476,6 +505,12 @@ void radioToPcLinkStatus(VC_SERIAL_MESSAGE_HEADER * header, uint8_t * data, uint
newState = vcMsg->vcState;
virtualCircuitList[srcVc].vcState = newState;

//Display the state if requested
if (DISPLAY_STATE_TRANSITION || (newState == VC_STATE_LINK_DOWN)
|| (previousState == VC_STATE_LINK_DOWN)
|| ((newState != previousState) && (virtualCircuitList[srcVc].activeCommand < CMD_LIST_SIZE)))
printf("VC%d: %s --> %s\n", srcVc, vcStateNames[previousState], vcStateNames[newState]);

//Save the LoRaSerial radio's unique ID
//Determine if the PC's value is valid
memset(uniqueId, UNIQUE_ID_ERASE_VALUE, sizeof(uniqueId));
Expand Down Expand Up @@ -517,9 +552,6 @@ void radioToPcLinkStatus(VC_SERIAL_MESSAGE_HEADER * header, uint8_t * data, uint
}
}

//Display the state if requested
if (DISPLAY_STATE_TRANSITION)
printf("VC%d: %s --> %s\n", srcVc, vcStateNames[previousState], vcStateNames[newState]);
switch (newState)
{
default:
Expand All @@ -530,6 +562,9 @@ void radioToPcLinkStatus(VC_SERIAL_MESSAGE_HEADER * header, uint8_t * data, uint
break;

case VC_STATE_LINK_DOWN:
//Stop the command processing for this VC
virtualCircuitList[srcVc].activeCommand = CMD_LIST_SIZE;
virtualCircuitList[srcVc].commandTimer = 0;
if (DEBUG_PC_CMD_ISSUE)
printf("VC %d DOWN\n", srcVc);
if (DISPLAY_VC_STATE)
Expand Down Expand Up @@ -686,8 +721,27 @@ void radioCommandComplete(VC_SERIAL_MESSAGE_HEADER * header, uint8_t * data, uin
//The command processor is still running
commandProcessorRunning = STALL_CHECK_COUNT;

//Done with this command
//Validate the srcVc
srcVc = header->radio.srcVc;
if (srcVc >= PC_REMOTE_COMMAND)
{
if (srcVc < (uint8_t)VC_RSVD_SPECIAL_VCS)
srcVc &= VCAB_NUMBER_MASK;
else
switch(srcVc)
{
default:
fprintf(stderr, "ERROR: Unknown VC: %d (0x%02x)\n", srcVc, srcVc);
exit(-2);
break;

//Ignore this command
case (uint8_t)VC_UNASSIGNED:
return;
}
}

//Done with this command
if (srcVc == myVc)
{
if (pcActiveCommand < CMD_LIST_SIZE)
Expand Down