I ran my test. I was sending 512 bytes of UDP data from the Photon every 15 seconds. Each packet started with a byte value that increased each time, so I could tell if a packet is lost or corrupted. The server kept track of the time the packet was expected. And the server had a serial connection to the Photon so it could see the serial debugs in real time, and can also keep track if the Photon rebooted (it never did). And it checked a cloud variable every minute as well. A big log file was the result.
I was able to reproduce this problem once after about 18 hours. I got error -26 on the Photon for every udp.sendPacket(). After error, I did a stop() and begin() the UDP object (code below).
There were zero errors of any kind until that point, but once I got the -26, stop/begin were not sufficient to clear the error condition. I left it in the error state for about an hour and it was stuck. Though the cloud was still connected. Not only was the status LED breathing cyan (mostly), but I was polling a variable and it was updating as expected, even though udp.sendPacket was failing.
From looking at the Particle source I wanted to see if udp.begin() was returning true, as originally I was previously ignoring the result code. I modified my source to check that, and also Network.ready().
I loaded up the new code and started the test again. This time I got a failure after 6 minutes! And udpBegin() was returning true (success).
Curiously, this time it started to work again after about 45 minutes. There were a few more -26 errors, but then things stabilized. In fact, I got only 6 more errors, lasting only a single sendPacket each, in the next 48 hours.
I don’t know what this means. I was able to reproduce the problem, but not reliably enough that I would be particularly sure any fix really fixes the problem. Also, I reached a dead-end examining the source code because eventually it drops into the WICED code which I don’t have access to.
I didn’t try the deleting the UDP object. But since when it fails I also notice the status LED blinking cyan instead of breathing sometimes, I think I would be inclined to actually reboot the Photon from software for now on a -26 error, at least with my code that doesn’t mind the few seconds it takes to reboot.
SYSTEM_MODE(AUTOMATIC);
SYSTEM_THREAD(DISABLED);
UDP udp;
IPAddress remoteIP(192,168,2,6);
int remotePort = 7123;
const size_t bufferSize = 512;
unsigned char buffer[bufferSize];
unsigned char startValue = 0;
int cloudVal = 0;
void setup() {
Serial.begin(9600);
Particle.variable("val", cloudVal);
uint8_t res = udp.begin(0);
Serial.printlnf("udp.begin returned %d", (int)res);
}
void loop() {
unsigned char value = startValue++;
cloudVal = (int)startValue;
for(int ii = 0; ii < bufferSize; ii++) {
buffer[ii] = value++;
}
int result = udp.sendPacket(buffer, bufferSize, remoteIP, remotePort);
if (result == bufferSize) {
Serial.printlnf("sent %d", (int)buffer[0]);
}
else {
Serial.printlnf("error %d", result);
udp.stop();
delay(1000);
uint8_t res = udp.begin(0);
Serial.printlnf("udp.begin returned %d Network.ready=%d", (int)res, (int)Network.ready());
}
delay(15000);
}