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