From 08fcbb4e73e9d879f9ca633d87e9d190f12622e5 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 17 Nov 2023 10:49:03 +0100 Subject: [PATCH] Partly fix retransmit errors * move gotFragment flag --- src/hm/Communication.h | 26 +++++++++++--------------- src/hm/hmInverter.h | 2 ++ src/hm/hmRadio.h | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/hm/Communication.h b/src/hm/Communication.h index f23fe416..ce2a7175 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -14,7 +14,7 @@ #define MI_TIMEOUT 250 // timeout for MI type requests #define FRSTMSG_TIMEOUT 150 // how long to wait for first msg to be received #define DEFAULT_TIMEOUT 500 // timeout for regular requests -#define SINGLEFR_TIMEOUT 60 // timeout for single frame requests +#define SINGLEFR_TIMEOUT 65 // timeout for single frame requests #define MAX_BUFFER 250 typedef std::function *)> payloadListenerType; @@ -44,8 +44,8 @@ class Communication : public CommQueue<> { if(!valid) return; // empty - uint16_t timeout = q->iv->ivGen != IV_MI ? (mGotFragment && q->iv->mGotLastMsg) ? SINGLEFR_TIMEOUT : DEFAULT_TIMEOUT : MI_TIMEOUT; - uint16_t timeout_min = q->iv->ivGen != IV_MI ? mGotFragment ? SINGLEFR_TIMEOUT : FRSTMSG_TIMEOUT : MI_TIMEOUT; + uint16_t timeout = q->iv->ivGen != IV_MI ? (q->iv->mGotFragment && q->iv->mGotLastMsg) ? SINGLEFR_TIMEOUT : DEFAULT_TIMEOUT : MI_TIMEOUT; + uint16_t timeout_min = q->iv->ivGen != IV_MI ? q->iv->mGotFragment ? SINGLEFR_TIMEOUT : FRSTMSG_TIMEOUT : MI_TIMEOUT; bool testMode = false; switch(mState) { @@ -61,7 +61,7 @@ class Communication : public CommQueue<> { mHeu.printStatus(q->iv); mHeu.getTxCh(q->iv); testMode = mHeu.getTestModeEnabled(); - mGotFragment = false; + q->iv->mGotFragment = false; q->iv->mGotLastMsg = false; mFirstTry = mFirstTry ? false : ( ( (IV_HM == q->iv->ivGen) || (IV_MI == q->iv->ivGen) ) && (q->iv->isAvailable()) || (millis() < 120000) ); if(NULL == q->iv->radio) @@ -95,13 +95,10 @@ class Communication : public CommQueue<> { case States::WAIT: if(millis() > mWaitTimeout_min) { - if(!mGotFragment) { // nothing received yet? - if(q->iv->radio->get()) { // radio received sth.? - mGotFragment = true; - if(q->iv->mGotLastMsg) { + if(!q->iv->mGotFragment) { // nothing received yet? + if(q->iv->mGotLastMsg) { //mState = States::CHECK_FRAMES; mWaitTimeout = mWaitTimeout_min; - } } } else if(mFirstTry) { DPRINT_IVID(DBG_INFO, q->iv->id); @@ -127,7 +124,7 @@ class Communication : public CommQueue<> { DBGPRINT(String(millis() - mWaitTimeout + timeout)); DBGPRINTLN(F("ms")); - if(!mGotFragment) { // && !mFirstTry) { + if(!q->iv->mGotFragment) { if(!testMode) q->iv->radioStatistics.rxFailNoAnser++; // got nothing mHeu.setGotNothing(q->iv); @@ -143,7 +140,6 @@ class Communication : public CommQueue<> { break; } - mGotFragment = true; mFirstTry = false; // for correct reset States nextState = States::RESET; while(!q->iv->radio->mBufCtrl.empty()) { @@ -207,9 +203,10 @@ class Communication : public CommQueue<> { if(0 == mMaxFrameId) { uint8_t i = 0; while(i < MAX_PAYLOAD_ENTRIES) { - if(mLocalBuf[i].len == 0) + if(mLocalBuf[i].len == 0) { framnr = i+1; break; + } i++; } } @@ -280,9 +277,8 @@ class Communication : public CommQueue<> { return; // CRC8 is wrong, frame invalid } - if((*frameId & ALL_FRAMES) == ALL_FRAMES) { + if((*frameId & ALL_FRAMES) == ALL_FRAMES) mMaxFrameId = (*frameId & 0x7f); - } frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1]; memcpy(f->buf, &p->packet[10], p->len-11); @@ -773,7 +769,7 @@ class Communication : public CommQueue<> { uint32_t mWaitTimeout = 0; uint32_t mWaitTimeout_min = 0; std::array mLocalBuf; - bool mGotFragment = false; + //bool mGotFragment = false; bool mFirstTry = false; uint8_t mMaxFrameId; uint8_t mPayload[MAX_BUFFER]; diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 88a19a1b..0b87fbb1 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -126,6 +126,8 @@ class Inverter { uint16_t alarmLastId; // lastId which was received int8_t rssi; // RSSI uint8_t miMultiParts; // helper info for MI multiframe msgs + uint8_t outstandingFrames; // helper info to count difference between expected and received frames + bool mGotFragment; // shows if inverter has sent at least one fragment bool mGotLastMsg; // shows if inverter has already finished transmission cycle Radio *radio; // pointer to associated radio class statistics_t radioStatistics; // information about transmitted, failed, ... packets diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index a51504df..d0a7b250 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -252,6 +252,12 @@ class HmRadio : public Radio { p.millis = millis() - mMillis; mNrf24.read(p.packet, p.len); if (p.packet[0] != 0x00) { + if(!checkIvSerial(&p.packet[1], mLastIv)) { + DPRINT(DBG_WARN, "RX other inverter: "); + ah::dumpBuf(p.packet, p.len); + return false; + } + mLastIv->mGotFragment = true; mBufCtrl.push(p); if (p.packet[0] == (TX_REQ_INFO + ALL_FRAMES)) // response from get information command isLastPackage = (p.packet[9] > ALL_FRAMES); // > ALL_FRAMES indicates last packet received @@ -302,6 +308,16 @@ class HmRadio : public Radio { return iv->ivGen; } + inline bool checkIvSerial(uint8_t buf[], Inverter<> *iv) { + uint8_t tmp[4]; + CP_U32_BigEndian(tmp, iv->radioId.u64 >> 8); + for(uint8_t i = 0; i < 4; i++) { + if(tmp[i] != buf[i]) + return false; + } + return true; + } + uint64_t DTU_RADIO_ID; uint8_t mRfChLst[RF_CHANNELS] = {03, 23, 40, 61, 75}; // channel List:2403, 2423, 2440, 2461, 2475MHz uint8_t mTxChIdx = 0;