#include "PixelBot.h" #include #include #include "Utilities.h" PixelBot::PixelBot() { memset(serverIp, '\0', 16); } PixelBot::~PixelBot() { } /// /// Listens for PixelHub beacon pings in order to determine the location of the PixelHub server. /// /// /// Puts the details it finds into the `serverIp` and `portNumber` data members. /// void PixelBot::FindServer() { Serial.print("Initialising PixelHub auto detection system - "); // The UDP Client for sending and recieving UDP datagrams. WiFiUDP UdpClient; byte datagramBuffer[datagramBufferSize]; memset(datagramBuffer, '\0', datagramBufferSize); // Prefill the datagram buffer with zeros for protection later UdpClient.beginMulticast(WiFi.localIP(), beaconAddress, beaconPort); Serial.println("success!"); Serial.println("Listening for PixelHub beacon pings."); while(true) { int datagramSize = UdpClient.parsePacket(); if(!datagramSize) continue; Serial.print("Received datagram #"); Serial.print(datagramSize); Serial.print(" bytes in size from "); Serial.print(UdpClient.remoteIP()); Serial.print(":"); Serial.print(UdpClient.remotePort()); if(datagramSize > datagramBufferSize) { Serial.println(", but the message is larger than the datagram buffer size."); continue; } Serial.println("."); UdpClient.read(datagramBuffer, datagramSize); Serial.print("Content as hex: "); for(int i = 0; i < datagramSize; i++) { Serial.print(datagramBuffer[i], HEX); Serial.print(" "); } Serial.println(); Serial.print("Raw content: "); Serial.write(datagramBuffer, datagramSize); Serial.println(); Serial.print("Parsing datagram - "); // Parse the recieved message char* datagramStr = (char*)datagramBuffer; // Find the positions of the key characters //int atPos = getPosition(datagramStr, datagramSize, '@'); //int colonPos = getPosition(datagramStr, datagramSize, ':'); int atPos = findChar(datagramStr, '@'); int colonPos = findChar(datagramStr, ':'); char role[7]; char serverPortText[7]; memset(role, '\0', 7); memset(serverPortText, '\0', 7); strncpy(role, datagramStr, atPos); strncpy(serverIp, datagramStr + atPos + 1, colonPos - atPos - 1); strncpy(serverPortText, datagramStr + colonPos + 1, datagramSize - colonPos - 1); Serial.println("complete."); Serial.print("atPos: "); Serial.println(atPos); Serial.print("colonPos: "); Serial.println(colonPos); Serial.print("Role: "); Serial.print(role); Serial.print(" "); Serial.print("Remote IP: "); Serial.print(serverIp); Serial.print(" "); Serial.print("Port number: "); Serial.print(serverPortText); Serial.println(); // If the advertiser isn't playing the role of a server, then we're not interested if(strcmp(role, desiredRemoteRole) != 0) { Serial.print("Incompatible role "); Serial.print(role); Serial.println("."); continue; } Serial.println("Role ok!"); serverPort = atoi(serverPortText); return; } } bool PixelBot::Connect() { Serial.print("Connecting to "); Serial.print(serverIp); Serial.print(":"); Serial.print(serverPort); Serial.print(" - "); if(!tcpClient.connect(serverIp, serverPort)) { Serial.println("failed!"); return false; } Serial.println("success!"); return true; } void PixelBot::Listen() { while(true) { Serial.println("[PixelBot/Server] Entering main loop."); // Make sure that there's something to read if(tcpClient.available() == 0) { delay(10); // sleep for 10ms continue; } String nextLine = tcpClient.readStringUntil('\n'); Serial.print(" > "); Serial.println(nextLine); } } bool PixelBot::processCommand(String command) { return false; }