diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index c54c22950..eae095da2 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -506,18 +506,18 @@ bool GPS::setup() delay(250); _serial_gps->write("$CFGMSG,6,1,0\r\n"); delay(250); - } else if (gnssModel == GNSS_MODEL_AG3335) { + } else if (gnssModel == GNSS_MODEL_AG3335 || gnssModel == GNSS_MODEL_AG3352) { _serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC // Configure NMEA (sentences will output once per fix) - _serial_gps->write("$PAIR062,0,0*3F\r\n"); // GGA ON + _serial_gps->write("$PAIR062,0,1*3F\r\n"); // GGA ON _serial_gps->write("$PAIR062,1,0*3F\r\n"); // GLL OFF - _serial_gps->write("$PAIR062,2,1*3D\r\n"); // GSA ON + _serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF _serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF - _serial_gps->write("$PAIR062,4,0*3B\r\n"); // RMC ON + _serial_gps->write("$PAIR062,4,1*3B\r\n"); // RMC ON _serial_gps->write("$PAIR062,5,0*3B\r\n"); // VTG OFF - _serial_gps->write("$PAIR062,6,1*39\r\n"); // ZDA ON + _serial_gps->write("$PAIR062,6,0*38\r\n"); // ZDA ON delay(250); _serial_gps->write("$PAIR513*3D\r\n"); // save configuration @@ -1020,7 +1020,7 @@ void GPS::down() LOG_DEBUG("%us until next search\n", sleepTime / 1000); // If update interval less than 10 seconds, no attempt to sleep - if (updateInterval <= 10 * 1000UL) + if (updateInterval <= 10 * 1000UL || sleepTime == 0) setPowerState(GPS_IDLE); else { @@ -1205,9 +1205,6 @@ GnssModel_t GPS::probe(int serialSpeed) _serial_gps->updateBaudRate(serialSpeed); } #endif -#ifdef GNSS_AIROHA - return GNSS_MODEL_AG3335; -#endif memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); uint8_t buffer[768] = {0}; @@ -1226,7 +1223,12 @@ GnssModel_t GPS::probe(int serialSpeed) PROBE_SIMPLE("ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H, 500); /* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */ - PROBE_SIMPLE("AG3335", "PAIR020*38", "$PAIR020,AG3335", GNSS_MODEL_AG3335, 500); + _serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume + _serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume + _serial_gps->write("$PAIR513*3D\r\n"); // save configuration + PROBE_SIMPLE("AG3335", "$PAIR021*39", "$PAIR021,AG3335", GNSS_MODEL_AG3335, 500); + PROBE_SIMPLE("AG3352", "$PAIR021*39", "$PAIR021,AG3352", GNSS_MODEL_AG3352, 500); + PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500); PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500); @@ -1803,4 +1805,4 @@ void GPS::toggleGpsMode() enable(); } } -#endif // Exclude GPS \ No newline at end of file +#endif // Exclude GPS diff --git a/src/gps/GPS.h b/src/gps/GPS.h index c0e9fb8b6..caff48f32 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -30,7 +30,8 @@ typedef enum { GNSS_MODEL_UC6580, GNSS_MODEL_UNKNOWN, GNSS_MODEL_MTK_L76B, - GNSS_MODEL_AG3335 + GNSS_MODEL_AG3335, + GNSS_MODEL_AG3352 } GnssModel_t; typedef enum { @@ -297,7 +298,6 @@ class GPS : private concurrency::OSThread virtual int32_t runOnce() override; // Get GNSS model - String getNMEA(); GnssModel_t probe(int serialSpeed); // delay counter to allow more sats before fixed position stops GPS thread @@ -310,4 +310,4 @@ class GPS : private concurrency::OSThread }; extern GPS *gps; -#endif // Exclude GPS \ No newline at end of file +#endif // Exclude GPS diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp index 1bff49475..8aaebcb45 100644 --- a/src/input/cardKbI2cImpl.cpp +++ b/src/input/cardKbI2cImpl.cpp @@ -9,7 +9,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {} void CardKbI2cImpl::init() { -#ifndef ARCH_PORTDUINO +#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) if (cardkb_found.address == 0x00) { LOG_DEBUG("Rescanning for I2C keyboard\n"); uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR}; @@ -57,4 +57,4 @@ void CardKbI2cImpl::init() } #endif inputBroker->registerSource(this); -} +} \ No newline at end of file diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index bba7571d2..47c013443 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -13,10 +13,6 @@ #include "mqtt/MQTT.h" #endif -/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128) -static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, - 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01}; - Channels channels; const char *Channels::adminChannel = "admin"; diff --git a/src/mesh/Channels.h b/src/mesh/Channels.h index 4f87cb309..e5a750f71 100644 --- a/src/mesh/Channels.h +++ b/src/mesh/Channels.h @@ -129,4 +129,12 @@ class Channels }; /// Singleton channel table -extern Channels channels; \ No newline at end of file +extern Channels channels; + +/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128) +static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, + 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01}; + +static const uint8_t eventpsk[] = {0x38, 0x4b, 0xbc, 0xc0, 0x1d, 0xc0, 0x22, 0xd1, 0x81, 0xbf, 0x36, + 0xb8, 0x61, 0x21, 0xe1, 0xfb, 0x96, 0xb7, 0x2e, 0x55, 0xbf, 0x74, + 0x22, 0x7e, 0x9d, 0x6a, 0xfb, 0x48, 0xd6, 0x4c, 0xb1, 0xa1}; \ No newline at end of file diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 0e369ce94..8664a1d0b 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -121,6 +121,8 @@ NodeDB::NodeDB() owner.hw_model = HW_VENDOR; // Ensure user (nodeinfo) role is set to whatever we're configured to owner.role = config.device.role; + // Ensure macaddr is set to our macaddr as it will be copied in our info below + memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr)); // Include our owner in the node db under our nodenum meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum()); @@ -292,6 +294,7 @@ void NodeDB::installDefaultConfig() config.lora.tx_enabled = true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off) config.lora.override_duty_cycle = false; + config.lora.config_ok_to_mqtt = false; #ifdef CONFIG_LORA_REGION_USERPREFS config.lora.region = CONFIG_LORA_REGION_USERPREFS; #else @@ -1200,4 +1203,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co LOG_ERROR("A critical failure occurred, portduino is exiting..."); exit(2); #endif -} +} \ No newline at end of file diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index d8e578db1..b222872fa 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -378,6 +378,8 @@ bool perhapsDecode(meshtastic_MeshPacket *p) // parsing was successful p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded p->channel = chIndex; // change to store the index instead of the hash + if (p->decoded.has_bitfield) + p->decoded.want_response |= p->decoded.bitfield & BITFIELD_WANT_RESPONSE_MASK; /* Not actually ever used. // Decompress if needed. jm @@ -424,6 +426,12 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) // If the packet is not yet encrypted, do so now if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { + if (p->from == nodeDB->getNodeNum()) { + p->decoded.has_bitfield = true; + p->decoded.bitfield |= (config.lora.config_ok_to_mqtt << BITFIELD_OK_TO_MQTT_SHIFT); + p->decoded.bitfield |= (p->decoded.want_response << BITFIELD_WANT_RESPONSE_SHIFT); + } + size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); /* Not actually used, so save the cycles diff --git a/src/mesh/Router.h b/src/mesh/Router.h index 98486745b..fd4b0ccf9 100644 --- a/src/mesh/Router.h +++ b/src/mesh/Router.h @@ -148,3 +148,8 @@ extern Router *router; /// Generate a unique packet id // FIXME, move this someplace better PacketId generatePacketId(); + +#define BITFIELD_WANT_RESPONSE_SHIFT 1 +#define BITFIELD_OK_TO_MQTT_SHIFT 0 +#define BITFIELD_WANT_RESPONSE_MASK (1 << BITFIELD_WANT_RESPONSE_SHIFT) +#define BITFIELD_OK_TO_MQTT_MASK (1 << BITFIELD_OK_TO_MQTT_SHIFT) \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/T1000xSensor.cpp b/src/modules/Telemetry/Sensor/T1000xSensor.cpp index 4079d8ae3..4772aeb9e 100644 --- a/src/modules/Telemetry/Sensor/T1000xSensor.cpp +++ b/src/modules/Telemetry/Sensor/T1000xSensor.cpp @@ -95,7 +95,7 @@ float T1000xSensor::getTemp() Vout = ntc_vot; Rt = (HEATER_NTC_RP * vcc_vot) / Vout - HEATER_NTC_RP; - for (u8i = 0; u8i < 136; u8i++) { + for (u8i = 0; u8i < 135; u8i++) { if (Rt >= ntc_res2[u8i]) { break; } diff --git a/src/modules/TraceRouteModule.cpp b/src/modules/TraceRouteModule.cpp index dd3d0b4f9..23b4f1ccf 100644 --- a/src/modules/TraceRouteModule.cpp +++ b/src/modules/TraceRouteModule.cpp @@ -53,7 +53,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro uint8_t hopsTaken = p.hop_start - p.hop_limit; int8_t diff = hopsTaken - *route_count; for (uint8_t i = 0; i < diff; i++) { - if (*route_count < sizeof(*route) / sizeof(route[0])) { + if (*route_count < ROUTE_SIZE) { route[*route_count] = NODENUM_BROADCAST; // This will represent an unknown hop *route_count += 1; } @@ -61,7 +61,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro // Add unknown SNR values if necessary diff = *route_count - *snr_count; for (uint8_t i = 0; i < diff; i++) { - if (*snr_count < sizeof(*snr_list) / sizeof(snr_list[0])) { + if (*snr_count < ROUTE_SIZE) { snr_list[*snr_count] = INT8_MIN; // This will represent an unknown SNR *snr_count += 1; } @@ -89,7 +89,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa snr_list = updated->snr_back; } - if (*snr_count < sizeof(*snr_list) / sizeof(snr_list[0])) { + if (*snr_count < ROUTE_SIZE) { snr_list[*snr_count] = (int8_t)(snr * 4); // Convert SNR to 1 byte *snr_count += 1; } @@ -97,7 +97,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa return; // Length of route array can normally not be exceeded due to the max. hop_limit of 7 - if (*route_count < sizeof(*route) / sizeof(route[0])) { + if (*route_count < ROUTE_SIZE) { route[*route_count] = myNodeInfo.my_node_num; *route_count += 1; } else { diff --git a/src/modules/TraceRouteModule.h b/src/modules/TraceRouteModule.h index fe69300de..afe2b3871 100644 --- a/src/modules/TraceRouteModule.h +++ b/src/modules/TraceRouteModule.h @@ -1,6 +1,8 @@ #pragma once #include "ProtobufModule.h" +#define ROUTE_SIZE sizeof(((meshtastic_RouteDiscovery *)0)->route) / sizeof(((meshtastic_RouteDiscovery *)0)->route[0]) + /** * A module that traces the route to a certain destination node */ diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 797fc7dc3..d14c7a923 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -514,19 +514,29 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket & return; // no channels have an uplink enabled auto &ch = channels.getByIndex(chIndex); - if (mp_decoded.which_payload_variant != meshtastic_MeshPacket_decoded_tag) { - LOG_CRIT("MQTT::onSend(): mp_decoded isn't actually decoded\n"); - return; - } + if (!mp.pki_encrypted) { + if (mp_decoded.which_payload_variant != meshtastic_MeshPacket_decoded_tag) { + LOG_CRIT("MQTT::onSend(): mp_decoded isn't actually decoded\n"); + return; + } - if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0 && - (mp_decoded.decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP || - mp_decoded.decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP)) { - LOG_DEBUG("MQTT onSend - Ignoring range test or detection sensor message on public mqtt\n"); - return; - } + // check for the lowest bit of the data bitfield set false, and the use of one of the default keys. + if (mp_decoded.from != nodeDB->getNodeNum() && mp_decoded.decoded.has_bitfield && + !(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK) && + (ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) || + (ch.settings.psk.size == 32 && memcmp(ch.settings.psk.bytes, eventpsk, 32)))) { + LOG_INFO("MQTT onSend - Not forwarding packet due to DontMqttMeBro flag\n"); + return; + } - if (ch.settings.uplink_enabled || mp.pki_encrypted) { + if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0 && + (mp_decoded.decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP || + mp_decoded.decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP)) { + LOG_DEBUG("MQTT onSend - Ignoring range test or detection sensor message on public mqtt\n"); + return; + } + } + if (mp.pki_encrypted || ch.settings.uplink_enabled) { const char *channelId = mp.pki_encrypted ? "PKI" : channels.getGlobalId(chIndex); meshtastic_ServiceEnvelope *env = mqttPool.allocZeroed(); @@ -537,7 +547,8 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket & if (moduleConfig.mqtt.encryption_enabled) { env->packet = (meshtastic_MeshPacket *)∓ LOG_DEBUG("encrypted message\n"); - } else { + } else if (mp_decoded.which_payload_variant == + meshtastic_MeshPacket_decoded_tag) { // Don't upload a still-encrypted PKI packet env->packet = (meshtastic_MeshPacket *)&mp_decoded; LOG_DEBUG("portnum %i message\n", env->packet->decoded.portnum); } diff --git a/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp b/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp index 84264ef58..0a19a9c3b 100644 --- a/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp +++ b/src/platform/extra_variants/heltec_wireless_tracker/variant.cpp @@ -10,10 +10,14 @@ void lateInitVariant() { // LOG_DEBUG("Heltec tracker initVariant\n"); -#ifdef VEXT_ENABLE - GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE); - GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin(); +#ifndef MESHTASTIC_EXCLUDE_GPS + GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin(); +#else + GpioVirtPin *virtGpsEnable = new GpioVirtPin(); +#endif + +#ifndef MESHTASTIC_EXCLUDE_SCREEN // On this board we are actually using the backlightEnable signal to already be controlling a physical enable to the // display controller. But we'd _ALSO_ like to have that signal drive a virtual GPIO. So nest it as needed. GpioVirtPin *virtScreenEnable = new GpioVirtPin(); @@ -25,8 +29,11 @@ void lateInitVariant() // Assume screen is initially powered splitter->set(true); } +#endif +#if defined(VEXT_ENABLE) && (!defined(MESHTASTIC_EXCLUDE_GPS) || !defined(MESHTASTIC_EXCLUDE_SCREEN)) // If either the GPS or the screen is on, turn on the external power regulator + GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE); new GpioBinaryTransformer(virtGpsEnable, virtScreenEnable, hwEnable, GpioBinaryTransformer::Or); #endif } diff --git a/src/serialization/JSONValue.h b/src/serialization/JSONValue.h index 0380d324b..16d53e89f 100644 --- a/src/serialization/JSONValue.h +++ b/src/serialization/JSONValue.h @@ -40,15 +40,15 @@ class JSONValue public: JSONValue(/*NULL*/); - JSONValue(const char *m_char_value); - JSONValue(const std::string &m_string_value); - JSONValue(bool m_bool_value); - JSONValue(double m_number_value); - JSONValue(int m_integer_value); - JSONValue(unsigned int m_integer_value); - JSONValue(const JSONArray &m_array_value); - JSONValue(const JSONObject &m_object_value); - JSONValue(const JSONValue &m_source); + explicit JSONValue(const char *m_char_value); + explicit JSONValue(const std::string &m_string_value); + explicit JSONValue(bool m_bool_value); + explicit JSONValue(double m_number_value); + explicit JSONValue(int m_integer_value); + explicit JSONValue(unsigned int m_integer_value); + explicit JSONValue(const JSONArray &m_array_value); + explicit JSONValue(const JSONObject &m_object_value); + explicit JSONValue(const JSONValue &m_source); ~JSONValue(); bool IsNull() const;