#include "config.h" #include "parsing.h" #include "commands.h" #include "uart.h" #include #include #include #include // Read and parse command line and dispatch command void parseNextCommand() { const int bufferLength = 80; char buffer[bufferLength]; // Read next command CommandLine cmdLine = readNextCommand(buffer, bufferLength); // Execute command executeCommand(cmdLine); } // Read next command line from UART CommandLine readNextCommand(char* buffer, uint8_t bufferLength) { while (1) { // Read next command int readChars = uartGetLine(buffer, bufferLength); if (readChars >= bufferLength - 1) { // Reading was aborted after bufferLength-1 characters to prevent buffer overflow. uartPutLine("ERROR buffer overflow, discarding line"); // Discard everything until we read an actual end of line for (unsigned char c = 0; c != '\n' && c != '\r'; c = uartGetChar()); readChars = 0; } if (readChars != 0) { return tokenizeCommand(buffer); } } } // Splits a command "CMD ARGS" to two strings "CMD" and "ARGS". Returns pointer // to "ARGS" or NULL if no arguments were found. Changes the input string! CommandLine tokenizeCommand(char* cmd) { CommandLine cmdLine = { cmd, NULL }; if (cmd == NULL) { return cmdLine; } // Search for a space character for (char* p = cmd; *p != '\0'; p++) { if (*p == ' ') { // Split strings by replacing the space by \0, then set argument pointer. *p++ = '\0'; cmdLine.arg = p; break; } } return cmdLine; } // Address parsing bool parseSingleAddressTo(char* addressStr, address_t* address) { if (addressStr == NULL || strlen(addressStr) != 4 || address == NULL) { return false; } for (char* p = addressStr; *p != '\0'; p++) { if ((*p < '0' || *p > '9') && (*p < 'A' || *p > 'F')) { return false; } } *address = strtol(addressStr, NULL, 16); return true; } // Parses a single 2-byte hexadecimal address string "XXXX:YYYY" to an actual address. AddressRange parseSingleAddress(char* addressStr) { AddressRange range = {true, 0, 0}; if (!parseSingleAddressTo(addressStr, &range.from)) { return (AddressRange) {false, 0, 0}; } range.to = range.from; return range; } // Parses a hexadecimal address range string "XXXX:YYYY" to actual addresses. // A single address "XXXX" is equivalent to "XXXX:XXXX", with from == to. AddressRange parseAddressRange(char* addressStr) { if (addressStr == NULL) { return (AddressRange) {false, 0, 0}; } int len = strlen(addressStr); if (len != 4 && len != 9) { return (AddressRange) {false, 0, 0}; } if (len == 9) { if (addressStr[4] != ':') { return (AddressRange) {false, 0, 0}; } addressStr[4] = '\0'; } AddressRange range = parseSingleAddress(addressStr); if (range.isValid && len == 9) { if (!parseSingleAddressTo(addressStr + 5, &range.to)) { return (AddressRange) {false, 0, 0}; } } return range; }