meshtastic 0.0.143 → 0.0.145

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +27 -0
  3. data/.gitignore +29 -0
  4. data/.rubocop.yml +35 -0
  5. data/.rubocop_todo.yml +134 -0
  6. data/.ruby-gemset +1 -0
  7. data/.ruby-version +1 -0
  8. data/AUTOGEN_meshtastic_protobufs.sh +28 -0
  9. data/CHANGELOG_BETWEEN_TAGS.txt +196 -0
  10. data/CODE_OF_CONDUCT.md +84 -0
  11. data/Gemfile +23 -0
  12. data/LICENSE +21 -0
  13. data/README.md +106 -0
  14. data/Rakefile +21 -0
  15. data/bin/meshtastic_autoinc_version +38 -0
  16. data/build_meshtastic_gem.sh +58 -0
  17. data/git_commit.sh +29 -0
  18. data/lib/meshtastic/admin.rb +24 -0
  19. data/lib/meshtastic/admin_pb.rb +31 -0
  20. data/lib/meshtastic/apponly.rb +24 -0
  21. data/lib/meshtastic/apponly_pb.rb +18 -0
  22. data/lib/meshtastic/atak.rb +24 -0
  23. data/lib/meshtastic/atak_pb.rb +22 -0
  24. data/lib/meshtastic/cannedmessages.rb +24 -0
  25. data/lib/meshtastic/cannedmessages_pb.rb +15 -0
  26. data/lib/meshtastic/channel.rb +24 -0
  27. data/lib/meshtastic/channel_pb.rb +18 -0
  28. data/lib/meshtastic/clientonly.rb +24 -0
  29. data/lib/meshtastic/clientonly_pb.rb +18 -0
  30. data/lib/meshtastic/config.rb +24 -0
  31. data/lib/meshtastic/config_pb.rb +42 -0
  32. data/lib/meshtastic/connection_status.rb +24 -0
  33. data/lib/meshtastic/connection_status_pb.rb +20 -0
  34. data/lib/meshtastic/device_ui_pb.rb +23 -0
  35. data/lib/meshtastic/deviceonly.rb +24 -0
  36. data/lib/meshtastic/deviceonly_pb.rb +28 -0
  37. data/lib/meshtastic/interdevice_pb.rb +17 -0
  38. data/lib/meshtastic/localonly.rb +24 -0
  39. data/lib/meshtastic/localonly_pb.rb +19 -0
  40. data/lib/meshtastic/mesh_interface.rb +596 -0
  41. data/lib/meshtastic/mesh_pb.rb +65 -0
  42. data/lib/meshtastic/module_config.rb +24 -0
  43. data/lib/meshtastic/module_config_pb.rb +36 -0
  44. data/lib/meshtastic/mqtt.rb +383 -0
  45. data/lib/meshtastic/mqtt_pb.rb +19 -0
  46. data/lib/meshtastic/paxcount.rb +24 -0
  47. data/lib/meshtastic/paxcount_pb.rb +15 -0
  48. data/lib/meshtastic/portnums.rb +24 -0
  49. data/lib/meshtastic/portnums_pb.rb +15 -0
  50. data/lib/meshtastic/powermon_pb.rb +18 -0
  51. data/lib/meshtastic/remote_hardware.rb +24 -0
  52. data/lib/meshtastic/remote_hardware_pb.rb +16 -0
  53. data/lib/meshtastic/rtttl.rb +24 -0
  54. data/lib/meshtastic/rtttl_pb.rb +15 -0
  55. data/lib/meshtastic/serial_interface.rb +550 -0
  56. data/lib/meshtastic/storeforward.rb +24 -0
  57. data/lib/meshtastic/storeforward_pb.rb +19 -0
  58. data/lib/meshtastic/stream_interface.rb +132 -0
  59. data/lib/meshtastic/telemetry.rb +24 -0
  60. data/lib/meshtastic/telemetry_pb.rb +24 -0
  61. data/lib/meshtastic/util.rb +70 -0
  62. data/lib/meshtastic/version.rb +5 -0
  63. data/lib/meshtastic/xmodem.rb +24 -0
  64. data/lib/meshtastic/xmodem_pb.rb +16 -0
  65. data/lib/meshtastic.rb +71 -0
  66. data/lib/nanopb_pb.rb +19 -0
  67. data/meshtastic.gemspec +73 -0
  68. data/reinstall_meshtastic_gemset.sh +29 -0
  69. data/sig/meshtastic.rbs +4 -0
  70. data/spec/lib/meshtastic/admin_pb_spec.rb +7 -0
  71. data/spec/lib/meshtastic/admin_spec.rb +6 -0
  72. data/spec/lib/meshtastic/apponly_pb_spec.rb +6 -0
  73. data/spec/lib/meshtastic/apponly_spec.rb +6 -0
  74. data/spec/lib/meshtastic/atak_pb_spec.rb +6 -0
  75. data/spec/lib/meshtastic/atak_spec.rb +6 -0
  76. data/spec/lib/meshtastic/cannedmessages_pb_spec.rb +6 -0
  77. data/spec/lib/meshtastic/cannedmessages_spec.rb +6 -0
  78. data/spec/lib/meshtastic/channel_pb_spec.rb +6 -0
  79. data/spec/lib/meshtastic/channel_spec.rb +6 -0
  80. data/spec/lib/meshtastic/clientonly_pb_spec.rb +6 -0
  81. data/spec/lib/meshtastic/clientonly_spec.rb +6 -0
  82. data/spec/lib/meshtastic/config_pb_spec.rb +6 -0
  83. data/spec/lib/meshtastic/config_spec.rb +6 -0
  84. data/spec/lib/meshtastic/connection_status_pb_spec.rb +6 -0
  85. data/spec/lib/meshtastic/connection_status_spec.rb +6 -0
  86. data/spec/lib/meshtastic/device_ui_pb_spec.rb +6 -0
  87. data/spec/lib/meshtastic/deviceonly_pb_spec.rb +6 -0
  88. data/spec/lib/meshtastic/deviceonly_spec.rb +6 -0
  89. data/spec/lib/meshtastic/interdevice_pb_spec.rb +6 -0
  90. data/spec/lib/meshtastic/localonly_pb_spec.rb +6 -0
  91. data/spec/lib/meshtastic/localonly_spec.rb +6 -0
  92. data/spec/lib/meshtastic/mesh_interface_spec.rb +6 -0
  93. data/spec/lib/meshtastic/mesh_pb_spec.rb +6 -0
  94. data/spec/lib/meshtastic/module_config_pb_spec.rb +6 -0
  95. data/spec/lib/meshtastic/module_config_spec.rb +6 -0
  96. data/spec/lib/meshtastic/mqtt_pb_spec.rb +6 -0
  97. data/spec/lib/meshtastic/mqtt_spec.rb +6 -0
  98. data/spec/lib/meshtastic/paxcount_pb_spec.rb +6 -0
  99. data/spec/lib/meshtastic/paxcount_spec.rb +6 -0
  100. data/spec/lib/meshtastic/portnums_pb_spec.rb +6 -0
  101. data/spec/lib/meshtastic/portnums_spec.rb +6 -0
  102. data/spec/lib/meshtastic/powermon_pb_spec.rb +6 -0
  103. data/spec/lib/meshtastic/remote_hardware_pb_spec.rb +6 -0
  104. data/spec/lib/meshtastic/remote_hardware_spec.rb +6 -0
  105. data/spec/lib/meshtastic/rtttl_pb_spec.rb +6 -0
  106. data/spec/lib/meshtastic/rtttl_spec.rb +6 -0
  107. data/spec/lib/meshtastic/serial_interface_spec.rb +6 -0
  108. data/spec/lib/meshtastic/storeforward_pb_spec.rb +6 -0
  109. data/spec/lib/meshtastic/storeforward_spec.rb +6 -0
  110. data/spec/lib/meshtastic/stream_interface_spec.rb +6 -0
  111. data/spec/lib/meshtastic/telemetry_pb_spec.rb +6 -0
  112. data/spec/lib/meshtastic/telemetry_spec.rb +6 -0
  113. data/spec/lib/meshtastic/util_spec.rb +6 -0
  114. data/spec/lib/meshtastic/version_spec.rb +17 -0
  115. data/spec/lib/meshtastic/xmodem_pb_spec.rb +6 -0
  116. data/spec/lib/meshtastic/xmodem_spec.rb +6 -0
  117. data/spec/lib/meshtastic_spec.rb +6 -0
  118. data/spec/lib/nanopb_pb_spec.rb +6 -0
  119. data/spec/spec_helper.rb +3 -0
  120. data/upgrade_Gemfile_gems.sh +21 -0
  121. data/upgrade_gem.sh +4 -0
  122. data/upgrade_meshtastic.sh +13 -0
  123. data/upgrade_ruby.sh +45 -0
  124. metadata +126 -3
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: meshtastic/mesh.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+ require 'meshtastic/channel_pb'
8
+ require 'meshtastic/config_pb'
9
+ require 'meshtastic/device_ui_pb'
10
+ require 'meshtastic/module_config_pb'
11
+ require 'meshtastic/portnums_pb'
12
+ require 'meshtastic/telemetry_pb'
13
+ require 'meshtastic/xmodem_pb'
14
+
15
+
16
+ descriptor_data = "\n\x15meshtastic/mesh.proto\x12\nmeshtastic\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\x1a\x1ameshtastic/device_ui.proto\x1a\x1emeshtastic/module_config.proto\x1a\x19meshtastic/portnums.proto\x1a\x1ameshtastic/telemetry.proto\x1a\x17meshtastic/xmodem.proto\"\x87\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12\x37\n\x0flocation_source\x18\x05 \x01(\x0e\x32\x1e.meshtastic.Position.LocSource\x12\x37\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\x1e.meshtastic.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\x8a\x02\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12+\n\x08hw_model\x18\x05 \x01(\x0e\x32\x19.meshtastic.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12\x32\n\x04role\x18\x07 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xfb\x03\n\x07Routing\x12\x33\n\rroute_request\x18\x01 \x01(\x0b\x32\x1a.meshtastic.RouteDiscoveryH\x00\x12\x31\n\x0broute_reply\x18\x02 \x01(\x0b\x32\x1a.meshtastic.RouteDiscoveryH\x00\x12\x31\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\x19.meshtastic.Routing.ErrorH\x00\"\xc9\x02\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#\x12\x19\n\x15\x41\x44MIN_BAD_SESSION_KEY\x10$\x12!\n\x1d\x41\x44MIN_PUBLIC_KEY_UNAUTHORIZED\x10%\x12\x17\n\x13RATE_LIMIT_EXCEEDED\x10&B\t\n\x07variant\"\xcb\x01\n\x04\x44\x61ta\x12$\n\x07portnum\x18\x01 \x01(\x0e\x32\x13.meshtastic.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x42\x0b\n\t_bitfield\">\n\x0fKeyVerification\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\r\n\x05hash1\x18\x02 \x01(\x0c\x12\r\n\x05hash2\x18\x03 \x01(\x0c\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xb5\x07\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12#\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x10.meshtastic.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12\x31\n\x08priority\x18\x0b \x01(\x0e\x32\x1f.meshtastic.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12\x33\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\x1e.meshtastic.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\x12\x10\n\x08next_hop\x18\x12 \x01(\r\x12\x12\n\nrelay_node\x18\x13 \x01(\r\x12\x10\n\x08tx_after\x18\x14 \x01(\r\x12\x46\n\x13transport_mechanism\x18\x15 \x01(\x0e\x32).meshtastic.MeshPacket.TransportMechanism\"~\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x0c\n\x08RESPONSE\x10P\x12\x08\n\x04HIGH\x10\x64\x12\t\n\x05\x41LERT\x10n\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\"\xcf\x01\n\x12TransportMechanism\x12\x16\n\x12TRANSPORT_INTERNAL\x10\x00\x12\x12\n\x0eTRANSPORT_LORA\x10\x01\x12\x17\n\x13TRANSPORT_LORA_ALT1\x10\x02\x12\x17\n\x13TRANSPORT_LORA_ALT2\x10\x03\x12\x17\n\x13TRANSPORT_LORA_ALT3\x10\x04\x12\x12\n\x0eTRANSPORT_MQTT\x10\x05\x12\x1b\n\x17TRANSPORT_MULTICAST_UDP\x10\x06\x12\x11\n\rTRANSPORT_API\x10\x07\x42\x11\n\x0fpayload_variant\"\xc7\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1e\n\x04user\x18\x02 \x01(\x0b\x32\x10.meshtastic.User\x12&\n\x08position\x18\x03 \x01(\x0b\x32\x14.meshtastic.Position\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12\x31\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\x19.meshtastic.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x16\n\thops_away\x18\t \x01(\rH\x00\x88\x01\x01\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\x12\x12\n\nis_ignored\x18\x0b \x01(\x08\x12 \n\x18is_key_manually_verified\x18\x0c \x01(\x08\x42\x0c\n\n_hops_away\"\xc1\x01\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\x12\x11\n\tdevice_id\x18\x0c \x01(\x0c\x12\x0f\n\x07pio_env\x18\r \x01(\t\x12\x35\n\x10\x66irmware_edition\x18\x0e \x01(\x0e\x32\x1b.meshtastic.FirmwareEdition\x12\x14\n\x0cnodedb_count\x18\x0f \x01(\r\"\xc0\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12*\n\x05level\x18\x04 \x01(\x0e\x32\x1b.meshtastic.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf9\x05\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12(\n\x06packet\x18\x02 \x01(\x0b\x32\x16.meshtastic.MeshPacketH\x00\x12)\n\x07my_info\x18\x03 \x01(\x0b\x32\x16.meshtastic.MyNodeInfoH\x00\x12)\n\tnode_info\x18\x04 \x01(\x0b\x32\x14.meshtastic.NodeInfoH\x00\x12$\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x12.meshtastic.ConfigH\x00\x12+\n\nlog_record\x18\x06 \x01(\x0b\x32\x15.meshtastic.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x30\n\x0cmoduleConfig\x18\t \x01(\x0b\x32\x18.meshtastic.ModuleConfigH\x00\x12&\n\x07\x63hannel\x18\n \x01(\x0b\x32\x13.meshtastic.ChannelH\x00\x12.\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32\x17.meshtastic.QueueStatusH\x00\x12*\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x12.meshtastic.XModemH\x00\x12.\n\x08metadata\x18\r \x01(\x0b\x32\x1a.meshtastic.DeviceMetadataH\x00\x12\x44\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32\".meshtastic.MqttClientProxyMessageH\x00\x12(\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x14.meshtastic.FileInfoH\x00\x12<\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\x1e.meshtastic.ClientNotificationH\x00\x12\x34\n\x0e\x64\x65viceuiConfig\x18\x11 \x01(\x0b\x32\x1a.meshtastic.DeviceUIConfigH\x00\x42\x11\n\x0fpayload_variant\"\xfa\x03\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x01\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12*\n\x05level\x18\x03 \x01(\x0e\x32\x1b.meshtastic.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\t\x12Q\n\x1ekey_verification_number_inform\x18\x0b \x01(\x0b\x32\'.meshtastic.KeyVerificationNumberInformH\x00\x12S\n\x1fkey_verification_number_request\x18\x0c \x01(\x0b\x32(.meshtastic.KeyVerificationNumberRequestH\x00\x12\x42\n\x16key_verification_final\x18\r \x01(\x0b\x32 .meshtastic.KeyVerificationFinalH\x00\x12@\n\x15\x64uplicated_public_key\x18\x0e \x01(\x0b\x32\x1f.meshtastic.DuplicatedPublicKeyH\x00\x12\x34\n\x0flow_entropy_key\x18\x0f \x01(\x0b\x32\x19.meshtastic.LowEntropyKeyH\x00\x42\x11\n\x0fpayload_variantB\x0b\n\t_reply_id\"^\n\x1bKeyVerificationNumberInform\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x17\n\x0fremote_longname\x18\x02 \x01(\t\x12\x17\n\x0fsecurity_number\x18\x03 \x01(\r\"F\n\x1cKeyVerificationNumberRequest\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x17\n\x0fremote_longname\x18\x02 \x01(\t\"q\n\x14KeyVerificationFinal\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x17\n\x0fremote_longname\x18\x02 \x01(\t\x12\x10\n\x08isSender\x18\x03 \x01(\x08\x12\x1f\n\x17verification_characters\x18\x04 \x01(\t\"\x15\n\x13\x44uplicatedPublicKey\"\x0f\n\rLowEntropyKey\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\x94\x02\n\x07ToRadio\x12(\n\x06packet\x18\x01 \x01(\x0b\x32\x16.meshtastic.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12*\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x12.meshtastic.XModemH\x00\x12\x44\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32\".meshtastic.MqttClientProxyMessageH\x00\x12*\n\theartbeat\x18\x07 \x01(\x0b\x32\x15.meshtastic.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"@\n\nCompressed\x12$\n\x07portnum\x18\x01 \x01(\x0e\x32\x13.meshtastic.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x87\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\'\n\tneighbors\x18\x04 \x03(\x0b\x32\x14.meshtastic.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xd7\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12\x32\n\x04role\x18\x07 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12+\n\x08hw_model\x18\t \x01(\x0e\x32\x19.meshtastic.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\x12\x0e\n\x06hasPKC\x18\x0b \x01(\x08\x12\x18\n\x10\x65xcluded_modules\x18\x0c \x01(\r\"\x1a\n\tHeartbeat\x12\r\n\x05nonce\x18\x01 \x01(\r\"U\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12*\n\x03pin\x18\x02 \x01(\x0b\x32\x1d.meshtastic.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xaa\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12\x32\n\rresend_chunks\x18\x04 \x01(\x0b\x32\x19.meshtastic.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\x86\x12\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x1a\n\x16HELTEC_WIRELESS_BRIDGE\x10\x18\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0e\n\nNRF52840DK\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x18\n\x14RP2040_FEATHER_RFM95\x10L\x12\x15\n\x11M5STACK_COREBASIC\x10M\x12\x11\n\rM5STACK_CORE2\x10N\x12\r\n\tRPI_PICO2\x10O\x12\x12\n\x0eM5STACK_CORES3\x10P\x12\x11\n\rSEEED_XIAO_S3\x10Q\x12\x0b\n\x07MS24SF1\x10R\x12\x0c\n\x08TLORA_C6\x10S\x12\x0f\n\x0bWISMESH_TAP\x10T\x12\r\n\tROUTASTIC\x10U\x12\x0c\n\x08MESH_TAB\x10V\x12\x0c\n\x08MESHLINK\x10W\x12\x12\n\x0eXIAO_NRF52_KIT\x10X\x12\x10\n\x0cTHINKNODE_M1\x10Y\x12\x10\n\x0cTHINKNODE_M2\x10Z\x12\x0f\n\x0bT_ETH_ELITE\x10[\x12\x15\n\x11HELTEC_SENSOR_HUB\x10\\\x12\r\n\tMUZI_BASE\x10]\x12\x16\n\x12HELTEC_MESH_POCKET\x10^\x12\x14\n\x10SEEED_SOLAR_NODE\x10_\x12\x18\n\x14NOMADSTAR_METEOR_PRO\x10`\x12\r\n\tCROWPANEL\x10\x61\x12\x0b\n\x07LINK_32\x10\x62\x12\x18\n\x14SEEED_WIO_TRACKER_L1\x10\x63\x12\x1d\n\x19SEEED_WIO_TRACKER_L1_EINK\x10\x64\x12\x0f\n\x0bMUZI_R1_NEO\x10\x65\x12\x0e\n\nT_DECK_PRO\x10\x66\x12\x10\n\x0cT_LORA_PAGER\x10g\x12\x14\n\x10M5STACK_RESERVED\x10h\x12\x0f\n\x0bWISMESH_TAG\x10i\x12\x0b\n\x07RAK3312\x10j\x12\x10\n\x0cTHINKNODE_M5\x10k\x12\x15\n\x11HELTEC_MESH_SOLAR\x10l\x12\x0f\n\x0bT_ECHO_LITE\x10m\x12\r\n\tHELTEC_V4\x10n\x12\x0f\n\x0bM5STACK_C6L\x10o\x12\x19\n\x15M5STACK_CARDPUTER_ADV\x10p\x12\x1e\n\x1aHELTEC_WIRELESS_TRACKER_V2\x10q\x12\x11\n\rT_WATCH_ULTRA\x10r\x12\x10\n\x0cTHINKNODE_M3\x10s\x12\x12\n\x0eWISMESH_TAP_V2\x10t\x12\x0b\n\x07RAK3401\x10u\x12\x0b\n\x07RAK6421\x10v\x12\x10\n\x0cTHINKNODE_M4\x10w\x12\x10\n\x0cTHINKNODE_M6\x10x\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xe9\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\r*\x7f\n\x0f\x46irmwareEdition\x12\x0b\n\x07VANILLA\x10\x00\x12\x11\n\rSMART_CITIZEN\x10\x01\x12\x0e\n\nOPEN_SAUCE\x10\x10\x12\n\n\x06\x44\x45\x46\x43ON\x10\x11\x12\x0f\n\x0b\x42URNING_MAN\x10\x12\x12\x0e\n\nHAMVENTION\x10\x13\x12\x0f\n\x0b\x44IY_EDITION\x10\x7f*\x80\x03\n\x0f\x45xcludedModules\x12\x11\n\rEXCLUDED_NONE\x10\x00\x12\x0f\n\x0bMQTT_CONFIG\x10\x01\x12\x11\n\rSERIAL_CONFIG\x10\x02\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x04\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x08\x12\x14\n\x10RANGETEST_CONFIG\x10\x10\x12\x14\n\x10TELEMETRY_CONFIG\x10 \x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10@\x12\x11\n\x0c\x41UDIO_CONFIG\x10\x80\x01\x12\x1a\n\x15REMOTEHARDWARE_CONFIG\x10\x80\x02\x12\x18\n\x13NEIGHBORINFO_CONFIG\x10\x80\x04\x12\x1b\n\x16\x41MBIENTLIGHTING_CONFIG\x10\x80\x08\x12\x1b\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x80\x10\x12\x16\n\x11PAXCOUNTER_CONFIG\x10\x80 \x12\x15\n\x10\x42LUETOOTH_CONFIG\x10\x80@\x12\x14\n\x0eNETWORK_CONFIG\x10\x80\x80\x01\x42`\n\x14org.meshtastic.protoB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
17
+
18
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
19
+ pool.add_serialized_file(descriptor_data)
20
+
21
+ module Meshtastic
22
+ Position = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Position").msgclass
23
+ Position::LocSource = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Position.LocSource").enummodule
24
+ Position::AltSource = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Position.AltSource").enummodule
25
+ User = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.User").msgclass
26
+ RouteDiscovery = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.RouteDiscovery").msgclass
27
+ Routing = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Routing").msgclass
28
+ Routing::Error = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Routing.Error").enummodule
29
+ Data = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Data").msgclass
30
+ KeyVerification = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.KeyVerification").msgclass
31
+ Waypoint = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Waypoint").msgclass
32
+ MqttClientProxyMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.MqttClientProxyMessage").msgclass
33
+ MeshPacket = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.MeshPacket").msgclass
34
+ MeshPacket::Priority = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.MeshPacket.Priority").enummodule
35
+ MeshPacket::Delayed = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.MeshPacket.Delayed").enummodule
36
+ MeshPacket::TransportMechanism = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.MeshPacket.TransportMechanism").enummodule
37
+ NodeInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.NodeInfo").msgclass
38
+ MyNodeInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.MyNodeInfo").msgclass
39
+ LogRecord = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.LogRecord").msgclass
40
+ LogRecord::Level = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.LogRecord.Level").enummodule
41
+ QueueStatus = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.QueueStatus").msgclass
42
+ FromRadio = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.FromRadio").msgclass
43
+ ClientNotification = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ClientNotification").msgclass
44
+ KeyVerificationNumberInform = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.KeyVerificationNumberInform").msgclass
45
+ KeyVerificationNumberRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.KeyVerificationNumberRequest").msgclass
46
+ KeyVerificationFinal = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.KeyVerificationFinal").msgclass
47
+ DuplicatedPublicKey = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.DuplicatedPublicKey").msgclass
48
+ LowEntropyKey = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.LowEntropyKey").msgclass
49
+ FileInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.FileInfo").msgclass
50
+ ToRadio = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ToRadio").msgclass
51
+ Compressed = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Compressed").msgclass
52
+ NeighborInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.NeighborInfo").msgclass
53
+ Neighbor = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Neighbor").msgclass
54
+ DeviceMetadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.DeviceMetadata").msgclass
55
+ Heartbeat = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Heartbeat").msgclass
56
+ NodeRemoteHardwarePin = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.NodeRemoteHardwarePin").msgclass
57
+ ChunkedPayload = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ChunkedPayload").msgclass
58
+ Resend_chunks = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.resend_chunks").msgclass
59
+ ChunkedPayloadResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ChunkedPayloadResponse").msgclass
60
+ HardwareModel = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.HardwareModel").enummodule
61
+ Constants = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Constants").enummodule
62
+ CriticalErrorCode = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.CriticalErrorCode").enummodule
63
+ FirmwareEdition = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.FirmwareEdition").enummodule
64
+ ExcludedModules = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ExcludedModules").enummodule
65
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meshtastic/module_config_pb'
4
+
5
+ # Plugin used to interact with Meshtastic nodes
6
+ module Meshtastic
7
+ module ModuleConfig
8
+ # Author(s):: 0day Inc. <support@0dayinc.com>
9
+
10
+ public_class_method def self.authors
11
+ "AUTHOR(S):
12
+ 0day Inc. <support@0dayinc.com>
13
+ "
14
+ end
15
+
16
+ # Display Usage for this Module
17
+
18
+ public_class_method def self.help
19
+ puts "USAGE:
20
+ #{self}.authors
21
+ "
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: meshtastic/module_config.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x1emeshtastic/module_config.proto\x12\nmeshtastic\"\xb5&\n\x0cModuleConfig\x12\x33\n\x04mqtt\x18\x01 \x01(\x0b\x32#.meshtastic.ModuleConfig.MQTTConfigH\x00\x12\x37\n\x06serial\x18\x02 \x01(\x0b\x32%.meshtastic.ModuleConfig.SerialConfigH\x00\x12T\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32\x33.meshtastic.ModuleConfig.ExternalNotificationConfigH\x00\x12\x44\n\rstore_forward\x18\x04 \x01(\x0b\x32+.meshtastic.ModuleConfig.StoreForwardConfigH\x00\x12>\n\nrange_test\x18\x05 \x01(\x0b\x32(.meshtastic.ModuleConfig.RangeTestConfigH\x00\x12=\n\ttelemetry\x18\x06 \x01(\x0b\x32(.meshtastic.ModuleConfig.TelemetryConfigH\x00\x12\x46\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32,.meshtastic.ModuleConfig.CannedMessageConfigH\x00\x12\x35\n\x05\x61udio\x18\x08 \x01(\x0b\x32$.meshtastic.ModuleConfig.AudioConfigH\x00\x12H\n\x0fremote_hardware\x18\t \x01(\x0b\x32-.meshtastic.ModuleConfig.RemoteHardwareConfigH\x00\x12\x44\n\rneighbor_info\x18\n \x01(\x0b\x32+.meshtastic.ModuleConfig.NeighborInfoConfigH\x00\x12J\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32..meshtastic.ModuleConfig.AmbientLightingConfigH\x00\x12J\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32..meshtastic.ModuleConfig.DetectionSensorConfigH\x00\x12?\n\npaxcounter\x18\r \x01(\x0b\x32).meshtastic.ModuleConfig.PaxcounterConfigH\x00\x1a\xb0\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x14\n\x0cjson_enabled\x18\x06 \x01(\x08\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12G\n\x13map_report_settings\x18\x0b \x01(\x0b\x32*.meshtastic.ModuleConfig.MapReportSettings\x1an\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x12\x1e\n\x16should_report_location\x18\x03 \x01(\x08\x1a\x82\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12\x35\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32\x1d.meshtastic.RemoteHardwarePin\x1aZ\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x12\x1a\n\x12transmit_over_lora\x18\x03 \x01(\x08\x1a\x97\x03\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12Z\n\x16\x64\x65tection_trigger_type\x18\x07 \x01(\x0e\x32:.meshtastic.ModuleConfig.DetectionSensorConfig.TriggerType\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\"\x88\x01\n\x0bTriggerType\x12\r\n\tLOGIC_LOW\x10\x00\x12\x0e\n\nLOGIC_HIGH\x10\x01\x12\x10\n\x0c\x46\x41LLING_EDGE\x10\x02\x12\x0f\n\x0bRISING_EDGE\x10\x03\x12\x1a\n\x16\x45ITHER_EDGE_ACTIVE_LOW\x10\x04\x12\x1b\n\x17\x45ITHER_EDGE_ACTIVE_HIGH\x10\x05\x1a\xe4\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12@\n\x07\x62itrate\x18\x03 \x01(\x0e\x32/.meshtastic.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\x8c\x05\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12?\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32\x31.meshtastic.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12?\n\x04mode\x18\x07 \x01(\x0e\x32\x31.meshtastic.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"}\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x12\x08\n\x04WS85\x10\x06\x12\r\n\tVE_DIRECT\x10\x07\x12\r\n\tMS_CONFIG\x10\x08\x1a\xe9\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x14\n\x0coutput_vibra\x18\x08 \x01(\r\x12\x15\n\routput_buzzer\x18\t \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x13\n\x0bnag_timeout\x18\x0e \x01(\r\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x97\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x12\x11\n\tis_server\x18\x06 \x01(\x08\x1aY\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x12\x17\n\x0f\x63lear_on_reboot\x18\x04 \x01(\x08\x1a\xeb\x03\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x12\"\n\x1ahealth_measurement_enabled\x18\x0b \x01(\x08\x12\x1e\n\x16health_update_interval\x18\x0c \x01(\r\x12\x1d\n\x15health_screen_enabled\x18\r \x01(\x08\x12 \n\x18\x64\x65vice_telemetry_enabled\x18\x0e \x01(\x08\x1a\xde\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12Y\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32;.meshtastic.ModuleConfig.CannedMessageConfig.InputEventChar\x12Z\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32;.meshtastic.ModuleConfig.CannedMessageConfig.InputEventChar\x12\\\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32;.meshtastic.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x13\n\x07\x65nabled\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1e\n\x12\x61llow_input_source\x18\n \x01(\tB\x02\x18\x01\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x65\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\r\x12\x0b\n\x03red\x18\x03 \x01(\r\x12\r\n\x05green\x18\x04 \x01(\r\x12\x0c\n\x04\x62lue\x18\x05 \x01(\rB\x11\n\x0fpayload_variant\"d\n\x11RemoteHardwarePin\x12\x10\n\x08gpio_pin\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12/\n\x04type\x18\x03 \x01(\x0e\x32!.meshtastic.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42h\n\x14org.meshtastic.protoB\x12ModuleConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Meshtastic
14
+ ModuleConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig").msgclass
15
+ ModuleConfig::MQTTConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.MQTTConfig").msgclass
16
+ ModuleConfig::MapReportSettings = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.MapReportSettings").msgclass
17
+ ModuleConfig::RemoteHardwareConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.RemoteHardwareConfig").msgclass
18
+ ModuleConfig::NeighborInfoConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.NeighborInfoConfig").msgclass
19
+ ModuleConfig::DetectionSensorConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.DetectionSensorConfig").msgclass
20
+ ModuleConfig::DetectionSensorConfig::TriggerType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.DetectionSensorConfig.TriggerType").enummodule
21
+ ModuleConfig::AudioConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.AudioConfig").msgclass
22
+ ModuleConfig::AudioConfig::Audio_Baud = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.AudioConfig.Audio_Baud").enummodule
23
+ ModuleConfig::PaxcounterConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.PaxcounterConfig").msgclass
24
+ ModuleConfig::SerialConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.SerialConfig").msgclass
25
+ ModuleConfig::SerialConfig::Serial_Baud = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.SerialConfig.Serial_Baud").enummodule
26
+ ModuleConfig::SerialConfig::Serial_Mode = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.SerialConfig.Serial_Mode").enummodule
27
+ ModuleConfig::ExternalNotificationConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.ExternalNotificationConfig").msgclass
28
+ ModuleConfig::StoreForwardConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.StoreForwardConfig").msgclass
29
+ ModuleConfig::RangeTestConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.RangeTestConfig").msgclass
30
+ ModuleConfig::TelemetryConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.TelemetryConfig").msgclass
31
+ ModuleConfig::CannedMessageConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.CannedMessageConfig").msgclass
32
+ ModuleConfig::CannedMessageConfig::InputEventChar = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.CannedMessageConfig.InputEventChar").enummodule
33
+ ModuleConfig::AmbientLightingConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ModuleConfig.AmbientLightingConfig").msgclass
34
+ RemoteHardwarePin = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.RemoteHardwarePin").msgclass
35
+ RemoteHardwarePinType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.RemoteHardwarePinType").enummodule
36
+ end
@@ -0,0 +1,383 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'geocoder'
5
+ require 'json'
6
+ require 'mqtt'
7
+ require 'openssl'
8
+ require 'securerandom'
9
+
10
+ # Avoiding Namespace Collisions
11
+ MQTTClient = MQTT::Client
12
+
13
+ # Plugin used to interact with Meshtastic nodes
14
+ module Meshtastic
15
+ module MQTT
16
+ # Supported Method Parameters::
17
+ # mqtt_obj = Meshtastic::MQTT.connect(
18
+ # host: 'optional - mqtt host (default: mqtt.meshtastic.org)',
19
+ # port: 'optional - mqtt port (defaults: 1883)',
20
+ # tls: 'optional - use TLS (default: false)',
21
+ # username: 'optional - mqtt username (default: meshdev)',
22
+ # password: 'optional - (default: large4cats)',
23
+ # client_id: 'optional - client ID (default: random 4-byte hex string)',
24
+ # keep_alive: 'optional - keep alive interval (default: 15)',
25
+ # ack_timeout: 'optional - acknowledgement timeout (default: 30)'
26
+ # )
27
+
28
+ public_class_method def self.connect(opts = {})
29
+ # Publicly available MQTT server / credentials by default
30
+ host = opts[:host] ||= 'mqtt.meshtastic.org'
31
+ port = opts[:port] ||= 1883
32
+ tls = true if opts[:tls]
33
+ tls = false unless opts[:tls]
34
+ username = opts[:username] ||= 'meshdev'
35
+ password = opts[:password] ||= 'large4cats'
36
+ client_id = opts[:client_id] ||= SecureRandom.random_bytes(4).unpack1('H*').to_s
37
+ client_id = format("%0.8x", client_id) if client_id.is_a?(Integer)
38
+ client_id = client_id.delete('!') if client_id.include?('!')
39
+ keep_alive = opts[:keep_alive] ||= 15
40
+ ack_timeout = opts[:ack_timeout] ||= 30
41
+
42
+ mqtt_obj = MQTTClient.connect(
43
+ host: host,
44
+ port: port,
45
+ ssl: tls,
46
+ username: username,
47
+ password: password,
48
+ client_id: client_id
49
+ )
50
+
51
+ mqtt_obj.keep_alive = keep_alive
52
+ mqtt_obj.ack_timeout = ack_timeout
53
+
54
+ mqtt_obj
55
+ rescue StandardError => e
56
+ raise e
57
+ end
58
+
59
+ # Supported Method Parameters::
60
+ # Meshtastic::MQTT.subscribe(
61
+ # mqtt_obj: 'required - mqtt_obj returned from #connect method'
62
+ # root_topic: 'optional - root topic (default: msh)',
63
+ # region: 'optional - region e.g. 'US/VA', etc (default: US)',
64
+ # topic: 'optional - channel ID path e.g. "2/stat/#" (default: "2/e/LongFast/#")',
65
+ # psks: 'optional - hash of :channel_id => psk key value pairs (default: { LongFast: "AQ==" })',
66
+ # qos: 'optional - quality of service (default: 0)',
67
+ # exclude: 'optional - comma-delimited string(s) to exclude in message (default: nil)',
68
+ # include: 'optional - comma-delimited string(s) to include on in message (default: nil)',
69
+ # gps_metadata: 'optional - include GPS metadata in output (default: false)',
70
+ # include_raw: 'optional - include raw packet data in output (default: false)'
71
+ # )
72
+
73
+ public_class_method def self.subscribe(opts = {})
74
+ mqtt_obj = opts[:mqtt_obj]
75
+ root_topic = opts[:root_topic] ||= 'msh'
76
+ region = opts[:region] ||= 'US'
77
+ topic = opts[:topic] ||= '2/e/LongFast/#'
78
+ # TODO: Support Array of PSKs and attempt each until decrypted
79
+
80
+ public_psk = '1PG7OiApB1nwvP+rz05pAQ=='
81
+ psks = opts[:psks] ||= { LongFast: public_psk }
82
+ raise 'ERROR: psks parameter must be a hash of :channel_id => psk key value pairs' unless psks.is_a?(Hash)
83
+
84
+ psks[:LongFast] = public_psk if psks[:LongFast] == 'AQ=='
85
+ mui = Meshtastic::MeshInterface.new
86
+ psks = mui.get_cipher_keys(psks: psks)
87
+
88
+ qos = opts[:qos] ||= 0
89
+ json = opts[:json] ||= false
90
+ exclude = opts[:exclude]
91
+ include = opts[:include]
92
+ gps_metadata = opts[:gps_metadata] ||= false
93
+ include_raw = opts[:include_raw] ||= false
94
+
95
+ # NOTE: Use MQTT Explorer for topic discovery
96
+ full_topic = "#{root_topic}/#{region}/#{topic}"
97
+ full_topic = "#{root_topic}/#{region}" if region == '#'
98
+ mqtt_obj.subscribe(full_topic, qos)
99
+
100
+ # MQTT::ProtocolException: No Ping Response received for 23 seconds (MQTT::ProtocolException)
101
+
102
+ include_arr = include.to_s.split(',').map(&:strip)
103
+ exclude_arr = exclude.to_s.split(',').map(&:strip)
104
+ mqtt_obj.get_packet do |packet_bytes|
105
+ raw_packet = packet_bytes.to_s if include_raw
106
+ raw_topic = packet_bytes.topic ||= ''
107
+ raw_payload = packet_bytes.payload ||= ''
108
+
109
+ begin
110
+ decoded_payload_hash = {}
111
+ message = {}
112
+ stdout_message = ''
113
+
114
+ if json
115
+ decoded_payload_hash = JSON.parse(raw_payload, symbolize_names: true)
116
+ else
117
+ decoded_payload = Meshtastic::ServiceEnvelope.decode(raw_payload)
118
+ decoded_payload_hash = decoded_payload.to_h
119
+ end
120
+
121
+ next unless decoded_payload_hash[:packet].is_a?(Hash)
122
+
123
+ message = decoded_payload_hash[:packet] if decoded_payload_hash.keys.include?(:packet)
124
+ message[:topic] = raw_topic
125
+ message[:node_id_from] = "!#{message[:from].to_i.to_s(16)}"
126
+ message[:node_id_to] = "!#{message[:to].to_i.to_s(16)}"
127
+ if message.keys.include?(:rx_time)
128
+ rx_time_int = message[:rx_time]
129
+ if rx_time_int.is_a?(Integer)
130
+ rx_time_utc = Time.at(rx_time_int).utc.to_s
131
+ message[:rx_time_utc] = rx_time_utc
132
+ end
133
+ end
134
+
135
+ if message.keys.include?(:public_key)
136
+ raw_public_key = message[:public_key]
137
+ message[:public_key] = Base64.strict_encode64(raw_public_key)
138
+ end
139
+
140
+ # If encrypted_message is not nil, then decrypt
141
+ # the message prior to decoding.
142
+ encrypted_message = message[:encrypted]
143
+ if encrypted_message.to_s.length.positive? &&
144
+ message[:topic]
145
+
146
+ # if message[:pki_encrypted]
147
+ # # TODO: Display Decrypted PKI Message
148
+ # public_key = message[:public_key]
149
+ # dec_public_key = Base64.strict_decode64(public_key)
150
+ # else
151
+ packet_id = message[:id]
152
+ packet_from = message[:from]
153
+
154
+ nonce_packet_id = [packet_id].pack('V').ljust(8, "\x00")
155
+ nonce_from_node = [packet_from].pack('V').ljust(8, "\x00")
156
+ nonce = "#{nonce_packet_id}#{nonce_from_node}"
157
+
158
+ psk = psks[:LongFast]
159
+ target_channel = message[:topic].split('/')[-2].to_sym
160
+ psk = psks[target_channel] if psks.keys.include?(target_channel)
161
+ dec_psk = Base64.strict_decode64(psk)
162
+
163
+ cipher = OpenSSL::Cipher.new('AES-128-CTR')
164
+ cipher = OpenSSL::Cipher.new('AES-256-CTR') if dec_psk.length == 32
165
+ cipher.decrypt
166
+ cipher.key = dec_psk
167
+ cipher.iv = nonce
168
+
169
+ decrypted = cipher.update(encrypted_message) + cipher.final
170
+ # end
171
+ message[:decoded] = Meshtastic::Data.decode(decrypted).to_h
172
+ message[:encrypted] = :decrypted
173
+ end
174
+
175
+ if message[:decoded]
176
+ # payload = Meshtastic::Data.decode(message[:decoded][:payload]).to_h
177
+ payload = message[:decoded][:payload]
178
+ msg_type = message[:decoded][:portnum]
179
+ mui = Meshtastic::MeshInterface.new
180
+ message[:decoded][:payload] = mui.decode_payload(
181
+ payload: payload,
182
+ msg_type: msg_type,
183
+ gps_metadata: gps_metadata
184
+ )
185
+ end
186
+
187
+ message[:raw_packet] = raw_packet if include_raw
188
+ decoded_payload_hash[:packet] = message
189
+ unless block_given?
190
+ message[:stdout] = 'pretty'
191
+ stdout_message = JSON.pretty_generate(decoded_payload_hash)
192
+ end
193
+ rescue Encoding::CompatibilityError,
194
+ Google::Protobuf::ParseError,
195
+ JSON::GeneratorError,
196
+ ArgumentError => e
197
+
198
+ unless e.is_a?(Encoding::CompatibilityError)
199
+ message[:decrypted] = e.message if e.message.include?('key must be')
200
+ message[:decrypted] = 'unable to decrypt - psk?' if e.message.include?('occurred during parsing')
201
+ decoded_payload_hash[:packet] = message
202
+ unless block_given?
203
+ puts "WARNING: #{e.inspect} - MSG IS >>>"
204
+ # puts e.backtrace
205
+ message[:stdout] = 'inspect'
206
+ stdout_message = decoded_payload_hash.inspect
207
+ end
208
+ end
209
+
210
+ next
211
+ ensure
212
+ # include_arr = [message[:id].to_s] if include_arr.empty?
213
+ if message.is_a?(Hash)
214
+ flat_message = message.values.join(' ')
215
+
216
+ disp = false
217
+ # disp = true if exclude_arr.none? { |exclude| flat_message.include?(exclude) } && (
218
+ # include_arr.first == message[:id] ||
219
+ # include_arr.all? { |include| flat_message.include?(include) }
220
+ # )
221
+
222
+ disp = true if exclude_arr.none? { |exclude| flat_message.include?(exclude) } &&
223
+ include_arr.all? { |include| flat_message.include?(include) }
224
+
225
+ if disp
226
+ if block_given?
227
+ yield decoded_payload_hash
228
+ else
229
+ puts "\n"
230
+ puts '-' * 80
231
+ puts 'MSG:'
232
+ puts stdout_message
233
+ puts '-' * 80
234
+ puts "\n\n\n"
235
+ end
236
+ # else
237
+ # print '.'
238
+ end
239
+ end
240
+ end
241
+ end
242
+ rescue Interrupt
243
+ puts "\nCTRL+C detected. Exiting..."
244
+ rescue StandardError => e
245
+ raise e
246
+ ensure
247
+ mqtt_obj.disconnect if mqtt_obj
248
+ end
249
+
250
+ # Supported Method Parameters::
251
+ # Meshtastic::MQTT.send_text(
252
+ # mqtt_obj: 'required - mqtt_obj returned from #connect method',
253
+ # from: 'required - From ID (String or Integer) (Default: "!00000b0b")',
254
+ # to: 'optional - Destination ID (Default: "!ffffffff")',
255
+ # root_topic: 'optional - root topic (default: msh)',
256
+ # region: 'optional - region e.g. "US/VA", etc (default: US)',
257
+ # topic: 'optional - topic to publish to (default: "2/e/LongFast/#")',
258
+ # channel: 'optional - channel (Default: 6)',
259
+ # text: 'optional - Text Message (Default: SYN)',
260
+ # want_ack: 'optional - Want Acknowledgement (Default: false)',
261
+ # want_response: 'optional - Want Response (Default: false)',
262
+ # hop_limit: 'optional - Hop Limit (Default: 3)',
263
+ # on_response: 'optional - Callback on Response',
264
+ # psks: 'optional - hash of :channel_id => psk key value pairs (default: { LongFast: "AQ==" })'
265
+ # )
266
+ public_class_method def self.send_text(opts = {})
267
+ mqtt_obj = opts[:mqtt_obj]
268
+ opts[:from] ||= mqtt_obj.client_id
269
+ opts[:to] ||= '!ffffffff'
270
+ opts[:root_topic] ||= 'msh'
271
+ opts[:region] ||= 'US'
272
+ opts[:topic] ||= '2/e/LongFast/#'
273
+ opts[:topic] = opts[:topic].to_s.gsub('/#', '')
274
+ opts[:channel] ||= 6
275
+ absolute_topic = "#{opts[:root_topic]}/#{opts[:region]}/#{opts[:topic]}/#{opts[:from]}"
276
+ opts[:topic] = absolute_topic
277
+ opts[:via] = :mqtt
278
+
279
+ # TODO: Implement chunked message to deal with large messages
280
+ text = opts[:text].to_s
281
+ max_bytes = 231
282
+ mui = Meshtastic::MeshInterface.new
283
+
284
+ if text.bytesize > max_bytes
285
+ total_chunks = (text.bytesize.to_f / max_bytes).ceil
286
+ total_chunks.times do |i|
287
+ chunk_num = i + 1
288
+ chunk_prefix = " (#{chunk_num} of #{total_chunks})\n"
289
+ chunk_prefix_len = chunk_prefix.bytesize
290
+ start_index = i * (max_bytes - chunk_prefix_len)
291
+ end_index = (start_index + (max_bytes - chunk_prefix_len)) - 1
292
+ chunk = "#{chunk_prefix} #{text.byteslice(start_index..end_index)}"
293
+ # This addresses a weird bug in the protocal if the first byte
294
+ # is an h or H followed by a single byte, which returns
295
+ # {} or {bitfiled: INT}
296
+ opts[:text] = chunk
297
+ protobuf_chunk = mui.send_text(opts)
298
+ mqtt_obj.publish(absolute_topic, protobuf_chunk)
299
+ sleep 0.3
300
+ end
301
+ else
302
+ opts[:text] = " #{text}"
303
+ protobuf_text = mui.send_text(opts)
304
+ mqtt_obj.publish(absolute_topic, protobuf_text)
305
+ end
306
+ rescue StandardError => e
307
+ raise e
308
+ end
309
+
310
+ # Supported Method Parameters::
311
+ # mqtt_obj = Meshtastic.disconnect(
312
+ # mqtt_obj: 'required - mqtt_obj returned from #connect method'
313
+ # )
314
+ public_class_method def self.disconnect(opts = {})
315
+ mqtt_obj = opts[:mqtt_obj]
316
+
317
+ mqtt_obj.disconnect if mqtt_obj
318
+ nil
319
+ rescue StandardError => e
320
+ raise e
321
+ end
322
+
323
+ # Author(s):: 0day Inc. <support@0dayinc.com>
324
+
325
+ public_class_method def self.authors
326
+ "AUTHOR(S):
327
+ 0day Inc. <support@0dayinc.com>
328
+ "
329
+ end
330
+
331
+ # Display Usage for this Module
332
+
333
+ public_class_method def self.help
334
+ puts "USAGE:
335
+ mqtt_obj = #{self}.connect(
336
+ host: 'optional - mqtt host (default: mqtt.meshtastic.org)',
337
+ port: 'optional - mqtt port (defaults: 1883)',
338
+ tls: 'optional - use TLS (default: false)',
339
+ username: 'optional - mqtt username (default: meshdev)',
340
+ password: 'optional - (default: large4cats)',
341
+ client_id: 'optional - client ID (default: random 4-byte hex string)',
342
+ keep_alive: 'optional - keep alive interval (default: 15)',
343
+ ack_timeout: 'optional - acknowledgement timeout (default: 30)'
344
+ )
345
+
346
+ #{self}.subscribe(
347
+ mqtt_obj: 'required - mqtt_obj object returned from #connect method',
348
+ root_topic: 'optional - root topic (default: msh)',
349
+ region: 'optional - region e.g. 'US/VA', etc (default: US)',
350
+ topic: 'optional - channel ID path e.g. '2/stat/#' (default: '2/e/LongFast/#')',
351
+ psks: 'optional - hash of :channel_id => psk key value pairs (default: { LongFast: 'AQ==' })',
352
+ qos: 'optional - quality of service (default: 0)',
353
+ json: 'optional - JSON output (default: false)',
354
+ exclude: 'optional - comma-delimited string(s) to exclude in message (default: nil)',
355
+ include: 'optional - comma-delimited string(s) to include on in message (default: nil)',
356
+ gps_metadata: 'optional - include GPS metadata in output (default: false)'
357
+ )
358
+
359
+ #{self}.send_text(
360
+ mqtt_obj: 'required - mqtt_obj returned from #connect method',
361
+ from: 'required - From ID (String or Integer) (Default: \"!00000b0b\")',
362
+ to: 'optional - Destination ID (Default: \"!ffffffff\")',
363
+ root_topic: 'optional - root topic (default: msh)',
364
+ region: 'optional - region e.g. 'US/VA', etc (default: US)',
365
+ topic: 'optional - topic to publish to (default: '2/e/LongFast/#')',
366
+ channel: 'optional - channel (Default: 6)',
367
+ text: 'optional - Text Message (Default: SYN)',
368
+ want_ack: 'optional - Want Acknowledgement (Default: false)',
369
+ want_response: 'optional - Want Response (Default: false)',
370
+ hop_limit: 'optional - Hop Limit (Default: 3)',
371
+ on_response: 'optional - Callback on Response',
372
+ psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: 'AQ==' })'
373
+ )
374
+
375
+ mqtt_obj = #{self}.disconnect(
376
+ mqtt_obj: 'required - mqtt_obj object returned from #connect method'
377
+ )
378
+
379
+ #{self}.authors
380
+ "
381
+ end
382
+ end
383
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: meshtastic/mqtt.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+ require 'meshtastic/config_pb'
8
+ require 'meshtastic/mesh_pb'
9
+
10
+
11
+ descriptor_data = "\n\x15meshtastic/mqtt.proto\x12\nmeshtastic\x1a\x17meshtastic/config.proto\x1a\x15meshtastic/mesh.proto\"a\n\x0fServiceEnvelope\x12&\n\x06packet\x18\x01 \x01(\x0b\x32\x16.meshtastic.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"\xdf\x03\n\tMapReport\x12\x11\n\tlong_name\x18\x01 \x01(\t\x12\x12\n\nshort_name\x18\x02 \x01(\t\x12\x32\n\x04role\x18\x03 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.Role\x12+\n\x08hw_model\x18\x04 \x01(\x0e\x32\x19.meshtastic.HardwareModel\x12\x18\n\x10\x66irmware_version\x18\x05 \x01(\t\x12\x38\n\x06region\x18\x06 \x01(\x0e\x32(.meshtastic.Config.LoRaConfig.RegionCode\x12?\n\x0cmodem_preset\x18\x07 \x01(\x0e\x32).meshtastic.Config.LoRaConfig.ModemPreset\x12\x1b\n\x13has_default_channel\x18\x08 \x01(\x08\x12\x12\n\nlatitude_i\x18\t \x01(\x0f\x12\x13\n\x0blongitude_i\x18\n \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x0b \x01(\x05\x12\x1a\n\x12position_precision\x18\x0c \x01(\r\x12\x1e\n\x16num_online_local_nodes\x18\r \x01(\r\x12!\n\x19has_opted_report_location\x18\x0e \x01(\x08\x42`\n\x14org.meshtastic.protoB\nMQTTProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
12
+
13
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
14
+ pool.add_serialized_file(descriptor_data)
15
+
16
+ module Meshtastic
17
+ ServiceEnvelope = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.ServiceEnvelope").msgclass
18
+ MapReport = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.MapReport").msgclass
19
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meshtastic/paxcount_pb'
4
+
5
+ # Plugin used to interact with Meshtastic nodes
6
+ module Meshtastic
7
+ module Paxcount
8
+ # Author(s):: 0day Inc. <support@0dayinc.com>
9
+
10
+ public_class_method def self.authors
11
+ "AUTHOR(S):
12
+ 0day Inc. <support@0dayinc.com>
13
+ "
14
+ end
15
+
16
+ # Display Usage for this Module
17
+
18
+ public_class_method def self.help
19
+ puts "USAGE:
20
+ #{self}.authors
21
+ "
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: meshtastic/paxcount.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x19meshtastic/paxcount.proto\x12\nmeshtastic\"5\n\x08Paxcount\x12\x0c\n\x04wifi\x18\x01 \x01(\r\x12\x0b\n\x03\x62le\x18\x02 \x01(\r\x12\x0e\n\x06uptime\x18\x03 \x01(\rBd\n\x14org.meshtastic.protoB\x0ePaxcountProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Meshtastic
14
+ Paxcount = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Paxcount").msgclass
15
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meshtastic/portnums_pb'
4
+
5
+ # Plugin used to interact with Meshtastic nodes
6
+ module Meshtastic
7
+ module Portnums
8
+ # Author(s):: 0day Inc. <support@0dayinc.com>
9
+
10
+ public_class_method def self.authors
11
+ "AUTHOR(S):
12
+ 0day Inc. <support@0dayinc.com>
13
+ "
14
+ end
15
+
16
+ # Display Usage for this Module
17
+
18
+ public_class_method def self.help
19
+ puts "USAGE:
20
+ #{self}.authors
21
+ "
22
+ end
23
+ end
24
+ end