removed 'synchronized' part of the protocol :(

This commit is contained in:
Jelmer
2023-01-15 12:52:08 +01:00
parent 5e2ef25bf2
commit 5ee9cea68b
2 changed files with 62 additions and 399 deletions

View File

@@ -41,8 +41,6 @@ struct MacFrameBcast {
uint8_t src[8];
} __packed;
#define PKT_TIMING_REQ 0xE0
#define PKT_TIMING_RESPONSE 0xE1
#define PKT_AVAIL_DATA_REQ 0xE5
#define PKT_AVAIL_DATA_INFO 0xE6
#define PKT_BLOCK_PARTIAL_REQUEST 0xE7
@@ -51,17 +49,6 @@ struct MacFrameBcast {
#define PKT_BLOCK_PART 0xE8
#define PKT_XFER_COMPLETE 0xEA
#define PKT_XFER_COMPLETE_ACK 0xEB
#define PKT_SYNC_BURST 0xEF
struct timingResponse {
uint8_t checksum;
uint32_t burstInterval; // time between burst-start
uint8_t burstLength; // in packets; due to use of sequence field, limited to a 256-packet burst
uint16_t burstLengthMs; // burst length in ms
uint32_t timerValue; // current timer value (used to sync up other RC timers/oscillators)
uint32_t burstIntervalRemaining; // time until the next sync burst
uint8_t dataAvailable;
} __packed;
struct AvailDataReq {
uint8_t checksum;
@@ -103,23 +90,15 @@ struct pendingData {
struct AvailDataInfo availdatainfo;
uint8_t attemptsLeft;
uint8_t targetMac[8];
uint8_t includedThisBurst : 1;
} __packed;
struct burstMacData {
uint16_t offset;
uint8_t targetMac[8];
} __packed;
#define BLOCK_PART_DATA_SIZE 99
#define BLOCK_MAX_PARTS 42
#define BLOCK_DATA_SIZE 4096
#define BLOCK_XFER_BUFFER_SIZE BLOCK_DATA_SIZE + sizeof(struct blockData)
// #define BLOCK_XFER_BUFFER_SIZE 4096 + 4
#define BLOCK_REQ_PARTS_BYTES 6 // BLOCK_MAX_PARTS / 8 + 1
#define MAX_MACS_PER_SYNC 2
#define MAX_PENDING_MACS 10
#define SYNC_BURST_INTERVAL 30UL
#define HOUSEKEEPING_INTERVAL 60UL
struct pendingData __xdata pendingDataArr[MAX_PENDING_MACS];
@@ -153,16 +132,10 @@ struct espXferComplete {
uint8_t src[8];
} __packed;
struct espJoinNetwork {
struct espAvailDataReq {
uint8_t checksum;
uint8_t src[8];
} __packed;
// used to transmit AP update information - flashing the firmware
struct espSaveUpdateBlock {
uint8_t checksum;
uint8_t blockId;
uint16_t blockChecksum;
struct AvailDataReq adr;
} __packed;
#define TIMER_TICKS_PER_MS 1333UL
@@ -174,7 +147,6 @@ static uint8_t __xdata mRxBuf[COMMS_MAX_PACKET_SZ];
uint8_t __xdata radiotxbuffer[128];
uint8_t __xdata radiorxbuffer[128];
uint32_t __xdata burstLengthMs; // stores how fast we were able to send a syncburst
uint8_t __xdata mSelfMac[8];
// serial stuff
@@ -184,19 +156,18 @@ uint8_t __xdata serialbuffer[48];
uint8_t *__xdata serialbufferp;
uint8_t __xdata bytesRemain = 0;
static uint32_t __xdata burstIntervalTimer;
bool __xdata blockRequestInProgress = false; // set if we get a CRC error, or should do a full request for other reasons
static uint32_t __xdata housekeepingTimer;
struct blockRequest __xdata requestedData = {0};
uint8_t __xdata dstMac[8];
uint16_t __xdata dstPan;
static uint32_t __xdata blockStartTimer = 0;
struct blockRequest __xdata requestedData = {0}; // holds which data was requested by the tag
uint8_t seq = 0; // holds current sequence number for transmission
uint8_t __xdata dstMac[8]; // target for the block transfer
uint16_t __xdata dstPan; //
uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE];
#define SYNC_BURST_LENGTH 142 //(about 250ms)
static uint32_t __xdata blockStartTimer = 0; // reference that holds when the AP sends the next block
extern bool __idata serialBypassActive; // if the serial bypass is disabled, saves bytes straight to the block buffer
uint32_t __xdata nextBlockAttempt = 0; // reference time for when the AP can request a new block from the ESP32
uint8_t seq = 0; // holds current sequence number for transmission
uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE]; // block transfer buffer
void sendXferCompleteAck(uint8_t *dst);
@@ -255,11 +226,6 @@ uint8_t __xdata getPacketType(void *__xdata buffer) {
}
return 0;
}
uint16_t averageXmitDelay(uint16_t xfersize) {
// returns the about maximum time the base should spend on the transfer; about 6 seconds (6000ms) for a 8000 byte transfer. This is * 3 / 4, pretty conservative
// this includes a lot of retransmissions.
return (xfersize * 3) / 5;
}
// pendingdata slot stuff
int8_t findSlotForMac(const uint8_t *mac) {
@@ -282,7 +248,6 @@ int8_t findFreeSlot() {
// processing serial data
#define ZBS_RX_WAIT_HEADER 0
#define ZBS_RX_WAIT_SDA 1
#define ZBS_RX_WAIT_UPDBLOCK 2
void processSerial(uint8_t lastchar) {
// uartTx(lastchar); echo
switch (RXState) {
@@ -349,13 +314,18 @@ void espBlockRequest(const struct blockRequest *br) {
// pr("req ebr ver: %02X%02X%02X%02X%02X%02X%02X%02X\n", ((uint8_t *)&(ebr->ver))[0], ((uint8_t *)&(ebr->ver))[1], ((uint8_t *)&(ebr->ver))[2], ((uint8_t *)&(ebr->ver))[3], ((uint8_t *)&(ebr->ver))[4], ((uint8_t *)&(ebr->ver))[5], ((uint8_t *)&(ebr->ver))[6], ((uint8_t *)&(ebr->ver))[7]);
// pr("req br ver: %02X%02X%02X%02X%02X%02X%02X%02X\n", ((uint8_t *)&(br->ver))[0], ((uint8_t *)&(br->ver))[1], ((uint8_t *)&(br->ver))[2], ((uint8_t *)&(br->ver))[3], ((uint8_t *)&(br->ver))[4], ((uint8_t *)&(br->ver))[5], ((uint8_t *)&(br->ver))[6], ((uint8_t *)&(br->ver))[7]);
}
void espNotifyAvailDataReq(const struct AvailDataReq *adr) {
void espNotifyAvailDataReq(const struct AvailDataReq *adr, const uint8_t *src) {
uartTx('A');
uartTx('D');
uartTx('R');
uartTx('>');
for (uint8_t c = 0; c < sizeof(struct AvailDataReq); c++) {
uartTx(((uint8_t *)adr)[c]);
struct espAvailDataReq __xdata eadr = {0};
xMemCopyShort((void *__xdata)eadr.src, (void *__xdata)src, 8);
xMemCopyShort((void *__xdata) & eadr.adr, (void *__xdata)adr, sizeof(struct AvailDataReq));
addCRC(&eadr, sizeof(struct espAvailDataReq));
for (uint8_t c = 0; c < sizeof(struct espAvailDataReq); c++) {
uartTx(((uint8_t *)eadr)[c]);
}
}
void espNotifyXferComplete(const uint8_t *src) {
@@ -372,23 +342,8 @@ void espNotifyXferComplete(const uint8_t *src) {
}
void espNotifyTimeOut() {
}
void espNotifyJoinNetwork(const uint8_t *src) {
struct espJoinNetwork ejn;
xMemCopy8(&ejn.src, src);
uartTx('T');
uartTx('J');
uartTx('N');
uartTx('>');
addCRC(&ejn, sizeof(ejn));
for (uint8_t c = 0; c < sizeof(ejn); c++) {
uartTx(((uint8_t *)ejn)[c]);
}
}
// process data from tag
uint8_t __xdata blockReqFailcount = 0;
extern bool __idata serialBypassActive;
uint32_t __xdata nextBlockAttempt = 0;
void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
struct MacFrameNormal *__xdata rxHeader = (struct MacFrameNormal *)buffer;
struct blockRequest *__xdata blockReq = (struct blockRequest *)(buffer + sizeof(struct MacFrameNormal) + 1);
@@ -439,8 +394,6 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
memcpy(txHeader->src, mSelfMac, 8);
memcpy(txHeader->dst, rxHeader->src, 8);
memcpy(dstMac, rxHeader->src, 8);
dstPan = rxHeader->pan;
txHeader->pan = rxHeader->pan;
txHeader->fcs.frameType = 1;
@@ -452,9 +405,10 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
addCRC((void *)blockRequestAck, sizeof(struct blockRequestAck));
radioTx(radiotxbuffer);
// radioTx(radiotxbuffer);
// pr("req blockreq: %02X%02X%02X%02X%02X%02X%02X%02X\n", ((uint8_t *)&(blockReq->ver))[0], ((uint8_t *)&(blockReq->ver))[1], ((uint8_t *)&(blockReq->ver))[2], ((uint8_t *)&(blockReq->ver))[3], ((uint8_t *)&(blockReq->ver))[4], ((uint8_t *)&(blockReq->ver))[5], ((uint8_t *)&(blockReq->ver))[6], ((uint8_t *)&(blockReq->ver))[7]);
// save the target for the blockdata
memcpy(dstMac, rxHeader->src, 8);
dstPan = rxHeader->pan;
if (requestDataDownload) {
serialBypassActive = false;
@@ -476,22 +430,23 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
*/
}
void processAvailDataReq(uint8_t *buffer) {
struct MacFrameNormal *rxHeader = (struct MacFrameNormal *)buffer;
struct AvailDataReq *availDataReq = (struct AvailDataReq *)(buffer + sizeof(struct MacFrameNormal) + 1);
struct MacFrameBcast *rxHeader = (struct MacFrameBcast *)buffer;
struct AvailDataReq *availDataReq = (struct AvailDataReq *)(buffer + sizeof(struct MacFrameBcast) + 1);
if (!checkCRC(availDataReq, sizeof(struct AvailDataReq))) return;
if (!checkCRC(availDataReq, sizeof(struct AvailDataReq)))
return;
// prepare tx buffer to send a response
memset(radiotxbuffer, 0, 120);
memset(radiotxbuffer, 0, sizeof(struct MacFrameNormal)+sizeof(struct AvailDataInfo)+2);//120);
struct MacFrameNormal *txHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
struct AvailDataInfo *availDataInfo = (struct AvailDataInfo *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + sizeof(struct AvailDataInfo) + RAW_PKT_PADDING;
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_AVAIL_DATA_INFO;
// check to see if we were addressing this mac in this burst, and if yes, copy availdatainfo to the tx buffer
// check to see if we have data available for this mac
bool haveData = false;
for (uint8_t __xdata c = 0; c < MAX_PENDING_MACS; c++) {
if (pendingDataArr[c].includedThisBurst == 1) {
if (pendingDataArr[c].attemptsLeft) {
if (memcmp(pendingDataArr[c].targetMac, rxHeader->src, 8) == 0) {
haveData = true;
xMemCopyShort((void *__xdata)availDataInfo, &(pendingDataArr[c].availdatainfo), sizeof(struct AvailDataInfo));
@@ -499,14 +454,13 @@ void processAvailDataReq(uint8_t *buffer) {
}
}
}
if (!haveData) return;
// couldn't find data for this mac
if (!haveData) availDataInfo->dataType = DATATYPE_NOUPDATE;
xMemCopy8(txHeader->src, mSelfMac);
xMemCopy8(txHeader->dst, rxHeader->src);
// memcpy(txHeader->src, mSelfMac, 8);
// memcpy(txHeader->dst, rxHeader->src, 8);
txHeader->pan = rxHeader->pan;
txHeader->pan = rxHeader->dstPan;
txHeader->fcs.frameType = 1;
txHeader->fcs.panIdCompressed = 1;
txHeader->fcs.destAddrType = 3;
@@ -514,118 +468,17 @@ void processAvailDataReq(uint8_t *buffer) {
txHeader->seq = seq++;
addCRC(availDataInfo, sizeof(struct AvailDataInfo));
radioTx(radiotxbuffer);
espNotifyAvailDataReq(availDataReq);
espNotifyAvailDataReq(availDataReq, rxHeader->src);
}
void processXferComplete(uint8_t *buffer) {
struct MacFrameNormal *rxHeader = (struct MacFrameNormal *)buffer;
sendXferCompleteAck(rxHeader->src);
espNotifyXferComplete(rxHeader->src);
uint8_t slot = findSlotForMac(rxHeader->src);
pendingDataArr[slot].attemptsLeft = 0;
int8_t slot = findSlotForMac(rxHeader->src);
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
}
// send crap to the tag
void prepareMacForSyncBurst() {
// mark all pending macs as 'not included'
for (uint8_t __xdata c = 0; c < MAX_PENDING_MACS; c++) {
pendingDataArr[c].includedThisBurst = 0;
}
memset(radiotxbuffer, 0, sizeof(struct MacFrameBcast) + 1 + 20 + 2); // TODO, optimize
struct burstMacData *__xdata macdata = (struct burstMacData * __xdata)(((uint8_t *)radiotxbuffer) + sizeof(struct MacFrameBcast) + 3); // total len, pkt type sync, mac-count
uint8_t __xdata count = 0;
uint16_t __xdata currOffset = 500;
while (count < MAX_MACS_PER_SYNC) {
uint8_t __xdata tempmax = 0;
int8_t __xdata maxid = -1;
for (uint8_t __xdata c = 0; c < MAX_PENDING_MACS; c++) {
// check if this mac is already included in the planned sync burst
if (pendingDataArr[c].includedThisBurst == 0) {
// check if this current amount of 'attemptsleft' is the current maximum
if (pendingDataArr[c].attemptsLeft && (pendingDataArr[c].attemptsLeft > tempmax)) {
uint16_t timeoffset = SYNC_BURST_INTERVAL * 1000;
timeoffset -= 1000;
// check if the estimated transmission would fit in the remaining time
if (currOffset + averageXmitDelay(pendingDataArr[c].availdatainfo.dataSize) < timeoffset) {
tempmax = pendingDataArr[c].attemptsLeft;
maxid = c;
}
}
}
}
if (maxid == -1) {
// didn't find any valid mac's to add to the syncburst
return;
} else {
// found a pending-data info struct with the highest amount of attemptsLeft. Add this to the sync burst
// make sure we don't add this pending data mac twice
pendingDataArr[maxid].includedThisBurst = 1;
pendingDataArr[maxid].attemptsLeft--;
xMemCopyShort(macdata[count].targetMac, pendingDataArr[maxid].targetMac, 8);
macdata[count].offset = currOffset;
currOffset += averageXmitDelay(pendingDataArr[maxid].availdatainfo.dataSize);
count++;
*((uint8_t *)radiotxbuffer + sizeof(struct MacFrameBcast) + 2) = count;
}
}
}
void sendSyncBurst() {
struct MacFrameBcast *txframe = (struct MacFrameBcast *)(radiotxbuffer + 1);
memcpy(txframe->src, mSelfMac, 8);
*((uint8_t *)txframe + sizeof(struct MacFrameBcast)) = PKT_SYNC_BURST;
txframe->fcs.frameType = 1;
txframe->fcs.secure = 0;
txframe->fcs.framePending = 0;
txframe->fcs.ackReqd = 0;
txframe->fcs.panIdCompressed = 0;
txframe->fcs.destAddrType = 2;
txframe->fcs.frameVer = 0;
txframe->fcs.srcAddrType = 3;
txframe->seq = 0;
txframe->dstPan = 0xFFFF;
txframe->dstAddr = 0xFFFF;
txframe->srcPan = 0x4447;
radiotxbuffer[0] = sizeof(struct MacFrameBcast) + 1 + (MAX_MACS_PER_SYNC * sizeof(struct burstMacData)) + 2;
pr("BST>\n");
burstLengthMs = timerGet();
for (uint16_t c = 0; c < SYNC_BURST_LENGTH; c++) {
radioTx(radiotxbuffer);
txframe->seq++;
}
burstLengthMs = (timerGet() - burstLengthMs) / 1333;
// pr("atxc in %lu,\n", burstLengthMs);
}
void sendTimingReply(void *__xdata buf) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
struct timingResponse *response = (struct timingResponse *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_TIMING_RESPONSE;
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + sizeof(struct timingResponse) + 1 + RAW_PKT_PADDING;
memset(response, 0, sizeof(struct timingResponse) + sizeof(struct MacFrameNormal) + 1);
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, rxframe->src, 8);
response->timerValue = timerGet();
response->burstInterval = SYNC_BURST_INTERVAL * 1000;
response->burstLength = SYNC_BURST_LENGTH; // in packets; due to use of sequence field, limited to a 256-packet burst
response->burstLengthMs = burstLengthMs; // burst length in ms
response->burstIntervalRemaining = (TIMER_TICKS_PER_SECOND * SYNC_BURST_INTERVAL) - (timerGet() - burstIntervalTimer);
frameHeader->fcs.frameType = 1;
frameHeader->fcs.panIdCompressed = 1;
frameHeader->fcs.destAddrType = 3;
frameHeader->fcs.srcAddrType = 3;
frameHeader->seq = seq++;
frameHeader->pan = rxframe->srcPan;
addCRC(response, sizeof(struct timingResponse));
radioTx(radiotxbuffer);
espNotifyJoinNetwork(rxframe->src);
}
// send block data to the tag
void sendPart(uint8_t partNo) {
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
struct blockPart *blockPart = (struct blockPart *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
@@ -652,7 +505,6 @@ void sendBlockData() {
for (uint8_t c = 0; (c < BLOCK_MAX_PARTS) && (partNo < BLOCK_MAX_PARTS); c++) {
if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) {
sendPart(c);
// timerDelay(TIMER_TICKS_PER_MS);
partNo++;
}
}
@@ -692,11 +544,6 @@ void main(void) {
mSelfMac[c] = c;
}
// if (!eepromInit()) { // we'll need the eeprom here, init it.
// pr("failed to init eeprom\n");
// return;
// }
// clear the array with pending information
memset(pendingDataArr, 0, sizeof(pendingDataArr));
@@ -714,9 +561,7 @@ void main(void) {
// uint8_t __xdata fromMac[8];
pr("RDY>\n");
// send first burst, used to characterize the packet TX speed
burstIntervalTimer = timerGet(); // + (TIMER_TICKS_PER_SECOND * SYNC_BURST_INTERVAL);
sendSyncBurst();
housekeepingTimer = timerGet();
// really... if I do the call below, it'll cost me 8 bytes IRAM. Not the kind of 'optimization' I ever dreamed of doing
// pr("MAC>%02X%02X%02X%02X%02X%02X%02X%02X\n", mSelfMac[0], mSelfMac[1], mSelfMac[2], mSelfMac[3], mSelfMac[4], mSelfMac[5], mSelfMac[6], mSelfMac[7]);
@@ -727,17 +572,12 @@ void main(void) {
pr("VER>%04X\n", version);
while (1) {
radioRxFlush();
// spend about 30 seconds - 100ms in this while loop. The last 100ms are for preparing the sync burst
while ((timerGet() - burstIntervalTimer) < ((TIMER_TICKS_PER_SECOND * SYNC_BURST_INTERVAL) - 100 * TIMER_TICKS_PER_MS)) {
while ((timerGet() - housekeepingTimer) < ((TIMER_TICKS_PER_SECOND * HOUSEKEEPING_INTERVAL) - 100 * TIMER_TICKS_PER_MS)) {
int8_t ret = commsRxUnencrypted(radiorxbuffer);
if (ret > 1) {
// received a packet, lets see what it is
switch (getPacketType(radiorxbuffer)) {
case PKT_TIMING_REQ:
sendTimingReply(radiorxbuffer);
break;
case PKT_AVAIL_DATA_REQ:
processAvailDataReq(radiorxbuffer);
break;
@@ -752,7 +592,7 @@ void main(void) {
break;
//
default:
// pr("other packet...type = %02X\n", getPacketType(radiorxbuffer));
pr("type = %02X\n", getPacketType(radiorxbuffer));
// dump(radiorxbuffer, 128);
break;
}
@@ -765,7 +605,6 @@ void main(void) {
if (timerGet() > blockStartTimer) {
sendBlockData();
blockStartTimer = 0;
radioRxFlush();
}
}
}
@@ -774,14 +613,10 @@ void main(void) {
if (pendingDataArr[c].attemptsLeft == 1) {
espNotifyTimeOut();
pendingDataArr[c].attemptsLeft = 0;
} else if (pendingDataArr[c].attemptsLeft > 1) {
pendingDataArr[c].attemptsLeft--;
}
}
prepareMacForSyncBurst();
while ((timerGet() - burstIntervalTimer) < (TIMER_TICKS_PER_SECOND * SYNC_BURST_INTERVAL)) {
// wait here for maximum burst-start accuracy
}
burstIntervalTimer = timerGet();
sendSyncBurst();
housekeepingTimer = timerGet();
}
}
}

View File

@@ -267,10 +267,13 @@ void doSleep(uint32_t __xdata t) {
initAfterWake();
}
// timing
void sendTimingInfoReq() {
struct MacFrameBcast __xdata *txframe = (struct MacFrameBcast *)outBuffer;
memset(txframe, 0, sizeof(struct MacFrameBcast) + 2);
// data xfer stuff
void sendAvailDataReq() {
struct MacFrameBcast __xdata *txframe = (struct MacFrameBcast *)(outBuffer+1);
memset(outBuffer, 0, sizeof(struct MacFrameBcast) + sizeof(struct AvailDataReq) + 2 + 4);
struct AvailDataReq *__xdata availreq = (struct AvailDataReq *)(outBuffer + 2 + sizeof(struct MacFrameBcast));
outBuffer[0] = sizeof(struct MacFrameBcast) + sizeof(struct AvailDataReq) + 2 + 2;
outBuffer[sizeof(struct MacFrameBcast) + 1] = PKT_AVAIL_DATA_REQ;
memcpy(txframe->src, mSelfMac, 8);
txframe->fcs.frameType = 1;
txframe->fcs.ackReqd = 1;
@@ -280,114 +283,6 @@ void sendTimingInfoReq() {
txframe->dstPan = 0xFFFF;
txframe->dstAddr = 0xFFFF;
txframe->srcPan = 0x4447;
outBuffer[sizeof(struct MacFrameBcast)] = PKT_TIMING_REQ;
commsTxUnencrypted(outBuffer, sizeof(struct MacFrameBcast) + 1);
}
const struct timingResponse *__xdata getTimingInfo() {
radioRxFlush();
uint32_t __xdata mTimerWaitStart;
radioRxEnable(true, true);
for (uint8_t c = 0; c < 5; c++) {
sendTimingInfoReq();
mTimerWaitStart = timerGet() + TIMER_TICKS_PER_MS * 4;
while (timerGet() < mTimerWaitStart) {
int8_t ret = commsRxUnencrypted(inBuffer);
if (ret > 1) {
// radioRxEnable(false, true);
// radioRxFlush();
if (getPacketType(inBuffer) == PKT_TIMING_RESPONSE) {
struct timingResponse __xdata *tresponse = (struct timingResponse *)(inBuffer + sizeof(struct MacFrameNormal) + 1);
if (!checkCRC(tresponse, sizeof(struct timingResponse))) {
pr("Invalid CRC in timing info!\n");
dump((uint8_t *)tresponse, 16);
return NULL;
} else {
APburstInterval = tresponse->burstInterval; // time between burst-start
APburstLength = tresponse->burstLength; // in packets; due to use of sequence field, limited to a 256-packet burst
APburstLengthMs = tresponse->burstLengthMs;
return tresponse;
}
} else {
// pr("wrong packet type in getTimingInfo! %02X\n", getPacketType(inBuffer));
// return NULL;
}
}
}
}
radioRxEnable(false, true);
radioRxFlush();
return NULL;
}
const struct timingResponse *__xdata getCalibration() {
calib = SYNC_CALIB_TIME;
const struct timingResponse *__xdata r = getTimingInfo();
if (r == NULL) {
return NULL;
}
uint32_t __xdata timerBegin = r->timerValue;
doSleep(SYNC_CALIB_TIME);
r = getTimingInfo();
if (r != NULL) {
timerBegin = r->timerValue - timerBegin;
timerBegin *= 3UL;
timerBegin /= 4000UL;
calib = timerBegin;
} else {
return NULL;
}
return r;
}
uint32_t __xdata doResync() {
// resync to the network; try to find out when the next sync burst is going to be
const struct timingResponse *__xdata r = getTimingInfo();
killRadio();
uint32_t __xdata sleep;
if (r == NULL) {
// we didn't get anything from the AP
sleep = getNextAttemptDelay();
pr("NO_RESYNC, sleeping for %lu ms\n", sleep);
} else {
sleep = r->burstIntervalRemaining / TIMER_TICKS_PER_MS;
pr("RESYNC, sleeping for %lu ms\n", sleep);
isSynced = true;
nextAttempt = MIN_NEXT_ATTEMPT_DELAY_MS;
}
sleep += APburstLengthMs / 2;
return sleep;
}
struct MacFrameBcast *__xdata getSyncFrame() {
uint32_t __xdata t;
radioRxEnable(true, true);
t = timerGet() + (TIMER_TICKS_PER_MS * RX_WINDOW_SIZE);
do {
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
if (ret > 1) {
killRadio();
return (struct MacFrameBcast *)inBuffer;
}
} while (timerGet() < t);
return NULL;
}
// data xfer stuff
void sendAvailDataReq() {
memset(outBuffer, 0, sizeof(struct MacFrameNormal) + sizeof(struct AvailDataReq) + 2 + 4);
struct MacFrameNormal *__xdata f = (struct MacFrameNormal *)(outBuffer + 1);
struct AvailDataReq *__xdata availreq = (struct AvailDataReq *)(outBuffer + 2 + sizeof(struct MacFrameNormal));
outBuffer[0] = sizeof(struct MacFrameNormal) + sizeof(struct AvailDataReq) + 2 + 2;
outBuffer[sizeof(struct MacFrameNormal) + 1] = PKT_AVAIL_DATA_REQ;
memcpy(f->src, mSelfMac, 8);
memcpy(f->dst, APmac, 8);
f->fcs.frameType = 1;
f->fcs.secure = 0;
f->fcs.framePending = 0;
f->fcs.ackReqd = 0;
f->fcs.panIdCompressed = 1;
f->fcs.destAddrType = 3;
f->fcs.frameVer = 0;
f->fcs.srcAddrType = 3;
f->seq = seq++;
f->pan = APsrcPan;
// TODO: send some meaningful data
availreq->softVer = 1;
addCRC(availreq, sizeof(struct AvailDataReq));
@@ -403,6 +298,9 @@ struct AvailDataInfo *__xdata getAvailDataInfo() {
if (ret > 1) {
if (getPacketType(inBuffer) == PKT_AVAIL_DATA_INFO) {
if (checkCRC(inBuffer + sizeof(struct MacFrameNormal) + 1, sizeof(struct AvailDataInfo))) {
struct MacFrameNormal *__xdata f = (struct MacFrameNormal *)inBuffer;
memcpy(APmac, f->src, 8);
APsrcPan = f->pan;
return (struct AvailDataInfo *)(inBuffer + sizeof(struct MacFrameNormal) + 1);
}
}
@@ -676,7 +574,7 @@ bool validateBlockData() {
#define DEBUGBLOCKS
// Main download function
void doDataDownload() {
void doDataDownload(struct AvailDataInfo* __xdata avail){
// this is the main function for the download process
if (!eepromInit()) { // we'll need the eeprom here, init it.
@@ -685,8 +583,6 @@ void doDataDownload() {
}
// GET AVAIL DATA INFO - enable the radio and get data
radioRxEnable(true, true);
struct AvailDataInfo *__xdata avail = getAvailDataInfo();
if (avail == NULL) { // didn't receive a reply to get info about the data, we'll resync and try again later
#ifdef DEBUGBLOCKS
pr("didn't receive getavaildatainfo");
@@ -980,81 +876,13 @@ void mainProtocolLoop(void) {
// i2ctest();
while (1) {
uint8_t frameseq = 0;
dataPending = false;
// If synced to a network, try to see if we can receive a sync frame;
if (isSynced) {
struct MacFrameBcast *__xdata f = getSyncFrame();
struct burstMacData *__xdata macdata = (struct burstMacData * __xdata)(((uint8_t *)f) + sizeof(struct MacFrameBcast) + 2);
if (f != NULL) {
frameseq = f->seq + 1;
memcpy(APmac, f->src, 8);
APsrcPan = f->srcPan;
uint8_t totalmacs = *(((uint8_t *)f) + sizeof(struct MacFrameBcast) + 1);
for (uint8_t c = 0; c < totalmacs; c++) {
if (memcmp(mSelfMac, macdata[c].targetMac, 8) == 0) {
// we matched our MAC, prepare to start a download
// save AP mac and srcPan in order to send a AvailDataReq packet later on
dataPending = true;
// sleep until we can start our transaction with the AP
doSleep(macdata[c].offset);
break;
}
}
}
}
uint32_t __xdata sleep = 0;
if (frameseq != 0) {
// received a frame;
// math here can be optimized heavily!
int16_t __xdata packet_offset = (frameseq - (APburstLength / 2)) * APburstLengthMs;
packet_offset /= APburstLength;
calib += (packet_offset / 12);
if (dataPending) {
pr("OK f=%d DL!\n", frameseq);
doDataDownload();
eepromDeepPowerDown();
// wdtDeviceReset();
isSynced = false;
radioRxEnable(true, true); // probably not needed
sleep = doResync();
} else {
sleep = (uint32_t)(APburstInterval - packet_offset);
pr("OK f=%d\n", frameseq, sleep);
}
} else if (!isCalibrated) {
// uncalibrated; try to get two packages in order to calibrate
pr("\nDoing calibration... ");
const struct timingResponse *__xdata r;
r = getCalibration();
if (r != NULL) {
// calibration data received
pr("OK!\n");
sleep = r->burstIntervalRemaining / TIMER_TICKS_PER_MS;
sleep += (APburstLengthMs / 2);
isSynced = true;
isCalibrated = true;
// dataPending = r->dataAvailable;
} else {
// calibration failed...
sleep = getNextAttemptDelay();
pr("FAILED!\n");
}
radioRxEnable(true, true);
struct AvailDataInfo *__xdata avail = getAvailDataInfo();
if(avail->dataType!=DATATYPE_NOUPDATE){
doDataDownload(avail);
} else {
// we didn't receive anything... Ask for the next burst position
if (isSynced) {
// we were previously synced, we'll wait until we're 1 second away from (estimated) burst time
isSynced = false;
sleep = 2 * APburstInterval - 1000;
pr("NO JOY! sleeping for %lums\n", sleep);
} else {
// check when the next burst location is
sleep = doResync();
}
pr("nothing.\n");
}
doSleep(sleep);
doSleep(10000);
}
}