Merge branch 'master' into regulatory-gain

This commit is contained in:
Andrew Yong
2024-06-11 21:30:35 +08:00
committed by GitHub
co-authored by GitHub
39 changed files with 9297 additions and 151 deletions
+10 -6
View File
@@ -62,7 +62,10 @@ meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, Nod
meshtastic_MeshPacket *MeshModule::allocErrorResponse(meshtastic_Routing_Error err, const meshtastic_MeshPacket *p)
{
auto r = allocAckNak(err, getFrom(p), p->id, p->channel);
// If the original packet couldn't be decoded, use the primary channel
uint8_t channelIndex =
p->which_payload_variant == meshtastic_MeshPacket_decoded_tag ? p->channel : channels.getPrimaryIndex();
auto r = allocAckNak(err, getFrom(p), p->id, channelIndex);
setReplyTo(r, *p);
@@ -114,13 +117,13 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and
/// it needs to to be able to fetch the initial admin packets without yet knowing any channels.
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0);
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (ch && strcasecmp(ch->settings.name, pi.boundChannel) == 0);
if (!rxChannelOk) {
// no one should have already replied!
assert(!currentReply);
if (mp.decoded.want_response) {
if (isDecoded && mp.decoded.want_response) {
printPacket("packet on wrong channel, returning error", &mp);
currentReply = pi.allocErrorResponse(meshtastic_Routing_Error_NOT_AUTHORIZED, &mp);
} else
@@ -138,7 +141,8 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
// because currently when the phone sends things, it sends things using the local node ID as the from address. A
// better solution (FIXME) would be to let phones have their own distinct addresses and we 'route' to them like
// any other node.
if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) {
if (isDecoded && mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) &&
!currentReply) {
pi.sendResponse(mp);
ignoreRequest = ignoreRequest || pi.ignoreRequest; // If at least one module asks it, we may ignore a request
LOG_INFO("Asked module '%s' to send a response\n", pi.name);
@@ -163,7 +167,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
pi.currentRequest = NULL;
}
if (mp.decoded.want_response && toUs) {
if (isDecoded && mp.decoded.want_response && toUs) {
if (currentReply) {
printPacket("Sending response", currentReply);
service.sendToMesh(currentReply);
@@ -183,7 +187,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
}
}
if (!moduleFound) {
if (!moduleFound && isDecoded) {
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", mp.decoded.portnum,
(src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
}
+61 -3
View File
@@ -17,6 +17,48 @@
// if you set power to something higher than 17 or 20 you might fry your board.
#define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level
#ifdef RADIOMASTER_900_BANDIT_NANO
// Structure to hold DAC and DB values
typedef struct {
uint8_t dac;
uint8_t db;
} DACDB;
// Interpolation function
DACDB interpolate(uint8_t dbm, uint8_t dbm1, uint8_t dbm2, DACDB val1, DACDB val2) {
DACDB result;
double fraction = (double)(dbm - dbm1) / (dbm2 - dbm1);
result.dac = (uint8_t)(val1.dac + fraction * (val2.dac - val1.dac));
result.db = (uint8_t)(val1.db + fraction * (val2.db - val1.db));
return result;
}
// Function to find the correct DAC and DB values based on dBm using interpolation
DACDB getDACandDB(uint8_t dbm) {
// Predefined values
static const struct {
uint8_t dbm;
DACDB values;
} dbmToDACDB[] = {
{20, {168, 2}}, // 100mW
{24, {148, 6}}, // 250mW
{27, {128, 9}}, // 500mW
{30, {90, 12}} // 1000mW
};
const int numValues = sizeof(dbmToDACDB) / sizeof(dbmToDACDB[0]);
// Find the interval dbm falls within and interpolate
for (int i = 0; i < numValues - 1; i++) {
if (dbm >= dbmToDACDB[i].dbm && dbm <= dbmToDACDB[i + 1].dbm) {
return interpolate(dbm, dbmToDACDB[i].dbm, dbmToDACDB[i + 1].dbm, dbmToDACDB[i].values, dbmToDACDB[i + 1].values);
}
}
// Return a default value if no match is found and default to 100mW
DACDB defaultValue = {168, 2};
return defaultValue;
}
#endif
RF95Interface::RF95Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy)
@@ -52,9 +94,16 @@ bool RF95Interface::init()
{
RadioLibInterface::init();
#ifdef RADIOMASTER_900_BANDIT_NANO
// DAC and DB values based on dBm using interpolation
DACDB dacDbValues = getDACandDB(power);
int8_t powerDAC = dacDbValues.dac;
power = dacDbValues.db;
#endif
if (power > RF95_MAX_POWER) // This chip has lower power limits than some
power = RF95_MAX_POWER;
limitPower();
iface = lora = new RadioLibRF95(&module);
@@ -67,7 +116,13 @@ bool RF95Interface::init()
// enable PA
#ifdef RF95_PA_EN
#if defined(RF95_PA_DAC_EN)
dacWrite(RF95_PA_EN, RF95_PA_LEVEL);
#ifdef RADIOMASTER_900_BANDIT_NANO
// Use calculated DAC value
dacWrite(RF95_PA_EN, powerDAC);
#else
// Use Value set in /*/variant.h
dacWrite(RF95_PA_EN, RF95_PA_LEVEL);
#endif
#endif
#endif
@@ -107,6 +162,9 @@ bool RF95Interface::init()
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
#ifdef RADIOMASTER_900_BANDIT_NANO
LOG_INFO("DAC output set to %d\n", powerDAC);
#endif
if (res == RADIOLIB_ERR_NONE)
res = lora->setCRC(RADIOLIB_SX126X_LORA_CRC_ON);
@@ -259,4 +317,4 @@ bool RF95Interface::sleep()
#endif
return true;
}
}
+10 -10
View File
@@ -31,18 +31,18 @@ const RegionInfo regions[] = {
RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false, false),
/*
https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/
https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/
https://www.legislation.gov.uk/uksi/1999/930/schedule/6/part/III/made/data.xht?view=snippet&wrap=true
https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/
https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/
https://www.legislation.gov.uk/uksi/1999/930/schedule/6/part/III/made/data.xht?view=snippet&wrap=true
audio_permitted = false per regulation
audio_permitted = false per regulation
Special Note:
The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification,
we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is
500 mW, or 27 dBm. It also states that we can use interference avoidance and spectrum access techniques to avoid a duty
cycle. (Please refer to section 4.21 in the following document)
https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN
Special Note:
The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification,
we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is
500 mW, or 27 dBm. It also states that we can use interference avoidance and spectrum access techniques (such as LBT +
AFA) to avoid a duty cycle. (Please refer to line P page 22 of this document.)
https://www.etsi.org/deliver/etsi_en/300200_300299/30022002/03.01.01_60/en_30022002v030101p.pdf
*/
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false, false),
+2
View File
@@ -108,8 +108,10 @@ static void onNetworkConnected()
}
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
#ifndef MESHTASTIC_EXCLUDE_MQTT
if (mqtt)
mqtt->reconnect();
#endif
}
static int32_t reconnectWiFi()