mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-24 10:08:14 +01:00
fix duplicate data and timeout in apfw
+ implement pinging AP + fix some timings
This commit is contained in:
BIN
ap_fw/apfw.bin
BIN
ap_fw/apfw.bin
Binary file not shown.
23
ap_fw/main.c
23
ap_fw/main.c
@@ -138,7 +138,7 @@ struct espAvailDataReq {
|
||||
} __packed;
|
||||
|
||||
#define TIMER_TICKS_PER_MS 1333UL
|
||||
uint16_t __xdata version = 0x0006;
|
||||
uint16_t __xdata version = 0x0007;
|
||||
#define RAW_PKT_PADDING 2
|
||||
|
||||
static uint8_t __xdata mRxBuf[COMMS_MAX_PACKET_SZ];
|
||||
@@ -245,7 +245,8 @@ uint8_t getBlockDataLength() {
|
||||
// pendingdata slot stuff
|
||||
int8_t findSlotForMac(const uint8_t *mac) {
|
||||
for (uint8_t __xdata c = 0; c < MAX_PENDING_MACS; c++) {
|
||||
if (u64_isEq((uint64_t __xdata *)mac, (uint64_t __xdata *)&(pendingDataArr[c].targetMac))) { // this costs 1 sloc :(
|
||||
//if (u64_isEq((uint64_t __xdata *)mac, (uint64_t __xdata *)&(pendingDataArr[c].targetMac))) { // this costs 1 sloc :(
|
||||
if (memcmp(mac, ((uint8_t __xdata *)&(pendingDataArr[c].targetMac)), 8) == 0) {
|
||||
if (pendingDataArr[c].attemptsLeft != 0) {
|
||||
return c;
|
||||
}
|
||||
@@ -320,7 +321,9 @@ void processSerial(uint8_t lastchar) {
|
||||
bytesRemain--;
|
||||
if (bytesRemain == 0) {
|
||||
if (checkCRC(serialbuffer, sizeof(struct pendingData))) {
|
||||
int8_t slot = findFreeSlot();
|
||||
struct pendingData *pd = (struct pendingData *)serialbuffer;
|
||||
int8_t slot = findSlotForMac(pd->targetMac);
|
||||
if (slot == -1) slot = findFreeSlot();
|
||||
if (slot != -1) {
|
||||
xMemCopyShort(&(pendingDataArr[slot]), serialbuffer, sizeof(struct pendingData));
|
||||
pr("ACK>\n");
|
||||
@@ -396,7 +399,17 @@ void espNotifyXferComplete(const uint8_t *src) {
|
||||
uartTx(((uint8_t *)exfc)[c]);
|
||||
}
|
||||
}
|
||||
void espNotifyTimeOut() {
|
||||
void espNotifyTimeOut(const uint8_t *src) {
|
||||
struct espXferComplete exfc;
|
||||
xMemCopy8(&exfc.src, src);
|
||||
uartTx('X');
|
||||
uartTx('T');
|
||||
uartTx('O');
|
||||
uartTx('>');
|
||||
addCRC(&exfc, sizeof(exfc));
|
||||
for (uint8_t c = 0; c < sizeof(exfc); c++) {
|
||||
uartTx(((uint8_t *)exfc)[c]);
|
||||
}
|
||||
}
|
||||
|
||||
// process data from tag
|
||||
@@ -738,7 +751,7 @@ void main(void) {
|
||||
|
||||
for (uint8_t __xdata c = 0; c < MAX_PENDING_MACS; c++) {
|
||||
if (pendingDataArr[c].attemptsLeft == 1) {
|
||||
espNotifyTimeOut();
|
||||
espNotifyTimeOut(pendingDataArr[c].targetMac);
|
||||
pendingDataArr[c].attemptsLeft = 0;
|
||||
} else if (pendingDataArr[c].attemptsLeft > 1) {
|
||||
pendingDataArr[c].attemptsLeft--;
|
||||
|
||||
@@ -139,7 +139,7 @@ function updatecards() {
|
||||
if (item.dataset.lastseen && item.dataset.lastseen > 1672531200) {
|
||||
let idletime = (Date.now() / 1000) + servertimediff - item.dataset.lastseen;
|
||||
$('#tag' + tagmac + ' .lastseen').innerHTML = "<span>last seen</span>"+displayTime(Math.floor(idletime))+" ago";
|
||||
if ((Date.now() / 1000) + servertimediff - 60 > item.dataset.nextcheckin) {
|
||||
if ((Date.now() / 1000) + servertimediff - 300 > item.dataset.nextcheckin) {
|
||||
$('#tag' + tagmac + ' .warningicon').style.display='inline-block';
|
||||
$('#tag' + tagmac).classList.remove("tagpending")
|
||||
$('#tag' + tagmac).style.background = '#ffffcc';
|
||||
|
||||
@@ -8,4 +8,5 @@ extern void prepareIdleReq(uint8_t* dst, uint16_t nextCheckin);
|
||||
extern bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t nextCheckin);
|
||||
extern void processJoinNetwork(struct espJoinNetwork* xjn);
|
||||
extern void processXferComplete(struct espXferComplete* xfc);
|
||||
extern void processXferTimeout(struct espXferComplete* xfc);
|
||||
extern void processDataReq(struct espAvailDataReq* adr);
|
||||
@@ -88,26 +88,26 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
case Today:
|
||||
|
||||
drawDate(filename, taginfo);
|
||||
updateTagImage(filename, mac, (midnight - now) / 60 - 10);
|
||||
taginfo->nextupdate = midnight;
|
||||
updateTagImage(filename, mac, (midnight - now) / 60 - 10);
|
||||
break;
|
||||
|
||||
case CountDays:
|
||||
|
||||
if (buttonPressed) cfgobj["counter"] = 0;
|
||||
drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"], taginfo);
|
||||
updateTagImage(filename, mac, (buttonPressed?0:15));
|
||||
cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1;
|
||||
taginfo->nextupdate = midnight;
|
||||
updateTagImage(filename, mac, (buttonPressed ? 0 : 15));
|
||||
cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1;
|
||||
break;
|
||||
|
||||
case CountHours:
|
||||
|
||||
if (buttonPressed) cfgobj["counter"] = 0;
|
||||
drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"], taginfo);
|
||||
updateTagImage(filename, mac, (buttonPressed?0:5));
|
||||
cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1;
|
||||
taginfo->nextupdate = now + 3600;
|
||||
updateTagImage(filename, mac, (buttonPressed ? 0 : 5));
|
||||
cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1;
|
||||
break;
|
||||
|
||||
case Weather:
|
||||
@@ -118,8 +118,8 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
// https://github.com/erikflowers/weather-icons
|
||||
|
||||
drawWeather(filename, cfgobj["location"], taginfo);
|
||||
updateTagImage(filename, mac, 15);
|
||||
taginfo->nextupdate = now + 3600;
|
||||
updateTagImage(filename, mac, 15);
|
||||
break;
|
||||
|
||||
case Firmware:
|
||||
@@ -142,16 +142,16 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
case Memo:
|
||||
|
||||
drawIdentify(filename, taginfo);
|
||||
taginfo->nextupdate = now + 12 * 3600;
|
||||
updateTagImage(filename, mac, 0);
|
||||
taginfo->nextupdate = now + 12*3600;
|
||||
break;
|
||||
|
||||
case ImageUrl:
|
||||
|
||||
if (getImgURL(filename, cfgobj["url"], (time_t)cfgobj["#fetched"])) {
|
||||
taginfo->nextupdate = now + 60 * (cfgobj["interval"].as<int>() < 5 ? 5 : cfgobj["interval"].as<int>());
|
||||
updateTagImage(filename, mac, cfgobj["interval"].as<int>());
|
||||
cfgobj["#fetched"] = now;
|
||||
taginfo->nextupdate = now + 60 * (cfgobj["interval"].as<int>() < 5 ? 5 : cfgobj["interval"].as<int>());
|
||||
} else {
|
||||
taginfo->nextupdate = now + 300;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ void prepareIdleReq(uint8_t* dst, uint16_t nextCheckin) {
|
||||
memcpy(pending.targetMac, dst, 8);
|
||||
pending.availdatainfo.dataType = DATATYPE_NOUPDATE;
|
||||
pending.availdatainfo.nextCheckIn = nextCheckin;
|
||||
pending.attemptsLeft = 10;
|
||||
pending.attemptsLeft = 10 + MIN_RESPONSE_TIME;
|
||||
|
||||
char buffer[64];
|
||||
uint8_t src[8];
|
||||
@@ -124,6 +124,7 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
|
||||
md5.getBytes(md5bytes);
|
||||
}
|
||||
|
||||
uint16_t attempts = 60;
|
||||
uint8_t src[8];
|
||||
*((uint64_t*)src) = swap64(*((uint64_t*)dst));
|
||||
uint8_t mac[6];
|
||||
@@ -131,11 +132,20 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
|
||||
tagRecord* taginfo = nullptr;
|
||||
taginfo = tagRecord::findByMAC(mac);
|
||||
if (taginfo != nullptr) {
|
||||
|
||||
if (memcmp(md5bytes, taginfo->md5pending, 16) == 0) {
|
||||
wsLog("new image is the same as current image. not updating tag.");
|
||||
wsSendTaginfo(mac);
|
||||
return true;
|
||||
}
|
||||
|
||||
time_t now;
|
||||
time(&now);
|
||||
uint16_t minutesUntilNextCheckin = 0;
|
||||
if (taginfo->expectedNextCheckin > now) minutesUntilNextCheckin = (taginfo->expectedNextCheckin - now) / 60;
|
||||
attempts += minutesUntilNextCheckin;
|
||||
} else {
|
||||
wsErr("Tag not found, this shouldn't happen.");
|
||||
}
|
||||
|
||||
// the message that will be sent to the AP to tell the tag there is data pending
|
||||
@@ -145,7 +155,7 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
|
||||
pending.availdatainfo.dataVer = *((uint64_t*)md5bytes);
|
||||
pending.availdatainfo.dataSize = file.size();
|
||||
pending.availdatainfo.nextCheckIn = nextCheckin;
|
||||
pending.attemptsLeft = 10;
|
||||
pending.attemptsLeft = attempts;
|
||||
sendDataAvail(&pending);
|
||||
|
||||
// data for the cache on the esp32; needs to hold the data longer than the maximum timeout on the AP
|
||||
@@ -284,6 +294,29 @@ void processXferComplete(struct espXferComplete* xfc) {
|
||||
wsSendTaginfo(mac);
|
||||
}
|
||||
|
||||
void processXferTimeout(struct espXferComplete* xfc) {
|
||||
char buffer[64];
|
||||
uint8_t src[8];
|
||||
*((uint64_t*)src) = swap64(*((uint64_t*)xfc->src));
|
||||
sprintf(buffer, "< %02X%02X%02X%02X%02X%02X xfer timeout\n\0", src[2], src[3], src[4], src[5], src[6], src[7]);
|
||||
wsErr((String)buffer);
|
||||
Serial.print(buffer);
|
||||
uint8_t mac[6];
|
||||
memcpy(mac, src + 2, sizeof(mac));
|
||||
|
||||
time_t now;
|
||||
time(&now);
|
||||
tagRecord* taginfo = nullptr;
|
||||
taginfo = tagRecord::findByMAC(mac);
|
||||
if (taginfo != nullptr) {
|
||||
taginfo->expectedNextCheckin = now + 60;
|
||||
taginfo->CheckinInMinPending = 0;
|
||||
taginfo->pending = false;
|
||||
memset(taginfo->md5pending, 0, 16 * sizeof(uint8_t));
|
||||
}
|
||||
wsSendTaginfo(mac);
|
||||
}
|
||||
|
||||
void processDataReq(struct espAvailDataReq* eadr) {
|
||||
|
||||
digitalWrite(ONBOARD_LED, LOW);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define ZBS_RX_WAIT_XFERCOMPLETE 8
|
||||
#define ZBS_RX_WAIT_DATA_REQ 9
|
||||
#define ZBS_RX_WAIT_JOINNETWORK 10
|
||||
#define ZBS_RX_WAIT_XFERTIMEOUT 11
|
||||
|
||||
uint8_t restartBlockRequest = 0;
|
||||
|
||||
@@ -111,6 +112,7 @@ void Ping() {
|
||||
void SerialRXLoop() {
|
||||
if (Serial1.available()) {
|
||||
lastchar = Serial1.read();
|
||||
//Serial.write(lastchar);
|
||||
switch (RXState) {
|
||||
case ZBS_RX_WAIT_HEADER:
|
||||
Serial.write(lastchar);
|
||||
@@ -119,8 +121,7 @@ void SerialRXLoop() {
|
||||
cmdbuffer[c] = cmdbuffer[c + 1];
|
||||
}
|
||||
cmdbuffer[3] = lastchar;
|
||||
if ((strncmp(cmdbuffer, "VER>", 4) == 0) && waitingForVersion) {
|
||||
waitingForVersion = 0;
|
||||
if ((strncmp(cmdbuffer, "VER>", 4) == 0)) {
|
||||
pktindex = 0;
|
||||
RXState = ZBS_RX_WAIT_VER;
|
||||
charindex = 0;
|
||||
@@ -151,6 +152,12 @@ void SerialRXLoop() {
|
||||
packetp = (uint8_t*)calloc(sizeof(struct espXferComplete) + 8, 1);
|
||||
memset(cmdbuffer, 0x00, 4);
|
||||
}
|
||||
if (strncmp(cmdbuffer, "XTO>", 4) == 0) {
|
||||
RXState = ZBS_RX_WAIT_XFERTIMEOUT;
|
||||
pktindex = 0;
|
||||
packetp = (uint8_t*)calloc(sizeof(struct espXferComplete) + 8, 1);
|
||||
memset(cmdbuffer, 0x00, 4);
|
||||
}
|
||||
break;
|
||||
case ZBS_RX_BLOCK_REQUEST:
|
||||
packetp[pktindex] = lastchar;
|
||||
@@ -171,6 +178,16 @@ void SerialRXLoop() {
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
case ZBS_RX_WAIT_XFERTIMEOUT:
|
||||
packetp[pktindex] = lastchar;
|
||||
pktindex++;
|
||||
if (pktindex == sizeof(struct espXferComplete)) {
|
||||
struct espXferComplete* xfc = (struct espXferComplete*)packetp;
|
||||
processXferTimeout(xfc);
|
||||
free(packetp);
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
case ZBS_RX_WAIT_DATA_REQ:
|
||||
packetp[pktindex] = lastchar;
|
||||
pktindex++;
|
||||
@@ -182,6 +199,7 @@ void SerialRXLoop() {
|
||||
}
|
||||
break;
|
||||
case ZBS_RX_WAIT_VER:
|
||||
waitingForVersion = 0;
|
||||
cmdbuffer[charindex] = lastchar;
|
||||
charindex++;
|
||||
if (charindex == 4) {
|
||||
@@ -214,6 +232,8 @@ void zbsRxTask(void* parameter) {
|
||||
Serial1.begin(230400, SERIAL_8N1, RXD1, TXD1);
|
||||
|
||||
simplePowerOn();
|
||||
bool firstrun = true;
|
||||
|
||||
Serial1.print("VER?");
|
||||
waitingForVersion = esp_timer_get_time();
|
||||
while (1) {
|
||||
@@ -223,14 +243,30 @@ void zbsRxTask(void* parameter) {
|
||||
Serial1.write(Serial.read());
|
||||
}
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
|
||||
if (waitingForVersion) {
|
||||
if (esp_timer_get_time() - waitingForVersion > 10000*1000ULL) {
|
||||
waitingForVersion = esp_timer_get_time();
|
||||
waitingForVersion = 0;
|
||||
//performDeviceFlash();
|
||||
Serial.println("I wasn't able to connect to a ZBS tag, trying to reboot the tag.");
|
||||
Serial.println("If this problem persists, please check wiring and definitions in the settings.h file, and presence of the right firmware");
|
||||
simplePowerOn();
|
||||
}
|
||||
}
|
||||
|
||||
if (version && firstrun) {
|
||||
Serial.printf("ZBS/Zigbee FW version: %04X\n", version);
|
||||
uint16_t fsversion;
|
||||
lookupFirmwareFile(fsversion);
|
||||
if ((fsversion) && (version != fsversion)) {
|
||||
Serial.printf("Firmware version on LittleFS: %04X\n", fsversion);
|
||||
Serial.printf("Performing flash update in about 30 seconds");
|
||||
vTaskDelay(30000 / portTICK_PERIOD_MS);
|
||||
performDeviceFlash();
|
||||
} else if (!fsversion) {
|
||||
Serial.println("No ZBS/Zigbee FW binary found on SPIFFS, please upload a zigbeebase000X.bin - format binary to enable flashing");
|
||||
}
|
||||
firstrun = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user