Merge pull request #1 from GUVWAF/beegee-tokyo

Formatting for PR #4661
This commit is contained in:
Bernd Giesecke 2024-09-13 09:26:00 +08:00 committed by GitHub
commit 6c327d960d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 330 additions and 392 deletions

View File

@ -161,5 +161,4 @@ lib_deps =
mprograms/QMC5883LCompass@^1.2.0 mprograms/QMC5883LCompass@^1.2.0
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1

View File

@ -95,7 +95,7 @@ class AccelerometerThread : public concurrency::OSThread
return 500; return 500;
} }
#if defined(RAK_4631) #if defined(RAK_4631)
#if !defined (MESHTASTIC_EXCLUDE_SCREEN) #if !defined(MESHTASTIC_EXCLUDE_SCREEN)
} else if (acceleremoter_type == ScanI2C::DeviceType::BMX160) { } else if (acceleremoter_type == ScanI2C::DeviceType::BMX160) {
sBmx160SensorData_t magAccel; sBmx160SensorData_t magAccel;
sBmx160SensorData_t gAccel; sBmx160SensorData_t gAccel;

View File

@ -378,8 +378,9 @@ void MQTT::sendSubscriptions()
hasDownlink = true; hasDownlink = true;
std::string topic = cryptTopic + channels.getGlobalId(i) + "/+"; std::string topic = cryptTopic + channels.getGlobalId(i) + "/+";
LOG_INFO("Subscribing to %s\n", topic.c_str()); LOG_INFO("Subscribing to %s\n", topic.c_str());
pubSub.subscribe(topic.c_str(), 1); // FIXME, is QOS 1 right? pubSub.subscribe(topic.c_str(), 1); // FIXME, is QOS 1 right?
#if !defined(ARCH_NRF52) || defined(NRF52_USE_JSON) // JSON is not supported on nRF52, see issue #2804 ### Fixed by using ArduinoJSON ### #if !defined(ARCH_NRF52) || \
defined(NRF52_USE_JSON) // JSON is not supported on nRF52, see issue #2804 ### Fixed by using ArduinoJSON ###
if (moduleConfig.mqtt.json_enabled == true) { if (moduleConfig.mqtt.json_enabled == true) {
std::string topicDecoded = jsonTopic + channels.getGlobalId(i) + "/+"; std::string topicDecoded = jsonTopic + channels.getGlobalId(i) + "/+";
LOG_INFO("Subscribing to %s\n", topicDecoded.c_str()); LOG_INFO("Subscribing to %s\n", topicDecoded.c_str());
@ -480,7 +481,8 @@ void MQTT::publishQueuedMessages()
publish(topic.c_str(), bytes, numBytes, false); publish(topic.c_str(), bytes, numBytes, false);
#if !defined(ARCH_NRF52) || defined(NRF52_USE_JSON) // JSON is not supported on nRF52, see issue #2804 ### Fixed by using ArduinoJson ### #if !defined(ARCH_NRF52) || \
defined(NRF52_USE_JSON) // JSON is not supported on nRF52, see issue #2804 ### Fixed by using ArduinoJson ###
if (moduleConfig.mqtt.json_enabled) { if (moduleConfig.mqtt.json_enabled) {
// handle json topic // handle json topic
auto jsonString = MeshPacketSerializer::JsonSerialize(env->packet); auto jsonString = MeshPacketSerializer::JsonSerialize(env->packet);
@ -562,7 +564,8 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
publish(topic.c_str(), bytes, numBytes, false); publish(topic.c_str(), bytes, numBytes, false);
#if !defined(ARCH_NRF52) || defined(NRF52_USE_JSON) // JSON is not supported on nRF52, see issue #2804 ### Fixed by using ArduinoJson ### #if !defined(ARCH_NRF52) || \
defined(NRF52_USE_JSON) // JSON is not supported on nRF52, see issue #2804 ### Fixed by using ArduinoJson ###
if (moduleConfig.mqtt.json_enabled) { if (moduleConfig.mqtt.json_enabled) {
// handle json topic // handle json topic
auto jsonString = MeshPacketSerializer::JsonSerialize((meshtastic_MeshPacket *)&mp_decoded); auto jsonString = MeshPacketSerializer::JsonSerialize((meshtastic_MeshPacket *)&mp_decoded);

View File

@ -19,7 +19,7 @@ static BLEBas blebas; // BAS (Battery Service) helper class instance
#ifndef BLE_DFU_SECURE #ifndef BLE_DFU_SECURE
static BLEDfu bledfu; // DFU software update helper service static BLEDfu bledfu; // DFU software update helper service
#else #else
static BLEDfuSecure bledfusecure; // DFU software update helper service static BLEDfuSecure bledfusecure; // DFU software update helper service
#endif #endif
// This scratch buffer is used for various bluetooth reads/writes - but it is safe because only one bt operation can be in // This scratch buffer is used for various bluetooth reads/writes - but it is safe because only one bt operation can be in
@ -114,8 +114,8 @@ void startAdv(void)
*/ */
Bluefruit.Advertising.restartOnDisconnect(true); Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds. FIXME, we should stop advertising after X Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds. FIXME, we should stop advertising after X
} }
// Just ack that the caller is allowed to read // Just ack that the caller is allowed to read
static void authorizeRead(uint16_t conn_hdl) static void authorizeRead(uint16_t conn_hdl)
@ -172,7 +172,7 @@ void setupMeshService(void)
fromRadio.setMaxLen(sizeof(fromRadioBytes)); fromRadio.setMaxLen(sizeof(fromRadioBytes));
fromRadio.setReadAuthorizeCallback( fromRadio.setReadAuthorizeCallback(
onFromRadioAuthorize, onFromRadioAuthorize,
false); // We don't call this callback via the adafruit queue, because we can safely run in the BLE context false); // We don't call this callback via the adafruit queue, because we can safely run in the BLE context
fromRadio.setBuffer(fromRadioBytes, sizeof(fromRadioBytes)); // we preallocate our fromradio buffer so we won't waste space fromRadio.setBuffer(fromRadioBytes, sizeof(fromRadioBytes)); // we preallocate our fromradio buffer so we won't waste space
// for two copies // for two copies
fromRadio.begin(); fromRadio.begin();
@ -262,7 +262,7 @@ void NRF52Bluetooth::setup()
bledfu.begin(); // Install the DFU helper bledfu.begin(); // Install the DFU helper
#else #else
bledfusecure.setPermission(SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM); // add by WayenWeng bledfusecure.setPermission(SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM); // add by WayenWeng
bledfusecure.begin(); // Install the DFU helper bledfusecure.begin(); // Install the DFU helper
#endif #endif
// Configure and Start the Device Information Service // Configure and Start the Device Information Service
LOG_INFO("Configuring the Device Information Service\n"); LOG_INFO("Configuring the Device Information Service\n");
@ -286,7 +286,7 @@ void NRF52Bluetooth::resumeAdvertising()
{ {
Bluefruit.Advertising.restartOnDisconnect(true); Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
Bluefruit.Advertising.start(0); Bluefruit.Advertising.start(0);
} }
/// Given a level between 0-100, update the BLE attribute /// Given a level between 0-100, update the BLE attribute

View File

@ -1,417 +1,353 @@
#ifdef NRF52_USE_JSON #ifdef NRF52_USE_JSON
#warning 'Using nRF52 Serializer' #warning 'Using nRF52 Serializer'
#include "MeshPacketSerializer.h"
#include "ArduinoJson.h" #include "ArduinoJson.h"
#include "MeshPacketSerializer.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "mesh/generated/meshtastic/mqtt.pb.h" #include "mesh/generated/meshtastic/mqtt.pb.h"
#include "mesh/generated/meshtastic/remote_hardware.pb.h"
#include "mesh/generated/meshtastic/telemetry.pb.h" #include "mesh/generated/meshtastic/telemetry.pb.h"
#include "modules/RoutingModule.h" #include "modules/RoutingModule.h"
#include <DebugConfiguration.h> #include <DebugConfiguration.h>
#include <mesh-pb-constants.h> #include <mesh-pb-constants.h>
#include "mesh/generated/meshtastic/remote_hardware.pb.h"
StaticJsonDocument<1024> jsonObj; StaticJsonDocument<1024> jsonObj;
StaticJsonDocument<1024> arrayObj; StaticJsonDocument<1024> arrayObj;
std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp, bool shouldLog) std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp, bool shouldLog)
{ {
// the created jsonObj is immutable after creation, so // the created jsonObj is immutable after creation, so
// we need to do the heavy lifting before assembling it. // we need to do the heavy lifting before assembling it.
std::string msgType; std::string msgType;
jsonObj.clear(); jsonObj.clear();
arrayObj.clear(); arrayObj.clear();
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
{ switch (mp->decoded.portnum) {
switch (mp->decoded.portnum) case meshtastic_PortNum_TEXT_MESSAGE_APP: {
{ msgType = "text";
case meshtastic_PortNum_TEXT_MESSAGE_APP: // convert bytes to string
{ if (shouldLog)
msgType = "text"; LOG_DEBUG("got text message of size %u\n", mp->decoded.payload.size);
// convert bytes to string
if (shouldLog)
LOG_DEBUG("got text message of size %u\n", mp->decoded.payload.size);
char payloadStr[(mp->decoded.payload.size) + 1]; char payloadStr[(mp->decoded.payload.size) + 1];
memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size); memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size);
payloadStr[mp->decoded.payload.size] = 0; // null terminated string payloadStr[mp->decoded.payload.size] = 0; // null terminated string
// check if this is a JSON payload // check if this is a JSON payload
StaticJsonDocument<512> text_doc; StaticJsonDocument<512> text_doc;
DeserializationError error = deserializeJson(text_doc, payloadStr); DeserializationError error = deserializeJson(text_doc, payloadStr);
if (error) if (error) {
{ // if it isn't, then we need to create a json object
// if it isn't, then we need to create a json object // with the string as the value
// with the string as the value if (shouldLog)
if (shouldLog) LOG_INFO("text message payload is of type plaintext\n");
LOG_INFO("text message payload is of type plaintext\n"); jsonObj["payload"]["text"] = payloadStr;
jsonObj["payload"]["text"] = payloadStr; } else {
} // if it is, then we can just use the json object
else if (shouldLog)
{ LOG_INFO("text message payload is of type json\n");
// if it is, then we can just use the json object jsonObj["payload"] = text_doc;
if (shouldLog) }
LOG_INFO("text message payload is of type json\n"); break;
jsonObj["payload"] = text_doc; }
} case meshtastic_PortNum_TELEMETRY_APP: {
break; msgType = "telemetry";
} meshtastic_Telemetry scratch;
case meshtastic_PortNum_TELEMETRY_APP: meshtastic_Telemetry *decoded = NULL;
{ memset(&scratch, 0, sizeof(scratch));
msgType = "telemetry"; if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Telemetry_msg, &scratch)) {
meshtastic_Telemetry scratch; decoded = &scratch;
meshtastic_Telemetry *decoded = NULL; if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) {
memset(&scratch, 0, sizeof(scratch)); jsonObj["payload"]["battery_level"] = (unsigned int)decoded->variant.device_metrics.battery_level;
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Telemetry_msg, &scratch)) jsonObj["payload"]["voltage"] = decoded->variant.device_metrics.voltage;
{ jsonObj["payload"]["channel_utilization"] = decoded->variant.device_metrics.channel_utilization;
decoded = &scratch; jsonObj["payload"]["air_util_tx"] = decoded->variant.device_metrics.air_util_tx;
if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) jsonObj["payload"]["uptime_seconds"] = (unsigned int)decoded->variant.device_metrics.uptime_seconds;
{ } else if (decoded->which_variant == meshtastic_Telemetry_environment_metrics_tag) {
jsonObj["payload"]["battery_level"] = (unsigned int)decoded->variant.device_metrics.battery_level; jsonObj["payload"]["temperature"] = decoded->variant.environment_metrics.temperature;
jsonObj["payload"]["voltage"] = decoded->variant.device_metrics.voltage; jsonObj["payload"]["relative_humidity"] = decoded->variant.environment_metrics.relative_humidity;
jsonObj["payload"]["channel_utilization"] = decoded->variant.device_metrics.channel_utilization; jsonObj["payload"]["barometric_pressure"] = decoded->variant.environment_metrics.barometric_pressure;
jsonObj["payload"]["air_util_tx"] = decoded->variant.device_metrics.air_util_tx; jsonObj["payload"]["gas_resistance"] = decoded->variant.environment_metrics.gas_resistance;
jsonObj["payload"]["uptime_seconds"] = (unsigned int)decoded->variant.device_metrics.uptime_seconds; jsonObj["payload"]["voltage"] = decoded->variant.environment_metrics.voltage;
} jsonObj["payload"]["current"] = decoded->variant.environment_metrics.current;
else if (decoded->which_variant == meshtastic_Telemetry_environment_metrics_tag) jsonObj["payload"]["lux"] = decoded->variant.environment_metrics.lux;
{ jsonObj["payload"]["white_lux"] = decoded->variant.environment_metrics.white_lux;
jsonObj["payload"]["temperature"] = decoded->variant.environment_metrics.temperature; jsonObj["payload"]["iaq"] = (uint)decoded->variant.environment_metrics.iaq;
jsonObj["payload"]["relative_humidity"] = decoded->variant.environment_metrics.relative_humidity; jsonObj["payload"]["wind_speed"] = decoded->variant.environment_metrics.wind_speed;
jsonObj["payload"]["barometric_pressure"] = decoded->variant.environment_metrics.barometric_pressure; jsonObj["payload"]["wind_direction"] = (uint)decoded->variant.environment_metrics.wind_direction;
jsonObj["payload"]["gas_resistance"] = decoded->variant.environment_metrics.gas_resistance; jsonObj["payload"]["wind_gust"] = decoded->variant.environment_metrics.wind_gust;
jsonObj["payload"]["voltage"] = decoded->variant.environment_metrics.voltage; jsonObj["payload"]["wind_lull"] = decoded->variant.environment_metrics.wind_lull;
jsonObj["payload"]["current"] = decoded->variant.environment_metrics.current; } else if (decoded->which_variant == meshtastic_Telemetry_air_quality_metrics_tag) {
jsonObj["payload"]["lux"] = decoded->variant.environment_metrics.lux; jsonObj["payload"]["pm10"] = (unsigned int)decoded->variant.air_quality_metrics.pm10_standard;
jsonObj["payload"]["white_lux"] = decoded->variant.environment_metrics.white_lux; jsonObj["payload"]["pm25"] = (unsigned int)decoded->variant.air_quality_metrics.pm25_standard;
jsonObj["payload"]["iaq"] = (uint)decoded->variant.environment_metrics.iaq; jsonObj["payload"]["pm100"] = (unsigned int)decoded->variant.air_quality_metrics.pm100_standard;
jsonObj["payload"]["wind_speed"] = decoded->variant.environment_metrics.wind_speed; jsonObj["payload"]["pm10_e"] = (unsigned int)decoded->variant.air_quality_metrics.pm10_environmental;
jsonObj["payload"]["wind_direction"] = (uint)decoded->variant.environment_metrics.wind_direction; jsonObj["payload"]["pm25_e"] = (unsigned int)decoded->variant.air_quality_metrics.pm25_environmental;
jsonObj["payload"]["wind_gust"] = decoded->variant.environment_metrics.wind_gust; jsonObj["payload"]["pm100_e"] = (unsigned int)decoded->variant.air_quality_metrics.pm100_environmental;
jsonObj["payload"]["wind_lull"] = decoded->variant.environment_metrics.wind_lull; } else if (decoded->which_variant == meshtastic_Telemetry_power_metrics_tag) {
} jsonObj["payload"]["voltage_ch1"] = decoded->variant.power_metrics.ch1_voltage;
else if (decoded->which_variant == meshtastic_Telemetry_air_quality_metrics_tag) jsonObj["payload"]["current_ch1"] = decoded->variant.power_metrics.ch1_current;
{ jsonObj["payload"]["voltage_ch2"] = decoded->variant.power_metrics.ch2_voltage;
jsonObj["payload"]["pm10"] = (unsigned int)decoded->variant.air_quality_metrics.pm10_standard; jsonObj["payload"]["current_ch2"] = decoded->variant.power_metrics.ch2_current;
jsonObj["payload"]["pm25"] = (unsigned int)decoded->variant.air_quality_metrics.pm25_standard; jsonObj["payload"]["voltage_ch3"] = decoded->variant.power_metrics.ch3_voltage;
jsonObj["payload"]["pm100"] = (unsigned int)decoded->variant.air_quality_metrics.pm100_standard; jsonObj["payload"]["current_ch3"] = decoded->variant.power_metrics.ch3_current;
jsonObj["payload"]["pm10_e"] = (unsigned int)decoded->variant.air_quality_metrics.pm10_environmental; }
jsonObj["payload"]["pm25_e"] = (unsigned int)decoded->variant.air_quality_metrics.pm25_environmental; } else if (shouldLog) {
jsonObj["payload"]["pm100_e"] = (unsigned int)decoded->variant.air_quality_metrics.pm100_environmental; LOG_ERROR("Error decoding protobuf for telemetry message!\n");
} return "";
else if (decoded->which_variant == meshtastic_Telemetry_power_metrics_tag) }
{ break;
jsonObj["payload"]["voltage_ch1"] = decoded->variant.power_metrics.ch1_voltage; }
jsonObj["payload"]["current_ch1"] = decoded->variant.power_metrics.ch1_current; case meshtastic_PortNum_NODEINFO_APP: {
jsonObj["payload"]["voltage_ch2"] = decoded->variant.power_metrics.ch2_voltage; msgType = "nodeinfo";
jsonObj["payload"]["current_ch2"] = decoded->variant.power_metrics.ch2_current; meshtastic_User scratch;
jsonObj["payload"]["voltage_ch3"] = decoded->variant.power_metrics.ch3_voltage; meshtastic_User *decoded = NULL;
jsonObj["payload"]["current_ch3"] = decoded->variant.power_metrics.ch3_current; memset(&scratch, 0, sizeof(scratch));
} if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_User_msg, &scratch)) {
} decoded = &scratch;
else if (shouldLog) jsonObj["payload"]["id"] = decoded->id;
{ jsonObj["payload"]["longname"] = decoded->long_name;
LOG_ERROR("Error decoding protobuf for telemetry message!\n"); jsonObj["payload"]["shortname"] = decoded->short_name;
return ""; jsonObj["payload"]["hardware"] = decoded->hw_model;
} jsonObj["payload"]["role"] = (int)decoded->role;
break; } else if (shouldLog) {
} LOG_ERROR("Error decoding protobuf for nodeinfo message!\n");
case meshtastic_PortNum_NODEINFO_APP: return "";
{ }
msgType = "nodeinfo"; break;
meshtastic_User scratch; }
meshtastic_User *decoded = NULL; case meshtastic_PortNum_POSITION_APP: {
memset(&scratch, 0, sizeof(scratch)); msgType = "position";
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_User_msg, &scratch)) meshtastic_Position scratch;
{ meshtastic_Position *decoded = NULL;
decoded = &scratch; memset(&scratch, 0, sizeof(scratch));
jsonObj["payload"]["id"] = decoded->id; if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Position_msg, &scratch)) {
jsonObj["payload"]["longname"] = decoded->long_name; decoded = &scratch;
jsonObj["payload"]["shortname"] = decoded->short_name; if ((int)decoded->time) {
jsonObj["payload"]["hardware"] = decoded->hw_model; jsonObj["payload"]["time"] = (unsigned int)decoded->time;
jsonObj["payload"]["role"] = (int)decoded->role; }
} if ((int)decoded->timestamp) {
else if (shouldLog) jsonObj["payload"]["timestamp"] = (unsigned int)decoded->timestamp;
{ }
LOG_ERROR("Error decoding protobuf for nodeinfo message!\n"); jsonObj["payload"]["latitude_i"] = (int)decoded->latitude_i;
return ""; jsonObj["payload"]["longitude_i"] = (int)decoded->longitude_i;
} if ((int)decoded->altitude) {
break; jsonObj["payload"]["altitude"] = (int)decoded->altitude;
} }
case meshtastic_PortNum_POSITION_APP: if ((int)decoded->ground_speed) {
{ jsonObj["payload"]["ground_speed"] = (unsigned int)decoded->ground_speed;
msgType = "position"; }
meshtastic_Position scratch; if (int(decoded->ground_track)) {
meshtastic_Position *decoded = NULL; jsonObj["payload"]["ground_track"] = (unsigned int)decoded->ground_track;
memset(&scratch, 0, sizeof(scratch)); }
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Position_msg, &scratch)) if (int(decoded->sats_in_view)) {
{ jsonObj["payload"]["sats_in_view"] = (unsigned int)decoded->sats_in_view;
decoded = &scratch; }
if ((int)decoded->time) if ((int)decoded->PDOP) {
{ jsonObj["payload"]["PDOP"] = (int)decoded->PDOP;
jsonObj["payload"]["time"] = (unsigned int)decoded->time; }
} if ((int)decoded->HDOP) {
if ((int)decoded->timestamp) jsonObj["payload"]["HDOP"] = (int)decoded->HDOP;
{ }
jsonObj["payload"]["timestamp"] = (unsigned int)decoded->timestamp; if ((int)decoded->VDOP) {
} jsonObj["payload"]["VDOP"] = (int)decoded->VDOP;
jsonObj["payload"]["latitude_i"] = (int)decoded->latitude_i; }
jsonObj["payload"]["longitude_i"] = (int)decoded->longitude_i; if ((int)decoded->precision_bits) {
if ((int)decoded->altitude) jsonObj["payload"]["precision_bits"] = (int)decoded->precision_bits;
{ }
jsonObj["payload"]["altitude"] = (int)decoded->altitude; } else if (shouldLog) {
} LOG_ERROR("Error decoding protobuf for position message!\n");
if ((int)decoded->ground_speed) return "";
{ }
jsonObj["payload"]["ground_speed"] = (unsigned int)decoded->ground_speed; break;
} }
if (int(decoded->ground_track)) case meshtastic_PortNum_WAYPOINT_APP: {
{ msgType = "position";
jsonObj["payload"]["ground_track"] = (unsigned int)decoded->ground_track; meshtastic_Waypoint scratch;
} meshtastic_Waypoint *decoded = NULL;
if (int(decoded->sats_in_view)) memset(&scratch, 0, sizeof(scratch));
{ if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) {
jsonObj["payload"]["sats_in_view"] = (unsigned int)decoded->sats_in_view; decoded = &scratch;
} jsonObj["payload"]["id"] = (unsigned int)decoded->id;
if ((int)decoded->PDOP) jsonObj["payload"]["name"] = decoded->name;
{ jsonObj["payload"]["description"] = decoded->description;
jsonObj["payload"]["PDOP"] = (int)decoded->PDOP; jsonObj["payload"]["expire"] = (unsigned int)decoded->expire;
} jsonObj["payload"]["locked_to"] = (unsigned int)decoded->locked_to;
if ((int)decoded->HDOP) jsonObj["payload"]["latitude_i"] = (int)decoded->latitude_i;
{ jsonObj["payload"]["longitude_i"] = (int)decoded->longitude_i;
jsonObj["payload"]["HDOP"] = (int)decoded->HDOP; } else if (shouldLog) {
} LOG_ERROR("Error decoding protobuf for position message!\n");
if ((int)decoded->VDOP) return "";
{ }
jsonObj["payload"]["VDOP"] = (int)decoded->VDOP; break;
} }
if ((int)decoded->precision_bits) case meshtastic_PortNum_NEIGHBORINFO_APP: {
{ msgType = "neighborinfo";
jsonObj["payload"]["precision_bits"] = (int)decoded->precision_bits; meshtastic_NeighborInfo scratch;
} meshtastic_NeighborInfo *decoded = NULL;
} memset(&scratch, 0, sizeof(scratch));
else if (shouldLog) if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_NeighborInfo_msg,
{ &scratch)) {
LOG_ERROR("Error decoding protobuf for position message!\n"); decoded = &scratch;
return ""; jsonObj["payload"]["node_id"] = (unsigned int)decoded->node_id;
} jsonObj["payload"]["node_broadcast_interval_secs"] = (unsigned int)decoded->node_broadcast_interval_secs;
break; jsonObj["payload"]["last_sent_by_id"] = (unsigned int)decoded->last_sent_by_id;
} jsonObj["payload"]["neighbors_count"] = decoded->neighbors_count;
case meshtastic_PortNum_WAYPOINT_APP:
{
msgType = "position";
meshtastic_Waypoint scratch;
meshtastic_Waypoint *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Waypoint_msg, &scratch))
{
decoded = &scratch;
jsonObj["payload"]["id"] = (unsigned int)decoded->id;
jsonObj["payload"]["name"] = decoded->name;
jsonObj["payload"]["description"] = decoded->description;
jsonObj["payload"]["expire"] = (unsigned int)decoded->expire;
jsonObj["payload"]["locked_to"] = (unsigned int)decoded->locked_to;
jsonObj["payload"]["latitude_i"] = (int)decoded->latitude_i;
jsonObj["payload"]["longitude_i"] = (int)decoded->longitude_i;
}
else if (shouldLog)
{
LOG_ERROR("Error decoding protobuf for position message!\n");
return "";
}
break;
}
case meshtastic_PortNum_NEIGHBORINFO_APP:
{
msgType = "neighborinfo";
meshtastic_NeighborInfo scratch;
meshtastic_NeighborInfo *decoded = NULL;
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_NeighborInfo_msg,
&scratch))
{
decoded = &scratch;
jsonObj["payload"]["node_id"] = (unsigned int)decoded->node_id;
jsonObj["payload"]["node_broadcast_interval_secs"] = (unsigned int)decoded->node_broadcast_interval_secs;
jsonObj["payload"]["last_sent_by_id"] = (unsigned int)decoded->last_sent_by_id;
jsonObj["payload"]["neighbors_count"] = decoded->neighbors_count;
JsonObject neighbors_obj = arrayObj.to<JsonObject>(); JsonObject neighbors_obj = arrayObj.to<JsonObject>();
JsonArray neighbors = neighbors_obj.createNestedArray("neighbors"); JsonArray neighbors = neighbors_obj.createNestedArray("neighbors");
JsonObject neighbors_0 = neighbors.createNestedObject(); JsonObject neighbors_0 = neighbors.createNestedObject();
for (uint8_t i = 0; i < decoded->neighbors_count; i++) for (uint8_t i = 0; i < decoded->neighbors_count; i++) {
{ neighbors_0["node_id"] = (unsigned int)decoded->neighbors[i].node_id;
neighbors_0["node_id"] = (unsigned int)decoded->neighbors[i].node_id; neighbors_0["snr"] = (int)decoded->neighbors[i].snr;
neighbors_0["snr"] = (int)decoded->neighbors[i].snr; neighbors[i + 1] = neighbors_0;
neighbors[i + 1] = neighbors_0; neighbors_0.clear();
neighbors_0.clear(); }
} neighbors.remove(0);
neighbors.remove(0); jsonObj["payload"]["neighbors"] = neighbors;
jsonObj["payload"]["neighbors"] = neighbors; } else if (shouldLog) {
} LOG_ERROR("Error decoding protobuf for neighborinfo message!\n");
else if (shouldLog) return "";
{ }
LOG_ERROR("Error decoding protobuf for neighborinfo message!\n"); break;
return ""; }
} case meshtastic_PortNum_TRACEROUTE_APP: {
break; if (mp->decoded.request_id) { // Only report the traceroute response
} msgType = "traceroute";
case meshtastic_PortNum_TRACEROUTE_APP: meshtastic_RouteDiscovery scratch;
{ meshtastic_RouteDiscovery *decoded = NULL;
if (mp->decoded.request_id) memset(&scratch, 0, sizeof(scratch));
{ // Only report the traceroute response if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_RouteDiscovery_msg,
msgType = "traceroute"; &scratch)) {
meshtastic_RouteDiscovery scratch; decoded = &scratch;
meshtastic_RouteDiscovery *decoded = NULL; JsonArray route = arrayObj.createNestedArray("route");
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_RouteDiscovery_msg,
&scratch))
{
decoded = &scratch;
JsonArray route = arrayObj.createNestedArray("route");
auto addToRoute = [](JsonArray *route, NodeNum num) auto addToRoute = [](JsonArray *route, NodeNum num) {
{ char long_name[40] = "Unknown";
char long_name[40] = "Unknown"; meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(num);
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(num); bool name_known = node ? node->has_user : false;
bool name_known = node ? node->has_user : false; if (name_known)
if (name_known) memcpy(long_name, node->user.long_name, sizeof(long_name));
memcpy(long_name, node->user.long_name, sizeof(long_name)); route->add(long_name);
route->add(long_name); };
};
addToRoute(&route, mp->to); // route.add(mp->to); addToRoute(&route, mp->to); // route.add(mp->to);
for (uint8_t i = 0; i < decoded->route_count; i++) for (uint8_t i = 0; i < decoded->route_count; i++) {
{ addToRoute(&route, decoded->route[i]); // route.add(decoded->route[i]);
addToRoute(&route, decoded->route[i]); // route.add(decoded->route[i]); }
} addToRoute(&route,
addToRoute(&route, mp->from); // route.add(mp->from); // Ended at the original destination (source of response) mp->from); // route.add(mp->from); // Ended at the original destination (source of response)
jsonObj["payload"]["route"] = route; jsonObj["payload"]["route"] = route;
} } else if (shouldLog) {
else if (shouldLog) LOG_ERROR("Error decoding protobuf for traceroute message!\n");
{ return "";
LOG_ERROR("Error decoding protobuf for traceroute message!\n"); }
return ""; } else {
} LOG_WARN("Traceroute response not reported");
} return "";
else }
{ break;
LOG_WARN("Traceroute response not reported"); }
return ""; case meshtastic_PortNum_DETECTION_SENSOR_APP: {
} msgType = "detection";
break; char payloadStr[(mp->decoded.payload.size) + 1];
} memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size);
case meshtastic_PortNum_DETECTION_SENSOR_APP: payloadStr[mp->decoded.payload.size] = 0; // null terminated string
{ jsonObj["payload"]["text"] = payloadStr;
msgType = "detection"; break;
char payloadStr[(mp->decoded.payload.size) + 1]; }
memcpy(payloadStr, mp->decoded.payload.bytes, mp->decoded.payload.size); case meshtastic_PortNum_REMOTE_HARDWARE_APP: {
payloadStr[mp->decoded.payload.size] = 0; // null terminated string meshtastic_HardwareMessage scratch;
jsonObj["payload"]["text"] = payloadStr; meshtastic_HardwareMessage *decoded = NULL;
break; memset(&scratch, 0, sizeof(scratch));
} if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_HardwareMessage_msg,
case meshtastic_PortNum_REMOTE_HARDWARE_APP: &scratch)) {
{ decoded = &scratch;
meshtastic_HardwareMessage scratch; if (decoded->type == meshtastic_HardwareMessage_Type_GPIOS_CHANGED) {
meshtastic_HardwareMessage *decoded = NULL; msgType = "gpios_changed";
memset(&scratch, 0, sizeof(scratch)); jsonObj["payload"]["gpio_value"] = (unsigned int)decoded->gpio_value;
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_HardwareMessage_msg, } else if (decoded->type == meshtastic_HardwareMessage_Type_READ_GPIOS_REPLY) {
&scratch)) msgType = "gpios_read_reply";
{ jsonObj["payload"]["gpio_value"] = (unsigned int)decoded->gpio_value;
decoded = &scratch; jsonObj["payload"]["gpio_mask"] = (unsigned int)decoded->gpio_mask;
if (decoded->type == meshtastic_HardwareMessage_Type_GPIOS_CHANGED) }
{ } else if (shouldLog) {
msgType = "gpios_changed"; LOG_ERROR("Error decoding protobuf for RemoteHardware message!\n");
jsonObj["payload"]["gpio_value"] = (unsigned int)decoded->gpio_value; return "";
} }
else if (decoded->type == meshtastic_HardwareMessage_Type_READ_GPIOS_REPLY) break;
{ }
msgType = "gpios_read_reply"; // add more packet types here if needed
jsonObj["payload"]["gpio_value"] = (unsigned int)decoded->gpio_value; default:
jsonObj["payload"]["gpio_mask"] = (unsigned int)decoded->gpio_mask; LOG_WARN("Unsupported packet type %d\n", mp->decoded.portnum);
} return "";
} break;
else if (shouldLog) }
{ } else if (shouldLog) {
LOG_ERROR("Error decoding protobuf for RemoteHardware message!\n"); LOG_WARN("Couldn't convert encrypted payload of MeshPacket to JSON\n");
return ""; return "";
} }
break;
}
// add more packet types here if needed
default:
LOG_WARN("Unsupported packet type %d\n", mp->decoded.portnum);
return "";
break;
}
}
else if (shouldLog)
{
LOG_WARN("Couldn't convert encrypted payload of MeshPacket to JSON\n");
return "";
}
jsonObj["id"] = (unsigned int)mp->id; jsonObj["id"] = (unsigned int)mp->id;
jsonObj["timestamp"] = (unsigned int)mp->rx_time; jsonObj["timestamp"] = (unsigned int)mp->rx_time;
jsonObj["to"] = (unsigned int)mp->to; jsonObj["to"] = (unsigned int)mp->to;
jsonObj["from"] = (unsigned int)mp->from; jsonObj["from"] = (unsigned int)mp->from;
jsonObj["channel"] = (unsigned int)mp->channel; jsonObj["channel"] = (unsigned int)mp->channel;
jsonObj["type"] = msgType.c_str(); jsonObj["type"] = msgType.c_str();
jsonObj["sender"] = owner.id; jsonObj["sender"] = owner.id;
if (mp->rx_rssi != 0) if (mp->rx_rssi != 0)
jsonObj["rssi"] = (int)mp->rx_rssi; jsonObj["rssi"] = (int)mp->rx_rssi;
if (mp->rx_snr != 0) if (mp->rx_snr != 0)
jsonObj["snr"] = (float)mp->rx_snr; jsonObj["snr"] = (float)mp->rx_snr;
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
{ jsonObj["hops_away"] = (unsigned int)(mp->hop_start - mp->hop_limit);
jsonObj["hops_away"] = (unsigned int)(mp->hop_start - mp->hop_limit); jsonObj["hop_start"] = (unsigned int)(mp->hop_start);
jsonObj["hop_start"] = (unsigned int)(mp->hop_start); }
}
// serialize and write it to the stream // serialize and write it to the stream
// Serial.printf("serialized json message: \r\n"); // Serial.printf("serialized json message: \r\n");
// serializeJson(jsonObj, Serial); // serializeJson(jsonObj, Serial);
// Serial.println(""); // Serial.println("");
std::string jsonStr = ""; std::string jsonStr = "";
serializeJson(jsonObj, jsonStr); serializeJson(jsonObj, jsonStr);
if (shouldLog) if (shouldLog)
LOG_INFO("serialized json message: %s\n", jsonStr.c_str()); LOG_INFO("serialized json message: %s\n", jsonStr.c_str());
return jsonStr; return jsonStr;
} }
std::string MeshPacketSerializer::JsonSerializeEncrypted(const meshtastic_MeshPacket *mp) std::string MeshPacketSerializer::JsonSerializeEncrypted(const meshtastic_MeshPacket *mp)
{ {
jsonObj.clear(); jsonObj.clear();
jsonObj["id"] = (unsigned int)mp->id; jsonObj["id"] = (unsigned int)mp->id;
jsonObj["time_ms"] = (double)millis(); jsonObj["time_ms"] = (double)millis();
jsonObj["timestamp"] = (unsigned int)mp->rx_time; jsonObj["timestamp"] = (unsigned int)mp->rx_time;
jsonObj["to"] = (unsigned int)mp->to; jsonObj["to"] = (unsigned int)mp->to;
jsonObj["from"] = (unsigned int)mp->from; jsonObj["from"] = (unsigned int)mp->from;
jsonObj["channel"] = (unsigned int)mp->channel; jsonObj["channel"] = (unsigned int)mp->channel;
jsonObj["want_ack"] = mp->want_ack; jsonObj["want_ack"] = mp->want_ack;
if (mp->rx_rssi != 0) if (mp->rx_rssi != 0)
jsonObj["rssi"] = (int)mp->rx_rssi; jsonObj["rssi"] = (int)mp->rx_rssi;
if (mp->rx_snr != 0) if (mp->rx_snr != 0)
jsonObj["snr"] = (float)mp->rx_snr; jsonObj["snr"] = (float)mp->rx_snr;
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) {
{ jsonObj["hops_away"] = (unsigned int)(mp->hop_start - mp->hop_limit);
jsonObj["hops_away"] = (unsigned int)(mp->hop_start - mp->hop_limit); jsonObj["hop_start"] = (unsigned int)(mp->hop_start);
jsonObj["hop_start"] = (unsigned int)(mp->hop_start); }
} jsonObj["size"] = (unsigned int)mp->encrypted.size;
jsonObj["size"] = (unsigned int)mp->encrypted.size; auto encryptedStr = bytesToHex(mp->encrypted.bytes, mp->encrypted.size);
auto encryptedStr = bytesToHex(mp->encrypted.bytes, mp->encrypted.size); jsonObj["bytes"] = encryptedStr.c_str();
jsonObj["bytes"] = encryptedStr.c_str();
// serialize and write it to the stream // serialize and write it to the stream
std::string jsonStr = ""; std::string jsonStr = "";
serializeJson(jsonObj, jsonStr); serializeJson(jsonObj, jsonStr);
return jsonStr; return jsonStr;
} }
#endif #endif