Added inline comments to functions

This commit is contained in:
2026-01-25 16:41:05 +01:00
parent 056def88cc
commit 943b4e733e

View File

@@ -17,19 +17,28 @@
*/
void SerialConnector::cycle()
{
// Only proceed if there is at least a minimal number of bytes
// (message must include command, separators and checksum).
if (Serial.available() > 3)
{
// Read until message terminator '@' (terminator is removed by readStringUntil).
String raw = Serial.readStringUntil('@');
// Parse message parts: command and args.
String cmd = getCommandFromIncomming(raw);
String args = getArgsFromIncomming(raw);
// Verify checksum; if it fails, ask the peer to repeat the message.
if (!verifyCheckBit(cmd, args, getCheckBitFromIncomming(raw).toInt()))
{
repeat();
return;
}
// Send acknowledgement back for a valid message.
acknowledge(getCheckBitFromIncomming(raw).toInt());
// Dispatch known commands to their handlers if present.
if (cmd == "CAL-BGN")
{
if (calibrationBeginHandler)
@@ -42,6 +51,7 @@ void SerialConnector::cycle()
}
else
{
// Unknown/unused command - intentionally ignored for now.
}
}
}
@@ -58,27 +68,33 @@ String SerialConnector::stringToHex(String cmd)
for (const auto &item : cmd)
{
// Convert character to its ASCII code then to hexadecimal digits.
hex_dec = int(item);
// Temporary buffer to hold the hex digits in reverse order.
// Size 100 is intentionally generous for safety; characters only need 2 digits.
char hexaDeciNum[100];
int i = 0;
// Extract hex digits (least significant first).
while (hex_dec != 0)
{
int temp = 0;
temp = hex_dec % 16;
if (temp < 10)
{
hexaDeciNum[i] = temp + 48;
hexaDeciNum[i] = temp + 48; // '0'..'9'
i++;
}
else
{
hexaDeciNum[i] = temp + 55;
hexaDeciNum[i] = temp + 55; // 'A'..'F'
i++;
}
hex_dec = hex_dec / 16;
}
// Append the digits in the correct order (reverse the temporary buffer).
for (int j = i - 1; j >= 0; j--)
{
output += hexaDeciNum[j];
@@ -100,27 +116,31 @@ int SerialConnector::stringToCheckNum(String cmd)
for (const auto &item : cmd)
{
// Build a numeric checksum by converting each character to a set of
// hexadecimal digits and accumulating them into an integer.
hex_dec = int(item);
char hexaDeciNum[100];
int i = 0;
// Convert ASCII code to hex digits (LSB-first in buffer).
while (hex_dec != 0)
{
int temp = 0;
temp = hex_dec % 16;
if (temp < 10)
{
hexaDeciNum[i] = temp + 48;
hexaDeciNum[i] = temp + 48; // numeric digit
i++;
}
else
{
hexaDeciNum[i] = temp + 55;
hexaDeciNum[i] = temp + 55; // alphabetic hex digit
i++;
}
hex_dec = hex_dec / 16;
}
// Accumulate digits into the output integer (reverse order to correct endianness).
for (int j = i - 1; j >= 0; j--)
{
output += hexaDeciNum[j];
@@ -138,12 +158,15 @@ int SerialConnector::stringToCheckNum(String cmd)
*/
int SerialConnector::getCharIndex(char ch, String str)
{
// Linear search for the first occurrence of ch.
// Cache length in an int to avoid signed/unsigned comparison warnings.
for (int i = 0; i < str.length(); i++)
{
if (str.charAt(i) == ch)
return i;
return i; // return index on first match
}
// Not found
return -1;
}
@@ -155,6 +178,7 @@ int SerialConnector::getCharIndex(char ch, String str)
*/
String SerialConnector::getCommandFromIncomming(String incomming)
{
// Find position of first separator '#' and return everything before it.
int cmdEnd = getCharIndex('#', incomming);
return incomming.substring(0, cmdEnd);
}
@@ -166,11 +190,14 @@ String SerialConnector::getCommandFromIncomming(String incomming)
*/
String SerialConnector::getArgsFromIncomming(String incomming)
{
// Extract arguments between the first and second '#' separators.
int cmdEnd = getCharIndex('#', incomming);
String cm = incomming.substring(0, cmdEnd);
// substring containing args and checksum
String afterCmd = incomming.substring(cmdEnd + 1, incomming.length());
int cmdArgsEnd = getCharIndex('#', afterCmd);
// return args portion (may be empty)
return afterCmd.substring(0, cmdArgsEnd);
}
@@ -181,11 +208,13 @@ String SerialConnector::getArgsFromIncomming(String incomming)
*/
String SerialConnector::getCheckBitFromIncomming(String incomming)
{
// Extract checksum string which follows the second '#' separator.
int cmdEnd = getCharIndex('#', incomming);
String cm = incomming.substring(0, cmdEnd);
String afterCmd = incomming.substring(cmdEnd + 1, incomming.length());
int cmdArgsEnd = getCharIndex('#', afterCmd);
// substring from after the second '#' to the end contains the checksum
return afterCmd.substring(cmdArgsEnd + 1, afterCmd.length());
}
@@ -198,8 +227,10 @@ String SerialConnector::getCheckBitFromIncomming(String incomming)
*/
bool SerialConnector::verifyCheckBit(String cmd, String args, int checkBit)
{
// Compose the portion of the message that should have been used to compute the checksum
String toCheck = cmd + "#" + args;
// Compare computed checksum against the provided value
if (stringToCheckNum(toCheck) == checkBit)
return true;
else
@@ -212,6 +243,8 @@ bool SerialConnector::verifyCheckBit(String cmd, String args, int checkBit)
*/
void SerialConnector::repeat()
{
// Send a repeat request. Protocol: RPT##<code>@
// The hard-coded value '410' represents an application-specific code.
String cmd = "RPT##410@";
Serial.print(cmd);
}
@@ -222,8 +255,12 @@ void SerialConnector::repeat()
*/
void SerialConnector::acknowledge(int checkBit)
{
// Build an acknowledgement message that includes the original check bit
// so the sender can verify the ack corresponds to the correct message.
String cmd = "ACKG";
String toSend = cmd + "#" + (String)checkBit;
// Compute checksum for the acknowledgement itself and append terminator.
int checkNum = stringToCheckNum(toSend);
String final = toSend + "#" + (String)checkNum + "@";
Serial.print(final);
@@ -237,11 +274,13 @@ void SerialConnector::acknowledge(int checkBit)
*/
void SerialConnector::sendCommand(String cmd, String args)
{
// Compose message with args and computed checksum, then send over Serial.
String toSend = cmd + "#" + args;
int checkNum = stringToCheckNum(toSend);
String final = toSend + "#" + (String)checkNum + "@";
Serial.print(final);
// Wait for and handle the peer's response (ACKG or RPT).
afterSendCheck(final);
}
@@ -251,37 +290,46 @@ void SerialConnector::sendCommand(String cmd, String args)
*/
void SerialConnector::afterSendCheck(String cmd)
{
// Block until a response terminator '@' is received and read the raw message.
String raw = Serial.readStringUntil('@');
// If nothing was read, keep waiting (simple recursive wait). This is a blocking behavior.
if (raw == "")
afterSendCheck(cmd);
// Determine the type of response (RPT = repeat request, ACKG = acknowledgement).
String comm = getCommandFromIncomming(raw);
if (comm == "RPT")
{
// If peer requested a repeat, resend the original command (reconstruct from cmd string).
sendCommand(getCommandFromIncomming(cmd), getArgsFromIncomming(cmd));
}
else if (comm == "ACKG")
{
// Validate the acknowledgement corresponds to the command we sent.
int check = getArgsFromIncomming(raw).toInt();
int cmdCheck = getCheckBitFromIncomming(cmd).toInt();
if (check != cmdCheck)
{
// TODO: Implement a command to resend previous command
// Checksums do not match - TODO: implement resend logic or error reporting.
}
else
{
// Acknowledgement matches - nothing further to do for now.
}
}
}
void SerialConnector::onCalibrationBegin(void (*handler)(String args))
{
// Register the callback invoked when a CAL-BGN message is received.
calibrationBeginHandler = handler;
}
void SerialConnector::onCalibrationInterupt(void (*handler)(String args))
{
// Register the callback invoked when a CAL-INT message is received.
calibrationInteruptHandler = handler;
}