meshtastic 0.0.184 → 0.0.185

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +1 -0
  3. data/Gemfile +2 -1
  4. data/documentation/README.md +5 -0
  5. data/documentation/forwarder.md +149 -0
  6. data/documentation/mesh-interface.md +157 -1
  7. data/documentation/payload-formats.md +187 -0
  8. data/documentation/reticulum.md +89 -0
  9. data/lib/meshtastic/atak.rb +98 -13
  10. data/lib/meshtastic/atak_pb.rb +3 -1
  11. data/lib/meshtastic/config_pb.rb +1 -1
  12. data/lib/meshtastic/field_metadata_pb.rb +1 -1
  13. data/lib/meshtastic/forwarder.rb +190 -0
  14. data/lib/meshtastic/forwarder_pb.rb +77 -0
  15. data/lib/meshtastic/mesh_beacon_pb.rb +1 -1
  16. data/lib/meshtastic/mesh_interface.rb +115 -65
  17. data/lib/meshtastic/mesh_pb.rb +2 -1
  18. data/lib/meshtastic/module_config_pb.rb +1 -1
  19. data/lib/meshtastic/mqtt.rb +4 -34
  20. data/lib/meshtastic/payload_compression.rb +90 -0
  21. data/lib/meshtastic/payload_formats.rb +248 -0
  22. data/lib/meshtastic/reticulum.rb +71 -0
  23. data/lib/meshtastic/serial.rb +1 -19
  24. data/lib/meshtastic/telemetry_pb.rb +2 -2
  25. data/lib/meshtastic/unishox2.rb +467 -0
  26. data/lib/meshtastic/version.rb +1 -1
  27. data/lib/meshtastic.rb +4 -0
  28. data/meshtastic.gemspec +2 -0
  29. data/spec/lib/meshtastic/atak_spec.rb +50 -0
  30. data/spec/lib/meshtastic/bluetooth_spec.rb +14 -0
  31. data/spec/lib/meshtastic/forwarder_pb_spec.rb +11 -0
  32. data/spec/lib/meshtastic/forwarder_spec.rb +97 -0
  33. data/spec/lib/meshtastic/mesh_interface_spec.rb +169 -0
  34. data/spec/lib/meshtastic/mqtt_spec.rb +56 -0
  35. data/spec/lib/meshtastic/payload_compression_spec.rb +43 -0
  36. data/spec/lib/meshtastic/payload_formats_spec.rb +160 -0
  37. data/spec/lib/meshtastic/reticulum_spec.rb +91 -0
  38. data/spec/lib/meshtastic/serial_spec.rb +46 -0
  39. data/spec/lib/meshtastic/tcp_spec.rb +15 -0
  40. data/spec/lib/meshtastic/unishox2_spec.rb +34 -0
  41. data/spec/support/payload_fixtures.rb +124 -0
  42. data/spec/support/reticulum_fixtures.json +12 -0
  43. data/spec/support/tak_codec_fixtures.rb +4 -0
  44. data/spec/support/unishox_fixtures.rb +4 -0
  45. metadata +36 -3
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'meshtastic/atak_pb'
4
4
  require 'meshtastic/portnums_pb'
5
+ require 'meshtastic/payload_compression'
6
+ require 'meshtastic/unishox2'
5
7
  require 'zlib'
6
8
 
7
9
  module Meshtastic
@@ -52,17 +54,8 @@ module Meshtastic
52
54
  end
53
55
 
54
56
  public_class_method def self.decode_v2(opts = {})
55
- bytes = (opts[:wire] || opts[:payload]).to_s.b
56
- raise ArgumentError, 'empty ATAK V2 payload' if bytes.empty?
57
-
58
- flags = bytes.getbyte(0)
59
- body = bytes.byteslice(1..)
60
- if flags == V2_UNCOMPRESSED
61
- Meshtastic::TAKPacketV2.decode(body)
62
- else
63
- raise ArgumentError,
64
- "compressed ATAK V2 dictionary id #{flags & 0x3F} is not unpacked (flags=0x#{flags.to_s(16)})"
65
- end
57
+ body = Meshtastic::PayloadCompression.decode_v2(payload: opts[:wire] || opts[:payload])
58
+ Meshtastic::TAKPacketV2.decode(body)
66
59
  end
67
60
 
68
61
  public_class_method def self.compress_cot(opts = {})
@@ -80,7 +73,7 @@ module Meshtastic
80
73
  portnum = normalize_port(portnum: opts[:portnum])
81
74
  case portnum
82
75
  when V1_PORT, :ATAK_PLUGIN
83
- Meshtastic::TAKPacket.decode(payload.to_s.b)
76
+ Meshtastic::TAKPacket.decode(V1Strings.new(payload.to_s.b).decode)
84
77
  when V2_PORT, :ATAK_PLUGIN_V2
85
78
  decode_v2(payload: payload)
86
79
  when FORWARDER_PORT, :ATAK_FORWARDER
@@ -155,7 +148,7 @@ module Meshtastic
155
148
  message: 'optional - GeoChat text for the V2 chat variant'
156
149
  )
157
150
 
158
- # Decode an uncompressed V2 wire frame (flags 0xFF plus protobuf).
151
+ # Decode a bounded V2 frame using official dictionaries or raw flags 0xFF.
159
152
  #{self}.decode_v2(
160
153
  wire: 'optional - full V2 wire bytes including the flags byte',
161
154
  payload: 'optional - same as wire when wire is omitted'
@@ -220,6 +213,98 @@ module Meshtastic
220
213
  "
221
214
  end
222
215
 
216
+ # Compressed V1 fields contain arbitrary bytes despite being proto strings.
217
+ # Rewrite only firmware-compressed fields BEFORE the strict UTF-8 parser.
218
+ class V1Strings
219
+ def initialize(bytes)
220
+ raise ArgumentError, 'ATAK V1 input exceeds 4096 bytes' if bytes.bytesize > 4096
221
+
222
+ @bytes = bytes
223
+ end
224
+
225
+ def decode
226
+ fields = parse(@bytes)
227
+ compressed = fields.select { |number, kind, _| number == 1 && kind.zero? }.last
228
+ return @bytes unless compressed && compressed[2] != 0
229
+
230
+ output = fields.map do |number, kind, data|
231
+ data = 0 if number == 1 && kind.zero?
232
+ if kind == 2 && [2, 6].include?(number)
233
+ limit = number == 2 ? 2 : 3
234
+ data = parse(data).map do |inner, type, value|
235
+ value = Meshtastic::Unishox2.decode(payload: value).b if type == 2 && inner.between?(1, limit)
236
+ field(inner, type, value)
237
+ end.join.b
238
+ end
239
+ field(number, kind, data)
240
+ end.join.b
241
+ raise ArgumentError, 'ATAK V1 decoded output exceeds 4096 bytes' if output.bytesize > 4096
242
+
243
+ output
244
+ end
245
+
246
+ private
247
+
248
+ def varint(bytes, offset)
249
+ value = 0
250
+ 10.times do |index|
251
+ byte = bytes.getbyte(offset + index)
252
+ raise ArgumentError, 'truncated ATAK V1 varint' unless byte
253
+ raise ArgumentError, 'overflow ATAK V1 varint' if index == 9 && byte > 1
254
+
255
+ value |= (byte & 127) << (index * 7)
256
+ return [value, offset + index + 1] if byte < 128
257
+ end
258
+ raise ArgumentError, 'invalid ATAK V1 varint'
259
+ end
260
+
261
+ def parse(bytes)
262
+ offset = 0
263
+ fields = []
264
+ while offset < bytes.bytesize
265
+ tag, offset = varint(bytes, offset)
266
+ number = tag >> 3
267
+ kind = tag & 7
268
+ raise ArgumentError, 'invalid ATAK V1 field number' unless number.between?(1, 0x1fffffff)
269
+
270
+ if kind.zero?
271
+ data, offset = varint(bytes, offset)
272
+ else
273
+ if kind == 2
274
+ length, offset = varint(bytes, offset)
275
+ else
276
+ length = { 1 => 8, 5 => 4 }[kind]
277
+ raise ArgumentError, 'unsupported ATAK V1 protobuf wire type' unless length
278
+ end
279
+ raise ArgumentError, 'truncated ATAK V1 field' if offset + length > bytes.bytesize
280
+
281
+ data = bytes.byteslice(offset, length)
282
+ offset += length
283
+ end
284
+ fields << [number, kind, data]
285
+ end
286
+ fields
287
+ end
288
+
289
+ def encode_varint(value)
290
+ bytes = +''.b
291
+ while value > 127
292
+ bytes << ((value & 127) | 128)
293
+ value >>= 7
294
+ end
295
+ bytes << value
296
+ end
297
+
298
+ def field(number, kind, value)
299
+ prefix = encode_varint((number << 3) | kind)
300
+ return prefix + encode_varint(value) if kind.zero?
301
+
302
+ prefix << encode_varint(value.bytesize) if kind == 2
303
+ prefix + value
304
+ end
305
+ end
306
+ private_constant :V1Strings
307
+
223
308
  private_class_method def self.deliver(opts = {})
224
309
  data = Meshtastic::Data.new(portnum: opts[:port_num], payload: opts[:payload])
225
310
  Meshtastic.deliver_data(opts.merge(data: data, port_num: opts[:port_num]))
@@ -4,8 +4,10 @@
4
4
 
5
5
  require 'google/protobuf'
6
6
 
7
+ require 'meshtastic/field_metadata_pb'
7
8
 
8
- descriptor_data = "\n\x15meshtastic/atak.proto\x12\nmeshtastic\"\xf8\x01\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12$\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x13.meshtastic.Contact\x12 \n\x05group\x18\x03 \x01(\x0b\x32\x11.meshtastic.Group\x12\"\n\x06status\x18\x04 \x01(\x0b\x32\x12.meshtastic.Status\x12\x1e\n\x03pli\x18\x05 \x01(\x0b\x32\x0f.meshtastic.PLIH\x00\x12#\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x13.meshtastic.GeoChatH\x00\x12\x10\n\x06\x64\x65tail\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fpayload_variant\"\xf4\x02\n\x07GeoChat\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0f\n\x02to\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bto_callsign\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x17\n\x0freceipt_for_uid\x18\x04 \x01(\t\x12\x35\n\x0creceipt_type\x18\x05 \x01(\x0e\x32\x1f.meshtastic.GeoChat.ReceiptType\x12\x11\n\x04lang\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07room_id\x18\x07 \x01(\tH\x03\x88\x01\x01\x12\x1d\n\x10voice_profile_id\x18\x08 \x01(\tH\x04\x88\x01\x01\"T\n\x0bReceiptType\x12\x14\n\x10ReceiptType_None\x10\x00\x12\x19\n\x15ReceiptType_Delivered\x10\x01\x12\x14\n\x10ReceiptType_Read\x10\x02\x42\x05\n\x03_toB\x0e\n\x0c_to_callsignB\x07\n\x05_langB\n\n\x08_room_idB\x13\n\x11_voice_profile_id\"M\n\x05Group\x12$\n\x04role\x18\x01 \x01(\x0e\x32\x16.meshtastic.MemberRole\x12\x1e\n\x04team\x18\x02 \x01(\x0e\x32\x10.meshtastic.Team\"\x19\n\x06Status\x12\x0f\n\x07\x62\x61ttery\x18\x01 \x01(\r\"4\n\x07\x43ontact\x12\x10\n\x08\x63\x61llsign\x18\x01 \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x02 \x01(\t\"_\n\x03PLI\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\r\n\x05speed\x18\x04 \x01(\r\x12\x0e\n\x06\x63ourse\x18\x05 \x01(\r\"\xb0\x01\n\rAircraftTrack\x12\x0c\n\x04icao\x18\x01 \x01(\t\x12\x14\n\x0cregistration\x18\x02 \x01(\t\x12\x0e\n\x06\x66light\x18\x03 \x01(\t\x12\x15\n\raircraft_type\x18\x04 \x01(\t\x12\x0e\n\x06squawk\x18\x05 \x01(\r\x12\x10\n\x08\x63\x61tegory\x18\x06 \x01(\t\x12\x10\n\x08rssi_x10\x18\x07 \x01(\x11\x12\x0b\n\x03gps\x18\x08 \x01(\x08\x12\x13\n\x0b\x63ot_host_id\x18\t \x01(\t\"7\n\x0b\x43otGeoPoint\x12\x13\n\x0blat_delta_i\x18\x01 \x01(\x11\x12\x13\n\x0blon_delta_i\x18\x02 \x01(\x11\"\xdc\x06\n\nDrawnShape\x12)\n\x04kind\x18\x01 \x01(\x0e\x32\x1b.meshtastic.DrawnShape.Kind\x12/\n\x05style\x18\x02 \x01(\x0e\x32 .meshtastic.DrawnShape.StyleMode\x12\x10\n\x08major_cm\x18\x03 \x01(\r\x12\x10\n\x08minor_cm\x18\x04 \x01(\r\x12\x11\n\tangle_deg\x18\x05 \x01(\r\x12&\n\x0cstroke_color\x18\x06 \x01(\x0e\x32\x10.meshtastic.Team\x12\x13\n\x0bstroke_argb\x18\x07 \x01(\x07\x12\x19\n\x11stroke_weight_x10\x18\x08 \x01(\r\x12$\n\nfill_color\x18\t \x01(\x0e\x32\x10.meshtastic.Team\x12\x11\n\tfill_argb\x18\n \x01(\x07\x12\x11\n\tlabels_on\x18\x0b \x01(\x08\x12\x19\n\x11vertex_lat_deltas\x18\x12 \x03(\x11\x12\x19\n\x11vertex_lon_deltas\x18\x13 \x03(\x11\x12\x11\n\ttruncated\x18\r \x01(\x08\x12\x1c\n\x14\x62ullseye_distance_dm\x18\x0e \x01(\r\x12\x1c\n\x14\x62ullseye_bearing_ref\x18\x0f \x01(\r\x12\x16\n\x0e\x62ullseye_flags\x18\x10 \x01(\r\x12\x18\n\x10\x62ullseye_uid_ref\x18\x11 \x01(\t\"\xe2\x01\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\x0f\n\x0bKind_Circle\x10\x01\x12\x12\n\x0eKind_Rectangle\x10\x02\x12\x11\n\rKind_Freeform\x10\x03\x12\x15\n\x11Kind_Telestration\x10\x04\x12\x10\n\x0cKind_Polygon\x10\x05\x12\x16\n\x12Kind_RangingCircle\x10\x06\x12\x11\n\rKind_Bullseye\x10\x07\x12\x10\n\x0cKind_Ellipse\x10\x08\x12\x12\n\x0eKind_Vehicle2D\x10\t\x12\x12\n\x0eKind_Vehicle3D\x10\n\"u\n\tStyleMode\x12\x19\n\x15StyleMode_Unspecified\x10\x00\x12\x18\n\x14StyleMode_StrokeOnly\x10\x01\x12\x16\n\x12StyleMode_FillOnly\x10\x02\x12\x1b\n\x17StyleMode_StrokeAndFill\x10\x03J\x04\x08\x0c\x10\r\"\xe5\x03\n\x06Marker\x12%\n\x04kind\x18\x01 \x01(\x0e\x32\x17.meshtastic.Marker.Kind\x12\x1f\n\x05\x63olor\x18\x02 \x01(\x0e\x32\x10.meshtastic.Team\x12\x12\n\ncolor_argb\x18\x03 \x01(\x07\x12\x11\n\treadiness\x18\x04 \x01(\x08\x12\x12\n\nparent_uid\x18\x05 \x01(\t\x12\x13\n\x0bparent_type\x18\x06 \x01(\t\x12\x17\n\x0fparent_callsign\x18\x07 \x01(\t\x12\x0f\n\x07iconset\x18\x08 \x01(\t\"\x98\x02\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\r\n\tKind_Spot\x10\x01\x12\x11\n\rKind_Waypoint\x10\x02\x12\x13\n\x0fKind_Checkpoint\x10\x03\x12\x15\n\x11Kind_SelfPosition\x10\x04\x12\x13\n\x0fKind_Symbol2525\x10\x05\x12\x10\n\x0cKind_SpotMap\x10\x06\x12\x13\n\x0fKind_CustomIcon\x10\x07\x12\x12\n\x0eKind_GoToPoint\x10\x08\x12\x15\n\x11Kind_InitialPoint\x10\t\x12\x15\n\x11Kind_ContactPoint\x10\n\x12\x18\n\x14Kind_ObservationPost\x10\x0b\x12\x14\n\x10Kind_ImageMarker\x10\x0c\"\xce\x01\n\x0fRangeAndBearing\x12\'\n\x06\x61nchor\x18\x01 \x01(\x0b\x32\x17.meshtastic.CotGeoPoint\x12\x12\n\nanchor_uid\x18\x02 \x01(\t\x12\x10\n\x08range_cm\x18\x03 \x01(\r\x12\x14\n\x0c\x62\x65\x61ring_cdeg\x18\x04 \x01(\r\x12&\n\x0cstroke_color\x18\x05 \x01(\x0e\x32\x10.meshtastic.Team\x12\x13\n\x0bstroke_argb\x18\x06 \x01(\x07\x12\x19\n\x11stroke_weight_x10\x18\x07 \x01(\r\"\x84\x04\n\x05Route\x12(\n\x06method\x18\x01 \x01(\x0e\x32\x18.meshtastic.Route.Method\x12.\n\tdirection\x18\x02 \x01(\x0e\x32\x1b.meshtastic.Route.Direction\x12\x0e\n\x06prefix\x18\x03 \x01(\t\x12\x19\n\x11stroke_weight_x10\x18\x04 \x01(\r\x12%\n\x05links\x18\x05 \x03(\x0b\x32\x16.meshtastic.Route.Link\x12\x11\n\ttruncated\x18\x06 \x01(\x08\x1a`\n\x04Link\x12&\n\x05point\x18\x01 \x01(\x0b\x32\x17.meshtastic.CotGeoPoint\x12\x0b\n\x03uid\x18\x02 \x01(\t\x12\x10\n\x08\x63\x61llsign\x18\x03 \x01(\t\x12\x11\n\tlink_type\x18\x04 \x01(\r\"\x87\x01\n\x06Method\x12\x16\n\x12Method_Unspecified\x10\x00\x12\x12\n\x0eMethod_Driving\x10\x01\x12\x12\n\x0eMethod_Walking\x10\x02\x12\x11\n\rMethod_Flying\x10\x03\x12\x13\n\x0fMethod_Swimming\x10\x04\x12\x15\n\x11Method_Watercraft\x10\x05\"P\n\tDirection\x12\x19\n\x15\x44irection_Unspecified\x10\x00\x12\x13\n\x0f\x44irection_Infil\x10\x01\x12\x13\n\x0f\x44irection_Exfil\x10\x02\"\xd6\n\n\rCasevacReport\x12\x38\n\nprecedence\x18\x01 \x01(\x0e\x32$.meshtastic.CasevacReport.Precedence\x12\x17\n\x0f\x65quipment_flags\x18\x02 \x01(\r\x12\x17\n\x0flitter_patients\x18\x03 \x01(\r\x12\x1b\n\x13\x61mbulatory_patients\x18\x04 \x01(\r\x12\x34\n\x08security\x18\x05 \x01(\x0e\x32\".meshtastic.CasevacReport.Security\x12\x39\n\x0bhlz_marking\x18\x06 \x01(\x0e\x32$.meshtastic.CasevacReport.HlzMarking\x12\x13\n\x0bzone_marker\x18\x07 \x01(\t\x12\x13\n\x0bus_military\x18\x08 \x01(\r\x12\x13\n\x0bus_civilian\x18\t \x01(\r\x12\x17\n\x0fnon_us_military\x18\n \x01(\r\x12\x17\n\x0fnon_us_civilian\x18\x0b \x01(\r\x12\x0b\n\x03\x65pw\x18\x0c \x01(\r\x12\r\n\x05\x63hild\x18\r \x01(\r\x12\x15\n\rterrain_flags\x18\x0e \x01(\r\x12\x11\n\tfrequency\x18\x0f \x01(\t\x12\r\n\x05title\x18\x10 \x01(\t\x12\x17\n\x0fmedline_remarks\x18\x11 \x01(\t\x12\x14\n\x0curgent_count\x18\x12 \x01(\r\x12\x1d\n\x15urgent_surgical_count\x18\x13 \x01(\r\x12\x16\n\x0epriority_count\x18\x14 \x01(\r\x12\x15\n\rroutine_count\x18\x15 \x01(\r\x12\x19\n\x11\x63onvenience_count\x18\x16 \x01(\r\x12\x18\n\x10\x65quipment_detail\x18\x17 \x01(\t\x12\x1c\n\x14zone_protected_coord\x18\x18 \x01(\t\x12\x19\n\x11terrain_slope_dir\x18\x19 \x01(\t\x12\x1c\n\x14terrain_other_detail\x18\x1a \x01(\t\x12\x11\n\tmarked_by\x18\x1b \x01(\t\x12\x11\n\tobstacles\x18\x1c \x01(\t\x12\x16\n\x0ewinds_are_from\x18\x1d \x01(\t\x12\x12\n\nfriendlies\x18\x1e \x01(\t\x12\r\n\x05\x65nemy\x18\x1f \x01(\t\x12\x13\n\x0bhlz_remarks\x18 \x01(\t\x12%\n\x05zmist\x18! \x03(\x0b\x32\x16.meshtastic.ZMistEntry\"\xab\x01\n\nPrecedence\x12\x1a\n\x16Precedence_Unspecified\x10\x00\x12\x15\n\x11Precedence_Urgent\x10\x01\x12\x1d\n\x19Precedence_UrgentSurgical\x10\x02\x12\x17\n\x13Precedence_Priority\x10\x03\x12\x16\n\x12Precedence_Routine\x10\x04\x12\x1a\n\x16Precedence_Convenience\x10\x05\"\x9b\x01\n\nHlzMarking\x12\x1a\n\x16HlzMarking_Unspecified\x10\x00\x12\x15\n\x11HlzMarking_Panels\x10\x01\x12\x19\n\x15HlzMarking_PyroSignal\x10\x02\x12\x14\n\x10HlzMarking_Smoke\x10\x03\x12\x13\n\x0fHlzMarking_None\x10\x04\x12\x14\n\x10HlzMarking_Other\x10\x05\"\x92\x01\n\x08Security\x12\x18\n\x14Security_Unspecified\x10\x00\x12\x14\n\x10Security_NoEnemy\x10\x01\x12\x1a\n\x16Security_PossibleEnemy\x10\x02\x12\x18\n\x14Security_EnemyInArea\x10\x03\x12 \n\x1cSecurity_EnemyInArmedContact\x10\x04\"R\n\nZMistEntry\x12\r\n\x05title\x18\x01 \x01(\t\x12\t\n\x01z\x18\x02 \x01(\t\x12\t\n\x01m\x18\x03 \x01(\t\x12\t\n\x01i\x18\x04 \x01(\t\x12\t\n\x01s\x18\x05 \x01(\t\x12\t\n\x01t\x18\x06 \x01(\t\"\x8d\x02\n\x0e\x45mergencyAlert\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.meshtastic.EmergencyAlert.Type\x12\x15\n\rauthoring_uid\x18\x02 \x01(\t\x12\x1c\n\x14\x63\x61ncel_reference_uid\x18\x03 \x01(\t\"\x96\x01\n\x04Type\x12\x14\n\x10Type_Unspecified\x10\x00\x12\x11\n\rType_Alert911\x10\x01\x12\x14\n\x10Type_RingTheBell\x10\x02\x12\x12\n\x0eType_InContact\x10\x03\x12\x19\n\x15Type_GeoFenceBreached\x10\x04\x12\x0f\n\x0bType_Custom\x10\x05\x12\x0f\n\x0bType_Cancel\x10\x06\"\xc6\x03\n\x0bTaskRequest\x12\x11\n\ttask_type\x18\x01 \x01(\t\x12\x12\n\ntarget_uid\x18\x02 \x01(\t\x12\x14\n\x0c\x61ssignee_uid\x18\x03 \x01(\t\x12\x32\n\x08priority\x18\x04 \x01(\x0e\x32 .meshtastic.TaskRequest.Priority\x12.\n\x06status\x18\x05 \x01(\x0e\x32\x1e.meshtastic.TaskRequest.Status\x12\x0c\n\x04note\x18\x06 \x01(\t\"u\n\x08Priority\x12\x18\n\x14Priority_Unspecified\x10\x00\x12\x10\n\x0cPriority_Low\x10\x01\x12\x13\n\x0fPriority_Normal\x10\x02\x12\x11\n\rPriority_High\x10\x03\x12\x15\n\x11Priority_Critical\x10\x04\"\x90\x01\n\x06Status\x12\x16\n\x12Status_Unspecified\x10\x00\x12\x12\n\x0eStatus_Pending\x10\x01\x12\x17\n\x13Status_Acknowledged\x10\x02\x12\x15\n\x11Status_InProgress\x10\x03\x12\x14\n\x10Status_Completed\x10\x04\x12\x14\n\x10Status_Cancelled\x10\x05\"`\n\x0eTAKEnvironment\x12\x19\n\x11temperature_c_x10\x18\x01 \x01(\x11\x12\x1a\n\x12wind_direction_deg\x18\x02 \x01(\r\x12\x17\n\x0fwind_speed_cm_s\x18\x03 \x01(\r\"\x8d\x03\n\tSensorFov\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .meshtastic.SensorFov.SensorType\x12\x13\n\x0b\x61zimuth_deg\x18\x02 \x01(\r\x12\x14\n\x07range_m\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\x12\x66ov_horizontal_deg\x18\x04 \x01(\r\x12\x18\n\x10\x66ov_vertical_deg\x18\x05 \x01(\r\x12\x15\n\relevation_deg\x18\x06 \x01(\x11\x12\x10\n\x08roll_deg\x18\x07 \x01(\x11\x12\r\n\x05model\x18\x08 \x01(\t\"\xaa\x01\n\nSensorType\x12\x1a\n\x16SensorType_Unspecified\x10\x00\x12\x15\n\x11SensorType_Camera\x10\x01\x12\x16\n\x12SensorType_Thermal\x10\x02\x12\x14\n\x10SensorType_Laser\x10\x03\x12\x12\n\x0eSensorType_Nvg\x10\x04\x12\x11\n\rSensorType_Rf\x10\x05\x12\x14\n\x10SensorType_Other\x10\x06\x42\n\n\x08_range_m\"U\n\x0eTakTalkMessage\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x13\n\x0b\x63hatroom_id\x18\x02 \x01(\t\x12\x0c\n\x04lang\x18\x03 \x01(\t\x12\x12\n\nfrom_voice\x18\x04 \x01(\x08\"h\n\x0fTakTalkRoomData\x12\x1b\n\x0fsender_callsign\x18\x01 \x01(\tB\x02\x18\x01\x12\x0f\n\x07room_id\x18\x02 \x01(\t\x12\x11\n\troom_name\x18\x03 \x01(\t\x12\x14\n\x0cparticipants\x18\x04 \x03(\t\"\x1e\n\x05Marti\x12\x15\n\rdest_callsign\x18\x01 \x03(\t\"\x99\n\n\x0bTAKPacketV2\x12(\n\x0b\x63ot_type_id\x18\x01 \x01(\x0e\x32\x13.meshtastic.CotType\x12\x1f\n\x03how\x18\x02 \x01(\x0e\x32\x12.meshtastic.CotHow\x12\x10\n\x08\x63\x61llsign\x18\x03 \x01(\t\x12\x1e\n\x04team\x18\x04 \x01(\x0e\x32\x10.meshtastic.Team\x12$\n\x04role\x18\x05 \x01(\x0e\x32\x16.meshtastic.MemberRole\x12\x12\n\nlatitude_i\x18\x06 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x07 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x08 \x01(\x11\x12\r\n\x05speed\x18\t \x01(\r\x12\x0e\n\x06\x63ourse\x18\n \x01(\r\x12\x0f\n\x07\x62\x61ttery\x18\x0b \x01(\r\x12+\n\x07geo_src\x18\x0c \x01(\x0e\x32\x1a.meshtastic.GeoPointSource\x12+\n\x07\x61lt_src\x18\r \x01(\x0e\x32\x1a.meshtastic.GeoPointSource\x12\x0b\n\x03uid\x18\x0e \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x0f \x01(\t\x12\x15\n\rstale_seconds\x18\x10 \x01(\r\x12\x13\n\x0btak_version\x18\x11 \x01(\t\x12\x12\n\ntak_device\x18\x12 \x01(\t\x12\x14\n\x0ctak_platform\x18\x13 \x01(\t\x12\x0e\n\x06tak_os\x18\x14 \x01(\t\x12\x10\n\x08\x65ndpoint\x18\x15 \x01(\t\x12\r\n\x05phone\x18\x16 \x01(\t\x12\x14\n\x0c\x63ot_type_str\x18\x17 \x01(\t\x12\x0f\n\x07remarks\x18\x18 \x01(\t\x12\x34\n\x0b\x65nvironment\x18\x19 \x01(\x0b\x32\x1a.meshtastic.TAKEnvironmentH\x01\x88\x01\x01\x12.\n\nsensor_fov\x18\x1a \x01(\x0b\x32\x15.meshtastic.SensorFovH\x02\x88\x01\x01\x12%\n\x05marti\x18\x1d \x01(\x0b\x32\x11.meshtastic.MartiH\x03\x88\x01\x01\x12#\n\x04\x63hat\x18\x1f \x01(\x0b\x32\x13.meshtastic.GeoChatH\x00\x12-\n\x08\x61ircraft\x18 \x01(\x0b\x32\x19.meshtastic.AircraftTrackH\x00\x12\x14\n\nraw_detail\x18! \x01(\x0cH\x00\x12\'\n\x05shape\x18\" \x01(\x0b\x32\x16.meshtastic.DrawnShapeH\x00\x12$\n\x06marker\x18# \x01(\x0b\x32\x12.meshtastic.MarkerH\x00\x12*\n\x03rab\x18$ \x01(\x0b\x32\x1b.meshtastic.RangeAndBearingH\x00\x12\"\n\x05route\x18% \x01(\x0b\x32\x11.meshtastic.RouteH\x00\x12,\n\x07\x63\x61sevac\x18& \x01(\x0b\x32\x19.meshtastic.CasevacReportH\x00\x12/\n\temergency\x18\' \x01(\x0b\x32\x1a.meshtastic.EmergencyAlertH\x00\x12\'\n\x04task\x18( \x01(\x0b\x32\x17.meshtastic.TaskRequestH\x00\x12-\n\x07taktalk\x18) \x01(\x0b\x32\x1a.meshtastic.TakTalkMessageH\x00\x12\x33\n\x0ctaktalk_room\x18* \x01(\x0b\x32\x1b.meshtastic.TakTalkRoomDataH\x00\x42\x11\n\x0fpayload_variantB\x0e\n\x0c_environmentB\r\n\x0b_sensor_fovB\x08\n\x06_martiJ\x04\x08\x1b\x10\x1cJ\x04\x08\x1c\x10\x1dJ\x04\x08\x1e\x10\x1f*\xc0\x01\n\x04Team\x12\x14\n\x10Unspecifed_Color\x10\x00\x12\t\n\x05White\x10\x01\x12\n\n\x06Yellow\x10\x02\x12\n\n\x06Orange\x10\x03\x12\x0b\n\x07Magenta\x10\x04\x12\x07\n\x03Red\x10\x05\x12\n\n\x06Maroon\x10\x06\x12\n\n\x06Purple\x10\x07\x12\r\n\tDark_Blue\x10\x08\x12\x08\n\x04\x42lue\x10\t\x12\x08\n\x04\x43yan\x10\n\x12\x08\n\x04Teal\x10\x0b\x12\t\n\x05Green\x10\x0c\x12\x0e\n\nDark_Green\x10\r\x12\t\n\x05\x42rown\x10\x0e*\x7f\n\nMemberRole\x12\x0e\n\nUnspecifed\x10\x00\x12\x0e\n\nTeamMember\x10\x01\x12\x0c\n\x08TeamLead\x10\x02\x12\x06\n\x02HQ\x10\x03\x12\n\n\x06Sniper\x10\x04\x12\t\n\x05Medic\x10\x05\x12\x13\n\x0f\x46orwardObserver\x10\x06\x12\x07\n\x03RTO\x10\x07\x12\x06\n\x02K9\x10\x08*\x96\x01\n\x06\x43otHow\x12\x16\n\x12\x43otHow_Unspecified\x10\x00\x12\x0e\n\nCotHow_h_e\x10\x01\x12\x0e\n\nCotHow_m_g\x10\x02\x12\x14\n\x10\x43otHow_h_g_i_g_o\x10\x03\x12\x0e\n\nCotHow_m_r\x10\x04\x12\x0e\n\nCotHow_m_f\x10\x05\x12\x0e\n\nCotHow_m_p\x10\x06\x12\x0e\n\nCotHow_m_s\x10\x07*\x83\x17\n\x07\x43otType\x12\x11\n\rCotType_Other\x10\x00\x12\x15\n\x11\x43otType_a_f_G_U_C\x10\x01\x12\x17\n\x13\x43otType_a_f_G_U_C_I\x10\x02\x12\x15\n\x11\x43otType_a_n_A_C_F\x10\x03\x12\x15\n\x11\x43otType_a_n_A_C_H\x10\x04\x12\x13\n\x0f\x43otType_a_n_A_C\x10\x05\x12\x15\n\x11\x43otType_a_f_A_M_H\x10\x06\x12\x13\n\x0f\x43otType_a_f_A_M\x10\x07\x12\x17\n\x13\x43otType_a_f_A_M_F_F\x10\x08\x12\x17\n\x13\x43otType_a_f_A_M_H_A\x10\t\x12\x19\n\x15\x43otType_a_f_A_M_H_U_M\x10\n\x12\x17\n\x13\x43otType_a_h_A_M_F_F\x10\x0b\x12\x17\n\x13\x43otType_a_h_A_M_H_A\x10\x0c\x12\x13\n\x0f\x43otType_a_u_A_C\x10\r\x12\x13\n\x0f\x43otType_t_x_d_d\x10\x0e\x12\x17\n\x13\x43otType_a_f_G_E_S_E\x10\x0f\x12\x17\n\x13\x43otType_a_f_G_E_V_C\x10\x10\x12\x11\n\rCotType_a_f_S\x10\x11\x12\x15\n\x11\x43otType_a_f_A_M_F\x10\x12\x12\x19\n\x15\x43otType_a_f_A_M_F_C_H\x10\x13\x12\x19\n\x15\x43otType_a_f_A_M_F_U_L\x10\x14\x12\x17\n\x13\x43otType_a_f_A_M_F_L\x10\x15\x12\x17\n\x13\x43otType_a_f_A_M_F_P\x10\x16\x12\x15\n\x11\x43otType_a_f_A_C_H\x10\x17\x12\x17\n\x13\x43otType_a_n_A_M_F_Q\x10\x18\x12\x11\n\rCotType_b_t_f\x10\x19\x12\x15\n\x11\x43otType_b_r_f_h_c\x10\x1a\x12\x15\n\x11\x43otType_b_a_o_pan\x10\x1b\x12\x15\n\x11\x43otType_b_a_o_opn\x10\x1c\x12\x15\n\x11\x43otType_b_a_o_can\x10\x1d\x12\x15\n\x11\x43otType_b_a_o_tbl\x10\x1e\x12\x11\n\rCotType_b_a_g\x10\x1f\x12\x11\n\rCotType_a_f_G\x10 \x12\x13\n\x0f\x43otType_a_f_G_U\x10!\x12\x11\n\rCotType_a_h_G\x10\"\x12\x11\n\rCotType_a_u_G\x10#\x12\x11\n\rCotType_a_n_G\x10$\x12\x11\n\rCotType_b_m_r\x10%\x12\x13\n\x0f\x43otType_b_m_p_w\x10&\x12\x17\n\x13\x43otType_b_m_p_s_p_i\x10\'\x12\x11\n\rCotType_u_d_f\x10(\x12\x11\n\rCotType_u_d_r\x10)\x12\x13\n\x0f\x43otType_u_d_c_c\x10*\x12\x12\n\x0e\x43otType_u_rb_a\x10+\x12\x11\n\rCotType_a_h_A\x10,\x12\x11\n\rCotType_a_u_A\x10-\x12\x17\n\x13\x43otType_a_f_A_M_H_Q\x10.\x12\x15\n\x11\x43otType_a_f_A_C_F\x10/\x12\x13\n\x0f\x43otType_a_f_A_C\x10\x30\x12\x15\n\x11\x43otType_a_f_A_C_L\x10\x31\x12\x11\n\rCotType_a_f_A\x10\x32\x12\x17\n\x13\x43otType_a_f_A_M_H_C\x10\x33\x12\x17\n\x13\x43otType_a_n_A_M_F_F\x10\x34\x12\x15\n\x11\x43otType_a_u_A_C_F\x10\x35\x12\x1b\n\x17\x43otType_a_f_G_U_C_F_T_A\x10\x36\x12\x19\n\x15\x43otType_a_f_G_U_C_V_S\x10\x37\x12\x19\n\x15\x43otType_a_f_G_U_C_R_X\x10\x38\x12\x19\n\x15\x43otType_a_f_G_U_C_I_Z\x10\x39\x12\x1b\n\x17\x43otType_a_f_G_U_C_E_C_W\x10:\x12\x19\n\x15\x43otType_a_f_G_U_C_I_L\x10;\x12\x19\n\x15\x43otType_a_f_G_U_C_R_O\x10<\x12\x19\n\x15\x43otType_a_f_G_U_C_R_V\x10=\x12\x15\n\x11\x43otType_a_f_G_U_H\x10>\x12\x1b\n\x17\x43otType_a_f_G_U_U_M_S_E\x10?\x12\x19\n\x15\x43otType_a_f_G_U_S_M_C\x10@\x12\x15\n\x11\x43otType_a_f_G_E_S\x10\x41\x12\x13\n\x0f\x43otType_a_f_G_E\x10\x42\x12\x19\n\x15\x43otType_a_f_G_E_V_C_U\x10\x43\x12\x1a\n\x16\x43otType_a_f_G_E_V_C_ps\x10\x44\x12\x15\n\x11\x43otType_a_u_G_E_V\x10\x45\x12\x17\n\x13\x43otType_a_f_S_N_N_R\x10\x46\x12\x13\n\x0f\x43otType_a_f_F_B\x10G\x12\x19\n\x15\x43otType_b_m_p_s_p_loc\x10H\x12\x11\n\rCotType_b_i_v\x10I\x12\x13\n\x0f\x43otType_b_f_t_r\x10J\x12\x13\n\x0f\x43otType_b_f_t_a\x10K\x12\x13\n\x0f\x43otType_u_d_f_m\x10L\x12\x11\n\rCotType_u_d_p\x10M\x12\x15\n\x11\x43otType_b_m_p_s_m\x10N\x12\x13\n\x0f\x43otType_b_m_p_c\x10O\x12\x15\n\x11\x43otType_u_r_b_c_c\x10P\x12\x1a\n\x16\x43otType_u_r_b_bullseye\x10Q\x12\x17\n\x13\x43otType_a_f_G_E_V_A\x10R\x12\x11\n\rCotType_a_n_A\x10S\x12\x17\n\x13\x43otType_a_u_G_U_C_F\x10T\x12\x17\n\x13\x43otType_a_n_G_U_C_F\x10U\x12\x17\n\x13\x43otType_a_h_G_U_C_F\x10V\x12\x17\n\x13\x43otType_a_f_G_U_C_F\x10W\x12\x13\n\x0f\x43otType_a_u_G_I\x10X\x12\x13\n\x0f\x43otType_a_n_G_I\x10Y\x12\x13\n\x0f\x43otType_a_h_G_I\x10Z\x12\x13\n\x0f\x43otType_a_f_G_I\x10[\x12\x17\n\x13\x43otType_a_u_G_E_X_M\x10\\\x12\x17\n\x13\x43otType_a_n_G_E_X_M\x10]\x12\x17\n\x13\x43otType_a_h_G_E_X_M\x10^\x12\x17\n\x13\x43otType_a_f_G_E_X_M\x10_\x12\x11\n\rCotType_a_u_S\x10`\x12\x11\n\rCotType_a_n_S\x10\x61\x12\x11\n\rCotType_a_h_S\x10\x62\x12\x19\n\x15\x43otType_a_u_G_U_C_I_d\x10\x63\x12\x19\n\x15\x43otType_a_n_G_U_C_I_d\x10\x64\x12\x19\n\x15\x43otType_a_h_G_U_C_I_d\x10\x65\x12\x19\n\x15\x43otType_a_f_G_U_C_I_d\x10\x66\x12\x19\n\x15\x43otType_a_u_G_E_V_A_T\x10g\x12\x19\n\x15\x43otType_a_n_G_E_V_A_T\x10h\x12\x19\n\x15\x43otType_a_h_G_E_V_A_T\x10i\x12\x19\n\x15\x43otType_a_f_G_E_V_A_T\x10j\x12\x17\n\x13\x43otType_a_u_G_U_C_I\x10k\x12\x17\n\x13\x43otType_a_n_G_U_C_I\x10l\x12\x17\n\x13\x43otType_a_h_G_U_C_I\x10m\x12\x15\n\x11\x43otType_a_n_G_E_V\x10n\x12\x15\n\x11\x43otType_a_h_G_E_V\x10o\x12\x15\n\x11\x43otType_a_f_G_E_V\x10p\x12\x18\n\x14\x43otType_b_m_p_w_GOTO\x10q\x12\x16\n\x12\x43otType_b_m_p_c_ip\x10r\x12\x16\n\x12\x43otType_b_m_p_c_cp\x10s\x12\x18\n\x14\x43otType_b_m_p_s_p_op\x10t\x12\x11\n\rCotType_u_d_v\x10u\x12\x13\n\x0f\x43otType_u_d_v_m\x10v\x12\x13\n\x0f\x43otType_u_d_c_e\x10w\x12\x13\n\x0f\x43otType_b_i_x_i\x10x\x12\x13\n\x0f\x43otType_b_t_f_d\x10y\x12\x13\n\x0f\x43otType_b_t_f_r\x10z\x12\x13\n\x0f\x43otType_b_a_o_c\x10{\x12\x0f\n\x0b\x43otType_t_s\x10|\x12\x11\n\rCotType_m_t_t\x10}\x12\r\n\tCotType_y\x10~*}\n\x0eGeoPointSource\x12\x1e\n\x1aGeoPointSource_Unspecified\x10\x00\x12\x16\n\x12GeoPointSource_GPS\x10\x01\x12\x17\n\x13GeoPointSource_USER\x10\x02\x12\x1a\n\x16GeoPointSource_NETWORK\x10\x03\x42`\n\x14org.meshtastic.protoB\nATAKProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
9
+
10
+ descriptor_data = "\n\x15meshtastic/atak.proto\x12\nmeshtastic\x1a\x1fmeshtastic/field_metadata.proto\"\xf8\x01\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12$\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x13.meshtastic.Contact\x12 \n\x05group\x18\x03 \x01(\x0b\x32\x11.meshtastic.Group\x12\"\n\x06status\x18\x04 \x01(\x0b\x32\x12.meshtastic.Status\x12\x1e\n\x03pli\x18\x05 \x01(\x0b\x32\x0f.meshtastic.PLIH\x00\x12#\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x13.meshtastic.GeoChatH\x00\x12\x10\n\x06\x64\x65tail\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fpayload_variant\"\xf4\x02\n\x07GeoChat\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0f\n\x02to\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bto_callsign\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x17\n\x0freceipt_for_uid\x18\x04 \x01(\t\x12\x35\n\x0creceipt_type\x18\x05 \x01(\x0e\x32\x1f.meshtastic.GeoChat.ReceiptType\x12\x11\n\x04lang\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07room_id\x18\x07 \x01(\tH\x03\x88\x01\x01\x12\x1d\n\x10voice_profile_id\x18\x08 \x01(\tH\x04\x88\x01\x01\"T\n\x0bReceiptType\x12\x14\n\x10ReceiptType_None\x10\x00\x12\x19\n\x15ReceiptType_Delivered\x10\x01\x12\x14\n\x10ReceiptType_Read\x10\x02\x42\x05\n\x03_toB\x0e\n\x0c_to_callsignB\x07\n\x05_langB\n\n\x08_room_idB\x13\n\x11_voice_profile_id\"M\n\x05Group\x12$\n\x04role\x18\x01 \x01(\x0e\x32\x16.meshtastic.MemberRole\x12\x1e\n\x04team\x18\x02 \x01(\x0e\x32\x10.meshtastic.Team\"\x19\n\x06Status\x12\x0f\n\x07\x62\x61ttery\x18\x01 \x01(\r\"4\n\x07\x43ontact\x12\x10\n\x08\x63\x61llsign\x18\x01 \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x02 \x01(\t\"_\n\x03PLI\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\r\n\x05speed\x18\x04 \x01(\r\x12\x0e\n\x06\x63ourse\x18\x05 \x01(\r\"\xb0\x01\n\rAircraftTrack\x12\x0c\n\x04icao\x18\x01 \x01(\t\x12\x14\n\x0cregistration\x18\x02 \x01(\t\x12\x0e\n\x06\x66light\x18\x03 \x01(\t\x12\x15\n\raircraft_type\x18\x04 \x01(\t\x12\x0e\n\x06squawk\x18\x05 \x01(\r\x12\x10\n\x08\x63\x61tegory\x18\x06 \x01(\t\x12\x10\n\x08rssi_x10\x18\x07 \x01(\x11\x12\x0b\n\x03gps\x18\x08 \x01(\x08\x12\x13\n\x0b\x63ot_host_id\x18\t \x01(\t\"7\n\x0b\x43otGeoPoint\x12\x13\n\x0blat_delta_i\x18\x01 \x01(\x11\x12\x13\n\x0blon_delta_i\x18\x02 \x01(\x11\"\xdc\x06\n\nDrawnShape\x12)\n\x04kind\x18\x01 \x01(\x0e\x32\x1b.meshtastic.DrawnShape.Kind\x12/\n\x05style\x18\x02 \x01(\x0e\x32 .meshtastic.DrawnShape.StyleMode\x12\x10\n\x08major_cm\x18\x03 \x01(\r\x12\x10\n\x08minor_cm\x18\x04 \x01(\r\x12\x11\n\tangle_deg\x18\x05 \x01(\r\x12&\n\x0cstroke_color\x18\x06 \x01(\x0e\x32\x10.meshtastic.Team\x12\x13\n\x0bstroke_argb\x18\x07 \x01(\x07\x12\x19\n\x11stroke_weight_x10\x18\x08 \x01(\r\x12$\n\nfill_color\x18\t \x01(\x0e\x32\x10.meshtastic.Team\x12\x11\n\tfill_argb\x18\n \x01(\x07\x12\x11\n\tlabels_on\x18\x0b \x01(\x08\x12\x19\n\x11vertex_lat_deltas\x18\x12 \x03(\x11\x12\x19\n\x11vertex_lon_deltas\x18\x13 \x03(\x11\x12\x11\n\ttruncated\x18\r \x01(\x08\x12\x1c\n\x14\x62ullseye_distance_dm\x18\x0e \x01(\r\x12\x1c\n\x14\x62ullseye_bearing_ref\x18\x0f \x01(\r\x12\x16\n\x0e\x62ullseye_flags\x18\x10 \x01(\r\x12\x18\n\x10\x62ullseye_uid_ref\x18\x11 \x01(\t\"\xe2\x01\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\x0f\n\x0bKind_Circle\x10\x01\x12\x12\n\x0eKind_Rectangle\x10\x02\x12\x11\n\rKind_Freeform\x10\x03\x12\x15\n\x11Kind_Telestration\x10\x04\x12\x10\n\x0cKind_Polygon\x10\x05\x12\x16\n\x12Kind_RangingCircle\x10\x06\x12\x11\n\rKind_Bullseye\x10\x07\x12\x10\n\x0cKind_Ellipse\x10\x08\x12\x12\n\x0eKind_Vehicle2D\x10\t\x12\x12\n\x0eKind_Vehicle3D\x10\n\"u\n\tStyleMode\x12\x19\n\x15StyleMode_Unspecified\x10\x00\x12\x18\n\x14StyleMode_StrokeOnly\x10\x01\x12\x16\n\x12StyleMode_FillOnly\x10\x02\x12\x1b\n\x17StyleMode_StrokeAndFill\x10\x03J\x04\x08\x0c\x10\r\"\xe5\x03\n\x06Marker\x12%\n\x04kind\x18\x01 \x01(\x0e\x32\x17.meshtastic.Marker.Kind\x12\x1f\n\x05\x63olor\x18\x02 \x01(\x0e\x32\x10.meshtastic.Team\x12\x12\n\ncolor_argb\x18\x03 \x01(\x07\x12\x11\n\treadiness\x18\x04 \x01(\x08\x12\x12\n\nparent_uid\x18\x05 \x01(\t\x12\x13\n\x0bparent_type\x18\x06 \x01(\t\x12\x17\n\x0fparent_callsign\x18\x07 \x01(\t\x12\x0f\n\x07iconset\x18\x08 \x01(\t\"\x98\x02\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\r\n\tKind_Spot\x10\x01\x12\x11\n\rKind_Waypoint\x10\x02\x12\x13\n\x0fKind_Checkpoint\x10\x03\x12\x15\n\x11Kind_SelfPosition\x10\x04\x12\x13\n\x0fKind_Symbol2525\x10\x05\x12\x10\n\x0cKind_SpotMap\x10\x06\x12\x13\n\x0fKind_CustomIcon\x10\x07\x12\x12\n\x0eKind_GoToPoint\x10\x08\x12\x15\n\x11Kind_InitialPoint\x10\t\x12\x15\n\x11Kind_ContactPoint\x10\n\x12\x18\n\x14Kind_ObservationPost\x10\x0b\x12\x14\n\x10Kind_ImageMarker\x10\x0c\"\xce\x01\n\x0fRangeAndBearing\x12\'\n\x06\x61nchor\x18\x01 \x01(\x0b\x32\x17.meshtastic.CotGeoPoint\x12\x12\n\nanchor_uid\x18\x02 \x01(\t\x12\x10\n\x08range_cm\x18\x03 \x01(\r\x12\x14\n\x0c\x62\x65\x61ring_cdeg\x18\x04 \x01(\r\x12&\n\x0cstroke_color\x18\x05 \x01(\x0e\x32\x10.meshtastic.Team\x12\x13\n\x0bstroke_argb\x18\x06 \x01(\x07\x12\x19\n\x11stroke_weight_x10\x18\x07 \x01(\r\"\x84\x04\n\x05Route\x12(\n\x06method\x18\x01 \x01(\x0e\x32\x18.meshtastic.Route.Method\x12.\n\tdirection\x18\x02 \x01(\x0e\x32\x1b.meshtastic.Route.Direction\x12\x0e\n\x06prefix\x18\x03 \x01(\t\x12\x19\n\x11stroke_weight_x10\x18\x04 \x01(\r\x12%\n\x05links\x18\x05 \x03(\x0b\x32\x16.meshtastic.Route.Link\x12\x11\n\ttruncated\x18\x06 \x01(\x08\x1a`\n\x04Link\x12&\n\x05point\x18\x01 \x01(\x0b\x32\x17.meshtastic.CotGeoPoint\x12\x0b\n\x03uid\x18\x02 \x01(\t\x12\x10\n\x08\x63\x61llsign\x18\x03 \x01(\t\x12\x11\n\tlink_type\x18\x04 \x01(\r\"\x87\x01\n\x06Method\x12\x16\n\x12Method_Unspecified\x10\x00\x12\x12\n\x0eMethod_Driving\x10\x01\x12\x12\n\x0eMethod_Walking\x10\x02\x12\x11\n\rMethod_Flying\x10\x03\x12\x13\n\x0fMethod_Swimming\x10\x04\x12\x15\n\x11Method_Watercraft\x10\x05\"P\n\tDirection\x12\x19\n\x15\x44irection_Unspecified\x10\x00\x12\x13\n\x0f\x44irection_Infil\x10\x01\x12\x13\n\x0f\x44irection_Exfil\x10\x02\"\xd6\n\n\rCasevacReport\x12\x38\n\nprecedence\x18\x01 \x01(\x0e\x32$.meshtastic.CasevacReport.Precedence\x12\x17\n\x0f\x65quipment_flags\x18\x02 \x01(\r\x12\x17\n\x0flitter_patients\x18\x03 \x01(\r\x12\x1b\n\x13\x61mbulatory_patients\x18\x04 \x01(\r\x12\x34\n\x08security\x18\x05 \x01(\x0e\x32\".meshtastic.CasevacReport.Security\x12\x39\n\x0bhlz_marking\x18\x06 \x01(\x0e\x32$.meshtastic.CasevacReport.HlzMarking\x12\x13\n\x0bzone_marker\x18\x07 \x01(\t\x12\x13\n\x0bus_military\x18\x08 \x01(\r\x12\x13\n\x0bus_civilian\x18\t \x01(\r\x12\x17\n\x0fnon_us_military\x18\n \x01(\r\x12\x17\n\x0fnon_us_civilian\x18\x0b \x01(\r\x12\x0b\n\x03\x65pw\x18\x0c \x01(\r\x12\r\n\x05\x63hild\x18\r \x01(\r\x12\x15\n\rterrain_flags\x18\x0e \x01(\r\x12\x11\n\tfrequency\x18\x0f \x01(\t\x12\r\n\x05title\x18\x10 \x01(\t\x12\x17\n\x0fmedline_remarks\x18\x11 \x01(\t\x12\x14\n\x0curgent_count\x18\x12 \x01(\r\x12\x1d\n\x15urgent_surgical_count\x18\x13 \x01(\r\x12\x16\n\x0epriority_count\x18\x14 \x01(\r\x12\x15\n\rroutine_count\x18\x15 \x01(\r\x12\x19\n\x11\x63onvenience_count\x18\x16 \x01(\r\x12\x18\n\x10\x65quipment_detail\x18\x17 \x01(\t\x12\x1c\n\x14zone_protected_coord\x18\x18 \x01(\t\x12\x19\n\x11terrain_slope_dir\x18\x19 \x01(\t\x12\x1c\n\x14terrain_other_detail\x18\x1a \x01(\t\x12\x11\n\tmarked_by\x18\x1b \x01(\t\x12\x11\n\tobstacles\x18\x1c \x01(\t\x12\x16\n\x0ewinds_are_from\x18\x1d \x01(\t\x12\x12\n\nfriendlies\x18\x1e \x01(\t\x12\r\n\x05\x65nemy\x18\x1f \x01(\t\x12\x13\n\x0bhlz_remarks\x18 \x01(\t\x12%\n\x05zmist\x18! \x03(\x0b\x32\x16.meshtastic.ZMistEntry\"\xab\x01\n\nPrecedence\x12\x1a\n\x16Precedence_Unspecified\x10\x00\x12\x15\n\x11Precedence_Urgent\x10\x01\x12\x1d\n\x19Precedence_UrgentSurgical\x10\x02\x12\x17\n\x13Precedence_Priority\x10\x03\x12\x16\n\x12Precedence_Routine\x10\x04\x12\x1a\n\x16Precedence_Convenience\x10\x05\"\x9b\x01\n\nHlzMarking\x12\x1a\n\x16HlzMarking_Unspecified\x10\x00\x12\x15\n\x11HlzMarking_Panels\x10\x01\x12\x19\n\x15HlzMarking_PyroSignal\x10\x02\x12\x14\n\x10HlzMarking_Smoke\x10\x03\x12\x13\n\x0fHlzMarking_None\x10\x04\x12\x14\n\x10HlzMarking_Other\x10\x05\"\x92\x01\n\x08Security\x12\x18\n\x14Security_Unspecified\x10\x00\x12\x14\n\x10Security_NoEnemy\x10\x01\x12\x1a\n\x16Security_PossibleEnemy\x10\x02\x12\x18\n\x14Security_EnemyInArea\x10\x03\x12 \n\x1cSecurity_EnemyInArmedContact\x10\x04\"R\n\nZMistEntry\x12\r\n\x05title\x18\x01 \x01(\t\x12\t\n\x01z\x18\x02 \x01(\t\x12\t\n\x01m\x18\x03 \x01(\t\x12\t\n\x01i\x18\x04 \x01(\t\x12\t\n\x01s\x18\x05 \x01(\t\x12\t\n\x01t\x18\x06 \x01(\t\"\x8d\x02\n\x0e\x45mergencyAlert\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.meshtastic.EmergencyAlert.Type\x12\x15\n\rauthoring_uid\x18\x02 \x01(\t\x12\x1c\n\x14\x63\x61ncel_reference_uid\x18\x03 \x01(\t\"\x96\x01\n\x04Type\x12\x14\n\x10Type_Unspecified\x10\x00\x12\x11\n\rType_Alert911\x10\x01\x12\x14\n\x10Type_RingTheBell\x10\x02\x12\x12\n\x0eType_InContact\x10\x03\x12\x19\n\x15Type_GeoFenceBreached\x10\x04\x12\x0f\n\x0bType_Custom\x10\x05\x12\x0f\n\x0bType_Cancel\x10\x06\"\xc6\x03\n\x0bTaskRequest\x12\x11\n\ttask_type\x18\x01 \x01(\t\x12\x12\n\ntarget_uid\x18\x02 \x01(\t\x12\x14\n\x0c\x61ssignee_uid\x18\x03 \x01(\t\x12\x32\n\x08priority\x18\x04 \x01(\x0e\x32 .meshtastic.TaskRequest.Priority\x12.\n\x06status\x18\x05 \x01(\x0e\x32\x1e.meshtastic.TaskRequest.Status\x12\x0c\n\x04note\x18\x06 \x01(\t\"u\n\x08Priority\x12\x18\n\x14Priority_Unspecified\x10\x00\x12\x10\n\x0cPriority_Low\x10\x01\x12\x13\n\x0fPriority_Normal\x10\x02\x12\x11\n\rPriority_High\x10\x03\x12\x15\n\x11Priority_Critical\x10\x04\"\x90\x01\n\x06Status\x12\x16\n\x12Status_Unspecified\x10\x00\x12\x12\n\x0eStatus_Pending\x10\x01\x12\x17\n\x13Status_Acknowledged\x10\x02\x12\x15\n\x11Status_InProgress\x10\x03\x12\x14\n\x10Status_Completed\x10\x04\x12\x14\n\x10Status_Cancelled\x10\x05\"`\n\x0eTAKEnvironment\x12\x19\n\x11temperature_c_x10\x18\x01 \x01(\x11\x12\x1a\n\x12wind_direction_deg\x18\x02 \x01(\r\x12\x17\n\x0fwind_speed_cm_s\x18\x03 \x01(\r\"\x8d\x03\n\tSensorFov\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .meshtastic.SensorFov.SensorType\x12\x13\n\x0b\x61zimuth_deg\x18\x02 \x01(\r\x12\x14\n\x07range_m\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\x12\x66ov_horizontal_deg\x18\x04 \x01(\r\x12\x18\n\x10\x66ov_vertical_deg\x18\x05 \x01(\r\x12\x15\n\relevation_deg\x18\x06 \x01(\x11\x12\x10\n\x08roll_deg\x18\x07 \x01(\x11\x12\r\n\x05model\x18\x08 \x01(\t\"\xaa\x01\n\nSensorType\x12\x1a\n\x16SensorType_Unspecified\x10\x00\x12\x15\n\x11SensorType_Camera\x10\x01\x12\x16\n\x12SensorType_Thermal\x10\x02\x12\x14\n\x10SensorType_Laser\x10\x03\x12\x12\n\x0eSensorType_Nvg\x10\x04\x12\x11\n\rSensorType_Rf\x10\x05\x12\x14\n\x10SensorType_Other\x10\x06\x42\n\n\x08_range_m\"U\n\x0eTakTalkMessage\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x13\n\x0b\x63hatroom_id\x18\x02 \x01(\t\x12\x0c\n\x04lang\x18\x03 \x01(\t\x12\x12\n\nfrom_voice\x18\x04 \x01(\x08\"h\n\x0fTakTalkRoomData\x12\x1b\n\x0fsender_callsign\x18\x01 \x01(\tB\x02\x18\x01\x12\x0f\n\x07room_id\x18\x02 \x01(\t\x12\x11\n\troom_name\x18\x03 \x01(\t\x12\x14\n\x0cparticipants\x18\x04 \x03(\t\"\x1e\n\x05Marti\x12\x15\n\rdest_callsign\x18\x01 \x03(\t\"\x99\n\n\x0bTAKPacketV2\x12(\n\x0b\x63ot_type_id\x18\x01 \x01(\x0e\x32\x13.meshtastic.CotType\x12\x1f\n\x03how\x18\x02 \x01(\x0e\x32\x12.meshtastic.CotHow\x12\x10\n\x08\x63\x61llsign\x18\x03 \x01(\t\x12\x1e\n\x04team\x18\x04 \x01(\x0e\x32\x10.meshtastic.Team\x12$\n\x04role\x18\x05 \x01(\x0e\x32\x16.meshtastic.MemberRole\x12\x12\n\nlatitude_i\x18\x06 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x07 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x08 \x01(\x11\x12\r\n\x05speed\x18\t \x01(\r\x12\x0e\n\x06\x63ourse\x18\n \x01(\r\x12\x0f\n\x07\x62\x61ttery\x18\x0b \x01(\r\x12+\n\x07geo_src\x18\x0c \x01(\x0e\x32\x1a.meshtastic.GeoPointSource\x12+\n\x07\x61lt_src\x18\r \x01(\x0e\x32\x1a.meshtastic.GeoPointSource\x12\x0b\n\x03uid\x18\x0e \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x0f \x01(\t\x12\x15\n\rstale_seconds\x18\x10 \x01(\r\x12\x13\n\x0btak_version\x18\x11 \x01(\t\x12\x12\n\ntak_device\x18\x12 \x01(\t\x12\x14\n\x0ctak_platform\x18\x13 \x01(\t\x12\x0e\n\x06tak_os\x18\x14 \x01(\t\x12\x10\n\x08\x65ndpoint\x18\x15 \x01(\t\x12\r\n\x05phone\x18\x16 \x01(\t\x12\x14\n\x0c\x63ot_type_str\x18\x17 \x01(\t\x12\x0f\n\x07remarks\x18\x18 \x01(\t\x12\x34\n\x0b\x65nvironment\x18\x19 \x01(\x0b\x32\x1a.meshtastic.TAKEnvironmentH\x01\x88\x01\x01\x12.\n\nsensor_fov\x18\x1a \x01(\x0b\x32\x15.meshtastic.SensorFovH\x02\x88\x01\x01\x12%\n\x05marti\x18\x1d \x01(\x0b\x32\x11.meshtastic.MartiH\x03\x88\x01\x01\x12#\n\x04\x63hat\x18\x1f \x01(\x0b\x32\x13.meshtastic.GeoChatH\x00\x12-\n\x08\x61ircraft\x18 \x01(\x0b\x32\x19.meshtastic.AircraftTrackH\x00\x12\x14\n\nraw_detail\x18! \x01(\x0cH\x00\x12\'\n\x05shape\x18\" \x01(\x0b\x32\x16.meshtastic.DrawnShapeH\x00\x12$\n\x06marker\x18# \x01(\x0b\x32\x12.meshtastic.MarkerH\x00\x12*\n\x03rab\x18$ \x01(\x0b\x32\x1b.meshtastic.RangeAndBearingH\x00\x12\"\n\x05route\x18% \x01(\x0b\x32\x11.meshtastic.RouteH\x00\x12,\n\x07\x63\x61sevac\x18& \x01(\x0b\x32\x19.meshtastic.CasevacReportH\x00\x12/\n\temergency\x18\' \x01(\x0b\x32\x1a.meshtastic.EmergencyAlertH\x00\x12\'\n\x04task\x18( \x01(\x0b\x32\x17.meshtastic.TaskRequestH\x00\x12-\n\x07taktalk\x18) \x01(\x0b\x32\x1a.meshtastic.TakTalkMessageH\x00\x12\x33\n\x0ctaktalk_room\x18* \x01(\x0b\x32\x1b.meshtastic.TakTalkRoomDataH\x00\x42\x11\n\x0fpayload_variantB\x0e\n\x0c_environmentB\r\n\x0b_sensor_fovB\x08\n\x06_martiJ\x04\x08\x1b\x10\x1cJ\x04\x08\x1c\x10\x1dJ\x04\x08\x1e\x10\x1f*\x96\x03\n\x04Team\x12*\n\x10Unspecifed_Color\x10\x00\x1a\x14\xca\xf3\x18\x10:\x0e\x44\x65\x66\x61ult (Cyan)\x12\x16\n\x05White\x10\x01\x1a\x0b\xca\xf3\x18\x07:\x05White\x12\x18\n\x06Yellow\x10\x02\x1a\x0c\xca\xf3\x18\x08:\x06Yellow\x12\x18\n\x06Orange\x10\x03\x1a\x0c\xca\xf3\x18\x08:\x06Orange\x12\x1a\n\x07Magenta\x10\x04\x1a\r\xca\xf3\x18\t:\x07Magenta\x12\x12\n\x03Red\x10\x05\x1a\t\xca\xf3\x18\x05:\x03Red\x12\x18\n\x06Maroon\x10\x06\x1a\x0c\xca\xf3\x18\x08:\x06Maroon\x12\x18\n\x06Purple\x10\x07\x1a\x0c\xca\xf3\x18\x08:\x06Purple\x12\x1e\n\tDark_Blue\x10\x08\x1a\x0f\xca\xf3\x18\x0b:\tDark Blue\x12\x14\n\x04\x42lue\x10\t\x1a\n\xca\xf3\x18\x06:\x04\x42lue\x12\x14\n\x04\x43yan\x10\n\x1a\n\xca\xf3\x18\x06:\x04\x43yan\x12\x14\n\x04Teal\x10\x0b\x1a\n\xca\xf3\x18\x06:\x04Teal\x12\x16\n\x05Green\x10\x0c\x1a\x0b\xca\xf3\x18\x07:\x05Green\x12 \n\nDark_Green\x10\r\x1a\x10\xca\xf3\x18\x0c:\nDark Green\x12\x16\n\x05\x42rown\x10\x0e\x1a\x0b\xca\xf3\x18\x07:\x05\x42rown*\x92\x02\n\nMemberRole\x12+\n\nUnspecifed\x10\x00\x1a\x1b\xca\xf3\x18\x17:\x15\x44\x65\x66\x61ult (Team Member)\x12!\n\nTeamMember\x10\x01\x1a\x11\xca\xf3\x18\r:\x0bTeam Member\x12\x1d\n\x08TeamLead\x10\x02\x1a\x0f\xca\xf3\x18\x0b:\tTeam Lead\x12\x10\n\x02HQ\x10\x03\x1a\x08\xca\xf3\x18\x04:\x02HQ\x12\x18\n\x06Sniper\x10\x04\x1a\x0c\xca\xf3\x18\x08:\x06Sniper\x12\x16\n\x05Medic\x10\x05\x1a\x0b\xca\xf3\x18\x07:\x05Medic\x12+\n\x0f\x46orwardObserver\x10\x06\x1a\x16\xca\xf3\x18\x12:\x10\x46orward Observer\x12\x12\n\x03RTO\x10\x07\x1a\t\xca\xf3\x18\x05:\x03RTO\x12\x10\n\x02K9\x10\x08\x1a\x08\xca\xf3\x18\x04:\x02K9*\x96\x01\n\x06\x43otHow\x12\x16\n\x12\x43otHow_Unspecified\x10\x00\x12\x0e\n\nCotHow_h_e\x10\x01\x12\x0e\n\nCotHow_m_g\x10\x02\x12\x14\n\x10\x43otHow_h_g_i_g_o\x10\x03\x12\x0e\n\nCotHow_m_r\x10\x04\x12\x0e\n\nCotHow_m_f\x10\x05\x12\x0e\n\nCotHow_m_p\x10\x06\x12\x0e\n\nCotHow_m_s\x10\x07*\x83\x17\n\x07\x43otType\x12\x11\n\rCotType_Other\x10\x00\x12\x15\n\x11\x43otType_a_f_G_U_C\x10\x01\x12\x17\n\x13\x43otType_a_f_G_U_C_I\x10\x02\x12\x15\n\x11\x43otType_a_n_A_C_F\x10\x03\x12\x15\n\x11\x43otType_a_n_A_C_H\x10\x04\x12\x13\n\x0f\x43otType_a_n_A_C\x10\x05\x12\x15\n\x11\x43otType_a_f_A_M_H\x10\x06\x12\x13\n\x0f\x43otType_a_f_A_M\x10\x07\x12\x17\n\x13\x43otType_a_f_A_M_F_F\x10\x08\x12\x17\n\x13\x43otType_a_f_A_M_H_A\x10\t\x12\x19\n\x15\x43otType_a_f_A_M_H_U_M\x10\n\x12\x17\n\x13\x43otType_a_h_A_M_F_F\x10\x0b\x12\x17\n\x13\x43otType_a_h_A_M_H_A\x10\x0c\x12\x13\n\x0f\x43otType_a_u_A_C\x10\r\x12\x13\n\x0f\x43otType_t_x_d_d\x10\x0e\x12\x17\n\x13\x43otType_a_f_G_E_S_E\x10\x0f\x12\x17\n\x13\x43otType_a_f_G_E_V_C\x10\x10\x12\x11\n\rCotType_a_f_S\x10\x11\x12\x15\n\x11\x43otType_a_f_A_M_F\x10\x12\x12\x19\n\x15\x43otType_a_f_A_M_F_C_H\x10\x13\x12\x19\n\x15\x43otType_a_f_A_M_F_U_L\x10\x14\x12\x17\n\x13\x43otType_a_f_A_M_F_L\x10\x15\x12\x17\n\x13\x43otType_a_f_A_M_F_P\x10\x16\x12\x15\n\x11\x43otType_a_f_A_C_H\x10\x17\x12\x17\n\x13\x43otType_a_n_A_M_F_Q\x10\x18\x12\x11\n\rCotType_b_t_f\x10\x19\x12\x15\n\x11\x43otType_b_r_f_h_c\x10\x1a\x12\x15\n\x11\x43otType_b_a_o_pan\x10\x1b\x12\x15\n\x11\x43otType_b_a_o_opn\x10\x1c\x12\x15\n\x11\x43otType_b_a_o_can\x10\x1d\x12\x15\n\x11\x43otType_b_a_o_tbl\x10\x1e\x12\x11\n\rCotType_b_a_g\x10\x1f\x12\x11\n\rCotType_a_f_G\x10 \x12\x13\n\x0f\x43otType_a_f_G_U\x10!\x12\x11\n\rCotType_a_h_G\x10\"\x12\x11\n\rCotType_a_u_G\x10#\x12\x11\n\rCotType_a_n_G\x10$\x12\x11\n\rCotType_b_m_r\x10%\x12\x13\n\x0f\x43otType_b_m_p_w\x10&\x12\x17\n\x13\x43otType_b_m_p_s_p_i\x10\'\x12\x11\n\rCotType_u_d_f\x10(\x12\x11\n\rCotType_u_d_r\x10)\x12\x13\n\x0f\x43otType_u_d_c_c\x10*\x12\x12\n\x0e\x43otType_u_rb_a\x10+\x12\x11\n\rCotType_a_h_A\x10,\x12\x11\n\rCotType_a_u_A\x10-\x12\x17\n\x13\x43otType_a_f_A_M_H_Q\x10.\x12\x15\n\x11\x43otType_a_f_A_C_F\x10/\x12\x13\n\x0f\x43otType_a_f_A_C\x10\x30\x12\x15\n\x11\x43otType_a_f_A_C_L\x10\x31\x12\x11\n\rCotType_a_f_A\x10\x32\x12\x17\n\x13\x43otType_a_f_A_M_H_C\x10\x33\x12\x17\n\x13\x43otType_a_n_A_M_F_F\x10\x34\x12\x15\n\x11\x43otType_a_u_A_C_F\x10\x35\x12\x1b\n\x17\x43otType_a_f_G_U_C_F_T_A\x10\x36\x12\x19\n\x15\x43otType_a_f_G_U_C_V_S\x10\x37\x12\x19\n\x15\x43otType_a_f_G_U_C_R_X\x10\x38\x12\x19\n\x15\x43otType_a_f_G_U_C_I_Z\x10\x39\x12\x1b\n\x17\x43otType_a_f_G_U_C_E_C_W\x10:\x12\x19\n\x15\x43otType_a_f_G_U_C_I_L\x10;\x12\x19\n\x15\x43otType_a_f_G_U_C_R_O\x10<\x12\x19\n\x15\x43otType_a_f_G_U_C_R_V\x10=\x12\x15\n\x11\x43otType_a_f_G_U_H\x10>\x12\x1b\n\x17\x43otType_a_f_G_U_U_M_S_E\x10?\x12\x19\n\x15\x43otType_a_f_G_U_S_M_C\x10@\x12\x15\n\x11\x43otType_a_f_G_E_S\x10\x41\x12\x13\n\x0f\x43otType_a_f_G_E\x10\x42\x12\x19\n\x15\x43otType_a_f_G_E_V_C_U\x10\x43\x12\x1a\n\x16\x43otType_a_f_G_E_V_C_ps\x10\x44\x12\x15\n\x11\x43otType_a_u_G_E_V\x10\x45\x12\x17\n\x13\x43otType_a_f_S_N_N_R\x10\x46\x12\x13\n\x0f\x43otType_a_f_F_B\x10G\x12\x19\n\x15\x43otType_b_m_p_s_p_loc\x10H\x12\x11\n\rCotType_b_i_v\x10I\x12\x13\n\x0f\x43otType_b_f_t_r\x10J\x12\x13\n\x0f\x43otType_b_f_t_a\x10K\x12\x13\n\x0f\x43otType_u_d_f_m\x10L\x12\x11\n\rCotType_u_d_p\x10M\x12\x15\n\x11\x43otType_b_m_p_s_m\x10N\x12\x13\n\x0f\x43otType_b_m_p_c\x10O\x12\x15\n\x11\x43otType_u_r_b_c_c\x10P\x12\x1a\n\x16\x43otType_u_r_b_bullseye\x10Q\x12\x17\n\x13\x43otType_a_f_G_E_V_A\x10R\x12\x11\n\rCotType_a_n_A\x10S\x12\x17\n\x13\x43otType_a_u_G_U_C_F\x10T\x12\x17\n\x13\x43otType_a_n_G_U_C_F\x10U\x12\x17\n\x13\x43otType_a_h_G_U_C_F\x10V\x12\x17\n\x13\x43otType_a_f_G_U_C_F\x10W\x12\x13\n\x0f\x43otType_a_u_G_I\x10X\x12\x13\n\x0f\x43otType_a_n_G_I\x10Y\x12\x13\n\x0f\x43otType_a_h_G_I\x10Z\x12\x13\n\x0f\x43otType_a_f_G_I\x10[\x12\x17\n\x13\x43otType_a_u_G_E_X_M\x10\\\x12\x17\n\x13\x43otType_a_n_G_E_X_M\x10]\x12\x17\n\x13\x43otType_a_h_G_E_X_M\x10^\x12\x17\n\x13\x43otType_a_f_G_E_X_M\x10_\x12\x11\n\rCotType_a_u_S\x10`\x12\x11\n\rCotType_a_n_S\x10\x61\x12\x11\n\rCotType_a_h_S\x10\x62\x12\x19\n\x15\x43otType_a_u_G_U_C_I_d\x10\x63\x12\x19\n\x15\x43otType_a_n_G_U_C_I_d\x10\x64\x12\x19\n\x15\x43otType_a_h_G_U_C_I_d\x10\x65\x12\x19\n\x15\x43otType_a_f_G_U_C_I_d\x10\x66\x12\x19\n\x15\x43otType_a_u_G_E_V_A_T\x10g\x12\x19\n\x15\x43otType_a_n_G_E_V_A_T\x10h\x12\x19\n\x15\x43otType_a_h_G_E_V_A_T\x10i\x12\x19\n\x15\x43otType_a_f_G_E_V_A_T\x10j\x12\x17\n\x13\x43otType_a_u_G_U_C_I\x10k\x12\x17\n\x13\x43otType_a_n_G_U_C_I\x10l\x12\x17\n\x13\x43otType_a_h_G_U_C_I\x10m\x12\x15\n\x11\x43otType_a_n_G_E_V\x10n\x12\x15\n\x11\x43otType_a_h_G_E_V\x10o\x12\x15\n\x11\x43otType_a_f_G_E_V\x10p\x12\x18\n\x14\x43otType_b_m_p_w_GOTO\x10q\x12\x16\n\x12\x43otType_b_m_p_c_ip\x10r\x12\x16\n\x12\x43otType_b_m_p_c_cp\x10s\x12\x18\n\x14\x43otType_b_m_p_s_p_op\x10t\x12\x11\n\rCotType_u_d_v\x10u\x12\x13\n\x0f\x43otType_u_d_v_m\x10v\x12\x13\n\x0f\x43otType_u_d_c_e\x10w\x12\x13\n\x0f\x43otType_b_i_x_i\x10x\x12\x13\n\x0f\x43otType_b_t_f_d\x10y\x12\x13\n\x0f\x43otType_b_t_f_r\x10z\x12\x13\n\x0f\x43otType_b_a_o_c\x10{\x12\x0f\n\x0b\x43otType_t_s\x10|\x12\x11\n\rCotType_m_t_t\x10}\x12\r\n\tCotType_y\x10~*}\n\x0eGeoPointSource\x12\x1e\n\x1aGeoPointSource_Unspecified\x10\x00\x12\x16\n\x12GeoPointSource_GPS\x10\x01\x12\x17\n\x13GeoPointSource_USER\x10\x02\x12\x1a\n\x16GeoPointSource_NETWORK\x10\x03\x42`\n\x14org.meshtastic.protoB\nATAKProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
9
11
 
10
12
  pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
13
  pool.add_serialized_file(descriptor_data)
@@ -8,7 +8,7 @@ require 'meshtastic/device_ui_pb'
8
8
  require 'meshtastic/field_metadata_pb'
9
9
 
10
10
 
11
- descriptor_data = "\n\x17meshtastic/config.proto\x12\nmeshtastic\x1a\x1ameshtastic/device_ui.proto\x1a\x1fmeshtastic/field_metadata.proto\"\xe2g\n\x06\x43onfig\x12\x31\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x1f.meshtastic.Config.DeviceConfigH\x00\x12\x35\n\x08position\x18\x02 \x01(\x0b\x32!.meshtastic.Config.PositionConfigH\x00\x12/\n\x05power\x18\x03 \x01(\x0b\x32\x1e.meshtastic.Config.PowerConfigH\x00\x12\x33\n\x07network\x18\x04 \x01(\x0b\x32 .meshtastic.Config.NetworkConfigH\x00\x12\x33\n\x07\x64isplay\x18\x05 \x01(\x0b\x32 .meshtastic.Config.DisplayConfigH\x00\x12-\n\x04lora\x18\x06 \x01(\x0b\x32\x1d.meshtastic.Config.LoRaConfigH\x00\x12\x37\n\tbluetooth\x18\x07 \x01(\x0b\x32\".meshtastic.Config.BluetoothConfigH\x00\x12\x35\n\x08security\x18\x08 \x01(\x0b\x32!.meshtastic.Config.SecurityConfigH\x00\x12\x39\n\nsessionkey\x18\t \x01(\x0b\x32#.meshtastic.Config.SessionkeyConfigH\x00\x12/\n\tdevice_ui\x18\n \x01(\x0b\x32\x1a.meshtastic.DeviceUIConfigH\x00\x1a\xa2\x1c\n\x0c\x44\x65viceConfig\x12\x45\n\x04role\x18\x01 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.RoleB\x11\xca\xf3\x18\r:\x0b\x44\x65vice Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12&\n\x0b\x62utton_gpio\x18\x04 \x01(\rB\x11\xca\xf3\x18\r:\x0b\x42utton GPIO\x12&\n\x0b\x62uzzer_gpio\x18\x05 \x01(\rB\x11\xca\xf3\x18\r:\x0b\x42uzzer GPIO\x12\x61\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32/.meshtastic.Config.DeviceConfig.RebroadcastModeB\x16\xca\xf3\x18\x12:\x10Rebroadcast Mode\x12G\n\x18node_info_broadcast_secs\x18\x07 \x01(\rB%\xca\xf3\x18!*\x01s:\x1cNode Info Broadcast Interval\x12\x84\x01\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x42`\xca\xf3\x18\\:\x14\x44ouble Tap as ButtonBDTreat double tap on supported accelerometers as a user button press.\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12i\n\x14\x64isable_triple_click\x18\n \x01(\x08\x42K\xca\xf3\x18G:\x14\x44isable Triple ClickB/Disables the user button triple-press shortcut.\x12\x1e\n\x05tzdef\x18\x0b \x01(\tB\x0f\xca\xf3\x18\x0b:\tTime Zone\x12\xcc\x01\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\x42\xab\x01\xca\xf3\x18\xa6\x01:\rLED HeartbeatB\x94\x01\x43ontrols the blinking LED on the device. For most devices this will control one of the up to 4 LEDS, the charger and GPS LEDs are not controllable.\x12?\n\x0b\x62uzzer_mode\x18\r \x01(\x0e\x32*.meshtastic.Config.DeviceConfig.BuzzerMode\"\xc1\x0b\n\x04Role\x12H\n\x06\x43LIENT\x10\x00\x1a<\xca\xf3\x18\x38:\x06\x43lientB.App connected or stand alone messaging device.\x12\\\n\x0b\x43LIENT_MUTE\x10\x01\x1aK\xca\xf3\x18G:\x0b\x43lient MuteB8Device that does not forward packets from other devices.\x12\xb0\x01\n\x06ROUTER\x10\x02\x1a\xa3\x01\xca\xf3\x18\x9e\x01:\x06RouterB\x93\x01Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Needs exceptional coverage. Visible in Nodes list.\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\xb3\x01\n\x08REPEATER\x10\x04\x1a\xa4\x01\x08\x01\xca\xf3\x18\x9d\x01:\x08RepeaterB\x90\x01\x44\x65precated infrastructure role that creates gaps in the mesh rebroadcast chain. Switch this node to a Router-based role (Router or Router Late).\x12H\n\x07TRACKER\x10\x05\x1a;\xca\xf3\x18\x37:\x07TrackerB,Broadcasts GPS position packets as priority.\x12\x43\n\x06SENSOR\x10\x06\x1a\x37\xca\xf3\x18\x33:\x06SensorB)Broadcasts telemetry packets as priority.\x12X\n\x03TAK\x10\x07\x1aO\xca\xf3\x18K:\x03TAKBDOptimized for ATAK system communication, reduces routine broadcasts.\x12k\n\rCLIENT_HIDDEN\x10\x08\x1aX\xca\xf3\x18T:\rClient HiddenBCDevice that only broadcasts as needed for stealth or power savings.\x12\x89\x01\n\x0eLOST_AND_FOUND\x10\t\x1au\xca\xf3\x18q:\x0eLost and FoundB_Broadcasts location as message to default channel regularly for to assist with device recovery.\x12h\n\x0bTAK_TRACKER\x10\n\x1aW\xca\xf3\x18S:\x0bTAK TrackerBDEnables automatic TAK PLI broadcasts and reduces routine broadcasts.\x12\xbc\x01\n\x0bROUTER_LATE\x10\x0b\x1a\xaa\x01\xca\xf3\x18\xa5\x01:\x0bRouter LateB\x95\x01Infrastructure node that always rebroadcasts packets once but only after all other modes. Visible in Nodes list. Not a good choice for rooftop nodes.\x12\x85\x01\n\x0b\x43LIENT_BASE\x10\x0c\x1at\xca\xf3\x18p:\x0b\x43lient BaseBaUsed for rooftop nodes to distribute messages more widely from multiple nearby client mute nodes.\"\xc9\x08\n\x0fRebroadcastMode\x12\x8a\x01\n\x03\x41LL\x10\x00\x1a\x80\x01\xca\xf3\x18|:\x03\x41llBuRebroadcast any observed message, if it was on our private channel or from another channel with the same lora params.\x12\xe0\x01\n\x11\x41LL_SKIP_DECODING\x10\x01\x1a\xc8\x01\xca\xf3\x18\xc3\x01:\x11\x41ll Skip DecodingB\xad\x01Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. Only available in Repeater role. Setting this on any other roles will result in ALL behavior.\x12\xcd\x01\n\nLOCAL_ONLY\x10\x02\x1a\xbc\x01\xca\xf3\x18\xb7\x01:\nLocal OnlyB\xa8\x01Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts message on the nodes local primary / secondary channels.\x12\xc8\x01\n\nKNOWN_ONLY\x10\x03\x1a\xb7\x01\xca\xf3\x18\xb2\x01:\nKnown OnlyB\xa3\x01Ignores observed messages from foreign meshes like Local Only, but takes it step further by also ignoring messages from nodes not already in the node\'s known list.\x12\x92\x01\n\x04NONE\x10\x04\x1a\x87\x01\xca\xf3\x18\x82\x01:\x04NoneBzOnly permitted for SENSOR, TRACKER and TAK_TRACKER roles, this will inhibit all rebroadcasts, not unlike CLIENT_MUTE role.\x12\x95\x01\n\x12\x43ORE_PORTNUMS_ONLY\x10\x05\x1a}\xca\xf3\x18y:\x12\x43ore Portnums OnlyBcOnly rebroadcasts packets from the core portnums: NodeInfo, Text, Position, Telemetry, and Routing.\"i\n\nBuzzerMode\x12\x0f\n\x0b\x41LL_ENABLED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x16\n\x12NOTIFICATIONS_ONLY\x10\x02\x12\x0f\n\x0bSYSTEM_ONLY\x10\x03\x12\x13\n\x0f\x44IRECT_MSG_ONLY\x10\x04\x1a\x82\t\n\x0ePositionConfig\x12<\n\x17position_broadcast_secs\x18\x01 \x01(\rB\x1b\xca\xf3\x18\x17*\x01s:\x12\x42roadcast Interval\x12>\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x42\x14\xca\xf3\x18\x10:\x0eSmart Position\x12\xb2\x01\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x42\x99\x01\xca\xf3\x18\x94\x01:\x0e\x46ixed PositionB\x81\x01The last known latitude, longitude and altitude are broadcast over the mesh on the position interval, rather than a live GPS fix.\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x35\n\x13gps_update_interval\x18\x05 \x01(\rB\x18\xca\xf3\x18\x14*\x01s:\x0fUpdate Interval\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12)\n\x07rx_gpio\x18\x08 \x01(\rB\x18\xca\xf3\x18\x14\x08\x01:\x10GPS Receive GPIO\x12*\n\x07tx_gpio\x18\t \x01(\rB\x19\xca\xf3\x18\x15\x08\x01:\x11GPS Transmit GPIO\x12\x43\n broadcast_smart_minimum_distance\x18\n \x01(\rB\x19\xca\xf3\x18\x15*\x01m:\x10Minimum Distance\x12H\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\rB\x19\xca\xf3\x18\x15*\x01s:\x10Minimum Interval\x12&\n\x0bgps_en_gpio\x18\x0c \x01(\rB\x11\xca\xf3\x18\r:\x0bGPS EN GPIO\x12;\n\x08gps_mode\x18\r \x01(\x0e\x32).meshtastic.Config.PositionConfig.GpsMode\"\x82\x02\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x63\n\x08\x41LTITUDE\x10\x01\x1aU\xca\xf3\x18Q:\x08\x41ltitudeBEInclude an altitude value in position reports, when one is available.\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"g\n\x07GpsMode\x12\x1c\n\x08\x44ISABLED\x10\x00\x1a\x0e\xca\xf3\x18\n:\x08\x44isabled\x12\x1a\n\x07\x45NABLED\x10\x01\x1a\r\xca\xf3\x18\t:\x07\x45nabled\x12\"\n\x0bNOT_PRESENT\x10\x02\x1a\x11\xca\xf3\x18\r:\x0bNot Present\x1a\xbb\x04\n\x0bPowerConfig\x12\x98\x02\n\x0fis_power_saving\x18\x01 \x01(\x08\x42\xfe\x01\xca\xf3\x18\xf9\x01:\x0cPower SavingB\xe8\x01Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don\'t use this setting if you want to use your device with the phone apps or are using a device without a user button.\x12G\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\rB\x1f\xca\xf3\x18\x1b*\x01s:\x16Shutdown on Power Loss\x12\x33\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x42\x12\xca\xf3\x18\x0e:\x0c\x41\x44\x43 Override\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\xc5\x06\n\rNetworkConfig\x12i\n\x0cwifi_enabled\x18\x01 \x01(\x08\x42S\xca\xf3\x18O:\x0cWiFi EnabledB?Enabling WiFi will disable the bluetooth connection to the app.\x12\x1d\n\twifi_ssid\x18\x03 \x01(\tB\n\xca\xf3\x18\x06:\x04SSID\x12 \n\x08wifi_psk\x18\x04 \x01(\tB\x0e\xca\xf3\x18\n:\x08Password\x12$\n\nntp_server\x18\x05 \x01(\tB\x10\xca\xf3\x18\x0c:\nNTP Server\x12p\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x42[\xca\xf3\x18W:\x10\x45thernet EnabledBCEnabling Ethernet will disable the bluetooth connection to the app.\x12V\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32,.meshtastic.Config.NetworkConfig.AddressModeB\x12\xca\xf3\x18\x0e:\x0c\x41\x64\x64ress Mode\x12@\n\x0bipv4_config\x18\x08 \x01(\x0b\x32+.meshtastic.Config.NetworkConfig.IpV4Config\x12,\n\x0ersyslog_server\x18\t \x01(\tB\x14\xca\xf3\x18\x10:\x0eRsyslog Server\x12o\n\x11\x65nabled_protocols\x18\n \x01(\rBT\xca\xf3\x18P:\x11\x45nabled ProtocolsB;Enable broadcasting packets via UDP over the local network.\x12\x14\n\x0cipv6_enabled\x18\x0b \x01(\x08\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\"4\n\rProtocolFlags\x12\x10\n\x0cNO_BROADCAST\x10\x00\x12\x11\n\rUDP_BROADCAST\x10\x01\x1a\xbc\x0f\n\rDisplayConfig\x12.\n\x0escreen_on_secs\x18\x01 \x01(\rB\x16\xca\xf3\x18\x12*\x01s:\rScreen on for\x12V\n\ngps_format\x18\x02 \x01(\x0e\x32>.meshtastic.Config.DisplayConfig.DeprecatedGpsCoordinateFormatB\x02\x18\x01\x12=\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\rB\x1a\xca\xf3\x18\x16*\x01s:\x11\x43\x61rousel Interval\x12\x87\x01\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x42l\x18\x01\xca\xf3\x18\x66:\x12\x41lways point northBPThe compass heading on the screen outside of the circle will always point north.\x12>\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x42)\xca\xf3\x18%:\x0b\x46lip ScreenB\x16\x46lip screen vertically\x12Q\n\x05units\x18\x06 \x01(\x0e\x32-.meshtastic.Config.DisplayConfig.DisplayUnitsB\x13\xca\xf3\x18\x0f:\rDisplay Units\x12H\n\x04oled\x18\x07 \x01(\x0e\x32).meshtastic.Config.DisplayConfig.OledTypeB\x0f\xca\xf3\x18\x0b:\tOLED Type\x12U\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32,.meshtastic.Config.DisplayConfig.DisplayModeB\x12\xca\xf3\x18\x0e:\x0c\x44isplay Mode\x12N\n\x0cheading_bold\x18\t \x01(\x08\x42\x38\xca\xf3\x18\x34:\x0c\x42old HeadingB$Bold the heading text on the screen.\x12z\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x42[\xca\xf3\x18W:\x1cWake Screen on tap or motionB7Requires that there be an accelerometer on your device.\x12k\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32\x33.meshtastic.Config.DisplayConfig.CompassOrientationB\x19\xca\xf3\x18\x15:\x13\x43ompass Orientation\x12T\n\ruse_12h_clock\x18\x0c \x01(\x08\x42=\xca\xf3\x18\x39:\r12 Hour ClockB(Sets the screen clock format to 12-hour.\x12\x1a\n\x12use_long_node_name\x18\r \x01(\x08\x12\x1e\n\x16\x65nable_message_bubbles\x18\x0e \x01(\x08\"+\n\x1d\x44\x65precatedGpsCoordinateFormat\x12\n\n\x06UNUSED\x10\x00\"F\n\x0c\x44isplayUnits\x12\x18\n\x06METRIC\x10\x00\x1a\x0c\xca\xf3\x18\x08:\x06Metric\x12\x1c\n\x08IMPERIAL\x10\x01\x1a\x0e\xca\xf3\x18\n:\x08Imperial\"\xc9\x01\n\x08OledType\x12)\n\tOLED_AUTO\x10\x00\x1a\x1a\xca\xf3\x18\x16:\x14\x44\x65tect Automatically\x12 \n\x0cOLED_SSD1306\x10\x01\x1a\x0e\xca\xf3\x18\n:\x08SSD 1306\x12\x1e\n\x0bOLED_SH1106\x10\x02\x1a\r\xca\xf3\x18\t:\x07SH 1106\x12\x1e\n\x0bOLED_SH1107\x10\x03\x1a\r\xca\xf3\x18\t:\x07SH 1107\x12\x17\n\x13OLED_SH1107_128_128\x10\x04\x12\x17\n\x13OLED_SH1107_ROTATED\x10\x05\"\xd6\x01\n\x0b\x44isplayMode\x12/\n\x07\x44\x45\x46\x41ULT\x10\x00\x1a\"\xca\xf3\x18\x1e:\x1c\x44\x65\x66\x61ult 128x64 screen layout\x12\x32\n\x08TWOCOLOR\x10\x01\x1a$\xca\xf3\x18 :\x1eOptimized for 2 color displays\x12\x38\n\x08INVERTED\x10\x02\x1a*\xca\xf3\x18&:$Inverted top bar for 2 Color display\x12(\n\x05\x43OLOR\x10\x03\x1a\x1d\xca\xf3\x18\x19:\x17TFT Full Color Displays\"\xc0\x02\n\x12\x43ompassOrientation\x12\x18\n\tDEGREES_0\x10\x00\x1a\t\xca\xf3\x18\x05:\x03\x30\xc2\xb0\x12\x1a\n\nDEGREES_90\x10\x01\x1a\n\xca\xf3\x18\x06:\x04\x39\x30\xc2\xb0\x12\x1c\n\x0b\x44\x45GREES_180\x10\x02\x1a\x0b\xca\xf3\x18\x07:\x05\x31\x38\x30\xc2\xb0\x12\x1c\n\x0b\x44\x45GREES_270\x10\x03\x1a\x0b\xca\xf3\x18\x07:\x05\x32\x37\x30\xc2\xb0\x12*\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x1a\x12\xca\xf3\x18\x0e:\x0c\x30\xc2\xb0 Inverted\x12,\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x1a\x13\xca\xf3\x18\x0f:\r90\xc2\xb0 Inverted\x12.\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x1a\x14\xca\xf3\x18\x10:\x0e\x31\x38\x30\xc2\xb0 Inverted\x12.\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\x14\xca\xf3\x18\x10:\x0e\x32\x37\x30\xc2\xb0 Inverted\x1a\xb6\x1b\n\nLoRaConfig\x12$\n\nuse_preset\x18\x01 \x01(\x08\x42\x10\xca\xf3\x18\x0c:\nUse Preset\x12N\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32).meshtastic.Config.LoRaConfig.ModemPresetB\r\xca\xf3\x18\t:\x07Presets\x12\'\n\tbandwidth\x18\x03 \x01(\rB\x14\xca\xf3\x18\x10*\x03kHz:\tBandwidth\x12*\n\rspread_factor\x18\x04 \x01(\rB\x13\xca\xf3\x18\x0f:\rSpread Factor\x12&\n\x0b\x63oding_rate\x18\x05 \x01(\rB\x11\xca\xf3\x18\r:\x0b\x43oding Rate\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x46\n\x06region\x18\x07 \x01(\x0e\x32(.meshtastic.Config.LoRaConfig.RegionCodeB\x0c\xca\xf3\x18\x08:\x06Region\x12\x9d\x01\n\thop_limit\x18\x08 \x01(\rB\x89\x01\xca\xf3\x18\x84\x01\x19\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x1c@:\tHop LimitBIHow many times a message may be repeated before it stops being forwarded.J\x1ahops|ttl|range|rebroadcast\x12*\n\ntx_enabled\x18\t \x01(\x08\x42\x16\xca\xf3\x18\x12:\x10Transmit Enabled\x12\xd3\x01\n\x08tx_power\x18\n \x01(\x05\x42\xc0\x01\xca\xf3\x18\xbb\x01\x19\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00>@*\x03\x64\x42m:\x0eTransmit PowerBxRadio transmit power. Leave at zero to use the highest level legal for the region, which is what most radios should use.J\x18tx|power|dbm|output|gain\x12\xe0\x01\n\x0b\x63hannel_num\x18\x0b \x01(\rB\xca\x01\xca\xf3\x18\xc5\x01:\x0e\x46requency SlotB\xb2\x01Your node\xe2\x80\x99s operating frequency is calculated based on the region, modem preset, and this field. When 0, the slot is automatically calculated based on the primary channel name.\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x35\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x42\x15\xca\xf3\x18\x11:\x0fRX Boosted Gain\x12\x34\n\x12override_frequency\x18\x0e \x01(\x02\x42\x18\xca\xf3\x18\x14:\x12\x46requency Override\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12&\n\x0bignore_mqtt\x18h \x01(\x08\x42\x11\xca\xf3\x18\r:\x0bIgnore MQTT\x12+\n\x11\x63onfig_ok_to_mqtt\x18i \x01(\x08\x42\x10\xca\xf3\x18\x0c:\nOk to MQTT\x12@\n\x0c\x66\x65m_lna_mode\x18j \x01(\x0e\x32*.meshtastic.Config.LoRaConfig.FEM_LNA_Mode\x12\x17\n\x0fserial_hal_only\x18k \x01(\x08\"\xe5\n\n\nRegionCode\x12$\n\x05UNSET\x10\x00\x1a\x19\xca\xf3\x18\x15:\x13Please set a region\x12\x1b\n\x02US\x10\x01\x1a\x13\xca\xf3\x18\x0f:\rUnited States\x12\'\n\x06\x45U_433\x10\x02\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 433MHz\x12\'\n\x06\x45U_868\x10\x03\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 868MHz\x12\x13\n\x02\x43N\x10\x04\x1a\x0b\xca\xf3\x18\x07:\x05\x43hina\x12\x13\n\x02JP\x10\x05\x1a\x0b\xca\xf3\x18\x07:\x05Japan\x12&\n\x03\x41NZ\x10\x06\x1a\x1d\xca\xf3\x18\x19:\x17\x41ustralia / New Zealand\x12\x13\n\x02KR\x10\x07\x1a\x0b\xca\xf3\x18\x07:\x05Korea\x12\x14\n\x02TW\x10\x08\x1a\x0c\xca\xf3\x18\x08:\x06Taiwan\x12\x14\n\x02RU\x10\t\x1a\x0c\xca\xf3\x18\x08:\x06Russia\x12\x06\n\x02IN\x10\n\x12$\n\x06NZ_865\x10\x0b\x1a\x18\xca\xf3\x18\x14:\x12New Zealand 865MHz\x12\x16\n\x02TH\x10\x0c\x1a\x0e\xca\xf3\x18\n:\x08Thailand\x12\x1a\n\x07LORA_24\x10\r\x1a\r\xca\xf3\x18\t:\x07\x32.4 Ghz\x12 \n\x06UA_433\x10\x0e\x1a\x14\xca\xf3\x18\x10:\x0eUkraine 433MHz\x12\x0e\n\x06UA_868\x10\x0f\x1a\x02\x08\x01\x12!\n\x06MY_433\x10\x10\x1a\x15\xca\xf3\x18\x11:\x0fMalaysia 433MHz\x12!\n\x06MY_919\x10\x11\x1a\x15\xca\xf3\x18\x11:\x0fMalaysia 919MHz\x12\"\n\x06SG_923\x10\x12\x1a\x16\xca\xf3\x18\x12:\x10Singapore 923MHz\x12$\n\x06PH_433\x10\x13\x1a\x18\xca\xf3\x18\x14:\x12Philippines 433MHz\x12$\n\x06PH_868\x10\x14\x1a\x18\xca\xf3\x18\x14:\x12Philippines 868MHz\x12$\n\x06PH_915\x10\x15\x1a\x18\xca\xf3\x18\x14:\x12Philippines 915MHz\x12\x31\n\x07\x41NZ_433\x10\x16\x1a$\xca\xf3\x18 :\x1e\x41ustralia / New Zealand 433MHz\x12#\n\x06KZ_433\x10\x17\x1a\x17\xca\xf3\x18\x13:\x11Kazakhstan 433MHz\x12#\n\x06KZ_863\x10\x18\x1a\x17\xca\xf3\x18\x13:\x11Kazakhstan 863MHz\x12\x1e\n\x06NP_865\x10\x19\x1a\x12\xca\xf3\x18\x0e:\x0cNepal 865MHz\x12\x1f\n\x06\x42R_902\x10\x1a\x1a\x13\xca\xf3\x18\x0f:\rBrazil 902MHz\x12,\n\x07ITU1_2M\x10\x1b\x1a\x1f\xca\xf3\x18\x1b:\x19ITU Region 1 / Amateur 2m\x12,\n\x07ITU2_2M\x10\x1c\x1a\x1f\xca\xf3\x18\x1b:\x19ITU Region 2 / Amateur 2m\x12\'\n\x06\x45U_866\x10\x1d\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 866MHz\x12\'\n\x06\x45U_874\x10\x1e\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 874MHz\x12\'\n\x06\x45U_917\x10\x1f\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 917MHz\x12\x32\n\x08\x45U_N_868\x10 \x1a$\xca\xf3\x18 :\x1e\x45uropean Union 868MHz (Narrow)\x12,\n\x07ITU3_2M\x10!\x1a\x1f\xca\xf3\x18\x1b:\x19ITU Region 3 / Amateur 2m\x12\x30\n\tITU1_70CM\x10\"\x1a!\xca\xf3\x18\x1d:\x1bITU Region 1 / Amateur 70cm\x12\x30\n\tITU2_70CM\x10#\x1a!\xca\xf3\x18\x1d:\x1bITU Region 2 / Amateur 70cm\x12\x30\n\tITU3_70CM\x10$\x1a!\xca\xf3\x18\x1d:\x1bITU Region 3 / Amateur 70cm\x12\x32\n\nITU2_125CM\x10%\x1a\"\xca\xf3\x18\x1e:\x1cITU Region 2 / Amateur 1.25m\"\xbd\x05\n\x0bModemPreset\x12\x38\n\tLONG_FAST\x10\x00\x1a)\xca\xf3\x18%:\x11Long Range - FastJ\x10longfast|default\x12(\n\tLONG_SLOW\x10\x01\x1a\x19\x08\x01\xca\xf3\x18\x13:\x11Long Range - Slow\x12\x16\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x02\x08\x01\x12*\n\x0bMEDIUM_SLOW\x10\x03\x1a\x19\xca\xf3\x18\x15:\x13Medium Range - Slow\x12*\n\x0bMEDIUM_FAST\x10\x04\x1a\x19\xca\xf3\x18\x15:\x13Medium Range - Fast\x12(\n\nSHORT_SLOW\x10\x05\x1a\x18\xca\xf3\x18\x14:\x12Short Range - Slow\x12(\n\nSHORT_FAST\x10\x06\x1a\x18\xca\xf3\x18\x14:\x12Short Range - Fast\x12.\n\rLONG_MODERATE\x10\x07\x1a\x1b\xca\xf3\x18\x17:\x15Long Range - Moderate\x12*\n\x0bSHORT_TURBO\x10\x08\x1a\x19\xca\xf3\x18\x15:\x13Short Range - Turbo\x12(\n\nLONG_TURBO\x10\t\x1a\x18\xca\xf3\x18\x14:\x12Long Range - Turbo\x12 \n\tLITE_FAST\x10\n\x1a\x11\xca\xf3\x18\r:\x0bLite - Fast\x12 \n\tLITE_SLOW\x10\x0b\x1a\x11\xca\xf3\x18\r:\x0bLite - Slow\x12$\n\x0bNARROW_FAST\x10\x0c\x1a\x13\xca\xf3\x18\x0f:\rNarrow - Fast\x12$\n\x0bNARROW_SLOW\x10\r\x1a\x13\xca\xf3\x18\x0f:\rNarrow - Slow\x12 \n\tTINY_FAST\x10\x0e\x1a\x11\xca\xf3\x18\r:\x0bTiny - Fast\x12 \n\tTINY_SLOW\x10\x0f\x1a\x11\xca\xf3\x18\r:\x0bTiny - Slow\x12,\n\x0cMEDIUM_TURBO\x10\x10\x1a\x1a\xca\xf3\x18\x16:\x14Medium Range - Turbo\":\n\x0c\x46\x45M_LNA_Mode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xa9\x02\n\x0f\x42luetoothConfig\x12(\n\x07\x65nabled\x18\x01 \x01(\x08\x42\x17\xca\xf3\x18\x13:\x11\x42luetooth Enabled\x12P\n\x04mode\x18\x02 \x01(\x0e\x32..meshtastic.Config.BluetoothConfig.PairingModeB\x12\xca\xf3\x18\x0e:\x0cPairing Mode\x12\"\n\tfixed_pin\x18\x03 \x01(\rB\x0f\xca\xf3\x18\x0b:\tFixed Pin\"v\n\x0bPairingMode\x12 \n\nRANDOM_PIN\x10\x00\x1a\x10\xca\xf3\x18\x0c:\nRandom Pin\x12\x1e\n\tFIXED_PIN\x10\x01\x1a\x0f\xca\xf3\x18\x0b:\tFixed Pin\x12%\n\x06NO_PIN\x10\x02\x1a\x19\xca\xf3\x18\x15:\x13No PIN (Just Works)\x1a\xcc\x05\n\x0eSecurityConfig\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x13\n\x0bprivate_key\x18\x02 \x01(\x0c\x12\x11\n\tadmin_key\x18\x03 \x03(\x0c\x12\x8d\x01\n\nis_managed\x18\x04 \x01(\x08\x42y\xca\xf3\x18u:\x0eManaged DeviceBcDevice is managed by a mesh administrator, the user is unable to access any of the device settings.\x12Q\n\x0eserial_enabled\x18\x05 \x01(\x08\x42\x39\xca\xf3\x18\x35:\x0eSerial ConsoleB#Serial Console over the Stream API.\x12\x95\x01\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x42v\xca\xf3\x18r:\nDebug LogsBdOutput live debug logging over serial, view and export position-redacted device logs over Bluetooth.\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x12X\n\x17packet_signature_policy\x18\t \x01(\x0e\x32\x37.meshtastic.Config.SecurityConfig.PacketSignaturePolicy\"\x89\x01\n\x15PacketSignaturePolicy\x12&\n\"PACKET_SIGNATURE_POLICY_COMPATIBLE\x10\x00\x12$\n PACKET_SIGNATURE_POLICY_BALANCED\x10\x01\x12\"\n\x1ePACKET_SIGNATURE_POLICY_STRICT\x10\x02\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBb\n\x14org.meshtastic.protoB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
11
+ descriptor_data = "\n\x17meshtastic/config.proto\x12\nmeshtastic\x1a\x1ameshtastic/device_ui.proto\x1a\x1fmeshtastic/field_metadata.proto\"\xdb\x81\x01\n\x06\x43onfig\x12\x31\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x1f.meshtastic.Config.DeviceConfigH\x00\x12\x35\n\x08position\x18\x02 \x01(\x0b\x32!.meshtastic.Config.PositionConfigH\x00\x12/\n\x05power\x18\x03 \x01(\x0b\x32\x1e.meshtastic.Config.PowerConfigH\x00\x12\x33\n\x07network\x18\x04 \x01(\x0b\x32 .meshtastic.Config.NetworkConfigH\x00\x12\x33\n\x07\x64isplay\x18\x05 \x01(\x0b\x32 .meshtastic.Config.DisplayConfigH\x00\x12-\n\x04lora\x18\x06 \x01(\x0b\x32\x1d.meshtastic.Config.LoRaConfigH\x00\x12\x37\n\tbluetooth\x18\x07 \x01(\x0b\x32\".meshtastic.Config.BluetoothConfigH\x00\x12\x35\n\x08security\x18\x08 \x01(\x0b\x32!.meshtastic.Config.SecurityConfigH\x00\x12\x39\n\nsessionkey\x18\t \x01(\x0b\x32#.meshtastic.Config.SessionkeyConfigH\x00\x12/\n\tdevice_ui\x18\n \x01(\x0b\x32\x1a.meshtastic.DeviceUIConfigH\x00\x1a\x8f\x1e\n\x0c\x44\x65viceConfig\x12\x45\n\x04role\x18\x01 \x01(\x0e\x32$.meshtastic.Config.DeviceConfig.RoleB\x11\xca\xf3\x18\r:\x0b\x44\x65vice Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12u\n\x0b\x62utton_gpio\x18\x04 \x01(\rB`\xca\xf3\x18\\:\x0b\x42utton GPIOBMGPIO pin for the user button, can be remapped on boards with multiple buttons\x12\x43\n\x0b\x62uzzer_gpio\x18\x05 \x01(\rB.\xca\xf3\x18*:\x0b\x42uzzer GPIOB\x1bGPIO pin for the PWM buzzer\x12\x61\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32/.meshtastic.Config.DeviceConfig.RebroadcastModeB\x16\xca\xf3\x18\x12:\x10Rebroadcast Mode\x12\x85\x01\n\x18node_info_broadcast_secs\x18\x07 \x01(\rBc\xca\xf3\x18_*\x01s:\x1cNode Info Broadcast IntervalB<How often node information is sent. Defaults to 900 seconds.\x12\x84\x01\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x42`\xca\xf3\x18\\:\x14\x44ouble Tap as ButtonBDTreat double tap on supported accelerometers as a user button press.\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12i\n\x14\x64isable_triple_click\x18\n \x01(\x08\x42K\xca\xf3\x18G:\x14\x44isable Triple ClickB/Disables the user button triple-press shortcut.\x12@\n\x05tzdef\x18\x0b \x01(\tB1\xca\xf3\x18-:\tTime ZoneB POSIX timezone definition string\x12\xcc\x01\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\x42\xab\x01\xca\xf3\x18\xa6\x01:\rLED HeartbeatB\x94\x01\x43ontrols the blinking LED on the device. For most devices this will control one of the up to 4 LEDS, the charger and GPS LEDs are not controllable.\x12L\n\x0b\x62uzzer_mode\x18\r \x01(\x0e\x32*.meshtastic.Config.DeviceConfig.BuzzerModeB\x0b\xca\xf3\x18\x07R\x05\x32.7.0\"\xd4\x0b\n\x04Role\x12H\n\x06\x43LIENT\x10\x00\x1a<\xca\xf3\x18\x38:\x06\x43lientB.App connected or stand alone messaging device.\x12\\\n\x0b\x43LIENT_MUTE\x10\x01\x1aK\xca\xf3\x18G:\x0b\x43lient MuteB8Device that does not forward packets from other devices.\x12\xb0\x01\n\x06ROUTER\x10\x02\x1a\xa3\x01\xca\xf3\x18\x9e\x01:\x06RouterB\x93\x01Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Needs exceptional coverage. Visible in Nodes list.\x12(\n\rROUTER_CLIENT\x10\x03\x1a\x15\x08\x01\xca\xf3\x18\x0f:\rRouter Client\x12\xb3\x01\n\x08REPEATER\x10\x04\x1a\xa4\x01\x08\x01\xca\xf3\x18\x9d\x01:\x08RepeaterB\x90\x01\x44\x65precated infrastructure role that creates gaps in the mesh rebroadcast chain. Switch this node to a Router-based role (Router or Router Late).\x12H\n\x07TRACKER\x10\x05\x1a;\xca\xf3\x18\x37:\x07TrackerB,Broadcasts GPS position packets as priority.\x12\x43\n\x06SENSOR\x10\x06\x1a\x37\xca\xf3\x18\x33:\x06SensorB)Broadcasts telemetry packets as priority.\x12X\n\x03TAK\x10\x07\x1aO\xca\xf3\x18K:\x03TAKBDOptimized for ATAK system communication, reduces routine broadcasts.\x12k\n\rCLIENT_HIDDEN\x10\x08\x1aX\xca\xf3\x18T:\rClient HiddenBCDevice that only broadcasts as needed for stealth or power savings.\x12\x89\x01\n\x0eLOST_AND_FOUND\x10\t\x1au\xca\xf3\x18q:\x0eLost and FoundB_Broadcasts location as message to default channel regularly for to assist with device recovery.\x12h\n\x0bTAK_TRACKER\x10\n\x1aW\xca\xf3\x18S:\x0bTAK TrackerBDEnables automatic TAK PLI broadcasts and reduces routine broadcasts.\x12\xbc\x01\n\x0bROUTER_LATE\x10\x0b\x1a\xaa\x01\xca\xf3\x18\xa5\x01:\x0bRouter LateB\x95\x01Infrastructure node that always rebroadcasts packets once but only after all other modes. Visible in Nodes list. Not a good choice for rooftop nodes.\x12\x85\x01\n\x0b\x43LIENT_BASE\x10\x0c\x1at\xca\xf3\x18p:\x0b\x43lient BaseBaUsed for rooftop nodes to distribute messages more widely from multiple nearby client mute nodes.\"\xc9\x08\n\x0fRebroadcastMode\x12\x8a\x01\n\x03\x41LL\x10\x00\x1a\x80\x01\xca\xf3\x18|:\x03\x41llBuRebroadcast any observed message, if it was on our private channel or from another channel with the same lora params.\x12\xe0\x01\n\x11\x41LL_SKIP_DECODING\x10\x01\x1a\xc8\x01\xca\xf3\x18\xc3\x01:\x11\x41ll Skip DecodingB\xad\x01Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. Only available in Repeater role. Setting this on any other roles will result in ALL behavior.\x12\xcd\x01\n\nLOCAL_ONLY\x10\x02\x1a\xbc\x01\xca\xf3\x18\xb7\x01:\nLocal OnlyB\xa8\x01Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts message on the nodes local primary / secondary channels.\x12\xc8\x01\n\nKNOWN_ONLY\x10\x03\x1a\xb7\x01\xca\xf3\x18\xb2\x01:\nKnown OnlyB\xa3\x01Ignores observed messages from foreign meshes like Local Only, but takes it step further by also ignoring messages from nodes not already in the node\'s known list.\x12\x92\x01\n\x04NONE\x10\x04\x1a\x87\x01\xca\xf3\x18\x82\x01:\x04NoneBzOnly permitted for SENSOR, TRACKER and TAK_TRACKER roles, this will inhibit all rebroadcasts, not unlike CLIENT_MUTE role.\x12\x95\x01\n\x12\x43ORE_PORTNUMS_ONLY\x10\x05\x1a}\xca\xf3\x18y:\x12\x43ore Portnums OnlyBcOnly rebroadcasts packets from the core portnums: NodeInfo, Text, Position, Telemetry, and Routing.\"i\n\nBuzzerMode\x12\x0f\n\x0b\x41LL_ENABLED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x16\n\x12NOTIFICATIONS_ONLY\x10\x02\x12\x0f\n\x0bSYSTEM_ONLY\x10\x03\x12\x13\n\x0f\x44IRECT_MSG_ONLY\x10\x04\x1a\x96\x0f\n\x0ePositionConfig\x12y\n\x17position_broadcast_secs\x18\x01 \x01(\rBX\xca\xf3\x18T*\x01s:\x12\x42roadcast IntervalB;The longest a node will go without broadcasting a position.\x12>\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x42\x14\xca\xf3\x18\x10:\x0eSmart Position\x12\xb2\x01\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x42\x99\x01\xca\xf3\x18\x94\x01:\x0e\x46ixed PositionB\x81\x01The last known latitude, longitude and altitude are broadcast over the mesh on the position interval, rather than a live GPS fix.\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12^\n\x13gps_update_interval\x18\x05 \x01(\rBA\xca\xf3\x18=*\x01s:\x0fUpdate IntervalB\'How often to try to get a GPS position.\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12j\n\x0eposition_flags\x18\x07 \x01(\rBR\xca\xf3\x18N:\x0ePosition FlagsB<Optional fields to include when assembling position messages\x12>\n\x07rx_gpio\x18\x08 \x01(\rB-\xca\xf3\x18)\x08\x01:\x10GPS Receive GPIOB\x13GPIO pin for GPS RX\x12?\n\x07tx_gpio\x18\t \x01(\rB.\xca\xf3\x18*\x08\x01:\x11GPS Transmit GPIOB\x13GPIO pin for GPS TX\x12\x94\x01\n broadcast_smart_minimum_distance\x18\n \x01(\rBj\xca\xf3\x18\x66*\x01m:\x10Minimum DistanceBOThe minimum change in distance before a smart position broadcast is considered.\x12\xa0\x01\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\rBq\xca\xf3\x18m*\x01s:\x10Minimum IntervalBVThe shortest interval between position updates once the minimum distance has been met.\x12\x41\n\x0bgps_en_gpio\x18\x0c \x01(\rB,\xca\xf3\x18(\x08\x01:\x0bGPS EN GPIOB\x17GPIO pin for GPS enable\x12K\n\x08gps_mode\x18\r \x01(\x0e\x32).meshtastic.Config.PositionConfig.GpsModeB\x0e\xca\xf3\x18\n:\x08GPS Mode\"\xdc\x04\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x63\n\x08\x41LTITUDE\x10\x01\x1aU\xca\xf3\x18Q:\x08\x41ltitudeBEInclude an altitude value in position reports, when one is available.\x12\x32\n\x0c\x41LTITUDE_MSL\x10\x02\x1a \xca\xf3\x18\x1c:\x1a\x41ltitude is Mean Sea Level\x12\x39\n\x12GEOIDAL_SEPARATION\x10\x04\x1a!\xca\xf3\x18\x1d:\x1b\x41ltitude Geoidal Separation\x12U\n\x03\x44OP\x10\x08\x1aL\xca\xf3\x18H:\x03\x44OPBAInclude the dilution of precision value. PDOP is used by default.\x12`\n\x05HVDOP\x10\x10\x1aU\xca\xf3\x18Q:\x0bHDOP / VDOPBBIf DOP is set, send separate HDOP and VDOP values instead of PDOP.\x12)\n\tSATINVIEW\x10 \x1a\x1a\xca\xf3\x18\x16:\x14Number of satellites\x12!\n\x06SEQ_NO\x10@\x1a\x15\xca\xf3\x18\x11:\x0fSequence number\x12\x1f\n\tTIMESTAMP\x10\x80\x01\x1a\x0f\xca\xf3\x18\x0b:\tTimestamp\x12#\n\x07HEADING\x10\x80\x02\x1a\x15\xca\xf3\x18\x11:\x0fVehicle heading\x12\x1f\n\x05SPEED\x10\x80\x04\x1a\x13\xca\xf3\x18\x0f:\rVehicle speed\"g\n\x07GpsMode\x12\x1c\n\x08\x44ISABLED\x10\x00\x1a\x0e\xca\xf3\x18\n:\x08\x44isabled\x12\x1a\n\x07\x45NABLED\x10\x01\x1a\r\xca\xf3\x18\t:\x07\x45nabled\x12\"\n\x0bNOT_PRESENT\x10\x02\x1a\x11\xca\xf3\x18\r:\x0bNot Present\x1a\xb8\x05\n\x0bPowerConfig\x12\x98\x02\n\x0fis_power_saving\x18\x01 \x01(\x08\x42\xfe\x01\xca\xf3\x18\xf9\x01:\x0cPower SavingB\xe8\x01Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don\'t use this setting if you want to use your device with the phone apps or are using a device without a user button.\x12\xa0\x01\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\rBx\xca\xf3\x18t*\x01s:\x16Shutdown on Power LossBWHow long after external power is removed before the device powers off. Zero to disable.\x12\x33\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x42\x12\xca\xf3\x18\x0e:\x0c\x41\x44\x43 Override\x12>\n\x13wait_bluetooth_secs\x18\x04 \x01(\rB!\xca\xf3\x18\x1d:\x1bWait for Bluetooth Duration\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\xc3\x08\n\rNetworkConfig\x12i\n\x0cwifi_enabled\x18\x01 \x01(\x08\x42S\xca\xf3\x18O:\x0cWiFi EnabledB?Enabling WiFi will disable the bluetooth connection to the app.\x12>\n\twifi_ssid\x18\x03 \x01(\tB+\xca\xf3\x18\':\x04SSIDB\x1fWiFi network name to connect to\x12\x42\n\x08wifi_psk\x18\x04 \x01(\tB0\xca\xf3\x18,:\x08PasswordB WiFi password for authentication\x12]\n\nntp_server\x18\x05 \x01(\tBI\xca\xf3\x18\x45:\nNTP ServerB7NTP server address. Defaults to meshtastic.pool.ntp.org\x12p\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x42[\xca\xf3\x18W:\x10\x45thernet EnabledBCEnabling Ethernet will disable the bluetooth connection to the app.\x12V\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32,.meshtastic.Config.NetworkConfig.AddressModeB\x12\xca\xf3\x18\x0e:\x0c\x41\x64\x64ress Mode\x12@\n\x0bipv4_config\x18\x08 \x01(\x0b\x32+.meshtastic.Config.NetworkConfig.IpV4Config\x12,\n\x0ersyslog_server\x18\t \x01(\tB\x14\xca\xf3\x18\x10:\x0eRsyslog Server\x12v\n\x11\x65nabled_protocols\x18\n \x01(\rB[\xca\xf3\x18W:\x11\x45nabled ProtocolsB;Enable broadcasting packets via UDP over the local network.R\x05\x32.6.0\x12\"\n\x0cipv6_enabled\x18\x0b \x01(\x08\x42\x0c\xca\xf3\x18\x08R\x06\x32.7.16\x1ax\n\nIpV4Config\x12\x14\n\x02ip\x18\x01 \x01(\x07\x42\x08\xca\xf3\x18\x04:\x02IP\x12\x1e\n\x07gateway\x18\x02 \x01(\x07\x42\r\xca\xf3\x18\t:\x07Gateway\x12\x1c\n\x06subnet\x18\x03 \x01(\x07\x42\x0c\xca\xf3\x18\x08:\x06Subnet\x12\x16\n\x03\x64ns\x18\x04 \x01(\x07\x42\t\xca\xf3\x18\x05:\x03\x44NS\"=\n\x0b\x41\x64\x64ressMode\x12\x14\n\x04\x44HCP\x10\x00\x1a\n\xca\xf3\x18\x06:\x04\x44HCP\x12\x18\n\x06STATIC\x10\x01\x1a\x0c\xca\xf3\x18\x08:\x06Static\"U\n\rProtocolFlags\x12\x1c\n\x0cNO_BROADCAST\x10\x00\x1a\n\xca\xf3\x18\x06:\x04None\x12&\n\rUDP_BROADCAST\x10\x01\x1a\x13\xca\xf3\x18\x0f:\rUDP Broadcast\x1a\x8b\x13\n\rDisplayConfig\x12\x89\x01\n\x0escreen_on_secs\x18\x01 \x01(\rBq\xca\xf3\x18m*\x01s:\rScreen on forBYHow long the screen remains on after the user button is pressed or messages are received.\x12\x62\n\ngps_format\x18\x02 \x01(\x0e\x32>.meshtastic.Config.DisplayConfig.DeprecatedGpsCoordinateFormatB\x0e\x18\x01\xca\xf3\x18\x08Z\x06\x32.7.10\x12\x8e\x01\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\rBk\xca\xf3\x18g*\x01s:\x11\x43\x61rousel IntervalBOAutomatically moves to the next screen page, like a carousel, on this interval.\x12\x8e\x01\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x42s\x18\x01\xca\xf3\x18m:\x12\x41lways point northBPThe compass heading on the screen outside of the circle will always point north.Z\x05\x32.7.1\x12>\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x42)\xca\xf3\x18%:\x0b\x46lip ScreenB\x16\x46lip screen vertically\x12t\n\x05units\x18\x06 \x01(\x0e\x32-.meshtastic.Config.DisplayConfig.DisplayUnitsB6\xca\xf3\x18\x32:\rDisplay UnitsB!Units shown on the device screen.\x12s\n\x04oled\x18\x07 \x01(\x0e\x32).meshtastic.Config.DisplayConfig.OledTypeB:\xca\xf3\x18\x36:\tOLED TypeB)Override automatic OLED screen detection.\x12v\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32,.meshtastic.Config.DisplayConfig.DisplayModeB3\xca\xf3\x18/:\x0c\x44isplay ModeB\x1fOverride default screen layout.\x12N\n\x0cheading_bold\x18\t \x01(\x08\x42\x38\xca\xf3\x18\x34:\x0c\x42old HeadingB$Bold the heading text on the screen.\x12z\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x42[\xca\xf3\x18W:\x1cWake Screen on tap or motionB7Requires that there be an accelerometer on your device.\x12\xb7\x01\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32\x33.meshtastic.Config.DisplayConfig.CompassOrientationBe\xca\xf3\x18\x61:\x13\x43ompass OrientationBJIndicates how to rotate or invert the compass output for accurate display.\x12\\\n\ruse_12h_clock\x18\x0c \x01(\x08\x42\x45\xca\xf3\x18\x41:\r12 Hour ClockB(Sets the screen clock format to 12-hour.R\x06\x32.5.22\x12(\n\x12use_long_node_name\x18\r \x01(\x08\x42\x0c\xca\xf3\x18\x08R\x06\x32.7.13\x12,\n\x16\x65nable_message_bubbles\x18\x0e \x01(\x08\x42\x0c\xca\xf3\x18\x08R\x06\x32.7.19\"+\n\x1d\x44\x65precatedGpsCoordinateFormat\x12\n\n\x06UNUSED\x10\x00\"F\n\x0c\x44isplayUnits\x12\x18\n\x06METRIC\x10\x00\x1a\x0c\xca\xf3\x18\x08:\x06Metric\x12\x1c\n\x08IMPERIAL\x10\x01\x1a\x0e\xca\xf3\x18\n:\x08Imperial\"\xf7\x01\n\x08OledType\x12)\n\tOLED_AUTO\x10\x00\x1a\x1a\xca\xf3\x18\x16:\x14\x44\x65tect Automatically\x12 \n\x0cOLED_SSD1306\x10\x01\x1a\x0e\xca\xf3\x18\n:\x08SSD 1306\x12\x1e\n\x0bOLED_SH1106\x10\x02\x1a\r\xca\xf3\x18\t:\x07SH 1106\x12\x1e\n\x0bOLED_SH1107\x10\x03\x1a\r\xca\xf3\x18\t:\x07SH 1107\x12.\n\x13OLED_SH1107_128_128\x10\x04\x1a\x15\xca\xf3\x18\x11:\x0fSH 1107 128x128\x12.\n\x13OLED_SH1107_ROTATED\x10\x05\x1a\x15\xca\xf3\x18\x11:\x0fSH 1107 Rotated\"\xd6\x01\n\x0b\x44isplayMode\x12/\n\x07\x44\x45\x46\x41ULT\x10\x00\x1a\"\xca\xf3\x18\x1e:\x1c\x44\x65\x66\x61ult 128x64 screen layout\x12\x32\n\x08TWOCOLOR\x10\x01\x1a$\xca\xf3\x18 :\x1eOptimized for 2 color displays\x12\x38\n\x08INVERTED\x10\x02\x1a*\xca\xf3\x18&:$Inverted top bar for 2 Color display\x12(\n\x05\x43OLOR\x10\x03\x1a\x1d\xca\xf3\x18\x19:\x17TFT Full Color Displays\"\xc0\x02\n\x12\x43ompassOrientation\x12\x18\n\tDEGREES_0\x10\x00\x1a\t\xca\xf3\x18\x05:\x03\x30\xc2\xb0\x12\x1a\n\nDEGREES_90\x10\x01\x1a\n\xca\xf3\x18\x06:\x04\x39\x30\xc2\xb0\x12\x1c\n\x0b\x44\x45GREES_180\x10\x02\x1a\x0b\xca\xf3\x18\x07:\x05\x31\x38\x30\xc2\xb0\x12\x1c\n\x0b\x44\x45GREES_270\x10\x03\x1a\x0b\xca\xf3\x18\x07:\x05\x32\x37\x30\xc2\xb0\x12*\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x1a\x12\xca\xf3\x18\x0e:\x0c\x30\xc2\xb0 Inverted\x12,\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x1a\x13\xca\xf3\x18\x0f:\r90\xc2\xb0 Inverted\x12.\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x1a\x14\xca\xf3\x18\x10:\x0e\x31\x38\x30\xc2\xb0 Inverted\x12.\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\x14\xca\xf3\x18\x10:\x0e\x32\x37\x30\xc2\xb0 Inverted\x1a\x85 \n\nLoRaConfig\x12\x80\x01\n\nuse_preset\x18\x01 \x01(\x08\x42l\xca\xf3\x18h:\nUse PresetBZUse the modem preset settings instead of a manual bandwidth, spread factor and coding rate\x12N\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32).meshtastic.Config.LoRaConfig.ModemPresetB\r\xca\xf3\x18\t:\x07Presets\x12\'\n\tbandwidth\x18\x03 \x01(\rB\x14\xca\xf3\x18\x10*\x03kHz:\tBandwidth\x12u\n\rspread_factor\x18\x04 \x01(\rB^\xca\xf3\x18Z\x19\x00\x00\x00\x00\x00\x00\x14@!\x00\x00\x00\x00\x00\x00(@:\rSpread FactorB7Number of chirps per symbol, as 2 raised to this value.\x12&\n\x0b\x63oding_rate\x18\x05 \x01(\rB\x11\xca\xf3\x18\r:\x0b\x43oding Rate\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12w\n\x06region\x18\x07 \x01(\x0e\x32(.meshtastic.Config.LoRaConfig.RegionCodeB=\xca\xf3\x18\x39:\x06RegionB/The region where you will be using your radios.\x12\x9d\x01\n\thop_limit\x18\x08 \x01(\rB\x89\x01\xca\xf3\x18\x84\x01\x19\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x1c@:\tHop LimitBIHow many times a message may be repeated before it stops being forwarded.J\x1ahops|ttl|range|rebroadcast\x12\x84\x01\n\ntx_enabled\x18\t \x01(\x08\x42p\xca\xf3\x18l:\x10Transmit EnabledBXAllow the LoRa radio to transmit. Turn off while hot-swapping antennas or bench testing.\x12\xd3\x01\n\x08tx_power\x18\n \x01(\x05\x42\xc0\x01\xca\xf3\x18\xbb\x01\x19\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00>@*\x03\x64\x42m:\x0eTransmit PowerBxRadio transmit power. Leave at zero to use the highest level legal for the region, which is what most radios should use.J\x18tx|power|dbm|output|gain\x12\xe0\x01\n\x0b\x63hannel_num\x18\x0b \x01(\rB\xca\x01\xca\xf3\x18\xc5\x01:\x0e\x46requency SlotB\xb2\x01Your node\xe2\x80\x99s operating frequency is calculated based on the region, modem preset, and this field. When 0, the slot is automatically calculated based on the primary channel name.\x12\x36\n\x13override_duty_cycle\x18\x0c \x01(\x08\x42\x19\xca\xf3\x18\x15:\x13Override Duty Cycle\x12i\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x42I\xca\xf3\x18\x45:\x0fRX Boosted GainB2Enable RX boosted gain mode on SX126X based radios\x12\x34\n\x12override_frequency\x18\x0e \x01(\x02\x42\x18\xca\xf3\x18\x14:\x12\x46requency Override\x12.\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x42\x15\xca\xf3\x18\x11:\x0fPA Fan Disabled\x12.\n\x0fignore_incoming\x18g \x03(\rB\x15\xca\xf3\x18\x11:\x0fIgnore Incoming\x12y\n\x0bignore_mqtt\x18h \x01(\x08\x42\x64\xca\xf3\x18`:\x0bIgnore MQTTBQIgnore packets received over LoRa that travelled via MQTT anywhere on their path.\x12+\n\x11\x63onfig_ok_to_mqtt\x18i \x01(\x08\x42\x10\xca\xf3\x18\x0c:\nOk to MQTT\x12N\n\x0c\x66\x65m_lna_mode\x18j \x01(\x0e\x32*.meshtastic.Config.LoRaConfig.FEM_LNA_ModeB\x0c\xca\xf3\x18\x08R\x06\x32.7.20\x12\x17\n\x0fserial_hal_only\x18k \x01(\x08\"\x86\x0b\n\nRegionCode\x12$\n\x05UNSET\x10\x00\x1a\x19\xca\xf3\x18\x15:\x13Please set a region\x12\x1b\n\x02US\x10\x01\x1a\x13\xca\xf3\x18\x0f:\rUnited States\x12\'\n\x06\x45U_433\x10\x02\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 433MHz\x12\'\n\x06\x45U_868\x10\x03\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 868MHz\x12\x13\n\x02\x43N\x10\x04\x1a\x0b\xca\xf3\x18\x07:\x05\x43hina\x12\x13\n\x02JP\x10\x05\x1a\x0b\xca\xf3\x18\x07:\x05Japan\x12&\n\x03\x41NZ\x10\x06\x1a\x1d\xca\xf3\x18\x19:\x17\x41ustralia / New Zealand\x12\x13\n\x02KR\x10\x07\x1a\x0b\xca\xf3\x18\x07:\x05Korea\x12\x14\n\x02TW\x10\x08\x1a\x0c\xca\xf3\x18\x08:\x06Taiwan\x12\x14\n\x02RU\x10\t\x1a\x0c\xca\xf3\x18\x08:\x06Russia\x12\x13\n\x02IN\x10\n\x1a\x0b\xca\xf3\x18\x07:\x05India\x12$\n\x06NZ_865\x10\x0b\x1a\x18\xca\xf3\x18\x14:\x12New Zealand 865MHz\x12\x16\n\x02TH\x10\x0c\x1a\x0e\xca\xf3\x18\n:\x08Thailand\x12\x1a\n\x07LORA_24\x10\r\x1a\r\xca\xf3\x18\t:\x07\x32.4 Ghz\x12 \n\x06UA_433\x10\x0e\x1a\x14\xca\xf3\x18\x10:\x0eUkraine 433MHz\x12\"\n\x06UA_868\x10\x0f\x1a\x16\x08\x01\xca\xf3\x18\x10:\x0eUkraine 868MHz\x12!\n\x06MY_433\x10\x10\x1a\x15\xca\xf3\x18\x11:\x0fMalaysia 433MHz\x12!\n\x06MY_919\x10\x11\x1a\x15\xca\xf3\x18\x11:\x0fMalaysia 919MHz\x12\"\n\x06SG_923\x10\x12\x1a\x16\xca\xf3\x18\x12:\x10Singapore 923MHz\x12$\n\x06PH_433\x10\x13\x1a\x18\xca\xf3\x18\x14:\x12Philippines 433MHz\x12$\n\x06PH_868\x10\x14\x1a\x18\xca\xf3\x18\x14:\x12Philippines 868MHz\x12$\n\x06PH_915\x10\x15\x1a\x18\xca\xf3\x18\x14:\x12Philippines 915MHz\x12\x31\n\x07\x41NZ_433\x10\x16\x1a$\xca\xf3\x18 :\x1e\x41ustralia / New Zealand 433MHz\x12#\n\x06KZ_433\x10\x17\x1a\x17\xca\xf3\x18\x13:\x11Kazakhstan 433MHz\x12#\n\x06KZ_863\x10\x18\x1a\x17\xca\xf3\x18\x13:\x11Kazakhstan 863MHz\x12\x1e\n\x06NP_865\x10\x19\x1a\x12\xca\xf3\x18\x0e:\x0cNepal 865MHz\x12\x1f\n\x06\x42R_902\x10\x1a\x1a\x13\xca\xf3\x18\x0f:\rBrazil 902MHz\x12,\n\x07ITU1_2M\x10\x1b\x1a\x1f\xca\xf3\x18\x1b:\x19ITU Region 1 / Amateur 2m\x12,\n\x07ITU2_2M\x10\x1c\x1a\x1f\xca\xf3\x18\x1b:\x19ITU Region 2 / Amateur 2m\x12\'\n\x06\x45U_866\x10\x1d\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 866MHz\x12\'\n\x06\x45U_874\x10\x1e\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 874MHz\x12\'\n\x06\x45U_917\x10\x1f\x1a\x1b\xca\xf3\x18\x17:\x15\x45uropean Union 917MHz\x12\x32\n\x08\x45U_N_868\x10 \x1a$\xca\xf3\x18 :\x1e\x45uropean Union 868MHz (Narrow)\x12,\n\x07ITU3_2M\x10!\x1a\x1f\xca\xf3\x18\x1b:\x19ITU Region 3 / Amateur 2m\x12\x30\n\tITU1_70CM\x10\"\x1a!\xca\xf3\x18\x1d:\x1bITU Region 1 / Amateur 70cm\x12\x30\n\tITU2_70CM\x10#\x1a!\xca\xf3\x18\x1d:\x1bITU Region 2 / Amateur 70cm\x12\x30\n\tITU3_70CM\x10$\x1a!\xca\xf3\x18\x1d:\x1bITU Region 3 / Amateur 70cm\x12\x32\n\nITU2_125CM\x10%\x1a\"\xca\xf3\x18\x1e:\x1cITU Region 2 / Amateur 1.25m\"\xd9\x05\n\x0bModemPreset\x12\x38\n\tLONG_FAST\x10\x00\x1a)\xca\xf3\x18%:\x11Long Range - FastJ\x10longfast|default\x12(\n\tLONG_SLOW\x10\x01\x1a\x19\x08\x01\xca\xf3\x18\x13:\x11Long Range - Slow\x12\x32\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x1e\x08\x01\xca\xf3\x18\x18:\x16Very Long Range - Slow\x12*\n\x0bMEDIUM_SLOW\x10\x03\x1a\x19\xca\xf3\x18\x15:\x13Medium Range - Slow\x12*\n\x0bMEDIUM_FAST\x10\x04\x1a\x19\xca\xf3\x18\x15:\x13Medium Range - Fast\x12(\n\nSHORT_SLOW\x10\x05\x1a\x18\xca\xf3\x18\x14:\x12Short Range - Slow\x12(\n\nSHORT_FAST\x10\x06\x1a\x18\xca\xf3\x18\x14:\x12Short Range - Fast\x12.\n\rLONG_MODERATE\x10\x07\x1a\x1b\xca\xf3\x18\x17:\x15Long Range - Moderate\x12*\n\x0bSHORT_TURBO\x10\x08\x1a\x19\xca\xf3\x18\x15:\x13Short Range - Turbo\x12(\n\nLONG_TURBO\x10\t\x1a\x18\xca\xf3\x18\x14:\x12Long Range - Turbo\x12 \n\tLITE_FAST\x10\n\x1a\x11\xca\xf3\x18\r:\x0bLite - Fast\x12 \n\tLITE_SLOW\x10\x0b\x1a\x11\xca\xf3\x18\r:\x0bLite - Slow\x12$\n\x0bNARROW_FAST\x10\x0c\x1a\x13\xca\xf3\x18\x0f:\rNarrow - Fast\x12$\n\x0bNARROW_SLOW\x10\r\x1a\x13\xca\xf3\x18\x0f:\rNarrow - Slow\x12 \n\tTINY_FAST\x10\x0e\x1a\x11\xca\xf3\x18\r:\x0bTiny - Fast\x12 \n\tTINY_SLOW\x10\x0f\x1a\x11\xca\xf3\x18\r:\x0bTiny - Slow\x12,\n\x0cMEDIUM_TURBO\x10\x10\x1a\x1a\xca\xf3\x18\x16:\x14Medium Range - Turbo\":\n\x0c\x46\x45M_LNA_Mode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xb2\x03\n\x0f\x42luetoothConfig\x12H\n\x07\x65nabled\x18\x01 \x01(\x08\x42\x37\xca\xf3\x18\x33:\x11\x42luetooth EnabledB\x1e\x45nable Bluetooth on the device\x12l\n\x04mode\x18\x02 \x01(\x0e\x32..meshtastic.Config.BluetoothConfig.PairingModeB.\xca\xf3\x18*:\x0cPairing ModeB\x1a\x42luetooth pairing strategy\x12o\n\tfixed_pin\x18\x03 \x01(\rB\\\xca\xf3\x18X:\tFixed PinBKFixed PIN for Bluetooth pairing. Used when pairing mode is set to fixed PIN\"v\n\x0bPairingMode\x12 \n\nRANDOM_PIN\x10\x00\x1a\x10\xca\xf3\x18\x0c:\nRandom Pin\x12\x1e\n\tFIXED_PIN\x10\x01\x1a\x0f\xca\xf3\x18\x0b:\tFixed Pin\x12%\n\x06NO_PIN\x10\x02\x1a\x19\xca\xf3\x18\x15:\x13No PIN (Just Works)\x1a\xa2\x0b\n\x0eSecurityConfig\x12\x9c\x01\n\npublic_key\x18\x01 \x01(\x0c\x42\x87\x01\xca\xf3\x18\x82\x01:\nPublic KeyBtGenerated from your private key and sent out to other nodes on the mesh to allow them to compute a shared secret key\x12X\n\x0bprivate_key\x18\x02 \x01(\x0c\x42\x43\xca\xf3\x18?:\x0bPrivate KeyB0Used to create a shared key with a remote device\x12\x61\n\tadmin_key\x18\x03 \x03(\x0c\x42N\xca\xf3\x18J:\tAdmin KeyB=The public key authorized to send admin messages to this node\x12\x8d\x01\n\nis_managed\x18\x04 \x01(\x08\x42y\xca\xf3\x18u:\x0eManaged DeviceBcDevice is managed by a mesh administrator, the user is unable to access any of the device settings.\x12Q\n\x0eserial_enabled\x18\x05 \x01(\x08\x42\x39\xca\xf3\x18\x35:\x0eSerial ConsoleB#Serial Console over the Stream API.\x12\x95\x01\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x42v\xca\xf3\x18r:\nDebug LogsBdOutput live debug logging over serial, view and export position-redacted device logs over Bluetooth.\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x12\x65\n\x17packet_signature_policy\x18\t \x01(\x0e\x32\x37.meshtastic.Config.SecurityConfig.PacketSignaturePolicyB\x0b\xca\xf3\x18\x07R\x05\x32.8.0\"\xb2\x04\n\x15PacketSignaturePolicy\x12\xa5\x01\n\"PACKET_SIGNATURE_POLICY_COMPATIBLE\x10\x00\x1a}\xca\xf3\x18y:\x1c\x43ompatible - Accept UnsignedBYAuthenticate packets when possible, but accept unsigned traffic for maximum compatibility\x12\xac\x01\n PACKET_SIGNATURE_POLICY_BALANCED\x10\x01\x1a\x85\x01\xca\xf3\x18\x80\x01:\x1f\x42\x61lanced - Prefer AuthenticatedB]Prefer authenticated packets, but still accept unsigned traffic from nodes not known to sign.\x12\xc1\x01\n\x1ePACKET_SIGNATURE_POLICY_STRICT\x10\x02\x1a\x9c\x01\xca\xf3\x18\x97\x01:\x1fStrict - Require AuthenticationBtAccept only packets with a verified signature or successful PKI decryption. Packets from older nodes may be ignored.\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBb\n\x14org.meshtastic.protoB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
12
12
 
13
13
  pool = ::Google::Protobuf::DescriptorPool.generated_pool
14
14
  pool.add_serialized_file(descriptor_data)
@@ -7,7 +7,7 @@ require 'google/protobuf'
7
7
  require 'google/protobuf/descriptor_pb'
8
8
 
9
9
 
10
- descriptor_data = "\n\x1fmeshtastic/field_metadata.proto\x12\nmeshtastic\x1a google/protobuf/descriptor.proto\"\xb3\x01\n\rFieldMetadata\x12\x10\n\x08\x64iy_only\x18\x01 \x01(\x08\x12\x12\n\nadmin_only\x18\x02 \x01(\x08\x12\x11\n\tmin_value\x18\x03 \x01(\x01\x12\x11\n\tmax_value\x18\x04 \x01(\x01\x12\x0c\n\x04unit\x18\x05 \x01(\t\x12\x12\n\ndeprecated\x18\x06 \x01(\x08\x12\r\n\x05label\x18\x07 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x08 \x01(\t\x12\x10\n\x08keywords\x18\t \x01(\t:R\n\x0e\x66ield_metadata\x12\x1d.google.protobuf.FieldOptions\x18\xb9\x8e\x03 \x01(\x0b\x32\x19.meshtastic.FieldMetadata:[\n\x13\x65num_value_metadata\x12!.google.protobuf.EnumValueOptions\x18\xb9\x8e\x03 \x01(\x0b\x32\x19.meshtastic.FieldMetadataBi\n\x14org.meshtastic.protoB\x13\x46ieldMetadataProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00"
10
+ descriptor_data = "\n\x1fmeshtastic/field_metadata.proto\x12\nmeshtastic\x1a google/protobuf/descriptor.proto\"\xe5\x01\n\rFieldMetadata\x12\x10\n\x08\x64iy_only\x18\x01 \x01(\x08\x12\x12\n\nadmin_only\x18\x02 \x01(\x08\x12\x11\n\tmin_value\x18\x03 \x01(\x01\x12\x11\n\tmax_value\x18\x04 \x01(\x01\x12\x0c\n\x04unit\x18\x05 \x01(\t\x12\x12\n\ndeprecated\x18\x06 \x01(\x08\x12\r\n\x05label\x18\x07 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x08 \x01(\t\x12\x10\n\x08keywords\x18\t \x01(\t\x12\x16\n\x0esince_firmware\x18\n \x01(\t\x12\x18\n\x10\x64\x65precated_since\x18\x0b \x01(\t:R\n\x0e\x66ield_metadata\x12\x1d.google.protobuf.FieldOptions\x18\xb9\x8e\x03 \x01(\x0b\x32\x19.meshtastic.FieldMetadata:[\n\x13\x65num_value_metadata\x12!.google.protobuf.EnumValueOptions\x18\xb9\x8e\x03 \x01(\x0b\x32\x19.meshtastic.FieldMetadataBi\n\x14org.meshtastic.protoB\x13\x46ieldMetadataProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00"
11
11
 
12
12
  pool = ::Google::Protobuf::DescriptorPool.generated_pool
13
13
  pool.add_serialized_file(descriptor_data)
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meshtastic/forwarder_pb'
4
+ require 'zlib'
5
+ require 'stringio'
6
+ require 'time'
7
+
8
+ module Meshtastic
9
+ # libcotshrink protobuf decoding. Detail is a schema-level hash, not CoT XML.
10
+ module Forwarder
11
+ MAX_BYTES = 1_048_576
12
+ class UnsupportedFormat < ArgumentError
13
+ end
14
+ SOURCES = %w[DTED0 DTED1 DTED2 DTED3 LIDAR PFI USER ??? GPS SRTM1 COT PRI CALC ESTIMATED RTK DGPS GPS_PPS].freeze
15
+ EXTENSIONS = [
16
+ [:how, 3, %w[h-e h-g-i-g-o m-g]],
17
+ [:geopointsrc, 6, SOURCES], [:altsrc, 6, SOURCES],
18
+ [:role, 5, ['Team Member', 'Team Lead', 'HQ', 'Sniper', 'Medic', 'Forward Observer', 'RTO', 'K9']],
19
+ [:battery, 8, nil], [:readiness, 2, :boolean], [:labels_on, 2, :boolean],
20
+ [:height_unit, 4, nil], [:ce_human_input, 2, :boolean], [:tog, 2, :boolean],
21
+ [:route_planning_method, 2, %w[Infil Exfil]],
22
+ [:route_method, 4, %w[Driving Walking Flying Swimming Watercraft]],
23
+ [:route_type, 2, ['On Foot', 'Vehicle']], [:route_route_type, 2, %w[Primary Secondary]],
24
+ [:route_order, 2, ['Ascending Check Points', 'Descending Check Points']], [:route_stroke, 8, nil]
25
+ ].freeze
26
+
27
+ public_class_method def self.decode(opts = {})
28
+ bytes = opts[:payload].to_s.b
29
+ limit = byte_limit(opts)
30
+ raise ArgumentError, 'Forwarder input exceeds byte limit' if bytes.bytesize > limit
31
+
32
+ compression = bytes.start_with?("\x1f\x8b".b) ? :gzip : :none
33
+ bytes = gunzip(payload: bytes, max_bytes: limit) if compression == :gzip
34
+ raise UnsupportedFormat, 'libcotshrink EXI requires a schema-less EXI grammar decoder; not implemented in Ruby' if bytes.start_with?('$EXI') || (bytes.getbyte(0) && (bytes.getbyte(0) & 0xC0) == 0x80)
35
+
36
+ message = ForwarderProtobuf::CotEvent.decode(bytes)
37
+ extensions = unpack_extensions(value: message.customBytesExt)
38
+ event = unpack_event(message: message, start_of_year: opts[:start_of_year])
39
+ event[:how] = extensions[:how]
40
+ {
41
+ format: :libcotshrink_protobuf, compression: compression,
42
+ protobuf: message.to_h, event: event, extensions: extensions
43
+ }
44
+ rescue Google::Protobuf::ParseError => e
45
+ raise ArgumentError, "invalid libcotshrink protobuf: #{e.message}"
46
+ end
47
+
48
+ # Packet payload includes the upstream (index << 4 | count) byte.
49
+ public_class_method def self.decode_packet(opts = {})
50
+ fragment = parse_fragment(opts.merge({}))
51
+ return fragment unless fragment[:count] == 1
52
+
53
+ decode_body(opts.merge(payload: fragment[:body]))
54
+ end
55
+
56
+ # Stateless reassembly: callers group only chunks known to belong together.
57
+ public_class_method def self.decode_chunks(opts = {})
58
+ chunks = opts[:chunks]
59
+ raise ArgumentError, 'Forwarder requires one to fifteen chunks' unless chunks.is_a?(Array) && (1..15).cover?(chunks.length)
60
+
61
+ fragments = chunks.map { |payload| parse_fragment(payload: payload) }
62
+ count = fragments.first[:count]
63
+ raise ArgumentError, 'inconsistent Forwarder chunk counts' unless fragments.all? { |fragment| fragment[:count] == count }
64
+ raise ArgumentError, 'duplicate Forwarder chunk index' unless fragments.map { |fragment| fragment[:index] }.uniq.length == fragments.length
65
+ raise ArgumentError, 'missing Forwarder chunks' unless fragments.length == count
66
+ raise ArgumentError, 'Forwarder reassembly exceeds byte limit' if fragments.sum { |fragment| fragment[:body].bytesize } > byte_limit(opts)
67
+
68
+ bytes = fragments.sort_by { |fragment| fragment[:index] }.map { |fragment| fragment[:body] }.join.b
69
+ decode_body(opts.merge(payload: bytes))
70
+ end
71
+
72
+ public_class_method def self.authors
73
+ '0day Inc.; libcotshrink schema and format: paulmandal (MIT)'
74
+ end
75
+
76
+ public_class_method def self.help
77
+ puts "USAGE:
78
+ # Decode reassembled libcotshrink event bytes.
79
+ #{self}.decode(
80
+ payload: 'required - reassembled protobuf or GZIP bytes without chunk header',
81
+ max_bytes: 'optional - input and decompressed byte ceiling up to 1048576',
82
+ start_of_year: 'optional - explicit Time epoch matching sender year and timezone; otherwise return offsets'
83
+ )
84
+ # Decode one header-bearing port 257 packet.
85
+ #{self}.decode_packet(
86
+ payload: 'required - one complete Meshtastic Forwarder port payload',
87
+ max_bytes: 'optional - maximum input and decompressed bytes',
88
+ start_of_year: 'optional - explicit Time epoch for sender timestamps'
89
+ )
90
+ # Reassemble an explicitly grouped complete message.
91
+ #{self}.decode_chunks(
92
+ chunks: 'required - array of header-bearing packets from one message and sender',
93
+ max_bytes: 'optional - maximum reassembled and decompressed bytes',
94
+ start_of_year: 'optional - explicit Time epoch for sender timestamps'
95
+ )
96
+ # List decoder authors and upstream attribution.
97
+ #{self}.authors
98
+ "
99
+ end
100
+
101
+ private_class_method def self.byte_limit(opts = {})
102
+ limit = opts[:max_bytes] || MAX_BYTES
103
+ raise ArgumentError, 'invalid Forwarder byte limit' unless limit.is_a?(Integer) && limit.positive? && limit <= MAX_BYTES
104
+
105
+ limit
106
+ end
107
+
108
+ private_class_method def self.parse_fragment(opts = {})
109
+ bytes = opts[:payload].to_s.b
110
+ limit = byte_limit(opts)
111
+ raise ArgumentError, 'Forwarder chunk exceeds byte limit' if bytes.bytesize > limit
112
+ raise ArgumentError, 'missing Forwarder chunk header' if bytes.empty?
113
+
114
+ index = bytes.getbyte(0) >> 4
115
+ count = bytes.getbyte(0) & 15
116
+ raise ArgumentError, 'invalid Forwarder chunk header' unless count.positive? && index < count
117
+
118
+ { format: :forwarder_fragment, index: index, count: count, body: bytes.byteslice(1..) }
119
+ end
120
+
121
+ private_class_method def self.decode_body(opts = {})
122
+ bytes = opts[:payload]
123
+ return decode(opts) unless bytes.start_with?('ATAKBCAST,')
124
+
125
+ fields = bytes.dup.force_encoding(Encoding::UTF_8)
126
+ raise ArgumentError, 'invalid Forwarder discovery UTF-8' unless fields.valid_encoding?
127
+
128
+ fields = fields.split(',', -1)
129
+ raise ArgumentError, 'invalid Forwarder discovery fields' unless fields.length == 5 && %w[0 1].include?(fields[4])
130
+
131
+ { format: :forwarder_discovery, mesh_id: fields[1], uid: fields[2], callsign: fields[3], initial: fields[4] == '1' }
132
+ end
133
+
134
+ private_class_method def self.gunzip(opts = {})
135
+ reader = Zlib::GzipReader.new(StringIO.new(opts[:payload]))
136
+ output = reader.read(opts[:max_bytes] + 1)
137
+ raise ArgumentError, 'Forwarder GZIP output exceeds byte limit' if output.bytesize > opts[:max_bytes]
138
+ raise ArgumentError, 'Forwarder GZIP trailing bytes are unsupported' if reader.unused && !reader.unused.empty?
139
+
140
+ output
141
+ rescue Zlib::Error, EOFError => e
142
+ raise ArgumentError, "invalid Forwarder GZIP: #{e.message}"
143
+ ensure
144
+ reader&.close
145
+ end
146
+
147
+ private_class_method def self.unpack_event(opts = {})
148
+ message = opts[:message]
149
+ packed = message.customBytes
150
+ offset = packed >> 39
151
+ stale = (packed >> 16) & 0x7FFFFF
152
+ hae = ((packed & 0xFFFF) / 3.0) - 900
153
+ hae = 9_999_999 if hae == 20_945
154
+ event = {
155
+ uid: message.uid, type: message.type.empty? ? 'a-f-G-U-C' : message.type,
156
+ lat: message.lat / 10_000_000.0, lon: message.lon / 10_000_000.0,
157
+ ce: message.ce, le: message.le, hae: hae,
158
+ time_offset_seconds: offset, stale_after_seconds: stale
159
+ }
160
+ epoch = opts[:start_of_year]
161
+ if epoch
162
+ raise ArgumentError, 'start_of_year must be a Time' unless epoch.is_a?(Time)
163
+
164
+ event[:time] = (epoch + offset).utc.iso8601
165
+ event[:start] = event[:time]
166
+ event[:stale] = (epoch + offset + stale).utc.iso8601
167
+ end
168
+ event
169
+ end
170
+
171
+ private_class_method def self.unpack_extensions(opts = {})
172
+ shift = 64
173
+ EXTENSIONS.to_h do |name, width, mapping|
174
+ shift -= width
175
+ value = (opts[:value] >> shift) & ((1 << width) - 1)
176
+ nullable = name != :how
177
+ decoded = if nullable && value[width - 1] == 1
178
+ nil
179
+ elsif mapping == :boolean
180
+ value == 1
181
+ elsif mapping
182
+ mapping.fetch(value) { raise ArgumentError, "invalid libcotshrink #{name} mapping" }
183
+ else
184
+ value
185
+ end
186
+ [name, decoded]
187
+ end
188
+ end
189
+ end
190
+ end