JP: update MAX_TEXT_LEN limits based on measured airtimes, add getMaxGroupTextLen()

Measured actual TimeOnAir via RadioLib getTimeOnAir() on RAK WisMesh Tag
(SF12/BW125, CR4/5-8) to verify ARIB STD-T108 4-second TX limit compliance.

DM limits (getMaxTextLen):
  CR4/5: 64 bytes (3874ms)
  CR4/6: 48 bytes (3874ms)
  CR4/7: 32 bytes (3678ms)
  CR4/8: 24 bytes (3547ms)

Channel message limits (getMaxGroupTextLen):
  CR4/5: 64 bytes (3710ms)
  CR4/6: 48 bytes (3678ms)
  CR4/7: 39 bytes (3907ms)
  CR4/8: 29 bytes (3809ms)

DM and channel packets differ by 1 byte overhead, warranting separate
limits for CR4/7 and CR4/8. Non-JP returns default 160 bytes unchanged.

Also apply dynamic limit to sendCommandData() and sendGroupMessage()
via getMaxTextLen()/getMaxGroupTextLen() instead of hardcoded MAX_TEXT_LEN.
This commit is contained in:
jirogit 2026-04-01 00:39:19 -07:00
parent 56a2d93aa4
commit 9e03dc6366
3 changed files with 20 additions and 7 deletions

View file

@ -39,6 +39,7 @@ public:
virtual float packetScore(float snr, int packet_len) = 0;
virtual int getMaxTextLen() const { return 10 * 16; } // default: non-JP
virtual int getMaxGroupTextLen() const { return 10 * 16; } // default: non-JP
/**
* \brief starts the raw packet send. (no wait)

View file

@ -436,7 +436,8 @@ int BaseChatMesh::sendMessage(const ContactInfo& recipient, uint32_t timestamp,
int BaseChatMesh::sendCommandData(const ContactInfo& recipient, uint32_t timestamp, uint8_t attempt, const char* text, uint32_t& est_timeout) {
int text_len = strlen(text);
if (text_len > MAX_TEXT_LEN) return MSG_SEND_FAILED;
int max_len = _radio->getMaxTextLen();
if (text_len > max_len) return MSG_SEND_FAILED;
uint8_t temp[5+MAX_TEXT_LEN+1];
memcpy(temp, &timestamp, 4); // mostly an extra blob to help make packet_hash unique
@ -469,7 +470,9 @@ bool BaseChatMesh::sendGroupMessage(uint32_t timestamp, mesh::GroupChannel& chan
char *ep = strchr((char *) &temp[5], 0);
int prefix_len = ep - (char *) &temp[5];
if (text_len + prefix_len > MAX_TEXT_LEN) text_len = MAX_TEXT_LEN - prefix_len;
int max_len = _radio->getMaxGroupTextLen();
if (text_len + prefix_len > max_len) text_len = max_len - prefix_len;
memcpy(ep, text, text_len);
ep[text_len] = 0; // null terminator

View file

@ -50,12 +50,21 @@ public:
}
int getMaxTextLen() const {
if (!isJapanMode()) return 10 * 16; // default
if (!isJapanMode()) return 10 * 16; // default 160 bytes
uint8_t cr = getCodingRate();
if (cr <= 5) return 3 * 16; // 48 bytes ~16 JP chars
if (cr == 6) return 2 * 16; // 32 bytes ~10 JP chars
if (cr == 7) return 1 * 16 + 8; // 24 bytes ~8 JP chars
return 1 * 16; // 16 bytes ~5 JP chars
if (cr <= 5) return 64; // 3874ms @ SF12/BW125/CR4-5
if (cr == 6) return 48; // 3874ms @ SF12/BW125/CR4-6
if (cr == 7) return 32; // 3678ms @ SF12/BW125/CR4-7
return 24; // 3547ms @ SF12/BW125/CR4-8
}
int getMaxGroupTextLen() const {
if (!isJapanMode()) return 10 * 16; // default 160 bytes
uint8_t cr = getCodingRate();
if (cr <= 5) return 64; // 3710ms @ SF12/BW125/CR4-5
if (cr == 6) return 48; // 3678ms @ SF12/BW125/CR4-6
if (cr == 7) return 39; // 3907ms @ SF12/BW125/CR4-7
return 29; // 3809ms @ SF12/BW125/CR4-8
}
virtual int16_t performChannelScan();