diff --git a/README.md b/README.md index 157a0c4..17f1e25 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Installation is easily done through the Python package installer pip (note, you - check that your computer has the required serial drivers installed, if not download them from [here](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers). - check that your computer has Python 3 installed. -- check that your computer has “pip3” installed, if not follow [this guide](https://www.makeuseof.com/tag/install-pip-for-python/). +- check that your computer has "pip3" installed, if not follow [this guide](https://www.makeuseof.com/tag/install-pip-for-python/). - check that pytap2 is installed by pip3. If not, install it: ``` sudo pip3 install --upgrade pytap2 @@ -100,14 +100,6 @@ This indicates an OS permission problem for access by your user to the USB seria sudo usermod -a -G dialout ``` -## A note to developers of this lib - -If you need to build a new release you'll need: -``` -apt install pandoc -sudo pip3 install markdown pandoc webencodings pyparsing -``` - ## Mac OS Big Sur There is a problem with Big Sur and pyserial. The workaround is to install a newer version of pyserial: @@ -117,3 +109,13 @@ pip3 install -U --pre pyserial ``` Afterwards you can use the meshatstic python client again on MacOS. + +## A note to developers of this lib + +We use the visual-studio-code default python formatting conventions (autopep8). So if you use that IDE you should be able to use "Format Document" and not generate unrelated diffs. If you use some other editor, please don't change formatting on lines you haven't changed. + +If you need to build a new release you'll need: +``` +apt install pandoc +sudo pip3 install markdown pandoc webencodings pyparsing twine autopep8 +``` \ No newline at end of file diff --git a/docs/meshtastic/admin_pb2.html b/docs/meshtastic/admin_pb2.html new file mode 100644 index 0000000..46d9221 --- /dev/null +++ b/docs/meshtastic/admin_pb2.html @@ -0,0 +1,277 @@ + + + + + + +meshtastic.admin_pb2 API documentation + + + + + + + + + + + +
+
+
+

Module meshtastic.admin_pb2

+
+
+

Generated protocol buffer code.

+
+ +Expand source code + +
# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: admin.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import mesh_pb2 as mesh__pb2
+from . import radioconfig_pb2 as radioconfig__pb2
+from . import channel_pb2 as channel__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='admin.proto',
+  package='',
+  syntax='proto3',
+  serialized_options=b'\n\023com.geeksville.meshB\013AdminProtosH\003',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x0b\x61\x64min.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\x1a\rchannel.proto\"\x8b\x02\n\x0c\x41\x64minMessage\x12!\n\tset_radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1a\n\tset_owner\x18\x02 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18\x03 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_radio_request\x18\x04 \x01(\x08H\x00\x12*\n\x12get_radio_response\x18\x05 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1d\n\x13get_channel_request\x18\x06 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x07 \x01(\x0b\x32\x08.ChannelH\x00\x42\t\n\x07variantB$\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03\x62\x06proto3'
+  ,
+  dependencies=[mesh__pb2.DESCRIPTOR,radioconfig__pb2.DESCRIPTOR,channel__pb2.DESCRIPTOR,])
+
+
+
+
+_ADMINMESSAGE = _descriptor.Descriptor(
+  name='AdminMessage',
+  full_name='AdminMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='set_radio', full_name='AdminMessage.set_radio', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='set_owner', full_name='AdminMessage.set_owner', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='set_channel', full_name='AdminMessage.set_channel', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='get_radio_request', full_name='AdminMessage.get_radio_request', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='get_radio_response', full_name='AdminMessage.get_radio_response', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='get_channel_request', full_name='AdminMessage.get_channel_request', index=5,
+      number=6, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='get_channel_response', full_name='AdminMessage.get_channel_response', index=6,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='variant', full_name='AdminMessage.variant',
+      index=0, containing_type=None,
+      create_key=_descriptor._internal_create_key,
+    fields=[]),
+  ],
+  serialized_start=62,
+  serialized_end=329,
+)
+
+_ADMINMESSAGE.fields_by_name['set_radio'].message_type = radioconfig__pb2._RADIOCONFIG
+_ADMINMESSAGE.fields_by_name['set_owner'].message_type = mesh__pb2._USER
+_ADMINMESSAGE.fields_by_name['set_channel'].message_type = channel__pb2._CHANNEL
+_ADMINMESSAGE.fields_by_name['get_radio_response'].message_type = radioconfig__pb2._RADIOCONFIG
+_ADMINMESSAGE.fields_by_name['get_channel_response'].message_type = channel__pb2._CHANNEL
+_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
+  _ADMINMESSAGE.fields_by_name['set_radio'])
+_ADMINMESSAGE.fields_by_name['set_radio'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
+_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
+  _ADMINMESSAGE.fields_by_name['set_owner'])
+_ADMINMESSAGE.fields_by_name['set_owner'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
+_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
+  _ADMINMESSAGE.fields_by_name['set_channel'])
+_ADMINMESSAGE.fields_by_name['set_channel'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
+_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
+  _ADMINMESSAGE.fields_by_name['get_radio_request'])
+_ADMINMESSAGE.fields_by_name['get_radio_request'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
+_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
+  _ADMINMESSAGE.fields_by_name['get_radio_response'])
+_ADMINMESSAGE.fields_by_name['get_radio_response'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
+_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
+  _ADMINMESSAGE.fields_by_name['get_channel_request'])
+_ADMINMESSAGE.fields_by_name['get_channel_request'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
+_ADMINMESSAGE.oneofs_by_name['variant'].fields.append(
+  _ADMINMESSAGE.fields_by_name['get_channel_response'])
+_ADMINMESSAGE.fields_by_name['get_channel_response'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant']
+DESCRIPTOR.message_types_by_name['AdminMessage'] = _ADMINMESSAGE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+AdminMessage = _reflection.GeneratedProtocolMessageType('AdminMessage', (_message.Message,), {
+  'DESCRIPTOR' : _ADMINMESSAGE,
+  '__module__' : 'admin_pb2'
+  # @@protoc_insertion_point(class_scope:AdminMessage)
+  })
+_sym_db.RegisterMessage(AdminMessage)
+
+
+DESCRIPTOR._options = None
+# @@protoc_insertion_point(module_scope)
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class AdminMessage +(*args, **kwargs) +
+
+

A ProtocolMessage

+

Ancestors

+
    +
  • google.protobuf.pyext._message.CMessage
  • +
  • google.protobuf.message.Message
  • +
+

Class variables

+
+
var DESCRIPTOR
+
+
+
+
+

Instance variables

+
+
var get_channel_request
+
+

Field AdminMessage.get_channel_request

+
+
var get_channel_response
+
+

Field AdminMessage.get_channel_response

+
+
var get_radio_request
+
+

Field AdminMessage.get_radio_request

+
+
var get_radio_response
+
+

Field AdminMessage.get_radio_response

+
+
var set_channel
+
+

Field AdminMessage.set_channel

+
+
var set_owner
+
+

Field AdminMessage.set_owner

+
+
var set_radio
+
+

Field AdminMessage.set_radio

+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/docs/meshtastic/apponly_pb2.html b/docs/meshtastic/apponly_pb2.html index 5fd09c6..ba968d5 100644 --- a/docs/meshtastic/apponly_pb2.html +++ b/docs/meshtastic/apponly_pb2.html @@ -5,7 +5,7 @@ meshtastic.apponly_pb2 API documentation - + @@ -22,6 +22,7 @@

Module meshtastic.apponly_pb2

+

Generated protocol buffer code.

Expand source code @@ -29,7 +30,7 @@
# -*- coding: utf-8 -*-
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: apponly.proto
-
+"""Generated protocol buffer code."""
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
 from google.protobuf import reflection as _reflection
@@ -40,16 +41,18 @@ _sym_db = _symbol_database.Default()
 
 
 from . import mesh_pb2 as mesh__pb2
+from . import channel_pb2 as channel__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='apponly.proto',
   package='',
   syntax='proto3',
-  serialized_options=b'\n\023com.geeksville.meshB\007AppOnlyH\003',
-  serialized_pb=b'\n\rapponly.proto\x1a\nmesh.proto\"V\n\x0fServiceEnvelope\x12\x1b\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\tB \n\x13\x63om.geeksville.meshB\x07\x41ppOnlyH\x03\x62\x06proto3'
+  serialized_options=b'\n\023com.geeksville.meshB\rAppOnlyProtosH\003',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rapponly.proto\x1a\nmesh.proto\x1a\rchannel.proto\"V\n\x0fServiceEnvelope\x12\x1b\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"0\n\nChannelSet\x12\"\n\x08settings\x18\x01 \x03(\x0b\x32\x10.ChannelSettingsB&\n\x13\x63om.geeksville.meshB\rAppOnlyProtosH\x03\x62\x06proto3'
   ,
-  dependencies=[mesh__pb2.DESCRIPTOR,])
+  dependencies=[mesh__pb2.DESCRIPTOR,channel__pb2.DESCRIPTOR,])
 
 
 
@@ -60,6 +63,7 @@ _SERVICEENVELOPE = _descriptor.Descriptor(
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
+  create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
       name='packet', full_name='ServiceEnvelope.packet', index=0,
@@ -67,21 +71,21 @@ _SERVICEENVELOPE = _descriptor.Descriptor(
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR),
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
       name='channel_id', full_name='ServiceEnvelope.channel_id', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR),
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
       name='gateway_id', full_name='ServiceEnvelope.gateway_id', index=2,
       number=3, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR),
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
@@ -94,12 +98,46 @@ _SERVICEENVELOPE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=29,
-  serialized_end=115,
+  serialized_start=44,
+  serialized_end=130,
+)
+
+
+_CHANNELSET = _descriptor.Descriptor(
+  name='ChannelSet',
+  full_name='ChannelSet',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='settings', full_name='ChannelSet.settings', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=132,
+  serialized_end=180,
 )
 
 _SERVICEENVELOPE.fields_by_name['packet'].message_type = mesh__pb2._MESHPACKET
+_CHANNELSET.fields_by_name['settings'].message_type = channel__pb2._CHANNELSETTINGS
 DESCRIPTOR.message_types_by_name['ServiceEnvelope'] = _SERVICEENVELOPE
+DESCRIPTOR.message_types_by_name['ChannelSet'] = _CHANNELSET
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 ServiceEnvelope = _reflection.GeneratedProtocolMessageType('ServiceEnvelope', (_message.Message,), {
@@ -109,6 +147,13 @@ ServiceEnvelope = _reflection.GeneratedProtocolMessageType('ServiceEnvelope&
   })
 _sym_db.RegisterMessage(ServiceEnvelope)
 
+ChannelSet = _reflection.GeneratedProtocolMessageType('ChannelSet', (_message.Message,), {
+  'DESCRIPTOR' : _CHANNELSET,
+  '__module__' : 'apponly_pb2'
+  # @@protoc_insertion_point(class_scope:ChannelSet)
+  })
+_sym_db.RegisterMessage(ChannelSet)
+
 
 DESCRIPTOR._options = None
 # @@protoc_insertion_point(module_scope)
@@ -123,6 +168,32 @@ DESCRIPTOR._options = None

Classes

+
+class ChannelSet +(*args, **kwargs) +
+
+

A ProtocolMessage

+

Ancestors

+
    +
  • google.protobuf.pyext._message.CMessage
  • +
  • google.protobuf.message.Message
  • +
+

Class variables

+
+
var DESCRIPTOR
+
+
+
+
+

Instance variables

+
+
var settings
+
+

Field ChannelSet.settings

+
+
+
class ServiceEnvelope (*args, **kwargs) @@ -174,6 +245,13 @@ DESCRIPTOR._options = None
  • Classes

    • +

      ChannelSet

      + +
    • +
    • ServiceEnvelope

      • DESCRIPTOR
      • diff --git a/docs/meshtastic/channel_pb2.html b/docs/meshtastic/channel_pb2.html new file mode 100644 index 0000000..cd9b0b7 --- /dev/null +++ b/docs/meshtastic/channel_pb2.html @@ -0,0 +1,504 @@ + + + + + + +meshtastic.channel_pb2 API documentation + + + + + + + + + + + +
        +
        +
        +

        Module meshtastic.channel_pb2

        +
        +
        +

        Generated protocol buffer code.

        +
        + +Expand source code + +
        # -*- coding: utf-8 -*-
        +# Generated by the protocol buffer compiler.  DO NOT EDIT!
        +# source: channel.proto
        +"""Generated protocol buffer code."""
        +from google.protobuf import descriptor as _descriptor
        +from google.protobuf import message as _message
        +from google.protobuf import reflection as _reflection
        +from google.protobuf import symbol_database as _symbol_database
        +# @@protoc_insertion_point(imports)
        +
        +_sym_db = _symbol_database.Default()
        +
        +
        +
        +
        +DESCRIPTOR = _descriptor.FileDescriptor(
        +  name='channel.proto',
        +  package='',
        +  syntax='proto3',
        +  serialized_options=b'\n\023com.geeksville.meshB\rChannelProtosH\003',
        +  create_key=_descriptor._internal_create_key,
        +  serialized_pb=b'\n\rchannel.proto\"\xe6\x02\n\x0f\x43hannelSettings\x12\x10\n\x08tx_power\x18\x01 \x01(\x05\x12\x32\n\x0cmodem_config\x18\x03 \x01(\x0e\x32\x1c.ChannelSettings.ModemConfig\x12\x11\n\tbandwidth\x18\x06 \x01(\r\x12\x15\n\rspread_factor\x18\x07 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x08 \x01(\r\x12\x13\n\x0b\x63hannel_num\x18\t \x01(\r\x12\x0b\n\x03psk\x18\x04 \x01(\x0c\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\n\n\x02id\x18\n \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x10 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x11 \x01(\x08\"`\n\x0bModemConfig\x12\x12\n\x0e\x42w125Cr45Sf128\x10\x00\x12\x12\n\x0e\x42w500Cr45Sf128\x10\x01\x12\x14\n\x10\x42w31_25Cr48Sf512\x10\x02\x12\x13\n\x0f\x42w125Cr48Sf4096\x10\x03\"\x8b\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\r\x12\"\n\x08settings\x18\x02 \x01(\x0b\x32\x10.ChannelSettings\x12\x1b\n\x04role\x18\x03 \x01(\x0e\x32\r.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42&\n\x13\x63om.geeksville.meshB\rChannelProtosH\x03\x62\x06proto3'
        +)
        +
        +
        +
        +_CHANNELSETTINGS_MODEMCONFIG = _descriptor.EnumDescriptor(
        +  name='ModemConfig',
        +  full_name='ChannelSettings.ModemConfig',
        +  filename=None,
        +  file=DESCRIPTOR,
        +  create_key=_descriptor._internal_create_key,
        +  values=[
        +    _descriptor.EnumValueDescriptor(
        +      name='Bw125Cr45Sf128', index=0, number=0,
        +      serialized_options=None,
        +      type=None,
        +      create_key=_descriptor._internal_create_key),
        +    _descriptor.EnumValueDescriptor(
        +      name='Bw500Cr45Sf128', index=1, number=1,
        +      serialized_options=None,
        +      type=None,
        +      create_key=_descriptor._internal_create_key),
        +    _descriptor.EnumValueDescriptor(
        +      name='Bw31_25Cr48Sf512', index=2, number=2,
        +      serialized_options=None,
        +      type=None,
        +      create_key=_descriptor._internal_create_key),
        +    _descriptor.EnumValueDescriptor(
        +      name='Bw125Cr48Sf4096', index=3, number=3,
        +      serialized_options=None,
        +      type=None,
        +      create_key=_descriptor._internal_create_key),
        +  ],
        +  containing_type=None,
        +  serialized_options=None,
        +  serialized_start=280,
        +  serialized_end=376,
        +)
        +_sym_db.RegisterEnumDescriptor(_CHANNELSETTINGS_MODEMCONFIG)
        +
        +_CHANNEL_ROLE = _descriptor.EnumDescriptor(
        +  name='Role',
        +  full_name='Channel.Role',
        +  filename=None,
        +  file=DESCRIPTOR,
        +  create_key=_descriptor._internal_create_key,
        +  values=[
        +    _descriptor.EnumValueDescriptor(
        +      name='DISABLED', index=0, number=0,
        +      serialized_options=None,
        +      type=None,
        +      create_key=_descriptor._internal_create_key),
        +    _descriptor.EnumValueDescriptor(
        +      name='PRIMARY', index=1, number=1,
        +      serialized_options=None,
        +      type=None,
        +      create_key=_descriptor._internal_create_key),
        +    _descriptor.EnumValueDescriptor(
        +      name='SECONDARY', index=2, number=2,
        +      serialized_options=None,
        +      type=None,
        +      create_key=_descriptor._internal_create_key),
        +  ],
        +  containing_type=None,
        +  serialized_options=None,
        +  serialized_start=470,
        +  serialized_end=518,
        +)
        +_sym_db.RegisterEnumDescriptor(_CHANNEL_ROLE)
        +
        +
        +_CHANNELSETTINGS = _descriptor.Descriptor(
        +  name='ChannelSettings',
        +  full_name='ChannelSettings',
        +  filename=None,
        +  file=DESCRIPTOR,
        +  containing_type=None,
        +  create_key=_descriptor._internal_create_key,
        +  fields=[
        +    _descriptor.FieldDescriptor(
        +      name='tx_power', full_name='ChannelSettings.tx_power', index=0,
        +      number=1, type=5, cpp_type=1, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='modem_config', full_name='ChannelSettings.modem_config', index=1,
        +      number=3, type=14, cpp_type=8, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='bandwidth', full_name='ChannelSettings.bandwidth', index=2,
        +      number=6, type=13, cpp_type=3, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='spread_factor', full_name='ChannelSettings.spread_factor', index=3,
        +      number=7, type=13, cpp_type=3, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='coding_rate', full_name='ChannelSettings.coding_rate', index=4,
        +      number=8, type=13, cpp_type=3, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='channel_num', full_name='ChannelSettings.channel_num', index=5,
        +      number=9, type=13, cpp_type=3, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='psk', full_name='ChannelSettings.psk', index=6,
        +      number=4, type=12, cpp_type=9, label=1,
        +      has_default_value=False, default_value=b"",
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='name', full_name='ChannelSettings.name', index=7,
        +      number=5, type=9, cpp_type=9, label=1,
        +      has_default_value=False, default_value=b"".decode('utf-8'),
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='id', full_name='ChannelSettings.id', index=8,
        +      number=10, type=7, cpp_type=3, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='uplink_enabled', full_name='ChannelSettings.uplink_enabled', index=9,
        +      number=16, type=8, cpp_type=7, label=1,
        +      has_default_value=False, default_value=False,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='downlink_enabled', full_name='ChannelSettings.downlink_enabled', index=10,
        +      number=17, type=8, cpp_type=7, label=1,
        +      has_default_value=False, default_value=False,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +  ],
        +  extensions=[
        +  ],
        +  nested_types=[],
        +  enum_types=[
        +    _CHANNELSETTINGS_MODEMCONFIG,
        +  ],
        +  serialized_options=None,
        +  is_extendable=False,
        +  syntax='proto3',
        +  extension_ranges=[],
        +  oneofs=[
        +  ],
        +  serialized_start=18,
        +  serialized_end=376,
        +)
        +
        +
        +_CHANNEL = _descriptor.Descriptor(
        +  name='Channel',
        +  full_name='Channel',
        +  filename=None,
        +  file=DESCRIPTOR,
        +  containing_type=None,
        +  create_key=_descriptor._internal_create_key,
        +  fields=[
        +    _descriptor.FieldDescriptor(
        +      name='index', full_name='Channel.index', index=0,
        +      number=1, type=13, cpp_type=3, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='settings', full_name='Channel.settings', index=1,
        +      number=2, type=11, cpp_type=10, label=1,
        +      has_default_value=False, default_value=None,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +    _descriptor.FieldDescriptor(
        +      name='role', full_name='Channel.role', index=2,
        +      number=3, type=14, cpp_type=8, label=1,
        +      has_default_value=False, default_value=0,
        +      message_type=None, enum_type=None, containing_type=None,
        +      is_extension=False, extension_scope=None,
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
        +  ],
        +  extensions=[
        +  ],
        +  nested_types=[],
        +  enum_types=[
        +    _CHANNEL_ROLE,
        +  ],
        +  serialized_options=None,
        +  is_extendable=False,
        +  syntax='proto3',
        +  extension_ranges=[],
        +  oneofs=[
        +  ],
        +  serialized_start=379,
        +  serialized_end=518,
        +)
        +
        +_CHANNELSETTINGS.fields_by_name['modem_config'].enum_type = _CHANNELSETTINGS_MODEMCONFIG
        +_CHANNELSETTINGS_MODEMCONFIG.containing_type = _CHANNELSETTINGS
        +_CHANNEL.fields_by_name['settings'].message_type = _CHANNELSETTINGS
        +_CHANNEL.fields_by_name['role'].enum_type = _CHANNEL_ROLE
        +_CHANNEL_ROLE.containing_type = _CHANNEL
        +DESCRIPTOR.message_types_by_name['ChannelSettings'] = _CHANNELSETTINGS
        +DESCRIPTOR.message_types_by_name['Channel'] = _CHANNEL
        +_sym_db.RegisterFileDescriptor(DESCRIPTOR)
        +
        +ChannelSettings = _reflection.GeneratedProtocolMessageType('ChannelSettings', (_message.Message,), {
        +  'DESCRIPTOR' : _CHANNELSETTINGS,
        +  '__module__' : 'channel_pb2'
        +  # @@protoc_insertion_point(class_scope:ChannelSettings)
        +  })
        +_sym_db.RegisterMessage(ChannelSettings)
        +
        +Channel = _reflection.GeneratedProtocolMessageType('Channel', (_message.Message,), {
        +  'DESCRIPTOR' : _CHANNEL,
        +  '__module__' : 'channel_pb2'
        +  # @@protoc_insertion_point(class_scope:Channel)
        +  })
        +_sym_db.RegisterMessage(Channel)
        +
        +
        +DESCRIPTOR._options = None
        +# @@protoc_insertion_point(module_scope)
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +

        Classes

        +
        +
        +class Channel +(*args, **kwargs) +
        +
        +

        A ProtocolMessage

        +

        Ancestors

        +
          +
        • google.protobuf.pyext._message.CMessage
        • +
        • google.protobuf.message.Message
        • +
        +

        Class variables

        +
        +
        var DESCRIPTOR
        +
        +
        +
        +
        var DISABLED
        +
        +
        +
        +
        var PRIMARY
        +
        +
        +
        +
        var Role
        +
        +
        +
        +
        var SECONDARY
        +
        +
        +
        +
        +

        Instance variables

        +
        +
        var index
        +
        +

        Field Channel.index

        +
        +
        var role
        +
        +

        Field Channel.role

        +
        +
        var settings
        +
        +

        Field Channel.settings

        +
        +
        +
        +
        +class ChannelSettings +(*args, **kwargs) +
        +
        +

        A ProtocolMessage

        +

        Ancestors

        +
          +
        • google.protobuf.pyext._message.CMessage
        • +
        • google.protobuf.message.Message
        • +
        +

        Class variables

        +
        +
        var Bw125Cr45Sf128
        +
        +
        +
        +
        var Bw125Cr48Sf4096
        +
        +
        +
        +
        var Bw31_25Cr48Sf512
        +
        +
        +
        +
        var Bw500Cr45Sf128
        +
        +
        +
        +
        var DESCRIPTOR
        +
        +
        +
        +
        var ModemConfig
        +
        +
        +
        +
        +

        Instance variables

        +
        +
        var bandwidth
        +
        +

        Field ChannelSettings.bandwidth

        +
        +
        var channel_num
        +
        +

        Field ChannelSettings.channel_num

        +
        +
        var coding_rate
        +
        +

        Field ChannelSettings.coding_rate

        +
        + +
        +

        Field ChannelSettings.downlink_enabled

        +
        +
        var id
        +
        +

        Field ChannelSettings.id

        +
        +
        var modem_config
        +
        +

        Field ChannelSettings.modem_config

        +
        +
        var name
        +
        +

        Field ChannelSettings.name

        +
        +
        var psk
        +
        +

        Field ChannelSettings.psk

        +
        +
        var spread_factor
        +
        +

        Field ChannelSettings.spread_factor

        +
        +
        var tx_power
        +
        +

        Field ChannelSettings.tx_power

        +
        + +
        +

        Field ChannelSettings.uplink_enabled

        +
        +
        +
        +
        +
        +
        + +
        + + + \ No newline at end of file diff --git a/docs/meshtastic/deviceonly_pb2.html b/docs/meshtastic/deviceonly_pb2.html index c2118be..e9b1ec6 100644 --- a/docs/meshtastic/deviceonly_pb2.html +++ b/docs/meshtastic/deviceonly_pb2.html @@ -5,7 +5,7 @@ meshtastic.deviceonly_pb2 API documentation - + @@ -22,6 +22,7 @@

        Module meshtastic.deviceonly_pb2

        +

        Generated protocol buffer code.

        Expand source code @@ -29,7 +30,7 @@
        # -*- coding: utf-8 -*-
         # Generated by the protocol buffer compiler.  DO NOT EDIT!
         # source: deviceonly.proto
        -
        +"""Generated protocol buffer code."""
         from google.protobuf import descriptor as _descriptor
         from google.protobuf import message as _message
         from google.protobuf import reflection as _reflection
        @@ -40,6 +41,8 @@ _sym_db = _symbol_database.Default()
         
         
         from . import mesh_pb2 as mesh__pb2
        +from . import radioconfig_pb2 as radioconfig__pb2
        +from . import channel_pb2 as channel__pb2
         
         
         DESCRIPTOR = _descriptor.FileDescriptor(
        @@ -47,9 +50,10 @@ DESCRIPTOR = _descriptor.FileDescriptor(
           package='',
           syntax='proto3',
           serialized_options=b'\n\023com.geeksville.meshB\nDeviceOnlyH\003',
        -  serialized_pb=b'\n\x10\x64\x65viceonly.proto\x1a\nmesh.proto\"\xab\x02\n\x0b\x44\x65viceState\x12\x1b\n\x05radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfig\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\x1a\n\x07node_db\x18\x04 \x03(\x0b\x32\t.NodeInfo\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07no_save\x18\t \x01(\x08\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\x12,\n\x12secondary_channels\x18\x0c \x03(\x0b\x32\x10.ChannelSettingsB#\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03\x62\x06proto3'
        +  create_key=_descriptor._internal_create_key,
        +  serialized_pb=b'\n\x10\x64\x65viceonly.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\x1a\rchannel.proto\"\x9f\x02\n\x0b\x44\x65viceState\x12\x1b\n\x05radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfig\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\x1a\n\x07node_db\x18\x04 \x03(\x0b\x32\t.NodeInfo\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07no_save\x18\t \x01(\x08\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\x12\x1a\n\x08\x63hannels\x18\r \x03(\x0b\x32\x08.ChannelJ\x04\x08\x0c\x10\rB#\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03\x62\x06proto3'
           ,
        -  dependencies=[mesh__pb2.DESCRIPTOR,])
        +  dependencies=[mesh__pb2.DESCRIPTOR,radioconfig__pb2.DESCRIPTOR,channel__pb2.DESCRIPTOR,])
         
         
         
        @@ -60,6 +64,7 @@ _DEVICESTATE = _descriptor.Descriptor(
           filename=None,
           file=DESCRIPTOR,
           containing_type=None,
        +  create_key=_descriptor._internal_create_key,
           fields=[
             _descriptor.FieldDescriptor(
               name='radio', full_name='DeviceState.radio', index=0,
        @@ -67,70 +72,70 @@ _DEVICESTATE = _descriptor.Descriptor(
               has_default_value=False, default_value=None,
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
               name='my_node', full_name='DeviceState.my_node', index=1,
               number=2, type=11, cpp_type=10, label=1,
               has_default_value=False, default_value=None,
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
               name='owner', full_name='DeviceState.owner', index=2,
               number=3, type=11, cpp_type=10, label=1,
               has_default_value=False, default_value=None,
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
               name='node_db', full_name='DeviceState.node_db', index=3,
               number=4, type=11, cpp_type=10, label=3,
               has_default_value=False, default_value=[],
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
               name='receive_queue', full_name='DeviceState.receive_queue', index=4,
               number=5, type=11, cpp_type=10, label=3,
               has_default_value=False, default_value=[],
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
               name='version', full_name='DeviceState.version', index=5,
               number=8, type=13, cpp_type=3, label=1,
               has_default_value=False, default_value=0,
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
               name='rx_text_message', full_name='DeviceState.rx_text_message', index=6,
               number=7, type=11, cpp_type=10, label=1,
               has_default_value=False, default_value=None,
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
               name='no_save', full_name='DeviceState.no_save', index=7,
               number=9, type=8, cpp_type=7, label=1,
               has_default_value=False, default_value=False,
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
               name='did_gps_reset', full_name='DeviceState.did_gps_reset', index=8,
               number=11, type=8, cpp_type=7, label=1,
               has_default_value=False, default_value=False,
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             _descriptor.FieldDescriptor(
        -      name='secondary_channels', full_name='DeviceState.secondary_channels', index=9,
        -      number=12, type=11, cpp_type=10, label=3,
        +      name='channels', full_name='DeviceState.channels', index=9,
        +      number=13, type=11, cpp_type=10, label=3,
               has_default_value=False, default_value=[],
               message_type=None, enum_type=None, containing_type=None,
               is_extension=False, extension_scope=None,
        -      serialized_options=None, file=DESCRIPTOR),
        +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           ],
           extensions=[
           ],
        @@ -143,17 +148,17 @@ _DEVICESTATE = _descriptor.Descriptor(
           extension_ranges=[],
           oneofs=[
           ],
        -  serialized_start=33,
        -  serialized_end=332,
        +  serialized_start=67,
        +  serialized_end=354,
         )
         
        -_DEVICESTATE.fields_by_name['radio'].message_type = mesh__pb2._RADIOCONFIG
        +_DEVICESTATE.fields_by_name['radio'].message_type = radioconfig__pb2._RADIOCONFIG
         _DEVICESTATE.fields_by_name['my_node'].message_type = mesh__pb2._MYNODEINFO
         _DEVICESTATE.fields_by_name['owner'].message_type = mesh__pb2._USER
         _DEVICESTATE.fields_by_name['node_db'].message_type = mesh__pb2._NODEINFO
         _DEVICESTATE.fields_by_name['receive_queue'].message_type = mesh__pb2._MESHPACKET
         _DEVICESTATE.fields_by_name['rx_text_message'].message_type = mesh__pb2._MESHPACKET
        -_DEVICESTATE.fields_by_name['secondary_channels'].message_type = mesh__pb2._CHANNELSETTINGS
        +_DEVICESTATE.fields_by_name['channels'].message_type = channel__pb2._CHANNEL
         DESCRIPTOR.message_types_by_name['DeviceState'] = _DEVICESTATE
         _sym_db.RegisterFileDescriptor(DESCRIPTOR)
         
        @@ -198,6 +203,10 @@ DESCRIPTOR._options = None
         
  • Instance variables

    +
    var channels
    +
    +

    Field DeviceState.channels

    +
    var did_gps_reset

    Field DeviceState.did_gps_reset

    @@ -230,10 +239,6 @@ DESCRIPTOR._options = None

    Field DeviceState.rx_text_message

    -
    var secondary_channels
    -
    -

    Field DeviceState.secondary_channels

    -
    var version

    Field DeviceState.version

    @@ -260,6 +265,7 @@ DESCRIPTOR._options = None

    DeviceState

    diff --git a/docs/meshtastic/environmental_measurement_pb2.html b/docs/meshtastic/environmental_measurement_pb2.html new file mode 100644 index 0000000..919316f --- /dev/null +++ b/docs/meshtastic/environmental_measurement_pb2.html @@ -0,0 +1,193 @@ + + + + + + +meshtastic.environmental_measurement_pb2 API documentation + + + + + + + + + + + +
    +
    +
    +

    Module meshtastic.environmental_measurement_pb2

    +
    +
    +

    Generated protocol buffer code.

    +
    + +Expand source code + +
    # -*- coding: utf-8 -*-
    +# Generated by the protocol buffer compiler.  DO NOT EDIT!
    +# source: environmental_measurement.proto
    +"""Generated protocol buffer code."""
    +from google.protobuf import descriptor as _descriptor
    +from google.protobuf import message as _message
    +from google.protobuf import reflection as _reflection
    +from google.protobuf import symbol_database as _symbol_database
    +# @@protoc_insertion_point(imports)
    +
    +_sym_db = _symbol_database.Default()
    +
    +
    +
    +
    +DESCRIPTOR = _descriptor.FileDescriptor(
    +  name='environmental_measurement.proto',
    +  package='',
    +  syntax='proto3',
    +  serialized_options=None,
    +  create_key=_descriptor._internal_create_key,
    +  serialized_pb=b'\n\x1f\x65nvironmental_measurement.proto\"g\n\x18\x45nvironmentalMeasurement\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x62\x06proto3'
    +)
    +
    +
    +
    +
    +_ENVIRONMENTALMEASUREMENT = _descriptor.Descriptor(
    +  name='EnvironmentalMeasurement',
    +  full_name='EnvironmentalMeasurement',
    +  filename=None,
    +  file=DESCRIPTOR,
    +  containing_type=None,
    +  create_key=_descriptor._internal_create_key,
    +  fields=[
    +    _descriptor.FieldDescriptor(
    +      name='temperature', full_name='EnvironmentalMeasurement.temperature', index=0,
    +      number=1, type=2, cpp_type=6, label=1,
    +      has_default_value=False, default_value=float(0),
    +      message_type=None, enum_type=None, containing_type=None,
    +      is_extension=False, extension_scope=None,
    +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    +    _descriptor.FieldDescriptor(
    +      name='relative_humidity', full_name='EnvironmentalMeasurement.relative_humidity', index=1,
    +      number=2, type=2, cpp_type=6, label=1,
    +      has_default_value=False, default_value=float(0),
    +      message_type=None, enum_type=None, containing_type=None,
    +      is_extension=False, extension_scope=None,
    +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    +    _descriptor.FieldDescriptor(
    +      name='barometric_pressure', full_name='EnvironmentalMeasurement.barometric_pressure', index=2,
    +      number=3, type=2, cpp_type=6, label=1,
    +      has_default_value=False, default_value=float(0),
    +      message_type=None, enum_type=None, containing_type=None,
    +      is_extension=False, extension_scope=None,
    +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    +  ],
    +  extensions=[
    +  ],
    +  nested_types=[],
    +  enum_types=[
    +  ],
    +  serialized_options=None,
    +  is_extendable=False,
    +  syntax='proto3',
    +  extension_ranges=[],
    +  oneofs=[
    +  ],
    +  serialized_start=35,
    +  serialized_end=138,
    +)
    +
    +DESCRIPTOR.message_types_by_name['EnvironmentalMeasurement'] = _ENVIRONMENTALMEASUREMENT
    +_sym_db.RegisterFileDescriptor(DESCRIPTOR)
    +
    +EnvironmentalMeasurement = _reflection.GeneratedProtocolMessageType('EnvironmentalMeasurement', (_message.Message,), {
    +  'DESCRIPTOR' : _ENVIRONMENTALMEASUREMENT,
    +  '__module__' : 'environmental_measurement_pb2'
    +  # @@protoc_insertion_point(class_scope:EnvironmentalMeasurement)
    +  })
    +_sym_db.RegisterMessage(EnvironmentalMeasurement)
    +
    +
    +# @@protoc_insertion_point(module_scope)
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +class EnvironmentalMeasurement +(*args, **kwargs) +
    +
    +

    A ProtocolMessage

    +

    Ancestors

    +
      +
    • google.protobuf.pyext._message.CMessage
    • +
    • google.protobuf.message.Message
    • +
    +

    Class variables

    +
    +
    var DESCRIPTOR
    +
    +
    +
    +
    +

    Instance variables

    +
    +
    var barometric_pressure
    +
    +

    Field EnvironmentalMeasurement.barometric_pressure

    +
    +
    var relative_humidity
    +
    +

    Field EnvironmentalMeasurement.relative_humidity

    +
    +
    var temperature
    +
    +

    Field EnvironmentalMeasurement.temperature

    +
    +
    +
    +
    +
    +
    + +
    + + + \ No newline at end of file diff --git a/docs/meshtastic/index.html b/docs/meshtastic/index.html index 8a8e58d..7943728 100644 --- a/docs/meshtastic/index.html +++ b/docs/meshtastic/index.html @@ -142,18 +142,29 @@ interface = meshtastic.SerialInterface() """ -import socket import pygatt import google.protobuf.json_format -import serial, threading, logging, sys, random, traceback, time, base64, platform -from . import mesh_pb2, portnums_pb2, util +import serial +import threading +import logging +import sys +import random +import traceback +import time +import base64 +import platform +import socket +from . import mesh_pb2, portnums_pb2, apponly_pb2, admin_pb2, environmental_measurement_pb2, remote_hardware_pb2, channel_pb2, radioconfig_pb2, util +from .util import fixme, catchAndIgnore, stripnl from pubsub import pub from dotmap import DotMap +from typing import * START1 = 0x94 START2 = 0xc3 HEADER_LEN = 4 MAX_TO_FROM_RADIO_SIZE = 512 +defaultHopLimit = 3 BROADCAST_ADDR = "^all" # A special ID that means broadcast @@ -166,7 +177,25 @@ MY_CONFIG_ID = 42 format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20 """ -OUR_APP_VERSION = 20120 +OUR_APP_VERSION = 20200 + + +class ResponseHandler(NamedTuple): + """A pending response callback, waiting for a response to one of our messages""" + # requestId: int - used only as a key + callback: Callable + # FIXME, add timestamp and age out old requests + + +class KnownProtocol(NamedTuple): + """Used to automatically decode known protocol payloads""" + name: str + # portnum: int, now a key + # If set, will be called to prase as a protocol buffer + protobufFactory: Callable = None + # If set, invoked as onReceive(interface, packet) + onReceive: Callable = None + class MeshInterface: """Interface class for meshtastic devices @@ -188,7 +217,10 @@ class MeshInterface: self.nodes = None # FIXME self.isConnected = threading.Event() self.noProto = noProto - random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it + self.myInfo = None # We don't have device info yet + self.responseHandlers = {} # A map from request ID to the handler + self.failure = None # If we've encountered a fatal exception it will be kept here + random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it self.currentPacketId = random.randint(0, 0xffffffff) self._startConfig() @@ -197,12 +229,18 @@ class MeshInterface: def __exit__(self, exc_type, exc_value, traceback): if exc_type is not None and exc_value is not None: - logging.error(f'An exception of type {exc_type} with value {exc_value} has occurred') + logging.error( + f'An exception of type {exc_type} with value {exc_value} has occurred') if traceback is not None: logging.error(f'Traceback: {traceback}') self.close() - def sendText(self, text, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False): + def sendText(self, text: AnyStr, + destinationId=BROADCAST_ADDR, + wantAck=False, + wantResponse=False, + hopLimit=defaultHopLimit, + onResponse=None): """Send a utf8 string to some other node, if the node has a display it will also be shown on the device. Arguments: @@ -212,13 +250,22 @@ class MeshInterface: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery) + wantResponse -- True if you want the service on the other side to send an application layer response Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ return self.sendData(text.encode("utf-8"), destinationId, - portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, wantAck=wantAck, wantResponse=wantResponse) + portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, + wantAck=wantAck, + wantResponse=wantResponse, + hopLimit=hopLimit, + onResponse=onResponse) - def sendData(self, data, destinationId=BROADCAST_ADDR, portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False, wantResponse=False): + def sendData(self, data, destinationId=BROADCAST_ADDR, + portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False, + wantResponse=False, + hopLimit=defaultHopLimit, + onResponse=None): """Send a data packet to some other node Keyword Arguments: @@ -226,20 +273,30 @@ class MeshInterface: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery) + wantResponse -- True if you want the service on the other side to send an application layer response + onResponse -- A closure of the form funct(packet), that will be called when a response packet arrives (or the transaction is NAKed due to non receipt) Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ if getattr(data, "SerializeToString", None): - logging.debug(f"Serializing protobuf as data: {data}") + logging.debug(f"Serializing protobuf as data: {stripnl(data)}") data = data.SerializeToString() if len(data) > mesh_pb2.Constants.DATA_PAYLOAD_LEN: raise Exception("Data payload too big") + + if portNum == portnums_pb2.PortNum.UNKNOWN_APP: # we are now more strict wrt port numbers + raise Exception("A non-zero port number must be specified") + meshPacket = mesh_pb2.MeshPacket() - meshPacket.decoded.data.payload = data - meshPacket.decoded.data.portnum = portNum + meshPacket.decoded.payload = data + meshPacket.decoded.portnum = portNum meshPacket.decoded.want_response = wantResponse - return self.sendPacket(meshPacket, destinationId, wantAck=wantAck) + + p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck, hopLimit=hopLimit) + if onResponse is not None: + self._addResponseHandler(p.id, onResponse) + return p def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False): """ @@ -266,18 +323,29 @@ class MeshInterface: timeSec = time.time() # returns unix timestamp in seconds p.time = int(timeSec) - return self.sendData(p, destinationId, portNum=portnums_pb2.PortNum.POSITION_APP, wantAck=wantAck, wantResponse=wantResponse) + return self.sendData(p, destinationId, + portNum=portnums_pb2.PortNum.POSITION_APP, + wantAck=wantAck, + wantResponse=wantResponse) - def sendPacket(self, meshPacket, destinationId=BROADCAST_ADDR, wantAck=False): + def _addResponseHandler(self, requestId, callback): + self.responseHandlers[requestId] = ResponseHandler(callback) + + def _sendPacket(self, meshPacket, + destinationId=BROADCAST_ADDR, + wantAck=False, hopLimit=defaultHopLimit): """Send a MeshPacket to the specified node (or if unspecified, broadcast). You probably don't want this - use sendData instead. - Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. + Returns the sent packet. The id field will be populated in this packet and + can be used to track future message acks/naks. """ - self._waitConnected() + + # We allow users to talk to the local node before we've completed the full connection flow... + if(self.myInfo is not None and destinationId != self.myInfo.my_node_num): + self._waitConnected() toRadio = mesh_pb2.ToRadio() - # FIXME add support for non broadcast addresses if destinationId is None: raise Exception("destinationId must not be None") @@ -290,6 +358,7 @@ class MeshInterface: meshPacket.to = nodeNum meshPacket.want_ack = wantAck + meshPacket.hop_limit = hopLimit # if the user hasn't set an ID for this packet (likely and recommended), we should pick a new unique ID # so the message can be tracked. @@ -297,10 +366,11 @@ class MeshInterface: meshPacket.id = self._generatePacketId() toRadio.packet.CopyFrom(meshPacket) + #logging.debug(f"Sending packet: {stripnl(meshPacket)}") self._sendToRadio(toRadio) return meshPacket - def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig')): + def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig', 'channels')): """Block until radio config is received. Returns True if config has been received.""" for _ in range(int(maxsecs/sleep)): if all(map(lambda a: getattr(self, a, None), attrs)): @@ -313,11 +383,25 @@ class MeshInterface: if self.radioConfig == None: raise Exception("No RadioConfig has been read") - t = mesh_pb2.ToRadio() - t.set_radio.CopyFrom(self.radioConfig) - self._sendToRadio(t) + p = admin_pb2.AdminMessage() + p.set_radio.CopyFrom(self.radioConfig) + + self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) logging.debug("Wrote config") + def writeChannel(self, channelIndex): + """Write the current (edited) channel to the device""" + + p = admin_pb2.AdminMessage() + p.set_channel.CopyFrom(self.channels[channelIndex]) + + self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) + logging.debug("Wrote channel {channelIndex}") + def getMyNodeInfo(self): if self.myInfo is None: return None @@ -358,43 +442,66 @@ class MeshInterface: short_name = long_name[0] + long_name[1:].translate(trans) if len(short_name) < nChars: short_name = long_name[:nChars] - t = mesh_pb2.ToRadio() + + p = admin_pb2.AdminMessage() + if long_name is not None: - t.set_owner.long_name = long_name + p.set_owner.long_name = long_name if short_name is not None: short_name = short_name.strip() if len(short_name) > nChars: short_name = short_name[:nChars] - t.set_owner.short_name = short_name - self._sendToRadio(t) + p.set_owner.short_name = short_name + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) @property def channelURL(self): """The sharable URL that describes the current channel """ - bytes = self.radioConfig.channel_settings.SerializeToString() + # Only keep the primary/secondary channels, assume primary is first + channelSet = apponly_pb2.ChannelSet() + for c in self.channels: + if c.role != channel_pb2.Channel.Role.DISABLED: + channelSet.settings.append(c.settings) + bytes = channelSet.SerializeToString() s = base64.urlsafe_b64encode(bytes).decode('ascii') - return f"https://www.meshtastic.org/c/#{s}" + return f"https://www.meshtastic.org/d/#{s}".replace("=", "") - def setURL(self, url, write=True): + def setURL(self, url): """Set mesh network URL""" if self.radioConfig == None: raise Exception("No RadioConfig has been read") - # URLs are of the form https://www.meshtastic.org/c/#{base64_channel_settings} + # URLs are of the form https://www.meshtastic.org/d/#{base64_channel_set} # Split on '/#' to find the base64 encoded channel settings splitURL = url.split("/#") decodedURL = base64.urlsafe_b64decode(splitURL[-1]) - self.radioConfig.channel_settings.ParseFromString(decodedURL) - if write: - self.writeConfig() + channelSet = apponly_pb2.ChannelSet() + channelSet.ParseFromString(decodedURL) + + i = 0 + for chs in channelSet.settings: + ch = channel_pb2.Channel() + ch.role = channel_pb2.Channel.Role.PRIMARY if i == 0 else channel_pb2.Channel.Role.SECONDARY + ch.index = i + ch.settings.CopyFrom(chs) + self.channels[ch.index] = ch + self.writeChannel(ch.index) + i = i + 1 def _waitConnected(self): """Block until the initial node db download is complete, or timeout and raise an exception""" - if not self.isConnected.wait(5.0): # timeout after 5 seconds + if not self.isConnected.wait(5.0): # timeout after 5 seconds raise Exception("Timed out waiting for connection completion") + # If we failed while connecting, raise the connection to the client + if self.failure: + raise self.failure + def _generatePacketId(self): """Get a new unique packet ID""" if self.currentPacketId is None: @@ -406,13 +513,15 @@ class MeshInterface: def _disconnected(self): """Called by subclasses to tell clients this interface has disconnected""" self.isConnected.clear() - pub.sendMessage("meshtastic.connection.lost", interface=self) + catchAndIgnore("disconnection publish", lambda: pub.sendMessage( + "meshtastic.connection.lost", interface=self)) def _connected(self): """Called by this class to tell clients we are now fully connected to a node """ self.isConnected.set() - pub.sendMessage("meshtastic.connection.established", interface=self) + catchAndIgnore("connection publish", lambda: pub.sendMessage( + "meshtastic.connection.established", interface=self)) def _startConfig(self): """Start device packets flowing""" @@ -420,6 +529,8 @@ class MeshInterface: self.nodes = {} # nodes keyed by ID self.nodesByNum = {} # nodes keyed by nodenum self.radioConfig = None + self.channels = None + self.partialChannels = [] # We keep our channels in a temp array until finished startConfig = mesh_pb2.ToRadio() startConfig.want_config_id = MY_CONFIG_ID # we don't use this value @@ -428,14 +539,74 @@ class MeshInterface: def _sendToRadio(self, toRadio): """Send a ToRadio protobuf to the device""" if self.noProto: - logging.warn(f"Not sending packet because protocol use is disabled by noProto") + logging.warn( + f"Not sending packet because protocol use is disabled by noProto") else: + #logging.debug(f"Sending toRadio: {stripnl(toRadio)}") self._sendToRadioImpl(toRadio) def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" logging.error(f"Subclass must provide toradio: {toRadio}") + def _handleConfigComplete(self): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings and channels + """ + self._requestSettings() + self._requestChannel(0) + + def _requestSettings(self): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings + """ + p = admin_pb2.AdminMessage() + p.get_radio_request = True + + def onResponse(p): + """A closure to handle the response packet""" + self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True, + wantResponse=True, + onResponse=onResponse) + + def _requestChannel(self, channelNum: int): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings + """ + p = admin_pb2.AdminMessage() + p.get_channel_request = channelNum + 1 + logging.debug(f"Requesting channel {channelNum}") + + def onResponse(p): + """A closure to handle the response packet""" + c = p["decoded"]["admin"]["raw"].get_channel_response + self.partialChannels.append(c) + logging.debug(f"Received channel {stripnl(c)}") + index = c.index + + # for stress testing, we can always download all channels + fastChannelDownload = True + + # Once we see a response that has NO settings, assume we are at the end of channels and stop fetching + quitEarly = (c.role == channel_pb2.Channel.Role.DISABLED) and fastChannelDownload + + if quitEarly or index >= self.myInfo.max_channels - 1: + self.channels = self.partialChannels + # FIXME, the following should only be called after we have settings and channels + self._connected() # Tell everone else we are ready to go + else: + self._requestChannel(index + 1) + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True, + wantResponse=True, + onResponse=onResponse) + def _handleFromRadio(self, fromRadioBytes): """ Handle a packet that arrived from the radio(update model and publish events) @@ -444,28 +615,41 @@ class MeshInterface: fromRadio = mesh_pb2.FromRadio() fromRadio.ParseFromString(fromRadioBytes) asDict = google.protobuf.json_format.MessageToDict(fromRadio) - logging.debug(f"Received: {asDict}") if fromRadio.HasField("my_info"): self.myInfo = fromRadio.my_info + logging.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}") + + failmsg = None + # Check for app too old if self.myInfo.min_app_version > OUR_APP_VERSION: - raise Exception( - "This device needs a newer python client, please \"pip install --upgrade meshtastic\"") - # start assigning our packet IDs from the opposite side of where our local device is assigning them - elif fromRadio.HasField("radio"): - self.radioConfig = fromRadio.radio + failmsg = "This device needs a newer python client, please \"pip install --upgrade meshtastic\". For more information see https://tinyurl.com/5bjsxu32" + + # check for firmware too old + if self.myInfo.max_channels == 0: + failmsg = "This version of meshtastic-python requires device firmware version 1.2 or later. For more information see https://tinyurl.com/5bjsxu32" + + if failmsg: + self.failure = Exception(failmsg) + self.isConnected.set() # let waitConnected return this exception + self.close() + elif fromRadio.HasField("node_info"): node = asDict["nodeInfo"] try: self._fixupPosition(node["position"]) except: logging.debug("Node without position") + + logging.debug(f"Received nodeinfo: {node}") + self.nodesByNum[node["num"]] = node if "user" in node: # Some nodes might not have user/ids assigned yet self.nodes[node["user"]["id"]] = node - pub.sendMessage("meshtastic.node.updated", node=node, interface=self) + pub.sendMessage("meshtastic.node.updated", + node=node, interface=self) elif fromRadio.config_complete_id == MY_CONFIG_ID: # we ignore the config_complete_id, it is unneeded for our stream API fromRadio.config_complete_id - self._connected() + self._handleConfigComplete() elif fromRadio.HasField("packet"): self._handlePacketFromRadio(fromRadio.packet) elif fromRadio.rebooted: @@ -528,6 +712,20 @@ class MeshInterface: """ asDict = google.protobuf.json_format.MessageToDict(meshPacket) + + # We normally decompose the payload into a dictionary so that the client + # doesn't need to understand protobufs. But advanced clients might + # want the raw protobuf, so we provide it in "raw" + asDict["raw"] = meshPacket + + # from might be missing if the nodenum was zero. + if not "from" in asDict: + asDict["from"] = 0 + logging.error(f"Device returned a packet we sent, ignoring: {stripnl(asDict)}") + return + if not "to" in asDict: + asDict["to"] = 0 + # /add fromId and toId fields based on the node ID asDict["fromId"] = self._nodeNumToId(asDict["from"]) asDict["toId"] = self._nodeNumToId(asDict["to"]) @@ -536,68 +734,59 @@ class MeshInterface: # asObj = DotMap(asDict) topic = "meshtastic.receive" # Generic unknown packet type - # Warn users if firmware doesn't use new portnum based data encodings - # But do not crash, because the lib will still basically work and ignore those packet types - if meshPacket.decoded.HasField("user") or meshPacket.decoded.HasField("position"): - logging.warn("Ignoring old position/user message. Recommend you update firmware to 1.1.20 or later") + decoded = asDict["decoded"] + # The default MessageToDict converts byte arrays into base64 strings. + # We don't want that - it messes up data payload. So slam in the correct + # byte array. + decoded["payload"] = meshPacket.decoded.payload - if meshPacket.decoded.HasField("data"): + # UNKNOWN_APP is the default protobuf portnum value, and therefore if not set it will not be populated at all + # to make API usage easier, set it to prevent confusion + if not "portnum" in decoded: + decoded["portnum"] = portnums_pb2.PortNum.Name( + portnums_pb2.PortNum.UNKNOWN_APP) - # The default MessageToDict converts byte arrays into base64 strings. - # We don't want that - it messes up data payload. So slam in the correct - # byte array. - asDict["decoded"]["data"]["payload"] = meshPacket.decoded.data.payload + portnum = decoded["portnum"] - # UNKNOWN_APP is the default protobuf portnum value, and therefore if not set it will not be populated at all - # to make API usage easier, set it to prevent confusion - if not "portnum" in asDict["decoded"]["data"]: - asDict["decoded"]["data"]["portnum"] = portnums_pb2.PortNum.Name(portnums_pb2.PortNum.UNKNOWN_APP) + topic = f"meshtastic.receive.data.{portnum}" - portnum = asDict["decoded"]["data"]["portnum"] + # decode position protobufs and update nodedb, provide decoded version as "position" in the published msg + # move the following into a 'decoders' API that clients could register? + portNumInt = meshPacket.decoded.portnum # we want portnum as an int + handler = protocols.get(portNumInt) + # The decoded protobuf as a dictionary (if we understand this message) + p = None + if handler is not None: + topic = f"meshtastic.receive.{handler.name}" - topic = f"meshtastic.receive.data.{portnum}" - - # For text messages, we go ahead and decode the text to ascii for our users - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.TEXT_MESSAGE_APP): - topic = "meshtastic.receive.text" - - # We don't throw if the utf8 is invalid in the text message. Instead we just don't populate - # the decoded.data.text and we log an error message. This at least allows some delivery to - # the app and the app can deal with the missing decoded representation. - # - # Usually btw this problem is caused by apps sending binary data but setting the payload type to - # text. - try: - asDict["decoded"]["data"]["text"] = meshPacket.decoded.data.payload.decode("utf-8") - except Exception as ex: - logging.error(f"Malformatted utf8 in text message: {ex}") - - # decode position protobufs and update nodedb, provide decoded version as "position" in the published msg - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.POSITION_APP): - topic = "meshtastic.receive.position" - pb = mesh_pb2.Position() - pb.ParseFromString(meshPacket.decoded.data.payload) + # Convert to protobuf if possible + if handler.protobufFactory is not None: + pb = handler.protobufFactory() + pb.ParseFromString(meshPacket.decoded.payload) p = google.protobuf.json_format.MessageToDict(pb) - self._fixupPosition(p) - asDict["decoded"]["data"]["position"] = p - # update node DB as needed - self._getOrCreateByNum(asDict["from"])["position"] = p + asDict["decoded"][handler.name] = p + # Also provide the protobuf raw + asDict["decoded"][handler.name]["raw"] = pb - # decode user protobufs and update nodedb, provide decoded version as "position" in the published msg - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.NODEINFO_APP): - topic = "meshtastic.receive.user" - pb = mesh_pb2.User() - pb.ParseFromString(meshPacket.decoded.data.payload) - u = google.protobuf.json_format.MessageToDict(pb) - asDict["decoded"]["data"]["user"] = u - # update node DB as needed - n = self._getOrCreateByNum(asDict["from"]) - n["user"] = u - # We now have a node ID, make sure it is uptodate in that table - self.nodes[u["id"]] = n + # Call specialized onReceive if necessary + if handler.onReceive is not None: + handler.onReceive(self, asDict) - logging.debug(f"Publishing topic {topic}") - pub.sendMessage(topic, packet=asDict, interface=self) + # Is this message in response to a request, if so, look for a handler + requestId = decoded.get("requestId") + if requestId is not None: + # We ignore ACK packets, but send NAKs and data responses to the handlers + routing = decoded.get("routing") + isAck = routing is not None and ("errorReason" not in routing) + if not isAck: + # we keep the responseHandler in dict until we get a non ack + handler = self.responseHandlers.pop(requestId, None) + if handler is not None: + handler.callback(asDict) + + logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ") + catchAndIgnore(f"publishing {topic}", lambda: pub.sendMessage( + topic, packet=asDict, interface=self)) # Our standard BLE characteristics @@ -628,7 +817,7 @@ class BLEInterface(MeshInterface): def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" - logging.debug(f"Sending: {toRadio}") + # logging.debug(f"Sending: {stripnl(toRadio)}") b = toRadio.SerializeToString() self.device.char_write(TORADIO_UUID, b) @@ -686,7 +875,7 @@ class StreamInterface(MeshInterface): time.sleep(0.1) # wait 100ms to give device time to start running self._rxThread.start() - if not self.noProto: # Wait for the db download if using the protocol + if not self.noProto: # Wait for the db download if using the protocol self._waitConnected() def _disconnected(self): @@ -708,7 +897,7 @@ class StreamInterface(MeshInterface): def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" - logging.debug(f"Sending: {toRadio}") + logging.debug(f"Sending: {stripnl(toRadio)}") b = toRadio.SerializeToString() bufLen = len(b) # We convert into a string, because the TCP code doesn't work with byte arrays @@ -772,13 +961,16 @@ class StreamInterface(MeshInterface): # logging.debug(f"timeout") pass except serial.SerialException as ex: - if not self._wantExit: # We might intentionally get an exception during shutdown - logging.warn(f"Meshtastic serial port disconnected, disconnecting... {ex}") + if not self._wantExit: # We might intentionally get an exception during shutdown + logging.warn( + f"Meshtastic serial port disconnected, disconnecting... {ex}") except OSError as ex: - if not self._wantExit: # We might intentionally get an exception during shutdown - logging.error(f"Unexpected OSError, terminating meshtastic reader... {ex}") + if not self._wantExit: # We might intentionally get an exception during shutdown + logging.error( + f"Unexpected OSError, terminating meshtastic reader... {ex}") except Exception as ex: - logging.error(f"Unexpected exception, terminating meshtastic reader... {ex}") + logging.error( + f"Unexpected exception, terminating meshtastic reader... {ex}") finally: logging.debug("reader is exiting") self._disconnected() @@ -826,10 +1018,11 @@ class SerialInterface(StreamInterface): StreamInterface.__init__( self, debugOut=debugOut, noProto=noProto, connectNow=connectNow) + class TCPInterface(StreamInterface): """Interface class for meshtastic devices over a TCP link""" - def __init__(self, hostname, debugOut=None, noProto=False, connectNow=True, portNumber=4403): + def __init__(self, hostname: AnyStr, debugOut=None, noProto=False, connectNow=True, portNumber=4403): """Constructor, opens a connection to a specified IP address/hostname Keyword Arguments: @@ -852,9 +1045,9 @@ class TCPInterface(StreamInterface): def close(self): """Close a connection to the device""" logging.debug("Closing TCP stream") - # Sometimes the socket read might be blocked in the reader thread. Therefore we force the shutdown by closing + # Sometimes the socket read might be blocked in the reader thread. Therefore we force the shutdown by closing # the socket here - self._wantExit = True + self._wantExit = True if not self.socket is None: self.socket.shutdown(socket.SHUT_RDWR) self.socket.close() @@ -866,31 +1059,94 @@ class TCPInterface(StreamInterface): def _readBytes(self, len): """Read an array of bytes from our stream""" - return self.socket.recv(len)
    + return self.socket.recv(len) + + +def _onTextReceive(iface, asDict): + """Special text auto parsing for received messages""" + # We don't throw if the utf8 is invalid in the text message. Instead we just don't populate + # the decoded.data.text and we log an error message. This at least allows some delivery to + # the app and the app can deal with the missing decoded representation. + # + # Usually btw this problem is caused by apps sending binary data but setting the payload type to + # text. + try: + asBytes = asDict["decoded"]["payload"] + asDict["decoded"]["text"] = asBytes.decode("utf-8") + except Exception as ex: + logging.error(f"Malformatted utf8 in text message: {ex}") + + +def _onPositionReceive(iface, asDict): + """Special auto parsing for received messages""" + p = asDict["decoded"]["position"] + iface._fixupPosition(p) + # update node DB as needed + iface._getOrCreateByNum(asDict["from"])["position"] = p + + +def _onNodeInfoReceive(iface, asDict): + """Special auto parsing for received messages""" + p = asDict["decoded"]["user"] + # decode user protobufs and update nodedb, provide decoded version as "position" in the published msg + # update node DB as needed + n = iface._getOrCreateByNum(asDict["from"]) + n["user"] = p + # We now have a node ID, make sure it is uptodate in that table + iface.nodes[p["id"]] = n + + +"""Well known message payloads can register decoders for automatic protobuf parsing""" +protocols = { + portnums_pb2.PortNum.TEXT_MESSAGE_APP: KnownProtocol("text", onReceive=_onTextReceive), + portnums_pb2.PortNum.POSITION_APP: KnownProtocol("position", mesh_pb2.Position, _onPositionReceive), + portnums_pb2.PortNum.NODEINFO_APP: KnownProtocol("user", mesh_pb2.User, _onNodeInfoReceive), + portnums_pb2.PortNum.ADMIN_APP: KnownProtocol("admin", admin_pb2.AdminMessage), + portnums_pb2.PortNum.ROUTING_APP: KnownProtocol("routing", mesh_pb2.Routing), + portnums_pb2.PortNum.ENVIRONMENTAL_MEASUREMENT_APP: KnownProtocol("environmental", environmental_measurement_pb2.EnvironmentalMeasurement), + portnums_pb2.PortNum.REMOTE_HARDWARE_APP: KnownProtocol( + "remotehw", remote_hardware_pb2.HardwareMessage) +}

    Sub-modules

    +
    meshtastic.admin_pb2
    +
    +

    Generated protocol buffer code.

    +
    meshtastic.apponly_pb2
    -
    +

    Generated protocol buffer code.

    meshtastic.ble
    +
    meshtastic.channel_pb2
    +
    +

    Generated protocol buffer code.

    +
    meshtastic.deviceonly_pb2
    -
    +

    Generated protocol buffer code.

    +
    +
    meshtastic.environmental_measurement_pb2
    +
    +

    Generated protocol buffer code.

    meshtastic.mesh_pb2
    -
    +

    Generated protocol buffer code.

    meshtastic.portnums_pb2
    -
    +

    Generated protocol buffer code.

    +
    +
    meshtastic.radioconfig_pb2
    +
    +

    Generated protocol buffer code.

    meshtastic.remote_hardware
    @@ -898,7 +1154,7 @@ class TCPInterface(StreamInterface):
    meshtastic.remote_hardware_pb2
    -
    +

    Generated protocol buffer code.

    meshtastic.test
    @@ -964,7 +1220,7 @@ noProto – If True, don't try to run our protocol on the link - just be a d def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" - logging.debug(f"Sending: {toRadio}") + # logging.debug(f"Sending: {stripnl(toRadio)}") b = toRadio.SerializeToString() self.device.char_write(TORADIO_UUID, b) @@ -1005,17 +1261,56 @@ noProto – If True, don't try to run our protocol on the link - just be a d
    +
    +class KnownProtocol +(name: str, protobufFactory: Callable = None, onReceive: Callable = None) +
    +
    +

    Used to automatically decode known protocol payloads

    +
    + +Expand source code + +
    class KnownProtocol(NamedTuple):
    +    """Used to automatically decode known protocol payloads"""
    +    name: str
    +    # portnum: int, now a key
    +    # If set, will be called to prase as a protocol buffer
    +    protobufFactory: Callable = None
    +    # If set, invoked as onReceive(interface, packet)
    +    onReceive: Callable = None
    +
    +

    Ancestors

    +
      +
    • builtins.tuple
    • +
    +

    Instance variables

    +
    +
    var name : str
    +
    +

    Alias for field number 0

    +
    +
    var onReceive : Callable
    +
    +

    Alias for field number 2

    +
    +
    var protobufFactory : Callable
    +
    +

    Alias for field number 1

    +
    +
    +
    class MeshInterface (debugOut=None, noProto=False) @@ -1053,7 +1348,10 @@ noProto – If True, don't try to run our protocol on the link - just be a d self.nodes = None # FIXME self.isConnected = threading.Event() self.noProto = noProto - random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it + self.myInfo = None # We don't have device info yet + self.responseHandlers = {} # A map from request ID to the handler + self.failure = None # If we've encountered a fatal exception it will be kept here + random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it self.currentPacketId = random.randint(0, 0xffffffff) self._startConfig() @@ -1062,12 +1360,18 @@ noProto – If True, don't try to run our protocol on the link - just be a d def __exit__(self, exc_type, exc_value, traceback): if exc_type is not None and exc_value is not None: - logging.error(f'An exception of type {exc_type} with value {exc_value} has occurred') + logging.error( + f'An exception of type {exc_type} with value {exc_value} has occurred') if traceback is not None: logging.error(f'Traceback: {traceback}') self.close() - def sendText(self, text, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False): + def sendText(self, text: AnyStr, + destinationId=BROADCAST_ADDR, + wantAck=False, + wantResponse=False, + hopLimit=defaultHopLimit, + onResponse=None): """Send a utf8 string to some other node, if the node has a display it will also be shown on the device. Arguments: @@ -1077,13 +1381,22 @@ noProto – If True, don't try to run our protocol on the link - just be a d destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery) + wantResponse -- True if you want the service on the other side to send an application layer response Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ return self.sendData(text.encode("utf-8"), destinationId, - portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, wantAck=wantAck, wantResponse=wantResponse) + portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, + wantAck=wantAck, + wantResponse=wantResponse, + hopLimit=hopLimit, + onResponse=onResponse) - def sendData(self, data, destinationId=BROADCAST_ADDR, portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False, wantResponse=False): + def sendData(self, data, destinationId=BROADCAST_ADDR, + portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False, + wantResponse=False, + hopLimit=defaultHopLimit, + onResponse=None): """Send a data packet to some other node Keyword Arguments: @@ -1091,20 +1404,30 @@ noProto – If True, don't try to run our protocol on the link - just be a d destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery) + wantResponse -- True if you want the service on the other side to send an application layer response + onResponse -- A closure of the form funct(packet), that will be called when a response packet arrives (or the transaction is NAKed due to non receipt) Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ if getattr(data, "SerializeToString", None): - logging.debug(f"Serializing protobuf as data: {data}") + logging.debug(f"Serializing protobuf as data: {stripnl(data)}") data = data.SerializeToString() if len(data) > mesh_pb2.Constants.DATA_PAYLOAD_LEN: raise Exception("Data payload too big") + + if portNum == portnums_pb2.PortNum.UNKNOWN_APP: # we are now more strict wrt port numbers + raise Exception("A non-zero port number must be specified") + meshPacket = mesh_pb2.MeshPacket() - meshPacket.decoded.data.payload = data - meshPacket.decoded.data.portnum = portNum + meshPacket.decoded.payload = data + meshPacket.decoded.portnum = portNum meshPacket.decoded.want_response = wantResponse - return self.sendPacket(meshPacket, destinationId, wantAck=wantAck) + + p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck, hopLimit=hopLimit) + if onResponse is not None: + self._addResponseHandler(p.id, onResponse) + return p def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False): """ @@ -1131,18 +1454,29 @@ noProto – If True, don't try to run our protocol on the link - just be a d timeSec = time.time() # returns unix timestamp in seconds p.time = int(timeSec) - return self.sendData(p, destinationId, portNum=portnums_pb2.PortNum.POSITION_APP, wantAck=wantAck, wantResponse=wantResponse) + return self.sendData(p, destinationId, + portNum=portnums_pb2.PortNum.POSITION_APP, + wantAck=wantAck, + wantResponse=wantResponse) - def sendPacket(self, meshPacket, destinationId=BROADCAST_ADDR, wantAck=False): + def _addResponseHandler(self, requestId, callback): + self.responseHandlers[requestId] = ResponseHandler(callback) + + def _sendPacket(self, meshPacket, + destinationId=BROADCAST_ADDR, + wantAck=False, hopLimit=defaultHopLimit): """Send a MeshPacket to the specified node (or if unspecified, broadcast). You probably don't want this - use sendData instead. - Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. + Returns the sent packet. The id field will be populated in this packet and + can be used to track future message acks/naks. """ - self._waitConnected() + + # We allow users to talk to the local node before we've completed the full connection flow... + if(self.myInfo is not None and destinationId != self.myInfo.my_node_num): + self._waitConnected() toRadio = mesh_pb2.ToRadio() - # FIXME add support for non broadcast addresses if destinationId is None: raise Exception("destinationId must not be None") @@ -1155,6 +1489,7 @@ noProto – If True, don't try to run our protocol on the link - just be a d meshPacket.to = nodeNum meshPacket.want_ack = wantAck + meshPacket.hop_limit = hopLimit # if the user hasn't set an ID for this packet (likely and recommended), we should pick a new unique ID # so the message can be tracked. @@ -1162,10 +1497,11 @@ noProto – If True, don't try to run our protocol on the link - just be a d meshPacket.id = self._generatePacketId() toRadio.packet.CopyFrom(meshPacket) + #logging.debug(f"Sending packet: {stripnl(meshPacket)}") self._sendToRadio(toRadio) return meshPacket - def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig')): + def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig', 'channels')): """Block until radio config is received. Returns True if config has been received.""" for _ in range(int(maxsecs/sleep)): if all(map(lambda a: getattr(self, a, None), attrs)): @@ -1178,11 +1514,25 @@ noProto – If True, don't try to run our protocol on the link - just be a d if self.radioConfig == None: raise Exception("No RadioConfig has been read") - t = mesh_pb2.ToRadio() - t.set_radio.CopyFrom(self.radioConfig) - self._sendToRadio(t) + p = admin_pb2.AdminMessage() + p.set_radio.CopyFrom(self.radioConfig) + + self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) logging.debug("Wrote config") + def writeChannel(self, channelIndex): + """Write the current (edited) channel to the device""" + + p = admin_pb2.AdminMessage() + p.set_channel.CopyFrom(self.channels[channelIndex]) + + self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) + logging.debug("Wrote channel {channelIndex}") + def getMyNodeInfo(self): if self.myInfo is None: return None @@ -1223,43 +1573,66 @@ noProto – If True, don't try to run our protocol on the link - just be a d short_name = long_name[0] + long_name[1:].translate(trans) if len(short_name) < nChars: short_name = long_name[:nChars] - t = mesh_pb2.ToRadio() + + p = admin_pb2.AdminMessage() + if long_name is not None: - t.set_owner.long_name = long_name + p.set_owner.long_name = long_name if short_name is not None: short_name = short_name.strip() if len(short_name) > nChars: short_name = short_name[:nChars] - t.set_owner.short_name = short_name - self._sendToRadio(t) + p.set_owner.short_name = short_name + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) @property def channelURL(self): """The sharable URL that describes the current channel """ - bytes = self.radioConfig.channel_settings.SerializeToString() + # Only keep the primary/secondary channels, assume primary is first + channelSet = apponly_pb2.ChannelSet() + for c in self.channels: + if c.role != channel_pb2.Channel.Role.DISABLED: + channelSet.settings.append(c.settings) + bytes = channelSet.SerializeToString() s = base64.urlsafe_b64encode(bytes).decode('ascii') - return f"https://www.meshtastic.org/c/#{s}" + return f"https://www.meshtastic.org/d/#{s}".replace("=", "") - def setURL(self, url, write=True): + def setURL(self, url): """Set mesh network URL""" if self.radioConfig == None: raise Exception("No RadioConfig has been read") - # URLs are of the form https://www.meshtastic.org/c/#{base64_channel_settings} + # URLs are of the form https://www.meshtastic.org/d/#{base64_channel_set} # Split on '/#' to find the base64 encoded channel settings splitURL = url.split("/#") decodedURL = base64.urlsafe_b64decode(splitURL[-1]) - self.radioConfig.channel_settings.ParseFromString(decodedURL) - if write: - self.writeConfig() + channelSet = apponly_pb2.ChannelSet() + channelSet.ParseFromString(decodedURL) + + i = 0 + for chs in channelSet.settings: + ch = channel_pb2.Channel() + ch.role = channel_pb2.Channel.Role.PRIMARY if i == 0 else channel_pb2.Channel.Role.SECONDARY + ch.index = i + ch.settings.CopyFrom(chs) + self.channels[ch.index] = ch + self.writeChannel(ch.index) + i = i + 1 def _waitConnected(self): """Block until the initial node db download is complete, or timeout and raise an exception""" - if not self.isConnected.wait(5.0): # timeout after 5 seconds + if not self.isConnected.wait(5.0): # timeout after 5 seconds raise Exception("Timed out waiting for connection completion") + # If we failed while connecting, raise the connection to the client + if self.failure: + raise self.failure + def _generatePacketId(self): """Get a new unique packet ID""" if self.currentPacketId is None: @@ -1271,13 +1644,15 @@ noProto – If True, don't try to run our protocol on the link - just be a d def _disconnected(self): """Called by subclasses to tell clients this interface has disconnected""" self.isConnected.clear() - pub.sendMessage("meshtastic.connection.lost", interface=self) + catchAndIgnore("disconnection publish", lambda: pub.sendMessage( + "meshtastic.connection.lost", interface=self)) def _connected(self): """Called by this class to tell clients we are now fully connected to a node """ self.isConnected.set() - pub.sendMessage("meshtastic.connection.established", interface=self) + catchAndIgnore("connection publish", lambda: pub.sendMessage( + "meshtastic.connection.established", interface=self)) def _startConfig(self): """Start device packets flowing""" @@ -1285,6 +1660,8 @@ noProto – If True, don't try to run our protocol on the link - just be a d self.nodes = {} # nodes keyed by ID self.nodesByNum = {} # nodes keyed by nodenum self.radioConfig = None + self.channels = None + self.partialChannels = [] # We keep our channels in a temp array until finished startConfig = mesh_pb2.ToRadio() startConfig.want_config_id = MY_CONFIG_ID # we don't use this value @@ -1293,14 +1670,74 @@ noProto – If True, don't try to run our protocol on the link - just be a d def _sendToRadio(self, toRadio): """Send a ToRadio protobuf to the device""" if self.noProto: - logging.warn(f"Not sending packet because protocol use is disabled by noProto") + logging.warn( + f"Not sending packet because protocol use is disabled by noProto") else: + #logging.debug(f"Sending toRadio: {stripnl(toRadio)}") self._sendToRadioImpl(toRadio) def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" logging.error(f"Subclass must provide toradio: {toRadio}") + def _handleConfigComplete(self): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings and channels + """ + self._requestSettings() + self._requestChannel(0) + + def _requestSettings(self): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings + """ + p = admin_pb2.AdminMessage() + p.get_radio_request = True + + def onResponse(p): + """A closure to handle the response packet""" + self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True, + wantResponse=True, + onResponse=onResponse) + + def _requestChannel(self, channelNum: int): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings + """ + p = admin_pb2.AdminMessage() + p.get_channel_request = channelNum + 1 + logging.debug(f"Requesting channel {channelNum}") + + def onResponse(p): + """A closure to handle the response packet""" + c = p["decoded"]["admin"]["raw"].get_channel_response + self.partialChannels.append(c) + logging.debug(f"Received channel {stripnl(c)}") + index = c.index + + # for stress testing, we can always download all channels + fastChannelDownload = True + + # Once we see a response that has NO settings, assume we are at the end of channels and stop fetching + quitEarly = (c.role == channel_pb2.Channel.Role.DISABLED) and fastChannelDownload + + if quitEarly or index >= self.myInfo.max_channels - 1: + self.channels = self.partialChannels + # FIXME, the following should only be called after we have settings and channels + self._connected() # Tell everone else we are ready to go + else: + self._requestChannel(index + 1) + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True, + wantResponse=True, + onResponse=onResponse) + def _handleFromRadio(self, fromRadioBytes): """ Handle a packet that arrived from the radio(update model and publish events) @@ -1309,28 +1746,41 @@ noProto – If True, don't try to run our protocol on the link - just be a d fromRadio = mesh_pb2.FromRadio() fromRadio.ParseFromString(fromRadioBytes) asDict = google.protobuf.json_format.MessageToDict(fromRadio) - logging.debug(f"Received: {asDict}") if fromRadio.HasField("my_info"): self.myInfo = fromRadio.my_info + logging.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}") + + failmsg = None + # Check for app too old if self.myInfo.min_app_version > OUR_APP_VERSION: - raise Exception( - "This device needs a newer python client, please \"pip install --upgrade meshtastic\"") - # start assigning our packet IDs from the opposite side of where our local device is assigning them - elif fromRadio.HasField("radio"): - self.radioConfig = fromRadio.radio + failmsg = "This device needs a newer python client, please \"pip install --upgrade meshtastic\". For more information see https://tinyurl.com/5bjsxu32" + + # check for firmware too old + if self.myInfo.max_channels == 0: + failmsg = "This version of meshtastic-python requires device firmware version 1.2 or later. For more information see https://tinyurl.com/5bjsxu32" + + if failmsg: + self.failure = Exception(failmsg) + self.isConnected.set() # let waitConnected return this exception + self.close() + elif fromRadio.HasField("node_info"): node = asDict["nodeInfo"] try: self._fixupPosition(node["position"]) except: logging.debug("Node without position") + + logging.debug(f"Received nodeinfo: {node}") + self.nodesByNum[node["num"]] = node if "user" in node: # Some nodes might not have user/ids assigned yet self.nodes[node["user"]["id"]] = node - pub.sendMessage("meshtastic.node.updated", node=node, interface=self) + pub.sendMessage("meshtastic.node.updated", + node=node, interface=self) elif fromRadio.config_complete_id == MY_CONFIG_ID: # we ignore the config_complete_id, it is unneeded for our stream API fromRadio.config_complete_id - self._connected() + self._handleConfigComplete() elif fromRadio.HasField("packet"): self._handlePacketFromRadio(fromRadio.packet) elif fromRadio.rebooted: @@ -1393,6 +1843,20 @@ noProto – If True, don't try to run our protocol on the link - just be a d """ asDict = google.protobuf.json_format.MessageToDict(meshPacket) + + # We normally decompose the payload into a dictionary so that the client + # doesn't need to understand protobufs. But advanced clients might + # want the raw protobuf, so we provide it in "raw" + asDict["raw"] = meshPacket + + # from might be missing if the nodenum was zero. + if not "from" in asDict: + asDict["from"] = 0 + logging.error(f"Device returned a packet we sent, ignoring: {stripnl(asDict)}") + return + if not "to" in asDict: + asDict["to"] = 0 + # /add fromId and toId fields based on the node ID asDict["fromId"] = self._nodeNumToId(asDict["from"]) asDict["toId"] = self._nodeNumToId(asDict["to"]) @@ -1401,68 +1865,59 @@ noProto – If True, don't try to run our protocol on the link - just be a d # asObj = DotMap(asDict) topic = "meshtastic.receive" # Generic unknown packet type - # Warn users if firmware doesn't use new portnum based data encodings - # But do not crash, because the lib will still basically work and ignore those packet types - if meshPacket.decoded.HasField("user") or meshPacket.decoded.HasField("position"): - logging.warn("Ignoring old position/user message. Recommend you update firmware to 1.1.20 or later") + decoded = asDict["decoded"] + # The default MessageToDict converts byte arrays into base64 strings. + # We don't want that - it messes up data payload. So slam in the correct + # byte array. + decoded["payload"] = meshPacket.decoded.payload - if meshPacket.decoded.HasField("data"): + # UNKNOWN_APP is the default protobuf portnum value, and therefore if not set it will not be populated at all + # to make API usage easier, set it to prevent confusion + if not "portnum" in decoded: + decoded["portnum"] = portnums_pb2.PortNum.Name( + portnums_pb2.PortNum.UNKNOWN_APP) - # The default MessageToDict converts byte arrays into base64 strings. - # We don't want that - it messes up data payload. So slam in the correct - # byte array. - asDict["decoded"]["data"]["payload"] = meshPacket.decoded.data.payload + portnum = decoded["portnum"] - # UNKNOWN_APP is the default protobuf portnum value, and therefore if not set it will not be populated at all - # to make API usage easier, set it to prevent confusion - if not "portnum" in asDict["decoded"]["data"]: - asDict["decoded"]["data"]["portnum"] = portnums_pb2.PortNum.Name(portnums_pb2.PortNum.UNKNOWN_APP) + topic = f"meshtastic.receive.data.{portnum}" - portnum = asDict["decoded"]["data"]["portnum"] + # decode position protobufs and update nodedb, provide decoded version as "position" in the published msg + # move the following into a 'decoders' API that clients could register? + portNumInt = meshPacket.decoded.portnum # we want portnum as an int + handler = protocols.get(portNumInt) + # The decoded protobuf as a dictionary (if we understand this message) + p = None + if handler is not None: + topic = f"meshtastic.receive.{handler.name}" - topic = f"meshtastic.receive.data.{portnum}" - - # For text messages, we go ahead and decode the text to ascii for our users - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.TEXT_MESSAGE_APP): - topic = "meshtastic.receive.text" - - # We don't throw if the utf8 is invalid in the text message. Instead we just don't populate - # the decoded.data.text and we log an error message. This at least allows some delivery to - # the app and the app can deal with the missing decoded representation. - # - # Usually btw this problem is caused by apps sending binary data but setting the payload type to - # text. - try: - asDict["decoded"]["data"]["text"] = meshPacket.decoded.data.payload.decode("utf-8") - except Exception as ex: - logging.error(f"Malformatted utf8 in text message: {ex}") - - # decode position protobufs and update nodedb, provide decoded version as "position" in the published msg - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.POSITION_APP): - topic = "meshtastic.receive.position" - pb = mesh_pb2.Position() - pb.ParseFromString(meshPacket.decoded.data.payload) + # Convert to protobuf if possible + if handler.protobufFactory is not None: + pb = handler.protobufFactory() + pb.ParseFromString(meshPacket.decoded.payload) p = google.protobuf.json_format.MessageToDict(pb) - self._fixupPosition(p) - asDict["decoded"]["data"]["position"] = p - # update node DB as needed - self._getOrCreateByNum(asDict["from"])["position"] = p + asDict["decoded"][handler.name] = p + # Also provide the protobuf raw + asDict["decoded"][handler.name]["raw"] = pb - # decode user protobufs and update nodedb, provide decoded version as "position" in the published msg - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.NODEINFO_APP): - topic = "meshtastic.receive.user" - pb = mesh_pb2.User() - pb.ParseFromString(meshPacket.decoded.data.payload) - u = google.protobuf.json_format.MessageToDict(pb) - asDict["decoded"]["data"]["user"] = u - # update node DB as needed - n = self._getOrCreateByNum(asDict["from"]) - n["user"] = u - # We now have a node ID, make sure it is uptodate in that table - self.nodes[u["id"]] = n + # Call specialized onReceive if necessary + if handler.onReceive is not None: + handler.onReceive(self, asDict) - logging.debug(f"Publishing topic {topic}") - pub.sendMessage(topic, packet=asDict, interface=self) + # Is this message in response to a request, if so, look for a handler + requestId = decoded.get("requestId") + if requestId is not None: + # We ignore ACK packets, but send NAKs and data responses to the handlers + routing = decoded.get("routing") + isAck = routing is not None and ("errorReason" not in routing) + if not isAck: + # we keep the responseHandler in dict until we get a non ack + handler = self.responseHandlers.pop(requestId, None) + if handler is not None: + handler.callback(asDict) + + logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ") + catchAndIgnore(f"publishing {topic}", lambda: pub.sendMessage( + topic, packet=asDict, interface=self))

    Subclasses

      @@ -1482,9 +1937,14 @@ noProto – If True, don't try to run our protocol on the link - just be a d def channelURL(self): """The sharable URL that describes the current channel """ - bytes = self.radioConfig.channel_settings.SerializeToString() + # Only keep the primary/secondary channels, assume primary is first + channelSet = apponly_pb2.ChannelSet() + for c in self.channels: + if c.role != channel_pb2.Channel.Role.DISABLED: + channelSet.settings.append(c.settings) + bytes = channelSet.SerializeToString() s = base64.urlsafe_b64encode(bytes).decode('ascii') - return f"https://www.meshtastic.org/c/#{s}" + return f"https://www.meshtastic.org/d/#{s}".replace("=", "")
    @@ -1554,7 +2014,7 @@ def channelURL(self):
    -def sendData(self, data, destinationId='^all', portNum=256, wantAck=False, wantResponse=False) +def sendData(self, data, destinationId='^all', portNum=256, wantAck=False, wantResponse=False, hopLimit=3, onResponse=None)

    Send a data packet to some other node

    @@ -1562,13 +2022,19 @@ def channelURL(self): data – the data to send, either as an array of bytes or as a protobuf (which will be automatically serialized to bytes) destinationId {nodeId or nodeNum} – where to send this message (default: {BROADCAST_ADDR}) portNum – the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list -wantAck – True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery)

    +wantAck – True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery) +wantResponse – True if you want the service on the other side to send an application layer response +onResponse – A closure of the form funct(packet), that will be called when a response packet arrives (or the transaction is NAKed due to non receipt)

    Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.

    Expand source code -
    def sendData(self, data, destinationId=BROADCAST_ADDR, portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False, wantResponse=False):
    +
    def sendData(self, data, destinationId=BROADCAST_ADDR,
    +             portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False,
    +             wantResponse=False,
    +             hopLimit=defaultHopLimit,
    +             onResponse=None):
         """Send a data packet to some other node
     
         Keyword Arguments:
    @@ -1576,64 +2042,30 @@ wantAck – True if you want the message sent in a reliable manner (with ret
             destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR})
             portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list
             wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery)
    +        wantResponse -- True if you want the service on the other side to send an application layer response
    +        onResponse -- A closure of the form funct(packet), that will be called when a response packet arrives (or the transaction is NAKed due to non receipt)
     
         Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.
         """
         if getattr(data, "SerializeToString", None):
    -        logging.debug(f"Serializing protobuf as data: {data}")
    +        logging.debug(f"Serializing protobuf as data: {stripnl(data)}")
             data = data.SerializeToString()
     
         if len(data) > mesh_pb2.Constants.DATA_PAYLOAD_LEN:
             raise Exception("Data payload too big")
    +
    +    if portNum == portnums_pb2.PortNum.UNKNOWN_APP: # we are now more strict wrt port numbers
    +        raise Exception("A non-zero port number must be specified")
    +
         meshPacket = mesh_pb2.MeshPacket()
    -    meshPacket.decoded.data.payload = data
    -    meshPacket.decoded.data.portnum = portNum
    +    meshPacket.decoded.payload = data
    +    meshPacket.decoded.portnum = portNum
         meshPacket.decoded.want_response = wantResponse
    -    return self.sendPacket(meshPacket, destinationId, wantAck=wantAck)
    -
    -
    -
    -def sendPacket(self, meshPacket, destinationId='^all', wantAck=False) -
    -
    -

    Send a MeshPacket to the specified node (or if unspecified, broadcast). -You probably don't want this - use sendData instead.

    -

    Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.

    -
    - -Expand source code - -
    def sendPacket(self, meshPacket, destinationId=BROADCAST_ADDR, wantAck=False):
    -    """Send a MeshPacket to the specified node (or if unspecified, broadcast).
    -    You probably don't want this - use sendData instead.
     
    -    Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.
    -    """
    -    self._waitConnected()
    -
    -    toRadio = mesh_pb2.ToRadio()
    -    # FIXME add support for non broadcast addresses
    -
    -    if destinationId is None:
    -        raise Exception("destinationId must not be None")
    -    elif isinstance(destinationId, int):
    -        nodeNum = destinationId
    -    elif destinationId == BROADCAST_ADDR:
    -        nodeNum = BROADCAST_NUM
    -    else:
    -        nodeNum = self.nodes[destinationId]['num']
    -
    -    meshPacket.to = nodeNum
    -    meshPacket.want_ack = wantAck
    -
    -    # if the user hasn't set an ID for this packet (likely and recommended), we should pick a new unique ID
    -    # so the message can be tracked.
    -    if meshPacket.id == 0:
    -        meshPacket.id = self._generatePacketId()
    -
    -    toRadio.packet.CopyFrom(meshPacket)
    -    self._sendToRadio(toRadio)
    -    return meshPacket
    + p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck, hopLimit=hopLimit) + if onResponse is not None: + self._addResponseHandler(p.id, onResponse) + return p
    @@ -1674,11 +2106,14 @@ the local position.

    timeSec = time.time() # returns unix timestamp in seconds p.time = int(timeSec) - return self.sendData(p, destinationId, portNum=portnums_pb2.PortNum.POSITION_APP, wantAck=wantAck, wantResponse=wantResponse)
    + return self.sendData(p, destinationId, + portNum=portnums_pb2.PortNum.POSITION_APP, + wantAck=wantAck, + wantResponse=wantResponse)
    -def sendText(self, text, destinationId='^all', wantAck=False, wantResponse=False) +def sendText(self, text: ~AnyStr, destinationId='^all', wantAck=False, wantResponse=False, hopLimit=3, onResponse=None)

    Send a utf8 string to some other node, if the node has a display it will also be shown on the device.

    @@ -1687,13 +2122,19 @@ the local position.

    Keyword Arguments: destinationId {nodeId or nodeNum} – where to send this message (default: {BROADCAST_ADDR}) portNum – the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list -wantAck – True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery)

    +wantAck – True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery) +wantResponse – True if you want the service on the other side to send an application layer response

    Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.

    Expand source code -
    def sendText(self, text, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False):
    +
    def sendText(self, text: AnyStr,
    +             destinationId=BROADCAST_ADDR,
    +             wantAck=False,
    +             wantResponse=False,
    +             hopLimit=defaultHopLimit,
    +             onResponse=None):
         """Send a utf8 string to some other node, if the node has a display it will also be shown on the device.
     
         Arguments:
    @@ -1703,11 +2144,16 @@ wantAck – True if you want the message sent in a reliable manner (with ret
             destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR})
             portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list
             wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery)
    +        wantResponse -- True if you want the service on the other side to send an application layer response
     
         Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.
         """
         return self.sendData(text.encode("utf-8"), destinationId,
    -                         portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, wantAck=wantAck, wantResponse=wantResponse)
    + portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, + wantAck=wantAck, + wantResponse=wantResponse, + hopLimit=hopLimit, + onResponse=onResponse)
    @@ -1736,19 +2182,24 @@ wantAck – True if you want the message sent in a reliable manner (with ret short_name = long_name[0] + long_name[1:].translate(trans) if len(short_name) < nChars: short_name = long_name[:nChars] - t = mesh_pb2.ToRadio() + + p = admin_pb2.AdminMessage() + if long_name is not None: - t.set_owner.long_name = long_name + p.set_owner.long_name = long_name if short_name is not None: short_name = short_name.strip() if len(short_name) > nChars: short_name = short_name[:nChars] - t.set_owner.short_name = short_name - self._sendToRadio(t) + p.set_owner.short_name = short_name + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True)
    -def setURL(self, url, write=True) +def setURL(self, url)

    Set mesh network URL

    @@ -1756,22 +2207,31 @@ wantAck – True if you want the message sent in a reliable manner (with ret Expand source code -
    def setURL(self, url, write=True):
    +
    def setURL(self, url):
         """Set mesh network URL"""
         if self.radioConfig == None:
             raise Exception("No RadioConfig has been read")
     
    -    # URLs are of the form https://www.meshtastic.org/c/#{base64_channel_settings}
    +    # URLs are of the form https://www.meshtastic.org/d/#{base64_channel_set}
         # Split on '/#' to find the base64 encoded channel settings
         splitURL = url.split("/#")
         decodedURL = base64.urlsafe_b64decode(splitURL[-1])
    -    self.radioConfig.channel_settings.ParseFromString(decodedURL)
    -    if write:
    -        self.writeConfig()
    + channelSet = apponly_pb2.ChannelSet() + channelSet.ParseFromString(decodedURL) + + i = 0 + for chs in channelSet.settings: + ch = channel_pb2.Channel() + ch.role = channel_pb2.Channel.Role.PRIMARY if i == 0 else channel_pb2.Channel.Role.SECONDARY + ch.index = i + ch.settings.CopyFrom(chs) + self.channels[ch.index] = ch + self.writeChannel(ch.index) + i = i + 1
    -def waitForConfig(self, sleep=0.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig')) +def waitForConfig(self, sleep=0.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig', 'channels'))

    Block until radio config is received. Returns True if config has been received.

    @@ -1779,7 +2239,7 @@ wantAck – True if you want the message sent in a reliable manner (with ret Expand source code -
    def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig')):
    +
    def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig', 'channels')):
         """Block until radio config is received. Returns True if config has been received."""
         for _ in range(int(maxsecs/sleep)):
             if all(map(lambda a: getattr(self, a, None), attrs)):
    @@ -1788,6 +2248,27 @@ wantAck – True if you want the message sent in a reliable manner (with ret
         return False
    +
    +def writeChannel(self, channelIndex) +
    +
    +

    Write the current (edited) channel to the device

    +
    + +Expand source code + +
    def writeChannel(self, channelIndex):
    +    """Write the current (edited) channel to the device"""
    +
    +    p = admin_pb2.AdminMessage()
    +    p.set_channel.CopyFrom(self.channels[channelIndex])
    +
    +    self.sendData(p, self.myInfo.my_node_num,
    +                  portNum=portnums_pb2.PortNum.ADMIN_APP,
    +                  wantAck=True)
    +    logging.debug("Wrote channel {channelIndex}")
    +
    +
    def writeConfig(self)
    @@ -1802,14 +2283,44 @@ wantAck – True if you want the message sent in a reliable manner (with ret if self.radioConfig == None: raise Exception("No RadioConfig has been read") - t = mesh_pb2.ToRadio() - t.set_radio.CopyFrom(self.radioConfig) - self._sendToRadio(t) + p = admin_pb2.AdminMessage() + p.set_radio.CopyFrom(self.radioConfig) + + self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) logging.debug("Wrote config")
    +
    +class ResponseHandler +(callback: Callable) +
    +
    +

    A pending response callback, waiting for a response to one of our messages

    +
    + +Expand source code + +
    class ResponseHandler(NamedTuple):
    +    """A pending response callback, waiting for a response to one of our messages"""
    +    # requestId: int - used only as a key
    +    callback: Callable
    +
    +

    Ancestors

    +
      +
    • builtins.tuple
    • +
    +

    Instance variables

    +
    +
    var callback : Callable
    +
    +

    Alias for field number 0

    +
    +
    +
    class SerialInterface (devPath=None, debugOut=None, noProto=False, connectNow=True) @@ -1880,12 +2391,12 @@ debugOut {stream} – If a stream is provided, any debug serial output from
  • close
  • connect
  • sendData
  • -
  • sendPacket
  • sendPosition
  • sendText
  • setOwner
  • setURL
  • waitForConfig
  • +
  • writeChannel
  • writeConfig
  • @@ -1954,7 +2465,7 @@ debugOut {stream} – If a stream is provided, any debug serial output from time.sleep(0.1) # wait 100ms to give device time to start running self._rxThread.start() - if not self.noProto: # Wait for the db download if using the protocol + if not self.noProto: # Wait for the db download if using the protocol self._waitConnected() def _disconnected(self): @@ -1976,7 +2487,7 @@ debugOut {stream} – If a stream is provided, any debug serial output from def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" - logging.debug(f"Sending: {toRadio}") + logging.debug(f"Sending: {stripnl(toRadio)}") b = toRadio.SerializeToString() bufLen = len(b) # We convert into a string, because the TCP code doesn't work with byte arrays @@ -2040,13 +2551,16 @@ debugOut {stream} – If a stream is provided, any debug serial output from # logging.debug(f"timeout") pass except serial.SerialException as ex: - if not self._wantExit: # We might intentionally get an exception during shutdown - logging.warn(f"Meshtastic serial port disconnected, disconnecting... {ex}") + if not self._wantExit: # We might intentionally get an exception during shutdown + logging.warn( + f"Meshtastic serial port disconnected, disconnecting... {ex}") except OSError as ex: - if not self._wantExit: # We might intentionally get an exception during shutdown - logging.error(f"Unexpected OSError, terminating meshtastic reader... {ex}") + if not self._wantExit: # We might intentionally get an exception during shutdown + logging.error( + f"Unexpected OSError, terminating meshtastic reader... {ex}") except Exception as ex: - logging.error(f"Unexpected exception, terminating meshtastic reader... {ex}") + logging.error( + f"Unexpected exception, terminating meshtastic reader... {ex}") finally: logging.debug("reader is exiting") self._disconnected()
    @@ -2103,7 +2617,7 @@ start the reading thread later.

    time.sleep(0.1) # wait 100ms to give device time to start running self._rxThread.start() - if not self.noProto: # Wait for the db download if using the protocol + if not self.noProto: # Wait for the db download if using the protocol self._waitConnected() @@ -2114,12 +2628,12 @@ start the reading thread later.

    @@ -2127,7 +2641,7 @@ start the reading thread later.

    class TCPInterface -(hostname, debugOut=None, noProto=False, connectNow=True, portNumber=4403) +(hostname: ~AnyStr, debugOut=None, noProto=False, connectNow=True, portNumber=4403)

    Interface class for meshtastic devices over a TCP link

    @@ -2141,7 +2655,7 @@ hostname {string} – Hostname/IP address of the device to connect to

    class TCPInterface(StreamInterface): """Interface class for meshtastic devices over a TCP link""" - def __init__(self, hostname, debugOut=None, noProto=False, connectNow=True, portNumber=4403): + def __init__(self, hostname: AnyStr, debugOut=None, noProto=False, connectNow=True, portNumber=4403): """Constructor, opens a connection to a specified IP address/hostname Keyword Arguments: @@ -2164,9 +2678,9 @@ hostname {string} – Hostname/IP address of the device to connect to

    close
  • connect
  • sendData
  • -
  • sendPacket
  • sendPosition
  • sendText
  • setOwner
  • setURL
  • waitForConfig
  • +
  • writeChannel
  • writeConfig
  • @@ -2219,11 +2733,15 @@ hostname {string} – Hostname/IP address of the device to connect to

  • Sub-modules

      +
    • meshtastic.admin_pb2
    • meshtastic.apponly_pb2
    • meshtastic.ble
    • +
    • meshtastic.channel_pb2
    • meshtastic.deviceonly_pb2
    • +
    • meshtastic.environmental_measurement_pb2
    • meshtastic.mesh_pb2
    • meshtastic.portnums_pb2
    • +
    • meshtastic.radioconfig_pb2
    • meshtastic.remote_hardware
    • meshtastic.remote_hardware_pb2
    • meshtastic.test
    • @@ -2245,6 +2763,14 @@ hostname {string} – Hostname/IP address of the device to connect to

    • +

      KnownProtocol

      + +
    • +
    • MeshInterface

    • +

      ResponseHandler

      + +
    • +
    • SerialInterface

    • diff --git a/docs/meshtastic/mesh_pb2.html b/docs/meshtastic/mesh_pb2.html index e38cda5..7e4b856 100644 --- a/docs/meshtastic/mesh_pb2.html +++ b/docs/meshtastic/mesh_pb2.html @@ -5,7 +5,7 @@ meshtastic.mesh_pb2 API documentation - + @@ -22,6 +22,7 @@

      Module meshtastic.mesh_pb2

      +

      Generated protocol buffer code.

      Expand source code @@ -29,7 +30,7 @@
      # -*- coding: utf-8 -*-
       # Generated by the protocol buffer compiler.  DO NOT EDIT!
       # source: mesh.proto
      -
      +"""Generated protocol buffer code."""
       from google.protobuf.internal import enum_type_wrapper
       from google.protobuf import descriptor as _descriptor
       from google.protobuf import message as _message
      @@ -48,361 +49,100 @@ DESCRIPTOR = _descriptor.FileDescriptor(
         package='',
         syntax='proto3',
         serialized_options=b'\n\023com.geeksville.meshB\nMeshProtosH\003',
      -  serialized_pb=b'\n\nmesh.proto\x1a\x0eportnums.proto\"j\n\x08Position\x12\x12\n\nlatitude_i\x18\x07 \x01(\x11\x12\x13\n\x0blongitude_i\x18\x08 \x01(\x11\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x15\n\rbattery_level\x18\x04 \x01(\x05\x12\x0c\n\x04time\x18\t \x01(\x07\"2\n\x04\x44\x61ta\x12\x19\n\x07portnum\x18\x01 \x01(\x0e\x32\x08.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"J\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x0f\n\x07macaddr\x18\x04 \x01(\x0c\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x02 \x03(\x05\"\xeb\x02\n\tSubPacket\x12\x15\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x05.DataH\x00\x12(\n\rroute_request\x18\x06 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0broute_reply\x18\x07 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12$\n\x0c\x65rror_reason\x18\r \x01(\x0e\x32\x0c.ErrorReasonH\x00\x12!\n\x08position\x18\x01 \x01(\x0b\x32\t.PositionB\x02\x18\x01H\x00\x12\x19\n\x04user\x18\x04 \x01(\x0b\x32\x05.UserB\x02\x18\x01H\x00\x12\x15\n\rwant_response\x18\x05 \x01(\x08\x12\x14\n\nsuccess_id\x18\n \x01(\rH\x01\x12\x11\n\x07\x66\x61il_id\x18\x0b \x01(\rH\x01\x12\x0c\n\x04\x64\x65st\x18\t \x01(\r\x12\x0e\n\x06source\x18\x0c \x01(\r\x12\x13\n\x0boriginal_id\x18\x02 \x01(\rB\x10\n\x0epayloadVariantB\x0c\n\nackVariant\"\xd5\x01\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\r\x12\n\n\x02to\x18\x02 \x01(\r\x12\x15\n\rchannel_index\x18\x04 \x01(\r\x12\x1d\n\x07\x64\x65\x63oded\x18\x03 \x01(\x0b\x32\n.SubPacketH\x00\x12\x13\n\tencrypted\x18\x08 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\r\x12\x0f\n\x07rx_time\x18\t \x01(\x07\x12\x0e\n\x06rx_snr\x18\x07 \x01(\x02\x12\x11\n\thop_limit\x18\n \x01(\r\x12\x10\n\x08want_ack\x18\x0b \x01(\x08\x42\x10\n\x0epayloadVariant\"\xe6\x02\n\x0f\x43hannelSettings\x12\x10\n\x08tx_power\x18\x01 \x01(\x05\x12\x32\n\x0cmodem_config\x18\x03 \x01(\x0e\x32\x1c.ChannelSettings.ModemConfig\x12\x11\n\tbandwidth\x18\x06 \x01(\r\x12\x15\n\rspread_factor\x18\x07 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x08 \x01(\r\x12\x13\n\x0b\x63hannel_num\x18\t \x01(\r\x12\x0b\n\x03psk\x18\x04 \x01(\x0c\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\n\n\x02id\x18\n \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x10 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x11 \x01(\x08\"`\n\x0bModemConfig\x12\x12\n\x0e\x42w125Cr45Sf128\x10\x00\x12\x12\n\x0e\x42w500Cr45Sf128\x10\x01\x12\x14\n\x10\x42w31_25Cr48Sf512\x10\x02\x12\x13\n\x0f\x42w125Cr48Sf4096\x10\x03\"\x82\x0b\n\x0bRadioConfig\x12\x31\n\x0bpreferences\x18\x01 \x01(\x0b\x32\x1c.RadioConfig.UserPreferences\x12.\n\x10\x63hannel_settings\x18\x02 \x01(\x0b\x32\x10.ChannelSettingsB\x02\x18\x01\x1a\x8f\n\n\x0fUserPreferences\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12\x1b\n\x13send_owner_interval\x18\x02 \x01(\r\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x16\n\x0escreen_on_secs\x18\x05 \x01(\r\x12\x1a\n\x12phone_timeout_secs\x18\x06 \x01(\r\x12\x1d\n\x15phone_sds_timeout_sec\x18\x07 \x01(\r\x12\x1d\n\x15mesh_sds_timeout_secs\x18\x08 \x01(\r\x12\x10\n\x08sds_secs\x18\t \x01(\r\x12\x0f\n\x07ls_secs\x18\n \x01(\r\x12\x15\n\rmin_wake_secs\x18\x0b \x01(\r\x12\x11\n\twifi_ssid\x18\x0c \x01(\t\x12\x15\n\rwifi_password\x18\r \x01(\t\x12\x14\n\x0cwifi_ap_mode\x18\x0e \x01(\x08\x12\x1b\n\x06region\x18\x0f \x01(\x0e\x32\x0b.RegionCode\x12&\n\x0e\x63harge_current\x18\x10 \x01(\x0e\x32\x0e.ChargeCurrent\x12\x11\n\tis_router\x18% \x01(\x08\x12\x14\n\x0cis_low_power\x18& \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\' \x01(\x08\x12\x15\n\rfactory_reset\x18\x64 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x65 \x01(\x08\x12(\n\x0elocation_share\x18  \x01(\x0e\x32\x10.LocationSharing\x12$\n\rgps_operation\x18! \x01(\x0e\x32\r.GpsOperation\x12\x1b\n\x13gps_update_interval\x18\" \x01(\r\x12\x18\n\x10gps_attempt_time\x18$ \x01(\r\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x1c\n\x14serialplugin_enabled\x18x \x01(\x08\x12\x19\n\x11serialplugin_echo\x18y \x01(\x08\x12\x18\n\x10serialplugin_rxd\x18z \x01(\r\x12\x18\n\x10serialplugin_txd\x18{ \x01(\r\x12\x1c\n\x14serialplugin_timeout\x18| \x01(\r\x12\x19\n\x11serialplugin_mode\x18} \x01(\r\x12\'\n\x1f\x65xt_notification_plugin_enabled\x18~ \x01(\x08\x12)\n!ext_notification_plugin_output_ms\x18\x7f \x01(\r\x12\'\n\x1e\x65xt_notification_plugin_output\x18\x80\x01 \x01(\r\x12\'\n\x1e\x65xt_notification_plugin_active\x18\x81\x01 \x01(\x08\x12.\n%ext_notification_plugin_alert_message\x18\x82\x01 \x01(\x08\x12+\n\"ext_notification_plugin_alert_bell\x18\x83\x01 \x01(\x08\x12\"\n\x19range_test_plugin_enabled\x18\x84\x01 \x01(\x08\x12!\n\x18range_test_plugin_sender\x18\x85\x01 \x01(\r\x12\x1f\n\x16range_test_plugin_save\x18\x86\x01 \x01(\x08\x12%\n\x1cstore_forward_plugin_enabled\x18\x88\x01 \x01(\x08\x12%\n\x1cstore_forward_plugin_records\x18\x89\x01 \x01(\r\"h\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1b\n\x08position\x18\x03 \x01(\x0b\x32\t.Position\x12\x0b\n\x03snr\x18\x07 \x01(\x02\x12\x10\n\x08next_hop\x18\x05 \x01(\r\"\xd9\x02\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x0f\n\x07has_gps\x18\x02 \x01(\x08\x12\x14\n\x0cnum_channels\x18\x03 \x01(\x05\x12\x0e\n\x06region\x18\x04 \x01(\t\x12\x10\n\x08hw_model\x18\x05 \x01(\t\x12\x18\n\x10\x66irmware_version\x18\x06 \x01(\t\x12&\n\nerror_code\x18\x07 \x01(\x0e\x32\x12.CriticalErrorCode\x12\x15\n\rerror_address\x18\x08 \x01(\r\x12\x13\n\x0b\x65rror_count\x18\t \x01(\r\x12\x16\n\x0epacket_id_bits\x18\n \x01(\r\x12\x19\n\x11\x63urrent_packet_id\x18\x0b \x01(\r\x12\x15\n\rnode_num_bits\x18\x0c \x01(\r\x12\x1c\n\x14message_timeout_msec\x18\r \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0e \x01(\r\"\xb5\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x1f\n\x05level\x18\x04 \x01(\x0e\x32\x10.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"\xa1\x02\n\tFromRadio\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1d\n\x06packet\x18\x02 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x1e\n\x07my_info\x18\x03 \x01(\x0b\x32\x0b.MyNodeInfoH\x00\x12\x1e\n\tnode_info\x18\x04 \x01(\x0b\x32\t.NodeInfoH\x00\x12\x1d\n\x05radio\x18\x06 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12 \n\nlog_record\x18\x07 \x01(\x0b\x32\n.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x08 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\t \x01(\x08H\x00\x12#\n\x07\x63hannel\x18\n \x01(\x0b\x32\x10.ChannelSettingsH\x00\x42\x10\n\x0epayloadVariant\"\xbc\x01\n\x07ToRadio\x12\x1d\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x64 \x01(\rH\x00\x12!\n\tset_radio\x18\x65 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1a\n\tset_owner\x18\x66 \x01(\x0b\x32\x05.UserH\x00\x12\'\n\x0bset_channel\x18g \x01(\x0b\x32\x10.ChannelSettingsH\x00\x42\x10\n\x0epayloadVariant*e\n\x0b\x45rrorReason\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05*.\n\tConstants\x12\n\n\x06Unused\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xf0\x01*^\n\nRegionCode\x12\t\n\x05Unset\x10\x00\x12\x06\n\x02US\x10\x01\x12\t\n\x05\x45U433\x10\x02\x12\t\n\x05\x45U865\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08*\xd1\x01\n\rChargeCurrent\x12\x0b\n\x07MAUnset\x10\x00\x12\t\n\x05MA100\x10\x01\x12\t\n\x05MA190\x10\x02\x12\t\n\x05MA280\x10\x03\x12\t\n\x05MA360\x10\x04\x12\t\n\x05MA450\x10\x05\x12\t\n\x05MA550\x10\x06\x12\t\n\x05MA630\x10\x07\x12\t\n\x05MA700\x10\x08\x12\t\n\x05MA780\x10\t\x12\t\n\x05MA880\x10\n\x12\t\n\x05MA960\x10\x0b\x12\n\n\x06MA1000\x10\x0c\x12\n\n\x06MA1080\x10\r\x12\n\n\x06MA1160\x10\x0e\x12\n\n\x06MA1240\x10\x0f\x12\n\n\x06MA1320\x10\x10*j\n\x0cGpsOperation\x12\x0e\n\nGpsOpUnset\x10\x00\x12\x13\n\x0fGpsOpStationary\x10\x01\x12\x0f\n\x0bGpsOpMobile\x10\x02\x12\x11\n\rGpsOpTimeOnly\x10\x03\x12\x11\n\rGpsOpDisabled\x10\x04*@\n\x0fLocationSharing\x12\x0c\n\x08LocUnset\x10\x00\x12\x0e\n\nLocEnabled\x10\x01\x12\x0f\n\x0bLocDisabled\x10\x02*\xaf\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04None\x10\x00\x12\x0e\n\nTxWatchdog\x10\x01\x12\x12\n\x0eSleepEnterWait\x10\x02\x12\x0b\n\x07NoRadio\x10\x03\x12\x0f\n\x0bUnspecified\x10\x04\x12\x13\n\x0fUBloxInitFailed\x10\x05\x12\x0c\n\x08NoAXP192\x10\x06\x12\x17\n\x13InvalidRadioSetting\x10\x07\x12\x12\n\x0eTransmitFailed\x10\x08\x42#\n\x13\x63om.geeksville.meshB\nMeshProtosH\x03\x62\x06proto3'
      +  create_key=_descriptor._internal_create_key,
      +  serialized_pb=b'\n\nmesh.proto\x1a\x0eportnums.proto\"v\n\x08Position\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\x15\n\rbattery_level\x18\x04 \x01(\x05\x12\x0c\n\x04time\x18\t \x01(\x07J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\t\"J\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x0f\n\x07macaddr\x18\x04 \x01(\x0c\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x02 \x03(\x07\"\x8e\x02\n\x07Routing\x12(\n\rroute_request\x18\x01 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0broute_reply\x18\x02 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\x0e.Routing.ErrorH\x00\"~\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x42\t\n\x07variant\"{\n\x04\x44\x61ta\x12\x19\n\x07portnum\x18\x01 \x01(\x0e\x32\x08.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\"\xcf\x02\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12\x18\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x05.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\n \x01(\r\x12\x10\n\x08want_ack\x18\x0b \x01(\x08\x12&\n\x08priority\x18\x0c \x01(\x0e\x32\x14.MeshPacket.Priority\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\x42\x10\n\x0epayloadVariant\"h\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1b\n\x08position\x18\x03 \x01(\x0b\x32\t.Position\x12\x0b\n\x03snr\x18\x07 \x01(\x02\x12\x10\n\x08next_hop\x18\x05 \x01(\r\"\xa6\x02\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x0f\n\x07has_gps\x18\x02 \x01(\x08\x12\x11\n\tnum_bands\x18\x03 \x01(\r\x12\x14\n\x0cmax_channels\x18\x0f \x01(\r\x12\x12\n\x06region\x18\x04 \x01(\tB\x02\x18\x01\x12\x10\n\x08hw_model\x18\x05 \x01(\t\x12\x18\n\x10\x66irmware_version\x18\x06 \x01(\t\x12&\n\nerror_code\x18\x07 \x01(\x0e\x32\x12.CriticalErrorCode\x12\x15\n\rerror_address\x18\x08 \x01(\r\x12\x13\n\x0b\x65rror_count\x18\t \x01(\r\x12\x1c\n\x14message_timeout_msec\x18\r \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0e \x01(\r\"\xb5\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x1f\n\x05level\x18\x04 \x01(\x0e\x32\x10.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"\xe9\x01\n\tFromRadio\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1d\n\x06packet\x18\x0b \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x1e\n\x07my_info\x18\x03 \x01(\x0b\x32\x0b.MyNodeInfoH\x00\x12\x1e\n\tnode_info\x18\x04 \x01(\x0b\x32\t.NodeInfoH\x00\x12 \n\nlog_record\x18\x07 \x01(\x0b\x32\n.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x08 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\t \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x02\x10\x03J\x04\x08\x06\x10\x07\"l\n\x07ToRadio\x12\x1d\n\x06packet\x18\x02 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x64 \x01(\rH\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x01\x10\x02J\x04\x08\x65\x10\x66J\x04\x08\x66\x10gJ\x04\x08g\x10h*.\n\tConstants\x12\n\n\x06Unused\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xf0\x01*\xaf\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04None\x10\x00\x12\x0e\n\nTxWatchdog\x10\x01\x12\x12\n\x0eSleepEnterWait\x10\x02\x12\x0b\n\x07NoRadio\x10\x03\x12\x0f\n\x0bUnspecified\x10\x04\x12\x13\n\x0fUBloxInitFailed\x10\x05\x12\x0c\n\x08NoAXP192\x10\x06\x12\x17\n\x13InvalidRadioSetting\x10\x07\x12\x12\n\x0eTransmitFailed\x10\x08\x42#\n\x13\x63om.geeksville.meshB\nMeshProtosH\x03\x62\x06proto3'
         ,
         dependencies=[portnums__pb2.DESCRIPTOR,])
       
      -_ERRORREASON = _descriptor.EnumDescriptor(
      -  name='ErrorReason',
      -  full_name='ErrorReason',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  values=[
      -    _descriptor.EnumValueDescriptor(
      -      name='NONE', index=0, number=0,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='NO_ROUTE', index=1, number=1,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='GOT_NAK', index=2, number=2,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='TIMEOUT', index=3, number=3,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='NO_INTERFACE', index=4, number=4,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MAX_RETRANSMIT', index=5, number=5,
      -      serialized_options=None,
      -      type=None),
      -  ],
      -  containing_type=None,
      -  serialized_options=None,
      -  serialized_start=3776,
      -  serialized_end=3877,
      -)
      -_sym_db.RegisterEnumDescriptor(_ERRORREASON)
      -
      -ErrorReason = enum_type_wrapper.EnumTypeWrapper(_ERRORREASON)
       _CONSTANTS = _descriptor.EnumDescriptor(
         name='Constants',
         full_name='Constants',
         filename=None,
         file=DESCRIPTOR,
      +  create_key=_descriptor._internal_create_key,
         values=[
           _descriptor.EnumValueDescriptor(
             name='Unused', index=0, number=0,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='DATA_PAYLOAD_LEN', index=1, number=240,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
         ],
         containing_type=None,
         serialized_options=None,
      -  serialized_start=3879,
      -  serialized_end=3925,
      +  serialized_start=1928,
      +  serialized_end=1974,
       )
       _sym_db.RegisterEnumDescriptor(_CONSTANTS)
       
       Constants = enum_type_wrapper.EnumTypeWrapper(_CONSTANTS)
      -_REGIONCODE = _descriptor.EnumDescriptor(
      -  name='RegionCode',
      -  full_name='RegionCode',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  values=[
      -    _descriptor.EnumValueDescriptor(
      -      name='Unset', index=0, number=0,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='US', index=1, number=1,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='EU433', index=2, number=2,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='EU865', index=3, number=3,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='CN', index=4, number=4,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='JP', index=5, number=5,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='ANZ', index=6, number=6,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='KR', index=7, number=7,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='TW', index=8, number=8,
      -      serialized_options=None,
      -      type=None),
      -  ],
      -  containing_type=None,
      -  serialized_options=None,
      -  serialized_start=3927,
      -  serialized_end=4021,
      -)
      -_sym_db.RegisterEnumDescriptor(_REGIONCODE)
      -
      -RegionCode = enum_type_wrapper.EnumTypeWrapper(_REGIONCODE)
      -_CHARGECURRENT = _descriptor.EnumDescriptor(
      -  name='ChargeCurrent',
      -  full_name='ChargeCurrent',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  values=[
      -    _descriptor.EnumValueDescriptor(
      -      name='MAUnset', index=0, number=0,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA100', index=1, number=1,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA190', index=2, number=2,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA280', index=3, number=3,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA360', index=4, number=4,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA450', index=5, number=5,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA550', index=6, number=6,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA630', index=7, number=7,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA700', index=8, number=8,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA780', index=9, number=9,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA880', index=10, number=10,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA960', index=11, number=11,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA1000', index=12, number=12,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA1080', index=13, number=13,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA1160', index=14, number=14,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA1240', index=15, number=15,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='MA1320', index=16, number=16,
      -      serialized_options=None,
      -      type=None),
      -  ],
      -  containing_type=None,
      -  serialized_options=None,
      -  serialized_start=4024,
      -  serialized_end=4233,
      -)
      -_sym_db.RegisterEnumDescriptor(_CHARGECURRENT)
      -
      -ChargeCurrent = enum_type_wrapper.EnumTypeWrapper(_CHARGECURRENT)
      -_GPSOPERATION = _descriptor.EnumDescriptor(
      -  name='GpsOperation',
      -  full_name='GpsOperation',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  values=[
      -    _descriptor.EnumValueDescriptor(
      -      name='GpsOpUnset', index=0, number=0,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='GpsOpStationary', index=1, number=1,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='GpsOpMobile', index=2, number=2,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='GpsOpTimeOnly', index=3, number=3,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='GpsOpDisabled', index=4, number=4,
      -      serialized_options=None,
      -      type=None),
      -  ],
      -  containing_type=None,
      -  serialized_options=None,
      -  serialized_start=4235,
      -  serialized_end=4341,
      -)
      -_sym_db.RegisterEnumDescriptor(_GPSOPERATION)
      -
      -GpsOperation = enum_type_wrapper.EnumTypeWrapper(_GPSOPERATION)
      -_LOCATIONSHARING = _descriptor.EnumDescriptor(
      -  name='LocationSharing',
      -  full_name='LocationSharing',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  values=[
      -    _descriptor.EnumValueDescriptor(
      -      name='LocUnset', index=0, number=0,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='LocEnabled', index=1, number=1,
      -      serialized_options=None,
      -      type=None),
      -    _descriptor.EnumValueDescriptor(
      -      name='LocDisabled', index=2, number=2,
      -      serialized_options=None,
      -      type=None),
      -  ],
      -  containing_type=None,
      -  serialized_options=None,
      -  serialized_start=4343,
      -  serialized_end=4407,
      -)
      -_sym_db.RegisterEnumDescriptor(_LOCATIONSHARING)
      -
      -LocationSharing = enum_type_wrapper.EnumTypeWrapper(_LOCATIONSHARING)
       _CRITICALERRORCODE = _descriptor.EnumDescriptor(
         name='CriticalErrorCode',
         full_name='CriticalErrorCode',
         filename=None,
         file=DESCRIPTOR,
      +  create_key=_descriptor._internal_create_key,
         values=[
           _descriptor.EnumValueDescriptor(
             name='None', index=0, number=0,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='TxWatchdog', index=1, number=1,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='SleepEnterWait', index=2, number=2,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='NoRadio', index=3, number=3,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='Unspecified', index=4, number=4,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='UBloxInitFailed', index=5, number=5,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='NoAXP192', index=6, number=6,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='InvalidRadioSetting', index=7, number=7,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='TransmitFailed', index=8, number=8,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
         ],
         containing_type=None,
         serialized_options=None,
      -  serialized_start=4410,
      -  serialized_end=4585,
      +  serialized_start=1977,
      +  serialized_end=2152,
       )
       _sym_db.RegisterEnumDescriptor(_CRITICALERRORCODE)
       
       CriticalErrorCode = enum_type_wrapper.EnumTypeWrapper(_CRITICALERRORCODE)
      -NONE = 0
      -NO_ROUTE = 1
      -GOT_NAK = 2
      -TIMEOUT = 3
      -NO_INTERFACE = 4
      -MAX_RETRANSMIT = 5
       Unused = 0
       DATA_PAYLOAD_LEN = 240
      -Unset = 0
      -US = 1
      -EU433 = 2
      -EU865 = 3
      -CN = 4
      -JP = 5
      -ANZ = 6
      -KR = 7
      -TW = 8
      -MAUnset = 0
      -MA100 = 1
      -MA190 = 2
      -MA280 = 3
      -MA360 = 4
      -MA450 = 5
      -MA550 = 6
      -MA630 = 7
      -MA700 = 8
      -MA780 = 9
      -MA880 = 10
      -MA960 = 11
      -MA1000 = 12
      -MA1080 = 13
      -MA1160 = 14
      -MA1240 = 15
      -MA1320 = 16
      -GpsOpUnset = 0
      -GpsOpStationary = 1
      -GpsOpMobile = 2
      -GpsOpTimeOnly = 3
      -GpsOpDisabled = 4
      -LocUnset = 0
      -LocEnabled = 1
      -LocDisabled = 2
       globals()['None'] = 0
       TxWatchdog = 1
       SleepEnterWait = 2
      @@ -414,75 +154,158 @@ InvalidRadioSetting = 7
       TransmitFailed = 8
       
       
      -_CHANNELSETTINGS_MODEMCONFIG = _descriptor.EnumDescriptor(
      -  name='ModemConfig',
      -  full_name='ChannelSettings.ModemConfig',
      +_ROUTING_ERROR = _descriptor.EnumDescriptor(
      +  name='Error',
      +  full_name='Routing.Error',
         filename=None,
         file=DESCRIPTOR,
      +  create_key=_descriptor._internal_create_key,
         values=[
           _descriptor.EnumValueDescriptor(
      -      name='Bw125Cr45Sf128', index=0, number=0,
      +      name='NONE', index=0, number=0,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
      -      name='Bw500Cr45Sf128', index=1, number=1,
      +      name='NO_ROUTE', index=1, number=1,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
      -      name='Bw31_25Cr48Sf512', index=2, number=2,
      +      name='GOT_NAK', index=2, number=2,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
      -      name='Bw125Cr48Sf4096', index=3, number=3,
      +      name='TIMEOUT', index=3, number=3,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='NO_INTERFACE', index=4, number=4,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='MAX_RETRANSMIT', index=5, number=5,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='NO_CHANNEL', index=6, number=6,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='TOO_LARGE', index=7, number=7,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
         ],
         containing_type=None,
         serialized_options=None,
      -  serialized_start=1144,
      -  serialized_end=1240,
      +  serialized_start=393,
      +  serialized_end=519,
       )
      -_sym_db.RegisterEnumDescriptor(_CHANNELSETTINGS_MODEMCONFIG)
      +_sym_db.RegisterEnumDescriptor(_ROUTING_ERROR)
      +
      +_MESHPACKET_PRIORITY = _descriptor.EnumDescriptor(
      +  name='Priority',
      +  full_name='MeshPacket.Priority',
      +  filename=None,
      +  file=DESCRIPTOR,
      +  create_key=_descriptor._internal_create_key,
      +  values=[
      +    _descriptor.EnumValueDescriptor(
      +      name='UNSET', index=0, number=0,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='MIN', index=1, number=1,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='BACKGROUND', index=2, number=10,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='DEFAULT', index=3, number=64,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='RELIABLE', index=4, number=70,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='ACK', index=5, number=120,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +    _descriptor.EnumValueDescriptor(
      +      name='MAX', index=6, number=127,
      +      serialized_options=None,
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
      +  ],
      +  containing_type=None,
      +  serialized_options=None,
      +  serialized_start=884,
      +  serialized_end=975,
      +)
      +_sym_db.RegisterEnumDescriptor(_MESHPACKET_PRIORITY)
       
       _LOGRECORD_LEVEL = _descriptor.EnumDescriptor(
         name='Level',
         full_name='LogRecord.Level',
         filename=None,
         file=DESCRIPTOR,
      +  create_key=_descriptor._internal_create_key,
         values=[
           _descriptor.EnumValueDescriptor(
             name='UNSET', index=0, number=0,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='CRITICAL', index=1, number=50,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='ERROR', index=2, number=40,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='WARNING', index=3, number=30,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='INFO', index=4, number=20,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='DEBUG', index=5, number=10,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
           _descriptor.EnumValueDescriptor(
             name='TRACE', index=6, number=5,
             serialized_options=None,
      -      type=None),
      +      type=None,
      +      create_key=_descriptor._internal_create_key),
         ],
         containing_type=None,
         serialized_options=None,
      -  serialized_start=3203,
      -  serialized_end=3291,
      +  serialized_start=1492,
      +  serialized_end=1580,
       )
       _sym_db.RegisterEnumDescriptor(_LOGRECORD_LEVEL)
       
      @@ -493,42 +316,43 @@ _POSITION = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='latitude_i', full_name='Position.latitude_i', index=0,
      -      number=7, type=17, cpp_type=1, label=1,
      +      number=1, type=15, cpp_type=1, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='longitude_i', full_name='Position.longitude_i', index=1,
      -      number=8, type=17, cpp_type=1, label=1,
      +      number=2, type=15, cpp_type=1, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='altitude', full_name='Position.altitude', index=2,
             number=3, type=5, cpp_type=1, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='battery_level', full_name='Position.battery_level', index=3,
             number=4, type=5, cpp_type=1, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='time', full_name='Position.time', index=4,
             number=9, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -542,45 +366,7 @@ _POSITION = _descriptor.Descriptor(
         oneofs=[
         ],
         serialized_start=30,
      -  serialized_end=136,
      -)
      -
      -
      -_DATA = _descriptor.Descriptor(
      -  name='Data',
      -  full_name='Data',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  containing_type=None,
      -  fields=[
      -    _descriptor.FieldDescriptor(
      -      name='portnum', full_name='Data.portnum', index=0,
      -      number=1, type=14, cpp_type=8, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='payload', full_name='Data.payload', index=1,
      -      number=2, type=12, cpp_type=9, label=1,
      -      has_default_value=False, default_value=b"",
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -  ],
      -  extensions=[
      -  ],
      -  nested_types=[],
      -  enum_types=[
      -  ],
      -  serialized_options=None,
      -  is_extendable=False,
      -  syntax='proto3',
      -  extension_ranges=[],
      -  oneofs=[
      -  ],
      -  serialized_start=138,
      -  serialized_end=188,
      +  serialized_end=148,
       )
       
       
      @@ -590,6 +376,7 @@ _USER = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='id', full_name='User.id', index=0,
      @@ -597,28 +384,28 @@ _USER = _descriptor.Descriptor(
             has_default_value=False, default_value=b"".decode('utf-8'),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='long_name', full_name='User.long_name', index=1,
             number=2, type=9, cpp_type=9, label=1,
             has_default_value=False, default_value=b"".decode('utf-8'),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='short_name', full_name='User.short_name', index=2,
             number=3, type=9, cpp_type=9, label=1,
             has_default_value=False, default_value=b"".decode('utf-8'),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='macaddr', full_name='User.macaddr', index=3,
             number=4, type=12, cpp_type=9, label=1,
             has_default_value=False, default_value=b"",
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -631,8 +418,8 @@ _USER = _descriptor.Descriptor(
         extension_ranges=[],
         oneofs=[
         ],
      -  serialized_start=190,
      -  serialized_end=264,
      +  serialized_start=150,
      +  serialized_end=224,
       )
       
       
      @@ -642,14 +429,15 @@ _ROUTEDISCOVERY = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='route', full_name='RouteDiscovery.route', index=0,
      -      number=2, type=5, cpp_type=1, label=3,
      +      number=2, type=7, cpp_type=3, label=3,
             has_default_value=False, default_value=[],
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -662,102 +450,113 @@ _ROUTEDISCOVERY = _descriptor.Descriptor(
         extension_ranges=[],
         oneofs=[
         ],
      -  serialized_start=266,
      -  serialized_end=297,
      +  serialized_start=226,
      +  serialized_end=257,
       )
       
       
      -_SUBPACKET = _descriptor.Descriptor(
      -  name='SubPacket',
      -  full_name='SubPacket',
      +_ROUTING = _descriptor.Descriptor(
      +  name='Routing',
      +  full_name='Routing',
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
      -      name='data', full_name='SubPacket.data', index=0,
      -      number=3, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='route_request', full_name='SubPacket.route_request', index=1,
      -      number=6, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='route_reply', full_name='SubPacket.route_reply', index=2,
      -      number=7, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='error_reason', full_name='SubPacket.error_reason', index=3,
      -      number=13, type=14, cpp_type=8, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='position', full_name='SubPacket.position', index=4,
      +      name='route_request', full_name='Routing.route_request', index=0,
             number=1, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=b'\030\001', file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='user', full_name='SubPacket.user', index=5,
      -      number=4, type=11, cpp_type=10, label=1,
      +      name='route_reply', full_name='Routing.route_reply', index=1,
      +      number=2, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=b'\030\001', file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='want_response', full_name='SubPacket.want_response', index=6,
      -      number=5, type=8, cpp_type=7, label=1,
      +      name='error_reason', full_name='Routing.error_reason', index=2,
      +      number=3, type=14, cpp_type=8, label=1,
      +      has_default_value=False, default_value=0,
      +      message_type=None, enum_type=None, containing_type=None,
      +      is_extension=False, extension_scope=None,
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
      +  ],
      +  extensions=[
      +  ],
      +  nested_types=[],
      +  enum_types=[
      +    _ROUTING_ERROR,
      +  ],
      +  serialized_options=None,
      +  is_extendable=False,
      +  syntax='proto3',
      +  extension_ranges=[],
      +  oneofs=[
      +    _descriptor.OneofDescriptor(
      +      name='variant', full_name='Routing.variant',
      +      index=0, containing_type=None,
      +      create_key=_descriptor._internal_create_key,
      +    fields=[]),
      +  ],
      +  serialized_start=260,
      +  serialized_end=530,
      +)
      +
      +
      +_DATA = _descriptor.Descriptor(
      +  name='Data',
      +  full_name='Data',
      +  filename=None,
      +  file=DESCRIPTOR,
      +  containing_type=None,
      +  create_key=_descriptor._internal_create_key,
      +  fields=[
      +    _descriptor.FieldDescriptor(
      +      name='portnum', full_name='Data.portnum', index=0,
      +      number=1, type=14, cpp_type=8, label=1,
      +      has_default_value=False, default_value=0,
      +      message_type=None, enum_type=None, containing_type=None,
      +      is_extension=False, extension_scope=None,
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
      +    _descriptor.FieldDescriptor(
      +      name='payload', full_name='Data.payload', index=1,
      +      number=2, type=12, cpp_type=9, label=1,
      +      has_default_value=False, default_value=b"",
      +      message_type=None, enum_type=None, containing_type=None,
      +      is_extension=False, extension_scope=None,
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
      +    _descriptor.FieldDescriptor(
      +      name='want_response', full_name='Data.want_response', index=2,
      +      number=3, type=8, cpp_type=7, label=1,
             has_default_value=False, default_value=False,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='success_id', full_name='SubPacket.success_id', index=7,
      -      number=10, type=13, cpp_type=3, label=1,
      +      name='dest', full_name='Data.dest', index=3,
      +      number=4, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='fail_id', full_name='SubPacket.fail_id', index=8,
      -      number=11, type=13, cpp_type=3, label=1,
      +      name='source', full_name='Data.source', index=4,
      +      number=5, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='dest', full_name='SubPacket.dest', index=9,
      -      number=9, type=13, cpp_type=3, label=1,
      +      name='request_id', full_name='Data.request_id', index=5,
      +      number=6, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='source', full_name='SubPacket.source', index=10,
      -      number=12, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='original_id', full_name='SubPacket.original_id', index=11,
      -      number=2, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -769,15 +568,9 @@ _SUBPACKET = _descriptor.Descriptor(
         syntax='proto3',
         extension_ranges=[],
         oneofs=[
      -    _descriptor.OneofDescriptor(
      -      name='payloadVariant', full_name='SubPacket.payloadVariant',
      -      index=0, containing_type=None, fields=[]),
      -    _descriptor.OneofDescriptor(
      -      name='ackVariant', full_name='SubPacket.ackVariant',
      -      index=1, containing_type=None, fields=[]),
         ],
      -  serialized_start=300,
      -  serialized_end=663,
      +  serialized_start=532,
      +  serialized_end=655,
       )
       
       
      @@ -787,82 +580,91 @@ _MESHPACKET = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='from', full_name='MeshPacket.from', index=0,
      -      number=1, type=13, cpp_type=3, label=1,
      +      number=1, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='to', full_name='MeshPacket.to', index=1,
      -      number=2, type=13, cpp_type=3, label=1,
      +      number=2, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='channel_index', full_name='MeshPacket.channel_index', index=2,
      -      number=4, type=13, cpp_type=3, label=1,
      +      name='channel', full_name='MeshPacket.channel', index=2,
      +      number=3, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='decoded', full_name='MeshPacket.decoded', index=3,
      -      number=3, type=11, cpp_type=10, label=1,
      +      number=4, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='encrypted', full_name='MeshPacket.encrypted', index=4,
      -      number=8, type=12, cpp_type=9, label=1,
      +      number=5, type=12, cpp_type=9, label=1,
             has_default_value=False, default_value=b"",
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='id', full_name='MeshPacket.id', index=5,
      -      number=6, type=13, cpp_type=3, label=1,
      +      number=6, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='rx_time', full_name='MeshPacket.rx_time', index=6,
      -      number=9, type=7, cpp_type=3, label=1,
      +      number=7, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='rx_snr', full_name='MeshPacket.rx_snr', index=7,
      -      number=7, type=2, cpp_type=6, label=1,
      +      number=8, type=2, cpp_type=6, label=1,
             has_default_value=False, default_value=float(0),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='hop_limit', full_name='MeshPacket.hop_limit', index=8,
             number=10, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='want_ack', full_name='MeshPacket.want_ack', index=9,
             number=11, type=8, cpp_type=7, label=1,
             has_default_value=False, default_value=False,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
      +    _descriptor.FieldDescriptor(
      +      name='priority', full_name='MeshPacket.priority', index=10,
      +      number=12, type=14, cpp_type=8, label=1,
      +      has_default_value=False, default_value=0,
      +      message_type=None, enum_type=None, containing_type=None,
      +      is_extension=False, extension_scope=None,
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
         nested_types=[],
         enum_types=[
      +    _MESHPACKET_PRIORITY,
         ],
         serialized_options=None,
         is_extendable=False,
      @@ -871,467 +673,12 @@ _MESHPACKET = _descriptor.Descriptor(
         oneofs=[
           _descriptor.OneofDescriptor(
             name='payloadVariant', full_name='MeshPacket.payloadVariant',
      -      index=0, containing_type=None, fields=[]),
      +      index=0, containing_type=None,
      +      create_key=_descriptor._internal_create_key,
      +    fields=[]),
         ],
      -  serialized_start=666,
      -  serialized_end=879,
      -)
      -
      -
      -_CHANNELSETTINGS = _descriptor.Descriptor(
      -  name='ChannelSettings',
      -  full_name='ChannelSettings',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  containing_type=None,
      -  fields=[
      -    _descriptor.FieldDescriptor(
      -      name='tx_power', full_name='ChannelSettings.tx_power', index=0,
      -      number=1, type=5, cpp_type=1, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='modem_config', full_name='ChannelSettings.modem_config', index=1,
      -      number=3, type=14, cpp_type=8, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='bandwidth', full_name='ChannelSettings.bandwidth', index=2,
      -      number=6, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='spread_factor', full_name='ChannelSettings.spread_factor', index=3,
      -      number=7, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='coding_rate', full_name='ChannelSettings.coding_rate', index=4,
      -      number=8, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='channel_num', full_name='ChannelSettings.channel_num', index=5,
      -      number=9, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='psk', full_name='ChannelSettings.psk', index=6,
      -      number=4, type=12, cpp_type=9, label=1,
      -      has_default_value=False, default_value=b"",
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='name', full_name='ChannelSettings.name', index=7,
      -      number=5, type=9, cpp_type=9, label=1,
      -      has_default_value=False, default_value=b"".decode('utf-8'),
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='id', full_name='ChannelSettings.id', index=8,
      -      number=10, type=7, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='uplink_enabled', full_name='ChannelSettings.uplink_enabled', index=9,
      -      number=16, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='downlink_enabled', full_name='ChannelSettings.downlink_enabled', index=10,
      -      number=17, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -  ],
      -  extensions=[
      -  ],
      -  nested_types=[],
      -  enum_types=[
      -    _CHANNELSETTINGS_MODEMCONFIG,
      -  ],
      -  serialized_options=None,
      -  is_extendable=False,
      -  syntax='proto3',
      -  extension_ranges=[],
      -  oneofs=[
      -  ],
      -  serialized_start=882,
      -  serialized_end=1240,
      -)
      -
      -
      -_RADIOCONFIG_USERPREFERENCES = _descriptor.Descriptor(
      -  name='UserPreferences',
      -  full_name='RadioConfig.UserPreferences',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  containing_type=None,
      -  fields=[
      -    _descriptor.FieldDescriptor(
      -      name='position_broadcast_secs', full_name='RadioConfig.UserPreferences.position_broadcast_secs', index=0,
      -      number=1, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='send_owner_interval', full_name='RadioConfig.UserPreferences.send_owner_interval', index=1,
      -      number=2, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='wait_bluetooth_secs', full_name='RadioConfig.UserPreferences.wait_bluetooth_secs', index=2,
      -      number=4, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='screen_on_secs', full_name='RadioConfig.UserPreferences.screen_on_secs', index=3,
      -      number=5, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='phone_timeout_secs', full_name='RadioConfig.UserPreferences.phone_timeout_secs', index=4,
      -      number=6, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='phone_sds_timeout_sec', full_name='RadioConfig.UserPreferences.phone_sds_timeout_sec', index=5,
      -      number=7, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='mesh_sds_timeout_secs', full_name='RadioConfig.UserPreferences.mesh_sds_timeout_secs', index=6,
      -      number=8, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='sds_secs', full_name='RadioConfig.UserPreferences.sds_secs', index=7,
      -      number=9, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='ls_secs', full_name='RadioConfig.UserPreferences.ls_secs', index=8,
      -      number=10, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='min_wake_secs', full_name='RadioConfig.UserPreferences.min_wake_secs', index=9,
      -      number=11, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='wifi_ssid', full_name='RadioConfig.UserPreferences.wifi_ssid', index=10,
      -      number=12, type=9, cpp_type=9, label=1,
      -      has_default_value=False, default_value=b"".decode('utf-8'),
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='wifi_password', full_name='RadioConfig.UserPreferences.wifi_password', index=11,
      -      number=13, type=9, cpp_type=9, label=1,
      -      has_default_value=False, default_value=b"".decode('utf-8'),
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='wifi_ap_mode', full_name='RadioConfig.UserPreferences.wifi_ap_mode', index=12,
      -      number=14, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='region', full_name='RadioConfig.UserPreferences.region', index=13,
      -      number=15, type=14, cpp_type=8, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='charge_current', full_name='RadioConfig.UserPreferences.charge_current', index=14,
      -      number=16, type=14, cpp_type=8, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='is_router', full_name='RadioConfig.UserPreferences.is_router', index=15,
      -      number=37, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='is_low_power', full_name='RadioConfig.UserPreferences.is_low_power', index=16,
      -      number=38, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='fixed_position', full_name='RadioConfig.UserPreferences.fixed_position', index=17,
      -      number=39, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='factory_reset', full_name='RadioConfig.UserPreferences.factory_reset', index=18,
      -      number=100, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='debug_log_enabled', full_name='RadioConfig.UserPreferences.debug_log_enabled', index=19,
      -      number=101, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='location_share', full_name='RadioConfig.UserPreferences.location_share', index=20,
      -      number=32, type=14, cpp_type=8, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='gps_operation', full_name='RadioConfig.UserPreferences.gps_operation', index=21,
      -      number=33, type=14, cpp_type=8, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='gps_update_interval', full_name='RadioConfig.UserPreferences.gps_update_interval', index=22,
      -      number=34, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='gps_attempt_time', full_name='RadioConfig.UserPreferences.gps_attempt_time', index=23,
      -      number=36, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='ignore_incoming', full_name='RadioConfig.UserPreferences.ignore_incoming', index=24,
      -      number=103, type=13, cpp_type=3, label=3,
      -      has_default_value=False, default_value=[],
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='serialplugin_enabled', full_name='RadioConfig.UserPreferences.serialplugin_enabled', index=25,
      -      number=120, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='serialplugin_echo', full_name='RadioConfig.UserPreferences.serialplugin_echo', index=26,
      -      number=121, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='serialplugin_rxd', full_name='RadioConfig.UserPreferences.serialplugin_rxd', index=27,
      -      number=122, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='serialplugin_txd', full_name='RadioConfig.UserPreferences.serialplugin_txd', index=28,
      -      number=123, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='serialplugin_timeout', full_name='RadioConfig.UserPreferences.serialplugin_timeout', index=29,
      -      number=124, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='serialplugin_mode', full_name='RadioConfig.UserPreferences.serialplugin_mode', index=30,
      -      number=125, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='ext_notification_plugin_enabled', full_name='RadioConfig.UserPreferences.ext_notification_plugin_enabled', index=31,
      -      number=126, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='ext_notification_plugin_output_ms', full_name='RadioConfig.UserPreferences.ext_notification_plugin_output_ms', index=32,
      -      number=127, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='ext_notification_plugin_output', full_name='RadioConfig.UserPreferences.ext_notification_plugin_output', index=33,
      -      number=128, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='ext_notification_plugin_active', full_name='RadioConfig.UserPreferences.ext_notification_plugin_active', index=34,
      -      number=129, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='ext_notification_plugin_alert_message', full_name='RadioConfig.UserPreferences.ext_notification_plugin_alert_message', index=35,
      -      number=130, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='ext_notification_plugin_alert_bell', full_name='RadioConfig.UserPreferences.ext_notification_plugin_alert_bell', index=36,
      -      number=131, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='range_test_plugin_enabled', full_name='RadioConfig.UserPreferences.range_test_plugin_enabled', index=37,
      -      number=132, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='range_test_plugin_sender', full_name='RadioConfig.UserPreferences.range_test_plugin_sender', index=38,
      -      number=133, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='range_test_plugin_save', full_name='RadioConfig.UserPreferences.range_test_plugin_save', index=39,
      -      number=134, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='store_forward_plugin_enabled', full_name='RadioConfig.UserPreferences.store_forward_plugin_enabled', index=40,
      -      number=136, type=8, cpp_type=7, label=1,
      -      has_default_value=False, default_value=False,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='store_forward_plugin_records', full_name='RadioConfig.UserPreferences.store_forward_plugin_records', index=41,
      -      number=137, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -  ],
      -  extensions=[
      -  ],
      -  nested_types=[],
      -  enum_types=[
      -  ],
      -  serialized_options=None,
      -  is_extendable=False,
      -  syntax='proto3',
      -  extension_ranges=[],
      -  oneofs=[
      -  ],
      -  serialized_start=1358,
      -  serialized_end=2653,
      -)
      -
      -_RADIOCONFIG = _descriptor.Descriptor(
      -  name='RadioConfig',
      -  full_name='RadioConfig',
      -  filename=None,
      -  file=DESCRIPTOR,
      -  containing_type=None,
      -  fields=[
      -    _descriptor.FieldDescriptor(
      -      name='preferences', full_name='RadioConfig.preferences', index=0,
      -      number=1, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='channel_settings', full_name='RadioConfig.channel_settings', index=1,
      -      number=2, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=b'\030\001', file=DESCRIPTOR),
      -  ],
      -  extensions=[
      -  ],
      -  nested_types=[_RADIOCONFIG_USERPREFERENCES, ],
      -  enum_types=[
      -  ],
      -  serialized_options=None,
      -  is_extendable=False,
      -  syntax='proto3',
      -  extension_ranges=[],
      -  oneofs=[
      -  ],
      -  serialized_start=1243,
      -  serialized_end=2653,
      +  serialized_start=658,
      +  serialized_end=993,
       )
       
       
      @@ -1341,6 +688,7 @@ _NODEINFO = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='num', full_name='NodeInfo.num', index=0,
      @@ -1348,35 +696,35 @@ _NODEINFO = _descriptor.Descriptor(
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='user', full_name='NodeInfo.user', index=1,
             number=2, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='position', full_name='NodeInfo.position', index=2,
             number=3, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='snr', full_name='NodeInfo.snr', index=3,
             number=7, type=2, cpp_type=6, label=1,
             has_default_value=False, default_value=float(0),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='next_hop', full_name='NodeInfo.next_hop', index=4,
             number=5, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -1389,8 +737,8 @@ _NODEINFO = _descriptor.Descriptor(
         extension_ranges=[],
         oneofs=[
         ],
      -  serialized_start=2655,
      -  serialized_end=2759,
      +  serialized_start=995,
      +  serialized_end=1099,
       )
       
       
      @@ -1400,6 +748,7 @@ _MYNODEINFO = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='my_node_num', full_name='MyNodeInfo.my_node_num', index=0,
      @@ -1407,98 +756,84 @@ _MYNODEINFO = _descriptor.Descriptor(
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='has_gps', full_name='MyNodeInfo.has_gps', index=1,
             number=2, type=8, cpp_type=7, label=1,
             has_default_value=False, default_value=False,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='num_channels', full_name='MyNodeInfo.num_channels', index=2,
      -      number=3, type=5, cpp_type=1, label=1,
      +      name='num_bands', full_name='MyNodeInfo.num_bands', index=2,
      +      number=3, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='region', full_name='MyNodeInfo.region', index=3,
      +      name='max_channels', full_name='MyNodeInfo.max_channels', index=3,
      +      number=15, type=13, cpp_type=3, label=1,
      +      has_default_value=False, default_value=0,
      +      message_type=None, enum_type=None, containing_type=None,
      +      is_extension=False, extension_scope=None,
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
      +    _descriptor.FieldDescriptor(
      +      name='region', full_name='MyNodeInfo.region', index=4,
             number=4, type=9, cpp_type=9, label=1,
             has_default_value=False, default_value=b"".decode('utf-8'),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=b'\030\001', file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='hw_model', full_name='MyNodeInfo.hw_model', index=4,
      +      name='hw_model', full_name='MyNodeInfo.hw_model', index=5,
             number=5, type=9, cpp_type=9, label=1,
             has_default_value=False, default_value=b"".decode('utf-8'),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='firmware_version', full_name='MyNodeInfo.firmware_version', index=5,
      +      name='firmware_version', full_name='MyNodeInfo.firmware_version', index=6,
             number=6, type=9, cpp_type=9, label=1,
             has_default_value=False, default_value=b"".decode('utf-8'),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='error_code', full_name='MyNodeInfo.error_code', index=6,
      +      name='error_code', full_name='MyNodeInfo.error_code', index=7,
             number=7, type=14, cpp_type=8, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='error_address', full_name='MyNodeInfo.error_address', index=7,
      +      name='error_address', full_name='MyNodeInfo.error_address', index=8,
             number=8, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='error_count', full_name='MyNodeInfo.error_count', index=8,
      +      name='error_count', full_name='MyNodeInfo.error_count', index=9,
             number=9, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='packet_id_bits', full_name='MyNodeInfo.packet_id_bits', index=9,
      -      number=10, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='current_packet_id', full_name='MyNodeInfo.current_packet_id', index=10,
      -      number=11, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='node_num_bits', full_name='MyNodeInfo.node_num_bits', index=11,
      -      number=12, type=13, cpp_type=3, label=1,
      -      has_default_value=False, default_value=0,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='message_timeout_msec', full_name='MyNodeInfo.message_timeout_msec', index=12,
      +      name='message_timeout_msec', full_name='MyNodeInfo.message_timeout_msec', index=10,
             number=13, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='min_app_version', full_name='MyNodeInfo.min_app_version', index=13,
      +      name='min_app_version', full_name='MyNodeInfo.min_app_version', index=11,
             number=14, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -1511,8 +846,8 @@ _MYNODEINFO = _descriptor.Descriptor(
         extension_ranges=[],
         oneofs=[
         ],
      -  serialized_start=2762,
      -  serialized_end=3107,
      +  serialized_start=1102,
      +  serialized_end=1396,
       )
       
       
      @@ -1522,6 +857,7 @@ _LOGRECORD = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='message', full_name='LogRecord.message', index=0,
      @@ -1529,28 +865,28 @@ _LOGRECORD = _descriptor.Descriptor(
             has_default_value=False, default_value=b"".decode('utf-8'),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='time', full_name='LogRecord.time', index=1,
             number=2, type=7, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='source', full_name='LogRecord.source', index=2,
             number=3, type=9, cpp_type=9, label=1,
             has_default_value=False, default_value=b"".decode('utf-8'),
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='level', full_name='LogRecord.level', index=3,
             number=4, type=14, cpp_type=8, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -1564,8 +900,8 @@ _LOGRECORD = _descriptor.Descriptor(
         extension_ranges=[],
         oneofs=[
         ],
      -  serialized_start=3110,
      -  serialized_end=3291,
      +  serialized_start=1399,
      +  serialized_end=1580,
       )
       
       
      @@ -1575,6 +911,7 @@ _FROMRADIO = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='num', full_name='FromRadio.num', index=0,
      @@ -1582,63 +919,49 @@ _FROMRADIO = _descriptor.Descriptor(
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='packet', full_name='FromRadio.packet', index=1,
      -      number=2, type=11, cpp_type=10, label=1,
      +      number=11, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='my_info', full_name='FromRadio.my_info', index=2,
             number=3, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='node_info', full_name='FromRadio.node_info', index=3,
             number=4, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='radio', full_name='FromRadio.radio', index=4,
      -      number=6, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='log_record', full_name='FromRadio.log_record', index=5,
      +      name='log_record', full_name='FromRadio.log_record', index=4,
             number=7, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='config_complete_id', full_name='FromRadio.config_complete_id', index=6,
      +      name='config_complete_id', full_name='FromRadio.config_complete_id', index=5,
             number=8, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
      -      name='rebooted', full_name='FromRadio.rebooted', index=7,
      +      name='rebooted', full_name='FromRadio.rebooted', index=6,
             number=9, type=8, cpp_type=7, label=1,
             has_default_value=False, default_value=False,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='channel', full_name='FromRadio.channel', index=8,
      -      number=10, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -1652,10 +975,12 @@ _FROMRADIO = _descriptor.Descriptor(
         oneofs=[
           _descriptor.OneofDescriptor(
             name='payloadVariant', full_name='FromRadio.payloadVariant',
      -      index=0, containing_type=None, fields=[]),
      +      index=0, containing_type=None,
      +      create_key=_descriptor._internal_create_key,
      +    fields=[]),
         ],
      -  serialized_start=3294,
      -  serialized_end=3583,
      +  serialized_start=1583,
      +  serialized_end=1816,
       )
       
       
      @@ -1665,42 +990,22 @@ _TORADIO = _descriptor.Descriptor(
         filename=None,
         file=DESCRIPTOR,
         containing_type=None,
      +  create_key=_descriptor._internal_create_key,
         fields=[
           _descriptor.FieldDescriptor(
             name='packet', full_name='ToRadio.packet', index=0,
      -      number=1, type=11, cpp_type=10, label=1,
      +      number=2, type=11, cpp_type=10, label=1,
             has_default_value=False, default_value=None,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
           _descriptor.FieldDescriptor(
             name='want_config_id', full_name='ToRadio.want_config_id', index=1,
             number=100, type=13, cpp_type=3, label=1,
             has_default_value=False, default_value=0,
             message_type=None, enum_type=None, containing_type=None,
             is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='set_radio', full_name='ToRadio.set_radio', index=2,
      -      number=101, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='set_owner', full_name='ToRadio.set_owner', index=3,
      -      number=102, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      -    _descriptor.FieldDescriptor(
      -      name='set_channel', full_name='ToRadio.set_channel', index=4,
      -      number=103, type=11, cpp_type=10, label=1,
      -      has_default_value=False, default_value=None,
      -      message_type=None, enum_type=None, containing_type=None,
      -      is_extension=False, extension_scope=None,
      -      serialized_options=None, file=DESCRIPTOR),
      +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
         ],
         extensions=[
         ],
      @@ -1714,59 +1019,37 @@ _TORADIO = _descriptor.Descriptor(
         oneofs=[
           _descriptor.OneofDescriptor(
             name='payloadVariant', full_name='ToRadio.payloadVariant',
      -      index=0, containing_type=None, fields=[]),
      +      index=0, containing_type=None,
      +      create_key=_descriptor._internal_create_key,
      +    fields=[]),
         ],
      -  serialized_start=3586,
      -  serialized_end=3774,
      +  serialized_start=1818,
      +  serialized_end=1926,
       )
       
      +_ROUTING.fields_by_name['route_request'].message_type = _ROUTEDISCOVERY
      +_ROUTING.fields_by_name['route_reply'].message_type = _ROUTEDISCOVERY
      +_ROUTING.fields_by_name['error_reason'].enum_type = _ROUTING_ERROR
      +_ROUTING_ERROR.containing_type = _ROUTING
      +_ROUTING.oneofs_by_name['variant'].fields.append(
      +  _ROUTING.fields_by_name['route_request'])
      +_ROUTING.fields_by_name['route_request'].containing_oneof = _ROUTING.oneofs_by_name['variant']
      +_ROUTING.oneofs_by_name['variant'].fields.append(
      +  _ROUTING.fields_by_name['route_reply'])
      +_ROUTING.fields_by_name['route_reply'].containing_oneof = _ROUTING.oneofs_by_name['variant']
      +_ROUTING.oneofs_by_name['variant'].fields.append(
      +  _ROUTING.fields_by_name['error_reason'])
      +_ROUTING.fields_by_name['error_reason'].containing_oneof = _ROUTING.oneofs_by_name['variant']
       _DATA.fields_by_name['portnum'].enum_type = portnums__pb2._PORTNUM
      -_SUBPACKET.fields_by_name['data'].message_type = _DATA
      -_SUBPACKET.fields_by_name['route_request'].message_type = _ROUTEDISCOVERY
      -_SUBPACKET.fields_by_name['route_reply'].message_type = _ROUTEDISCOVERY
      -_SUBPACKET.fields_by_name['error_reason'].enum_type = _ERRORREASON
      -_SUBPACKET.fields_by_name['position'].message_type = _POSITION
      -_SUBPACKET.fields_by_name['user'].message_type = _USER
      -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append(
      -  _SUBPACKET.fields_by_name['data'])
      -_SUBPACKET.fields_by_name['data'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant']
      -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append(
      -  _SUBPACKET.fields_by_name['route_request'])
      -_SUBPACKET.fields_by_name['route_request'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant']
      -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append(
      -  _SUBPACKET.fields_by_name['route_reply'])
      -_SUBPACKET.fields_by_name['route_reply'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant']
      -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append(
      -  _SUBPACKET.fields_by_name['error_reason'])
      -_SUBPACKET.fields_by_name['error_reason'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant']
      -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append(
      -  _SUBPACKET.fields_by_name['position'])
      -_SUBPACKET.fields_by_name['position'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant']
      -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append(
      -  _SUBPACKET.fields_by_name['user'])
      -_SUBPACKET.fields_by_name['user'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant']
      -_SUBPACKET.oneofs_by_name['ackVariant'].fields.append(
      -  _SUBPACKET.fields_by_name['success_id'])
      -_SUBPACKET.fields_by_name['success_id'].containing_oneof = _SUBPACKET.oneofs_by_name['ackVariant']
      -_SUBPACKET.oneofs_by_name['ackVariant'].fields.append(
      -  _SUBPACKET.fields_by_name['fail_id'])
      -_SUBPACKET.fields_by_name['fail_id'].containing_oneof = _SUBPACKET.oneofs_by_name['ackVariant']
      -_MESHPACKET.fields_by_name['decoded'].message_type = _SUBPACKET
      +_MESHPACKET.fields_by_name['decoded'].message_type = _DATA
      +_MESHPACKET.fields_by_name['priority'].enum_type = _MESHPACKET_PRIORITY
      +_MESHPACKET_PRIORITY.containing_type = _MESHPACKET
       _MESHPACKET.oneofs_by_name['payloadVariant'].fields.append(
         _MESHPACKET.fields_by_name['decoded'])
       _MESHPACKET.fields_by_name['decoded'].containing_oneof = _MESHPACKET.oneofs_by_name['payloadVariant']
       _MESHPACKET.oneofs_by_name['payloadVariant'].fields.append(
         _MESHPACKET.fields_by_name['encrypted'])
       _MESHPACKET.fields_by_name['encrypted'].containing_oneof = _MESHPACKET.oneofs_by_name['payloadVariant']
      -_CHANNELSETTINGS.fields_by_name['modem_config'].enum_type = _CHANNELSETTINGS_MODEMCONFIG
      -_CHANNELSETTINGS_MODEMCONFIG.containing_type = _CHANNELSETTINGS
      -_RADIOCONFIG_USERPREFERENCES.fields_by_name['region'].enum_type = _REGIONCODE
      -_RADIOCONFIG_USERPREFERENCES.fields_by_name['charge_current'].enum_type = _CHARGECURRENT
      -_RADIOCONFIG_USERPREFERENCES.fields_by_name['location_share'].enum_type = _LOCATIONSHARING
      -_RADIOCONFIG_USERPREFERENCES.fields_by_name['gps_operation'].enum_type = _GPSOPERATION
      -_RADIOCONFIG_USERPREFERENCES.containing_type = _RADIOCONFIG
      -_RADIOCONFIG.fields_by_name['preferences'].message_type = _RADIOCONFIG_USERPREFERENCES
      -_RADIOCONFIG.fields_by_name['channel_settings'].message_type = _CHANNELSETTINGS
       _NODEINFO.fields_by_name['user'].message_type = _USER
       _NODEINFO.fields_by_name['position'].message_type = _POSITION
       _MYNODEINFO.fields_by_name['error_code'].enum_type = _CRITICALERRORCODE
      @@ -1775,9 +1058,7 @@ _LOGRECORD_LEVEL.containing_type = _LOGRECORD
       _FROMRADIO.fields_by_name['packet'].message_type = _MESHPACKET
       _FROMRADIO.fields_by_name['my_info'].message_type = _MYNODEINFO
       _FROMRADIO.fields_by_name['node_info'].message_type = _NODEINFO
      -_FROMRADIO.fields_by_name['radio'].message_type = _RADIOCONFIG
       _FROMRADIO.fields_by_name['log_record'].message_type = _LOGRECORD
      -_FROMRADIO.fields_by_name['channel'].message_type = _CHANNELSETTINGS
       _FROMRADIO.oneofs_by_name['payloadVariant'].fields.append(
         _FROMRADIO.fields_by_name['packet'])
       _FROMRADIO.fields_by_name['packet'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant']
      @@ -1787,9 +1068,6 @@ _FROMRADIO.fields_by_name['my_info'].containing_oneof = _FROMRADIO.oneof
       _FROMRADIO.oneofs_by_name['payloadVariant'].fields.append(
         _FROMRADIO.fields_by_name['node_info'])
       _FROMRADIO.fields_by_name['node_info'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant']
      -_FROMRADIO.oneofs_by_name['payloadVariant'].fields.append(
      -  _FROMRADIO.fields_by_name['radio'])
      -_FROMRADIO.fields_by_name['radio'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant']
       _FROMRADIO.oneofs_by_name['payloadVariant'].fields.append(
         _FROMRADIO.fields_by_name['log_record'])
       _FROMRADIO.fields_by_name['log_record'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant']
      @@ -1799,47 +1077,25 @@ _FROMRADIO.fields_by_name['config_complete_id'].containing_oneof = _FROM
       _FROMRADIO.oneofs_by_name['payloadVariant'].fields.append(
         _FROMRADIO.fields_by_name['rebooted'])
       _FROMRADIO.fields_by_name['rebooted'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant']
      -_FROMRADIO.oneofs_by_name['payloadVariant'].fields.append(
      -  _FROMRADIO.fields_by_name['channel'])
      -_FROMRADIO.fields_by_name['channel'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant']
       _TORADIO.fields_by_name['packet'].message_type = _MESHPACKET
      -_TORADIO.fields_by_name['set_radio'].message_type = _RADIOCONFIG
      -_TORADIO.fields_by_name['set_owner'].message_type = _USER
      -_TORADIO.fields_by_name['set_channel'].message_type = _CHANNELSETTINGS
       _TORADIO.oneofs_by_name['payloadVariant'].fields.append(
         _TORADIO.fields_by_name['packet'])
       _TORADIO.fields_by_name['packet'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant']
       _TORADIO.oneofs_by_name['payloadVariant'].fields.append(
         _TORADIO.fields_by_name['want_config_id'])
       _TORADIO.fields_by_name['want_config_id'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant']
      -_TORADIO.oneofs_by_name['payloadVariant'].fields.append(
      -  _TORADIO.fields_by_name['set_radio'])
      -_TORADIO.fields_by_name['set_radio'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant']
      -_TORADIO.oneofs_by_name['payloadVariant'].fields.append(
      -  _TORADIO.fields_by_name['set_owner'])
      -_TORADIO.fields_by_name['set_owner'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant']
      -_TORADIO.oneofs_by_name['payloadVariant'].fields.append(
      -  _TORADIO.fields_by_name['set_channel'])
      -_TORADIO.fields_by_name['set_channel'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant']
       DESCRIPTOR.message_types_by_name['Position'] = _POSITION
      -DESCRIPTOR.message_types_by_name['Data'] = _DATA
       DESCRIPTOR.message_types_by_name['User'] = _USER
       DESCRIPTOR.message_types_by_name['RouteDiscovery'] = _ROUTEDISCOVERY
      -DESCRIPTOR.message_types_by_name['SubPacket'] = _SUBPACKET
      +DESCRIPTOR.message_types_by_name['Routing'] = _ROUTING
      +DESCRIPTOR.message_types_by_name['Data'] = _DATA
       DESCRIPTOR.message_types_by_name['MeshPacket'] = _MESHPACKET
      -DESCRIPTOR.message_types_by_name['ChannelSettings'] = _CHANNELSETTINGS
      -DESCRIPTOR.message_types_by_name['RadioConfig'] = _RADIOCONFIG
       DESCRIPTOR.message_types_by_name['NodeInfo'] = _NODEINFO
       DESCRIPTOR.message_types_by_name['MyNodeInfo'] = _MYNODEINFO
       DESCRIPTOR.message_types_by_name['LogRecord'] = _LOGRECORD
       DESCRIPTOR.message_types_by_name['FromRadio'] = _FROMRADIO
       DESCRIPTOR.message_types_by_name['ToRadio'] = _TORADIO
      -DESCRIPTOR.enum_types_by_name['ErrorReason'] = _ERRORREASON
       DESCRIPTOR.enum_types_by_name['Constants'] = _CONSTANTS
      -DESCRIPTOR.enum_types_by_name['RegionCode'] = _REGIONCODE
      -DESCRIPTOR.enum_types_by_name['ChargeCurrent'] = _CHARGECURRENT
      -DESCRIPTOR.enum_types_by_name['GpsOperation'] = _GPSOPERATION
      -DESCRIPTOR.enum_types_by_name['LocationSharing'] = _LOCATIONSHARING
       DESCRIPTOR.enum_types_by_name['CriticalErrorCode'] = _CRITICALERRORCODE
       _sym_db.RegisterFileDescriptor(DESCRIPTOR)
       
      @@ -1850,13 +1106,6 @@ Position = _reflection.GeneratedProtocolMessageType('Position', (_messag
         })
       _sym_db.RegisterMessage(Position)
       
      -Data = _reflection.GeneratedProtocolMessageType('Data', (_message.Message,), {
      -  'DESCRIPTOR' : _DATA,
      -  '__module__' : 'mesh_pb2'
      -  # @@protoc_insertion_point(class_scope:Data)
      -  })
      -_sym_db.RegisterMessage(Data)
      -
       User = _reflection.GeneratedProtocolMessageType('User', (_message.Message,), {
         'DESCRIPTOR' : _USER,
         '__module__' : 'mesh_pb2'
      @@ -1871,12 +1120,19 @@ RouteDiscovery = _reflection.GeneratedProtocolMessageType('RouteDiscovery
         })
       _sym_db.RegisterMessage(RouteDiscovery)
       
      -SubPacket = _reflection.GeneratedProtocolMessageType('SubPacket', (_message.Message,), {
      -  'DESCRIPTOR' : _SUBPACKET,
      +Routing = _reflection.GeneratedProtocolMessageType('Routing', (_message.Message,), {
      +  'DESCRIPTOR' : _ROUTING,
         '__module__' : 'mesh_pb2'
      -  # @@protoc_insertion_point(class_scope:SubPacket)
      +  # @@protoc_insertion_point(class_scope:Routing)
         })
      -_sym_db.RegisterMessage(SubPacket)
      +_sym_db.RegisterMessage(Routing)
      +
      +Data = _reflection.GeneratedProtocolMessageType('Data', (_message.Message,), {
      +  'DESCRIPTOR' : _DATA,
      +  '__module__' : 'mesh_pb2'
      +  # @@protoc_insertion_point(class_scope:Data)
      +  })
      +_sym_db.RegisterMessage(Data)
       
       MeshPacket = _reflection.GeneratedProtocolMessageType('MeshPacket', (_message.Message,), {
         'DESCRIPTOR' : _MESHPACKET,
      @@ -1885,28 +1141,6 @@ MeshPacket = _reflection.GeneratedProtocolMessageType('MeshPacket', (_me
         })
       _sym_db.RegisterMessage(MeshPacket)
       
      -ChannelSettings = _reflection.GeneratedProtocolMessageType('ChannelSettings', (_message.Message,), {
      -  'DESCRIPTOR' : _CHANNELSETTINGS,
      -  '__module__' : 'mesh_pb2'
      -  # @@protoc_insertion_point(class_scope:ChannelSettings)
      -  })
      -_sym_db.RegisterMessage(ChannelSettings)
      -
      -RadioConfig = _reflection.GeneratedProtocolMessageType('RadioConfig', (_message.Message,), {
      -
      -  'UserPreferences' : _reflection.GeneratedProtocolMessageType('UserPreferences', (_message.Message,), {
      -    'DESCRIPTOR' : _RADIOCONFIG_USERPREFERENCES,
      -    '__module__' : 'mesh_pb2'
      -    # @@protoc_insertion_point(class_scope:RadioConfig.UserPreferences)
      -    })
      -  ,
      -  'DESCRIPTOR' : _RADIOCONFIG,
      -  '__module__' : 'mesh_pb2'
      -  # @@protoc_insertion_point(class_scope:RadioConfig)
      -  })
      -_sym_db.RegisterMessage(RadioConfig)
      -_sym_db.RegisterMessage(RadioConfig.UserPreferences)
      -
       NodeInfo = _reflection.GeneratedProtocolMessageType('NodeInfo', (_message.Message,), {
         'DESCRIPTOR' : _NODEINFO,
         '__module__' : 'mesh_pb2'
      @@ -1944,9 +1178,7 @@ _sym_db.RegisterMessage(ToRadio)
       
       
       DESCRIPTOR._options = None
      -_SUBPACKET.fields_by_name['position']._options = None
      -_SUBPACKET.fields_by_name['user']._options = None
      -_RADIOCONFIG.fields_by_name['channel_settings']._options = None
      +_MYNODEINFO.fields_by_name['region']._options = None
       # @@protoc_insertion_point(module_scope)
      @@ -1959,92 +1191,6 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

      Classes

      -
      -class ChannelSettings -(*args, **kwargs) -
      -
      -

      A ProtocolMessage

      -

      Ancestors

      -
        -
      • google.protobuf.pyext._message.CMessage
      • -
      • google.protobuf.message.Message
      • -
      -

      Class variables

      -
      -
      var Bw125Cr45Sf128
      -
      -
      -
      -
      var Bw125Cr48Sf4096
      -
      -
      -
      -
      var Bw31_25Cr48Sf512
      -
      -
      -
      -
      var Bw500Cr45Sf128
      -
      -
      -
      -
      var DESCRIPTOR
      -
      -
      -
      -
      var ModemConfig
      -
      -
      -
      -
      -

      Instance variables

      -
      -
      var bandwidth
      -
      -

      Field ChannelSettings.bandwidth

      -
      -
      var channel_num
      -
      -

      Field ChannelSettings.channel_num

      -
      -
      var coding_rate
      -
      -

      Field ChannelSettings.coding_rate

      -
      - -
      -

      Field ChannelSettings.downlink_enabled

      -
      -
      var id
      -
      -

      Field ChannelSettings.id

      -
      -
      var modem_config
      -
      -

      Field ChannelSettings.modem_config

      -
      -
      var name
      -
      -

      Field ChannelSettings.name

      -
      -
      var psk
      -
      -

      Field ChannelSettings.psk

      -
      -
      var spread_factor
      -
      -

      Field ChannelSettings.spread_factor

      -
      -
      var tx_power
      -
      -

      Field ChannelSettings.tx_power

      -
      - -
      -

      Field ChannelSettings.uplink_enabled

      -
      -
      -
      class Data (*args, **kwargs) @@ -2065,6 +1211,10 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

      Instance variables

      +
      var dest
      +
      +

      Field Data.dest

      +
      var payload

      Field Data.payload

      @@ -2073,6 +1223,18 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

      Field Data.portnum

      +
      var request_id
      +
      +

      Field Data.request_id

      +
      +
      var source
      +
      +

      Field Data.source

      +
      +
      var want_response
      +
      +

      Field Data.want_response

      +
  • @@ -2095,10 +1257,6 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Instance variables

    -
    var channel
    -
    -

    Field FromRadio.channel

    -
    var config_complete_id

    Field FromRadio.config_complete_id

    @@ -2123,10 +1281,6 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Field FromRadio.packet

    -
    var radio
    -
    -

    Field FromRadio.radio

    -
    var rebooted

    Field FromRadio.rebooted

    @@ -2216,16 +1370,48 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Class variables

    +
    var ACK
    +
    +
    +
    +
    var BACKGROUND
    +
    +
    +
    +
    var DEFAULT
    +
    +
    +
    var DESCRIPTOR
    +
    var MAX
    +
    +
    +
    +
    var MIN
    +
    +
    +
    +
    var Priority
    +
    +
    +
    +
    var RELIABLE
    +
    +
    +
    +
    var UNSET
    +
    +
    +

    Instance variables

    -
    var channel_index
    +
    var channel
    -

    Field MeshPacket.channel_index

    +

    Field MeshPacket.channel

    var decoded
    @@ -2247,6 +1433,10 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Field MeshPacket.id

    +
    var priority
    +
    +

    Field MeshPacket.priority

    +
    var rx_snr

    Field MeshPacket.rx_snr

    @@ -2285,10 +1475,6 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Instance variables

    -
    var current_packet_id
    -
    -

    Field MyNodeInfo.current_packet_id

    -
    var error_address

    Field MyNodeInfo.error_address

    @@ -2313,6 +1499,10 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Field MyNodeInfo.hw_model

    +
    var max_channels
    +
    +

    Field MyNodeInfo.max_channels

    +
    var message_timeout_msec

    Field MyNodeInfo.message_timeout_msec

    @@ -2325,17 +1515,9 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Field MyNodeInfo.my_node_num

    -
    var node_num_bits
    +
    var num_bands
    -

    Field MyNodeInfo.node_num_bits

    -
    -
    var num_channels
    -
    -

    Field MyNodeInfo.num_channels

    -
    -
    var packet_id_bits
    -
    -

    Field MyNodeInfo.packet_id_bits

    +

    Field MyNodeInfo.num_bands

    var region
    @@ -2427,40 +1609,6 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None
    -
    -class RadioConfig -(*args, **kwargs) -
    -
    -

    A ProtocolMessage

    -

    Ancestors

    -
      -
    • google.protobuf.pyext._message.CMessage
    • -
    • google.protobuf.message.Message
    • -
    -

    Class variables

    -
    -
    var DESCRIPTOR
    -
    -
    -
    -
    var UserPreferences
    -
    -

    A ProtocolMessage

    -
    -
    -

    Instance variables

    -
    -
    var channel_settings
    -
    -

    Field RadioConfig.channel_settings

    -
    -
    var preferences
    -
    -

    Field RadioConfig.preferences

    -
    -
    -
    class RouteDiscovery (*args, **kwargs) @@ -2487,8 +1635,8 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None
    -
    -class SubPacket +
    +class Routing (*args, **kwargs)
    @@ -2500,60 +1648,60 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Class variables

    -
    var DESCRIPTOR
    +
    var DESCRIPTOR
    +
    +
    +
    +
    var Error
    +
    +
    +
    +
    var GOT_NAK
    +
    +
    +
    +
    var MAX_RETRANSMIT
    +
    +
    +
    +
    var NONE
    +
    +
    +
    +
    var NO_CHANNEL
    +
    +
    +
    +
    var NO_INTERFACE
    +
    +
    +
    +
    var NO_ROUTE
    +
    +
    +
    +
    var TIMEOUT
    +
    +
    +
    +
    var TOO_LARGE

    Instance variables

    -
    var data
    +
    var error_reason
    -

    Field SubPacket.data

    +

    Field Routing.error_reason

    -
    var dest
    +
    var route_reply
    -

    Field SubPacket.dest

    +

    Field Routing.route_reply

    -
    var error_reason
    +
    var route_request
    -

    Field SubPacket.error_reason

    -
    -
    var fail_id
    -
    -

    Field SubPacket.fail_id

    -
    -
    var original_id
    -
    -

    Field SubPacket.original_id

    -
    -
    var position
    -
    -

    Field SubPacket.position

    -
    -
    var route_reply
    -
    -

    Field SubPacket.route_reply

    -
    -
    var route_request
    -
    -

    Field SubPacket.route_request

    -
    -
    var source
    -
    -

    Field SubPacket.source

    -
    -
    var success_id
    -
    -

    Field SubPacket.success_id

    -
    -
    var user
    -
    -

    Field SubPacket.user

    -
    -
    var want_response
    -
    -

    Field SubPacket.want_response

    +

    Field Routing.route_request

    @@ -2581,18 +1729,6 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None

    Field ToRadio.packet

    -
    var set_channel
    -
    -

    Field ToRadio.set_channel

    -
    -
    var set_owner
    -
    -

    Field ToRadio.set_owner

    -
    -
    var set_radio
    -
    -

    Field ToRadio.set_radio

    -
    var want_config_id

    Field ToRadio.want_config_id

    @@ -2654,47 +1790,27 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None
  • Classes

    • -

      ChannelSettings

      - -
    • -
    • Data

      -
        +
      • FromRadio

      • @@ -2719,13 +1835,22 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None
      • MeshPacket

      • -

        RadioConfig

        - -
      • -
      • RouteDiscovery

        • DESCRIPTOR
        • @@ -2791,31 +1905,28 @@ _RADIOCONFIG.fields_by_name['channel_settings']._options = None
      • -

        SubPacket

        +

        Routing

      • ToRadio

        -
          + diff --git a/docs/meshtastic/portnums_pb2.html b/docs/meshtastic/portnums_pb2.html index ee809ab..a2fba87 100644 --- a/docs/meshtastic/portnums_pb2.html +++ b/docs/meshtastic/portnums_pb2.html @@ -5,7 +5,7 @@ meshtastic.portnums_pb2 API documentation - + @@ -22,6 +22,7 @@

          Module meshtastic.portnums_pb2

          +

          Generated protocol buffer code.

          Expand source code @@ -29,7 +30,7 @@
          # -*- coding: utf-8 -*-
           # Generated by the protocol buffer compiler.  DO NOT EDIT!
           # source: portnums.proto
          -
          +"""Generated protocol buffer code."""
           from google.protobuf.internal import enum_type_wrapper
           from google.protobuf import descriptor as _descriptor
           from google.protobuf import message as _message
          @@ -47,7 +48,8 @@ DESCRIPTOR = _descriptor.FileDescriptor(
             package='',
             syntax='proto3',
             serialized_options=b'\n\023com.geeksville.meshB\010PortnumsH\003',
          -  serialized_pb=b'\n\x0eportnums.proto*\xdd\x01\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x42!\n\x13\x63om.geeksville.meshB\x08PortnumsH\x03\x62\x06proto3'
          +  create_key=_descriptor._internal_create_key,
          +  serialized_pb=b'\n\x0eportnums.proto*\xbe\x02\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12!\n\x1d\x45NVIRONMENTAL_MEASUREMENT_APP\x10\x43\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42!\n\x13\x63om.geeksville.meshB\x08PortnumsH\x03\x62\x06proto3'
           )
           
           _PORTNUM = _descriptor.EnumDescriptor(
          @@ -55,56 +57,93 @@ _PORTNUM = _descriptor.EnumDescriptor(
             full_name='PortNum',
             filename=None,
             file=DESCRIPTOR,
          +  create_key=_descriptor._internal_create_key,
             values=[
               _descriptor.EnumValueDescriptor(
                 name='UNKNOWN_APP', index=0, number=0,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='TEXT_MESSAGE_APP', index=1, number=1,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='REMOTE_HARDWARE_APP', index=2, number=2,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='POSITION_APP', index=3, number=3,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='NODEINFO_APP', index=4, number=4,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
          -      name='REPLY_APP', index=5, number=32,
          +      name='ROUTING_APP', index=5, number=5,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
          -      name='IP_TUNNEL_APP', index=6, number=33,
          +      name='ADMIN_APP', index=6, number=6,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
          -      name='SERIAL_APP', index=7, number=64,
          +      name='REPLY_APP', index=7, number=32,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
          -      name='STORE_FORWARD_APP', index=8, number=65,
          +      name='IP_TUNNEL_APP', index=8, number=33,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
          -      name='PRIVATE_APP', index=9, number=256,
          +      name='SERIAL_APP', index=9, number=64,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
          -      name='ATAK_FORWARDER', index=10, number=257,
          +      name='STORE_FORWARD_APP', index=10, number=65,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='RANGE_TEST_APP', index=11, number=66,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='ENVIRONMENTAL_MEASUREMENT_APP', index=12, number=67,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='PRIVATE_APP', index=13, number=256,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='ATAK_FORWARDER', index=14, number=257,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MAX', index=15, number=511,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
             ],
             containing_type=None,
             serialized_options=None,
             serialized_start=19,
          -  serialized_end=240,
          +  serialized_end=337,
           )
           _sym_db.RegisterEnumDescriptor(_PORTNUM)
           
          @@ -114,12 +153,17 @@ TEXT_MESSAGE_APP = 1
           REMOTE_HARDWARE_APP = 2
           POSITION_APP = 3
           NODEINFO_APP = 4
          +ROUTING_APP = 5
          +ADMIN_APP = 6
           REPLY_APP = 32
           IP_TUNNEL_APP = 33
           SERIAL_APP = 64
           STORE_FORWARD_APP = 65
          +RANGE_TEST_APP = 66
          +ENVIRONMENTAL_MEASUREMENT_APP = 67
           PRIVATE_APP = 256
           ATAK_FORWARDER = 257
          +MAX = 511
           
           
           DESCRIPTOR.enum_types_by_name['PortNum'] = _PORTNUM
          diff --git a/docs/meshtastic/radioconfig_pb2.html b/docs/meshtastic/radioconfig_pb2.html
          new file mode 100644
          index 0000000..45aecbe
          --- /dev/null
          +++ b/docs/meshtastic/radioconfig_pb2.html
          @@ -0,0 +1,865 @@
          +
          +
          +
          +
          +
          +
          +meshtastic.radioconfig_pb2 API documentation
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +

          Module meshtastic.radioconfig_pb2

          +
          +
          +

          Generated protocol buffer code.

          +
          + +Expand source code + +
          # -*- coding: utf-8 -*-
          +# Generated by the protocol buffer compiler.  DO NOT EDIT!
          +# source: radioconfig.proto
          +"""Generated protocol buffer code."""
          +from google.protobuf.internal import enum_type_wrapper
          +from google.protobuf import descriptor as _descriptor
          +from google.protobuf import message as _message
          +from google.protobuf import reflection as _reflection
          +from google.protobuf import symbol_database as _symbol_database
          +# @@protoc_insertion_point(imports)
          +
          +_sym_db = _symbol_database.Default()
          +
          +
          +
          +
          +DESCRIPTOR = _descriptor.FileDescriptor(
          +  name='radioconfig.proto',
          +  package='',
          +  syntax='proto3',
          +  serialized_options=b'\n\023com.geeksville.meshB\021RadioConfigProtosH\003',
          +  create_key=_descriptor._internal_create_key,
          +  serialized_pb=b'\n\x11radioconfig.proto\"\xa5\x0f\n\x0bRadioConfig\x12\x31\n\x0bpreferences\x18\x01 \x01(\x0b\x32\x1c.RadioConfig.UserPreferences\x1a\xe2\x0e\n\x0fUserPreferences\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12\x1b\n\x13send_owner_interval\x18\x02 \x01(\r\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x16\n\x0escreen_on_secs\x18\x05 \x01(\r\x12\x1a\n\x12phone_timeout_secs\x18\x06 \x01(\r\x12\x1d\n\x15phone_sds_timeout_sec\x18\x07 \x01(\r\x12\x1d\n\x15mesh_sds_timeout_secs\x18\x08 \x01(\r\x12\x10\n\x08sds_secs\x18\t \x01(\r\x12\x0f\n\x07ls_secs\x18\n \x01(\r\x12\x15\n\rmin_wake_secs\x18\x0b \x01(\r\x12\x11\n\twifi_ssid\x18\x0c \x01(\t\x12\x15\n\rwifi_password\x18\r \x01(\t\x12\x14\n\x0cwifi_ap_mode\x18\x0e \x01(\x08\x12\x1b\n\x06region\x18\x0f \x01(\x0e\x32\x0b.RegionCode\x12&\n\x0e\x63harge_current\x18\x10 \x01(\x0e\x32\x0e.ChargeCurrent\x12\x11\n\tis_router\x18% \x01(\x08\x12\x14\n\x0cis_low_power\x18& \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\' \x01(\x08\x12\x15\n\rfactory_reset\x18\x64 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x65 \x01(\x08\x12(\n\x0elocation_share\x18  \x01(\x0e\x32\x10.LocationSharing\x12$\n\rgps_operation\x18! \x01(\x0e\x32\r.GpsOperation\x12\x1b\n\x13gps_update_interval\x18\" \x01(\r\x12\x18\n\x10gps_attempt_time\x18$ \x01(\r\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x1c\n\x14serialplugin_enabled\x18x \x01(\x08\x12\x19\n\x11serialplugin_echo\x18y \x01(\x08\x12\x18\n\x10serialplugin_rxd\x18z \x01(\r\x12\x18\n\x10serialplugin_txd\x18{ \x01(\r\x12\x1c\n\x14serialplugin_timeout\x18| \x01(\r\x12\x19\n\x11serialplugin_mode\x18} \x01(\r\x12\'\n\x1f\x65xt_notification_plugin_enabled\x18~ \x01(\x08\x12)\n!ext_notification_plugin_output_ms\x18\x7f \x01(\r\x12\'\n\x1e\x65xt_notification_plugin_output\x18\x80\x01 \x01(\r\x12\'\n\x1e\x65xt_notification_plugin_active\x18\x81\x01 \x01(\x08\x12.\n%ext_notification_plugin_alert_message\x18\x82\x01 \x01(\x08\x12+\n\"ext_notification_plugin_alert_bell\x18\x83\x01 \x01(\x08\x12\"\n\x19range_test_plugin_enabled\x18\x84\x01 \x01(\x08\x12!\n\x18range_test_plugin_sender\x18\x85\x01 \x01(\r\x12\x1f\n\x16range_test_plugin_save\x18\x86\x01 \x01(\x08\x12%\n\x1cstore_forward_plugin_enabled\x18\x88\x01 \x01(\x08\x12%\n\x1cstore_forward_plugin_records\x18\x89\x01 \x01(\r\x12=\n4environmental_measurement_plugin_measurement_enabled\x18\x8c\x01 \x01(\x08\x12\x38\n/environmental_measurement_plugin_screen_enabled\x18\x8d\x01 \x01(\x08\x12\x44\n;environmental_measurement_plugin_read_error_count_threshold\x18\x8e\x01 \x01(\r\x12\x39\n0environmental_measurement_plugin_update_interval\x18\x8f\x01 \x01(\r\x12;\n2environmental_measurement_plugin_recovery_interval\x18\x90\x01 \x01(\r\x12;\n2environmental_measurement_plugin_display_farenheit\x18\x91\x01 \x01(\x08\x12v\n,environmental_measurement_plugin_sensor_type\x18\x92\x01 \x01(\x0e\x32?.RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType\x12\x34\n+environmental_measurement_plugin_sensor_pin\x18\x93\x01 \x01(\r\"/\n\"EnvironmentalMeasurementSensorType\x12\t\n\x05\x44HT11\x10\x00*f\n\nRegionCode\x12\t\n\x05Unset\x10\x00\x12\x06\n\x02US\x10\x01\x12\t\n\x05\x45U433\x10\x02\x12\t\n\x05\x45U865\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t*\xd1\x01\n\rChargeCurrent\x12\x0b\n\x07MAUnset\x10\x00\x12\t\n\x05MA100\x10\x01\x12\t\n\x05MA190\x10\x02\x12\t\n\x05MA280\x10\x03\x12\t\n\x05MA360\x10\x04\x12\t\n\x05MA450\x10\x05\x12\t\n\x05MA550\x10\x06\x12\t\n\x05MA630\x10\x07\x12\t\n\x05MA700\x10\x08\x12\t\n\x05MA780\x10\t\x12\t\n\x05MA880\x10\n\x12\t\n\x05MA960\x10\x0b\x12\n\n\x06MA1000\x10\x0c\x12\n\n\x06MA1080\x10\r\x12\n\n\x06MA1160\x10\x0e\x12\n\n\x06MA1240\x10\x0f\x12\n\n\x06MA1320\x10\x10*j\n\x0cGpsOperation\x12\x0e\n\nGpsOpUnset\x10\x00\x12\x13\n\x0fGpsOpStationary\x10\x01\x12\x0f\n\x0bGpsOpMobile\x10\x02\x12\x11\n\rGpsOpTimeOnly\x10\x03\x12\x11\n\rGpsOpDisabled\x10\x04*@\n\x0fLocationSharing\x12\x0c\n\x08LocUnset\x10\x00\x12\x0e\n\nLocEnabled\x10\x01\x12\x0f\n\x0bLocDisabled\x10\x02\x42*\n\x13\x63om.geeksville.meshB\x11RadioConfigProtosH\x03\x62\x06proto3'
          +)
          +
          +_REGIONCODE = _descriptor.EnumDescriptor(
          +  name='RegionCode',
          +  full_name='RegionCode',
          +  filename=None,
          +  file=DESCRIPTOR,
          +  create_key=_descriptor._internal_create_key,
          +  values=[
          +    _descriptor.EnumValueDescriptor(
          +      name='Unset', index=0, number=0,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='US', index=1, number=1,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='EU433', index=2, number=2,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='EU865', index=3, number=3,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='CN', index=4, number=4,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='JP', index=5, number=5,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='ANZ', index=6, number=6,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='KR', index=7, number=7,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='TW', index=8, number=8,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='RU', index=9, number=9,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +  ],
          +  containing_type=None,
          +  serialized_options=None,
          +  serialized_start=1981,
          +  serialized_end=2083,
          +)
          +_sym_db.RegisterEnumDescriptor(_REGIONCODE)
          +
          +RegionCode = enum_type_wrapper.EnumTypeWrapper(_REGIONCODE)
          +_CHARGECURRENT = _descriptor.EnumDescriptor(
          +  name='ChargeCurrent',
          +  full_name='ChargeCurrent',
          +  filename=None,
          +  file=DESCRIPTOR,
          +  create_key=_descriptor._internal_create_key,
          +  values=[
          +    _descriptor.EnumValueDescriptor(
          +      name='MAUnset', index=0, number=0,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA100', index=1, number=1,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA190', index=2, number=2,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA280', index=3, number=3,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA360', index=4, number=4,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA450', index=5, number=5,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA550', index=6, number=6,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA630', index=7, number=7,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA700', index=8, number=8,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA780', index=9, number=9,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA880', index=10, number=10,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA960', index=11, number=11,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA1000', index=12, number=12,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA1080', index=13, number=13,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA1160', index=14, number=14,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA1240', index=15, number=15,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='MA1320', index=16, number=16,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +  ],
          +  containing_type=None,
          +  serialized_options=None,
          +  serialized_start=2086,
          +  serialized_end=2295,
          +)
          +_sym_db.RegisterEnumDescriptor(_CHARGECURRENT)
          +
          +ChargeCurrent = enum_type_wrapper.EnumTypeWrapper(_CHARGECURRENT)
          +_GPSOPERATION = _descriptor.EnumDescriptor(
          +  name='GpsOperation',
          +  full_name='GpsOperation',
          +  filename=None,
          +  file=DESCRIPTOR,
          +  create_key=_descriptor._internal_create_key,
          +  values=[
          +    _descriptor.EnumValueDescriptor(
          +      name='GpsOpUnset', index=0, number=0,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='GpsOpStationary', index=1, number=1,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='GpsOpMobile', index=2, number=2,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='GpsOpTimeOnly', index=3, number=3,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='GpsOpDisabled', index=4, number=4,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +  ],
          +  containing_type=None,
          +  serialized_options=None,
          +  serialized_start=2297,
          +  serialized_end=2403,
          +)
          +_sym_db.RegisterEnumDescriptor(_GPSOPERATION)
          +
          +GpsOperation = enum_type_wrapper.EnumTypeWrapper(_GPSOPERATION)
          +_LOCATIONSHARING = _descriptor.EnumDescriptor(
          +  name='LocationSharing',
          +  full_name='LocationSharing',
          +  filename=None,
          +  file=DESCRIPTOR,
          +  create_key=_descriptor._internal_create_key,
          +  values=[
          +    _descriptor.EnumValueDescriptor(
          +      name='LocUnset', index=0, number=0,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='LocEnabled', index=1, number=1,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +    _descriptor.EnumValueDescriptor(
          +      name='LocDisabled', index=2, number=2,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +  ],
          +  containing_type=None,
          +  serialized_options=None,
          +  serialized_start=2405,
          +  serialized_end=2469,
          +)
          +_sym_db.RegisterEnumDescriptor(_LOCATIONSHARING)
          +
          +LocationSharing = enum_type_wrapper.EnumTypeWrapper(_LOCATIONSHARING)
          +Unset = 0
          +US = 1
          +EU433 = 2
          +EU865 = 3
          +CN = 4
          +JP = 5
          +ANZ = 6
          +KR = 7
          +TW = 8
          +RU = 9
          +MAUnset = 0
          +MA100 = 1
          +MA190 = 2
          +MA280 = 3
          +MA360 = 4
          +MA450 = 5
          +MA550 = 6
          +MA630 = 7
          +MA700 = 8
          +MA780 = 9
          +MA880 = 10
          +MA960 = 11
          +MA1000 = 12
          +MA1080 = 13
          +MA1160 = 14
          +MA1240 = 15
          +MA1320 = 16
          +GpsOpUnset = 0
          +GpsOpStationary = 1
          +GpsOpMobile = 2
          +GpsOpTimeOnly = 3
          +GpsOpDisabled = 4
          +LocUnset = 0
          +LocEnabled = 1
          +LocDisabled = 2
          +
          +
          +_RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE = _descriptor.EnumDescriptor(
          +  name='EnvironmentalMeasurementSensorType',
          +  full_name='RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType',
          +  filename=None,
          +  file=DESCRIPTOR,
          +  create_key=_descriptor._internal_create_key,
          +  values=[
          +    _descriptor.EnumValueDescriptor(
          +      name='DHT11', index=0, number=0,
          +      serialized_options=None,
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
          +  ],
          +  containing_type=None,
          +  serialized_options=None,
          +  serialized_start=1932,
          +  serialized_end=1979,
          +)
          +_sym_db.RegisterEnumDescriptor(_RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE)
          +
          +
          +_RADIOCONFIG_USERPREFERENCES = _descriptor.Descriptor(
          +  name='UserPreferences',
          +  full_name='RadioConfig.UserPreferences',
          +  filename=None,
          +  file=DESCRIPTOR,
          +  containing_type=None,
          +  create_key=_descriptor._internal_create_key,
          +  fields=[
          +    _descriptor.FieldDescriptor(
          +      name='position_broadcast_secs', full_name='RadioConfig.UserPreferences.position_broadcast_secs', index=0,
          +      number=1, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='send_owner_interval', full_name='RadioConfig.UserPreferences.send_owner_interval', index=1,
          +      number=2, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='wait_bluetooth_secs', full_name='RadioConfig.UserPreferences.wait_bluetooth_secs', index=2,
          +      number=4, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='screen_on_secs', full_name='RadioConfig.UserPreferences.screen_on_secs', index=3,
          +      number=5, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='phone_timeout_secs', full_name='RadioConfig.UserPreferences.phone_timeout_secs', index=4,
          +      number=6, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='phone_sds_timeout_sec', full_name='RadioConfig.UserPreferences.phone_sds_timeout_sec', index=5,
          +      number=7, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='mesh_sds_timeout_secs', full_name='RadioConfig.UserPreferences.mesh_sds_timeout_secs', index=6,
          +      number=8, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='sds_secs', full_name='RadioConfig.UserPreferences.sds_secs', index=7,
          +      number=9, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='ls_secs', full_name='RadioConfig.UserPreferences.ls_secs', index=8,
          +      number=10, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='min_wake_secs', full_name='RadioConfig.UserPreferences.min_wake_secs', index=9,
          +      number=11, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='wifi_ssid', full_name='RadioConfig.UserPreferences.wifi_ssid', index=10,
          +      number=12, type=9, cpp_type=9, label=1,
          +      has_default_value=False, default_value=b"".decode('utf-8'),
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='wifi_password', full_name='RadioConfig.UserPreferences.wifi_password', index=11,
          +      number=13, type=9, cpp_type=9, label=1,
          +      has_default_value=False, default_value=b"".decode('utf-8'),
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='wifi_ap_mode', full_name='RadioConfig.UserPreferences.wifi_ap_mode', index=12,
          +      number=14, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='region', full_name='RadioConfig.UserPreferences.region', index=13,
          +      number=15, type=14, cpp_type=8, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='charge_current', full_name='RadioConfig.UserPreferences.charge_current', index=14,
          +      number=16, type=14, cpp_type=8, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='is_router', full_name='RadioConfig.UserPreferences.is_router', index=15,
          +      number=37, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='is_low_power', full_name='RadioConfig.UserPreferences.is_low_power', index=16,
          +      number=38, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='fixed_position', full_name='RadioConfig.UserPreferences.fixed_position', index=17,
          +      number=39, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='factory_reset', full_name='RadioConfig.UserPreferences.factory_reset', index=18,
          +      number=100, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='debug_log_enabled', full_name='RadioConfig.UserPreferences.debug_log_enabled', index=19,
          +      number=101, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='location_share', full_name='RadioConfig.UserPreferences.location_share', index=20,
          +      number=32, type=14, cpp_type=8, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='gps_operation', full_name='RadioConfig.UserPreferences.gps_operation', index=21,
          +      number=33, type=14, cpp_type=8, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='gps_update_interval', full_name='RadioConfig.UserPreferences.gps_update_interval', index=22,
          +      number=34, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='gps_attempt_time', full_name='RadioConfig.UserPreferences.gps_attempt_time', index=23,
          +      number=36, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='ignore_incoming', full_name='RadioConfig.UserPreferences.ignore_incoming', index=24,
          +      number=103, type=13, cpp_type=3, label=3,
          +      has_default_value=False, default_value=[],
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='serialplugin_enabled', full_name='RadioConfig.UserPreferences.serialplugin_enabled', index=25,
          +      number=120, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='serialplugin_echo', full_name='RadioConfig.UserPreferences.serialplugin_echo', index=26,
          +      number=121, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='serialplugin_rxd', full_name='RadioConfig.UserPreferences.serialplugin_rxd', index=27,
          +      number=122, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='serialplugin_txd', full_name='RadioConfig.UserPreferences.serialplugin_txd', index=28,
          +      number=123, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='serialplugin_timeout', full_name='RadioConfig.UserPreferences.serialplugin_timeout', index=29,
          +      number=124, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='serialplugin_mode', full_name='RadioConfig.UserPreferences.serialplugin_mode', index=30,
          +      number=125, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='ext_notification_plugin_enabled', full_name='RadioConfig.UserPreferences.ext_notification_plugin_enabled', index=31,
          +      number=126, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='ext_notification_plugin_output_ms', full_name='RadioConfig.UserPreferences.ext_notification_plugin_output_ms', index=32,
          +      number=127, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='ext_notification_plugin_output', full_name='RadioConfig.UserPreferences.ext_notification_plugin_output', index=33,
          +      number=128, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='ext_notification_plugin_active', full_name='RadioConfig.UserPreferences.ext_notification_plugin_active', index=34,
          +      number=129, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='ext_notification_plugin_alert_message', full_name='RadioConfig.UserPreferences.ext_notification_plugin_alert_message', index=35,
          +      number=130, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='ext_notification_plugin_alert_bell', full_name='RadioConfig.UserPreferences.ext_notification_plugin_alert_bell', index=36,
          +      number=131, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='range_test_plugin_enabled', full_name='RadioConfig.UserPreferences.range_test_plugin_enabled', index=37,
          +      number=132, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='range_test_plugin_sender', full_name='RadioConfig.UserPreferences.range_test_plugin_sender', index=38,
          +      number=133, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='range_test_plugin_save', full_name='RadioConfig.UserPreferences.range_test_plugin_save', index=39,
          +      number=134, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='store_forward_plugin_enabled', full_name='RadioConfig.UserPreferences.store_forward_plugin_enabled', index=40,
          +      number=136, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='store_forward_plugin_records', full_name='RadioConfig.UserPreferences.store_forward_plugin_records', index=41,
          +      number=137, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='environmental_measurement_plugin_measurement_enabled', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_measurement_enabled', index=42,
          +      number=140, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='environmental_measurement_plugin_screen_enabled', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_screen_enabled', index=43,
          +      number=141, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='environmental_measurement_plugin_read_error_count_threshold', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_read_error_count_threshold', index=44,
          +      number=142, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='environmental_measurement_plugin_update_interval', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_update_interval', index=45,
          +      number=143, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='environmental_measurement_plugin_recovery_interval', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_recovery_interval', index=46,
          +      number=144, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='environmental_measurement_plugin_display_farenheit', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_display_farenheit', index=47,
          +      number=145, type=8, cpp_type=7, label=1,
          +      has_default_value=False, default_value=False,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='environmental_measurement_plugin_sensor_type', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_sensor_type', index=48,
          +      number=146, type=14, cpp_type=8, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +    _descriptor.FieldDescriptor(
          +      name='environmental_measurement_plugin_sensor_pin', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_sensor_pin', index=49,
          +      number=147, type=13, cpp_type=3, label=1,
          +      has_default_value=False, default_value=0,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +  ],
          +  extensions=[
          +  ],
          +  nested_types=[],
          +  enum_types=[
          +    _RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE,
          +  ],
          +  serialized_options=None,
          +  is_extendable=False,
          +  syntax='proto3',
          +  extension_ranges=[],
          +  oneofs=[
          +  ],
          +  serialized_start=89,
          +  serialized_end=1979,
          +)
          +
          +_RADIOCONFIG = _descriptor.Descriptor(
          +  name='RadioConfig',
          +  full_name='RadioConfig',
          +  filename=None,
          +  file=DESCRIPTOR,
          +  containing_type=None,
          +  create_key=_descriptor._internal_create_key,
          +  fields=[
          +    _descriptor.FieldDescriptor(
          +      name='preferences', full_name='RadioConfig.preferences', index=0,
          +      number=1, type=11, cpp_type=10, label=1,
          +      has_default_value=False, default_value=None,
          +      message_type=None, enum_type=None, containing_type=None,
          +      is_extension=False, extension_scope=None,
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
          +  ],
          +  extensions=[
          +  ],
          +  nested_types=[_RADIOCONFIG_USERPREFERENCES, ],
          +  enum_types=[
          +  ],
          +  serialized_options=None,
          +  is_extendable=False,
          +  syntax='proto3',
          +  extension_ranges=[],
          +  oneofs=[
          +  ],
          +  serialized_start=22,
          +  serialized_end=1979,
          +)
          +
          +_RADIOCONFIG_USERPREFERENCES.fields_by_name['region'].enum_type = _REGIONCODE
          +_RADIOCONFIG_USERPREFERENCES.fields_by_name['charge_current'].enum_type = _CHARGECURRENT
          +_RADIOCONFIG_USERPREFERENCES.fields_by_name['location_share'].enum_type = _LOCATIONSHARING
          +_RADIOCONFIG_USERPREFERENCES.fields_by_name['gps_operation'].enum_type = _GPSOPERATION
          +_RADIOCONFIG_USERPREFERENCES.fields_by_name['environmental_measurement_plugin_sensor_type'].enum_type = _RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE
          +_RADIOCONFIG_USERPREFERENCES.containing_type = _RADIOCONFIG
          +_RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE.containing_type = _RADIOCONFIG_USERPREFERENCES
          +_RADIOCONFIG.fields_by_name['preferences'].message_type = _RADIOCONFIG_USERPREFERENCES
          +DESCRIPTOR.message_types_by_name['RadioConfig'] = _RADIOCONFIG
          +DESCRIPTOR.enum_types_by_name['RegionCode'] = _REGIONCODE
          +DESCRIPTOR.enum_types_by_name['ChargeCurrent'] = _CHARGECURRENT
          +DESCRIPTOR.enum_types_by_name['GpsOperation'] = _GPSOPERATION
          +DESCRIPTOR.enum_types_by_name['LocationSharing'] = _LOCATIONSHARING
          +_sym_db.RegisterFileDescriptor(DESCRIPTOR)
          +
          +RadioConfig = _reflection.GeneratedProtocolMessageType('RadioConfig', (_message.Message,), {
          +
          +  'UserPreferences' : _reflection.GeneratedProtocolMessageType('UserPreferences', (_message.Message,), {
          +    'DESCRIPTOR' : _RADIOCONFIG_USERPREFERENCES,
          +    '__module__' : 'radioconfig_pb2'
          +    # @@protoc_insertion_point(class_scope:RadioConfig.UserPreferences)
          +    })
          +  ,
          +  'DESCRIPTOR' : _RADIOCONFIG,
          +  '__module__' : 'radioconfig_pb2'
          +  # @@protoc_insertion_point(class_scope:RadioConfig)
          +  })
          +_sym_db.RegisterMessage(RadioConfig)
          +_sym_db.RegisterMessage(RadioConfig.UserPreferences)
          +
          +
          +DESCRIPTOR._options = None
          +# @@protoc_insertion_point(module_scope)
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +

          Classes

          +
          +
          +class RadioConfig +(*args, **kwargs) +
          +
          +

          A ProtocolMessage

          +

          Ancestors

          +
            +
          • google.protobuf.pyext._message.CMessage
          • +
          • google.protobuf.message.Message
          • +
          +

          Class variables

          +
          +
          var DESCRIPTOR
          +
          +
          +
          +
          var UserPreferences
          +
          +

          A ProtocolMessage

          +
          +
          +

          Instance variables

          +
          +
          var preferences
          +
          +

          Field RadioConfig.preferences

          +
          +
          +
          +
          +
          +
          + +
          + + + \ No newline at end of file diff --git a/docs/meshtastic/remote_hardware_pb2.html b/docs/meshtastic/remote_hardware_pb2.html index ccf79da..c591381 100644 --- a/docs/meshtastic/remote_hardware_pb2.html +++ b/docs/meshtastic/remote_hardware_pb2.html @@ -5,7 +5,7 @@ meshtastic.remote_hardware_pb2 API documentation - + @@ -22,6 +22,7 @@

          Module meshtastic.remote_hardware_pb2

          +

          Generated protocol buffer code.

          Expand source code @@ -29,7 +30,7 @@
          # -*- coding: utf-8 -*-
           # Generated by the protocol buffer compiler.  DO NOT EDIT!
           # source: remote_hardware.proto
          -
          +"""Generated protocol buffer code."""
           from google.protobuf import descriptor as _descriptor
           from google.protobuf import message as _message
           from google.protobuf import reflection as _reflection
          @@ -46,6 +47,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
             package='',
             syntax='proto3',
             serialized_options=b'\n\023com.geeksville.meshB\016RemoteHardwareH\003',
          +  create_key=_descriptor._internal_create_key,
             serialized_pb=b'\n\x15remote_hardware.proto\"\xca\x01\n\x0fHardwareMessage\x12\"\n\x03typ\x18\x01 \x01(\x0e\x32\x15.HardwareMessage.Type\x12\x11\n\tgpio_mask\x18\x02 \x01(\x04\x12\x12\n\ngpio_value\x18\x03 \x01(\x04\"l\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0f\n\x0bWRITE_GPIOS\x10\x01\x12\x0f\n\x0bWATCH_GPIOS\x10\x02\x12\x11\n\rGPIOS_CHANGED\x10\x03\x12\x0e\n\nREAD_GPIOS\x10\x04\x12\x14\n\x10READ_GPIOS_REPLY\x10\x05\x42\'\n\x13\x63om.geeksville.meshB\x0eRemoteHardwareH\x03\x62\x06proto3'
           )
           
          @@ -56,31 +58,38 @@ _HARDWAREMESSAGE_TYPE = _descriptor.EnumDescriptor(
             full_name='HardwareMessage.Type',
             filename=None,
             file=DESCRIPTOR,
          +  create_key=_descriptor._internal_create_key,
             values=[
               _descriptor.EnumValueDescriptor(
                 name='UNSET', index=0, number=0,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='WRITE_GPIOS', index=1, number=1,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='WATCH_GPIOS', index=2, number=2,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='GPIOS_CHANGED', index=3, number=3,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='READ_GPIOS', index=4, number=4,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
               _descriptor.EnumValueDescriptor(
                 name='READ_GPIOS_REPLY', index=5, number=5,
                 serialized_options=None,
          -      type=None),
          +      type=None,
          +      create_key=_descriptor._internal_create_key),
             ],
             containing_type=None,
             serialized_options=None,
          @@ -96,6 +105,7 @@ _HARDWAREMESSAGE = _descriptor.Descriptor(
             filename=None,
             file=DESCRIPTOR,
             containing_type=None,
          +  create_key=_descriptor._internal_create_key,
             fields=[
               _descriptor.FieldDescriptor(
                 name='typ', full_name='HardwareMessage.typ', index=0,
          @@ -103,21 +113,21 @@ _HARDWAREMESSAGE = _descriptor.Descriptor(
                 has_default_value=False, default_value=0,
                 message_type=None, enum_type=None, containing_type=None,
                 is_extension=False, extension_scope=None,
          -      serialized_options=None, file=DESCRIPTOR),
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
               _descriptor.FieldDescriptor(
                 name='gpio_mask', full_name='HardwareMessage.gpio_mask', index=1,
                 number=2, type=4, cpp_type=4, label=1,
                 has_default_value=False, default_value=0,
                 message_type=None, enum_type=None, containing_type=None,
                 is_extension=False, extension_scope=None,
          -      serialized_options=None, file=DESCRIPTOR),
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
               _descriptor.FieldDescriptor(
                 name='gpio_value', full_name='HardwareMessage.gpio_value', index=2,
                 number=3, type=4, cpp_type=4, label=1,
                 has_default_value=False, default_value=0,
                 message_type=None, enum_type=None, containing_type=None,
                 is_extension=False, extension_scope=None,
          -      serialized_options=None, file=DESCRIPTOR),
          +      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
             ],
             extensions=[
             ],
          diff --git a/docs/meshtastic/test.html b/docs/meshtastic/test.html
          index 25bd594..0a4ddc7 100644
          --- a/docs/meshtastic/test.html
          +++ b/docs/meshtastic/test.html
          @@ -47,18 +47,21 @@ testNumber = 0
           
           sendingInterface = None
           
          +
           def onReceive(packet, interface):
               """Callback invoked when a packet arrives"""
               if sendingInterface == interface:
          -        print("Ignoring sending interface")
          +        pass 
          +        # print("Ignoring sending interface")
               else:
          -        print(f"From {interface.stream.port}: {packet}")
          +        # print(f"From {interface.stream.port}: {packet}")
                   p = DotMap(packet)
           
          -        if p.decoded.data.portnum == "TEXT_MESSAGE_APP":
          +        if p.decoded.portnum == "TEXT_MESSAGE_APP":
                       # We only care a about clear text packets
                       receivedPackets.append(p)
           
          +
           def onNode(node):
               """Callback invoked when the node DB changes"""
               print(f"Node changed: {node}")
          @@ -70,7 +73,7 @@ def subscribe():
               pub.subscribe(onNode, "meshtastic.node")
           
           
          -def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False):
          +def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False, wantAck=False):
               """
               Sends one test packet between two nodes and then returns success or failure
           
          @@ -90,8 +93,7 @@ def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False):
               else:
                   toNode = toInterface.myInfo.my_node_num
           
          -    logging.info(f"Sending test packet from {fromNode} to {toNode}")
          -    wantAck = False # Don't want any sort of reliaible sending
          +    logging.debug(f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}")
               global sendingInterface
               sendingInterface = fromInterface
               if not asBinary:
          @@ -99,15 +101,15 @@ def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False):
               else:
                   fromInterface.sendData((f"Binary {testNumber}").encode(
                       "utf-8"), toNode, wantAck=wantAck)
          -    for sec in range(45): # max of 45 secs before we timeout
          +    for sec in range(60):  # max of 60 secs before we timeout
                   time.sleep(1)
                   if (len(receivedPackets) >= 1):
                       return True
          -    return False # Failed to send
          +    return False  # Failed to send
           
           
          -def testThread(numTests=50):
          -    logging.info("Found devices, starting tests...")
          +def runTests(numTests=50, wantAck=False, maxFailures=0):
          +    logging.info(f"Running {numTests} tests with wantAck={wantAck}")
               numFail = 0
               numSuccess = 0
               for i in range(numTests):
          @@ -116,32 +118,45 @@ def testThread(numTests=50):
                   isBroadcast = True
                   # asBinary=(i % 2 == 0)
                   success = testSend(
          -            interfaces[0], interfaces[1], isBroadcast, asBinary = False)
          +            interfaces[0], interfaces[1], isBroadcast, asBinary=False, wantAck=wantAck)
                   if not success:
                       numFail = numFail + 1
                       logging.error(
                           f"Test failed, expected packet not received ({numFail} failures so far)")
                   else:
                       numSuccess = numSuccess + 1
          -            logging.info(f"Test succeeded ({numSuccess} successes so far)")
          +            logging.info(
          +                f"Test succeeded {numSuccess} successes {numFail} failures so far")
           
          -        if numFail >= 3:
          -            for i in interfaces:
          -                i.close()
          -            return
          +        #if numFail >= 3:
          +        #    for i in interfaces:
          +        #        i.close()
          +        #    return
           
                   time.sleep(1)
           
          +    if numFail > maxFailures:
          +        logging.error("Too many failures! Test failed!")
          +
          +    return numFail
          +
          +def testThread(numTests=50):
          +    logging.info("Found devices, starting tests...")
          +    runTests(numTests, wantAck=True)
          +    runTests(numTests, wantAck=False, maxFailures=5) # Allow a few dropped packets
          +
           
           def onConnection(topic=pub.AUTO_TOPIC):
               """Callback invoked when we connect/disconnect from a radio"""
               print(f"Connection changed: {topic.getName()}")
           
          +
           def openDebugLog(portName):
               debugname = "log" + portName.replace("/", "_")
               logging.info(f"Writing serial debugging to {debugname}")
               return open(debugname, 'w+', buffering=1)
           
          +
           def testAll():
               """
               Run a series of tests using devices we can find.
          @@ -163,8 +178,7 @@ def testAll():
               testThread()
           
               for i in interfaces:
          -        i.close()
          -    
          + i.close()
          @@ -221,12 +235,13 @@ def testAll():
          def onReceive(packet, interface):
               """Callback invoked when a packet arrives"""
               if sendingInterface == interface:
          -        print("Ignoring sending interface")
          +        pass 
          +        # print("Ignoring sending interface")
               else:
          -        print(f"From {interface.stream.port}: {packet}")
          +        # print(f"From {interface.stream.port}: {packet}")
                   p = DotMap(packet)
           
          -        if p.decoded.data.portnum == "TEXT_MESSAGE_APP":
          +        if p.decoded.portnum == "TEXT_MESSAGE_APP":
                       # We only care a about clear text packets
                       receivedPackets.append(p)
          @@ -246,6 +261,48 @@ def testAll(): return open(debugname, 'w+', buffering=1)
  • +
    +def runTests(numTests=50, wantAck=False, maxFailures=0) +
    +
    +
    +
    + +Expand source code + +
    def runTests(numTests=50, wantAck=False, maxFailures=0):
    +    logging.info(f"Running {numTests} tests with wantAck={wantAck}")
    +    numFail = 0
    +    numSuccess = 0
    +    for i in range(numTests):
    +        global testNumber
    +        testNumber = testNumber + 1
    +        isBroadcast = True
    +        # asBinary=(i % 2 == 0)
    +        success = testSend(
    +            interfaces[0], interfaces[1], isBroadcast, asBinary=False, wantAck=wantAck)
    +        if not success:
    +            numFail = numFail + 1
    +            logging.error(
    +                f"Test failed, expected packet not received ({numFail} failures so far)")
    +        else:
    +            numSuccess = numSuccess + 1
    +            logging.info(
    +                f"Test succeeded {numSuccess} successes {numFail} failures so far")
    +
    +        #if numFail >= 3:
    +        #    for i in interfaces:
    +        #        i.close()
    +        #    return
    +
    +        time.sleep(1)
    +
    +    if numFail > maxFailures:
    +        logging.error("Too many failures! Test failed!")
    +
    +    return numFail
    +
    +
    def subscribe()
    @@ -300,7 +357,7 @@ def testAll():
    -def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False) +def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False, wantAck=False)

    Sends one test packet between two nodes and then returns success or failure

    @@ -313,7 +370,7 @@ toInterface {[type]} – [description]

    Expand source code -
    def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False):
    +
    def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False, wantAck=False):
         """
         Sends one test packet between two nodes and then returns success or failure
     
    @@ -333,8 +390,7 @@ toInterface {[type]} – [description]

    else: toNode = toInterface.myInfo.my_node_num - logging.info(f"Sending test packet from {fromNode} to {toNode}") - wantAck = False # Don't want any sort of reliaible sending + logging.debug(f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}") global sendingInterface sendingInterface = fromInterface if not asBinary: @@ -342,11 +398,11 @@ toInterface {[type]} – [description]

    else: fromInterface.sendData((f"Binary {testNumber}").encode( "utf-8"), toNode, wantAck=wantAck) - for sec in range(45): # max of 45 secs before we timeout + for sec in range(60): # max of 60 secs before we timeout time.sleep(1) if (len(receivedPackets) >= 1): return True - return False # Failed to send
    + return False # Failed to send
    @@ -360,29 +416,8 @@ toInterface {[type]} – [description]

    def testThread(numTests=50):
         logging.info("Found devices, starting tests...")
    -    numFail = 0
    -    numSuccess = 0
    -    for i in range(numTests):
    -        global testNumber
    -        testNumber = testNumber + 1
    -        isBroadcast = True
    -        # asBinary=(i % 2 == 0)
    -        success = testSend(
    -            interfaces[0], interfaces[1], isBroadcast, asBinary = False)
    -        if not success:
    -            numFail = numFail + 1
    -            logging.error(
    -                f"Test failed, expected packet not received ({numFail} failures so far)")
    -        else:
    -            numSuccess = numSuccess + 1
    -            logging.info(f"Test succeeded ({numSuccess} successes so far)")
    -
    -        if numFail >= 3:
    -            for i in interfaces:
    -                i.close()
    -            return
    -
    -        time.sleep(1)
    + runTests(numTests, wantAck=True) + runTests(numTests, wantAck=False, maxFailures=5) # Allow a few dropped packets
    @@ -412,6 +447,7 @@ toInterface {[type]} – [description]

  • onNode
  • onReceive
  • openDebugLog
  • +
  • runTests
  • subscribe
  • testAll
  • testSend
  • diff --git a/docs/meshtastic/tunnel.html b/docs/meshtastic/tunnel.html index 1952857..015a5e7 100644 --- a/docs/meshtastic/tunnel.html +++ b/docs/meshtastic/tunnel.html @@ -34,7 +34,7 @@ # sudo bin/run.sh --port /dev/ttyUSB0 --setch-shortfast # sudo bin/run.sh --port /dev/ttyUSB0 --tunnel --debug # ssh -Y root@192.168.10.151 (or dietpi), default password p -# ncat -e /bin/cat -k -u -l 1235 +# ncat -e /bin/cat -k -u -l 1235 # ncat -u 10.115.64.152 1235 # ping -c 1 -W 20 10.115.64.152 # ping -i 30 -W 30 10.115.64.152 @@ -43,7 +43,8 @@ from . import portnums_pb2 from pubsub import pub -import logging, threading +import logging +import threading # A new non standard log level that is lower level than DEBUG LOG_TRACE = 5 @@ -54,8 +55,8 @@ tunnelInstance = None """A list of chatty UDP services we should never accidentally forward to our slow network""" udpBlacklist = { - 1900, # SSDP - 5353, # multicast DNS + 1900, # SSDP + 5353, # multicast DNS } """A list of TCP services to block""" @@ -63,31 +64,36 @@ tcpBlacklist = {} """A list of protocols we ignore""" protocolBlacklist = { - 0x02, # IGMP - 0x80, # Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment + 0x02, # IGMP + 0x80, # Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment } + def hexstr(barray): """Print a string of hex digits""" return ":".join('{:02x}'.format(x) for x in barray) + def ipstr(barray): """Print a string of ip digits""" return ".".join('{}'.format(x) for x in barray) + def readnet_u16(p, offset): """Read big endian u16 (network byte order)""" return p[offset] * 256 + p[offset + 1] + def onTunnelReceive(packet, interface): """Callback for received tunneled messages from mesh - + FIXME figure out how to do closures with methods in python""" tunnelInstance.onReceive(packet) + class Tunnel: """A TUN based IP tunnel over meshtastic""" - + def __init__(self, iface, subnet=None, netmask="255.255.0.0"): """ Constructor @@ -105,7 +111,8 @@ class Tunnel: global tunnelInstance tunnelInstance = self - logging.info("Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:") + logging.info( + "Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:") pub.subscribe(onTunnelReceive, "meshtastic.receive.data.IP_TUNNEL_APP") myAddr = self._nodeNumToIp(self.iface.myInfo.my_node_num) @@ -113,24 +120,26 @@ class Tunnel: for node in self.iface.nodes.values(): nodeId = node["user"]["id"] ip = self._nodeNumToIp(node["num"]) - logging.info(f"Node { nodeId } has IP address { ip }") + logging.info(f"Node { nodeId } has IP address { ip }") logging.debug("creating TUN device with MTU=200") # FIXME - figure out real max MTU, it should be 240 - the overhead bytes for SubPacket and Data from pytap2 import TapDevice self.tun = TapDevice(name="mesh") self.tun.up() - self.tun.ifconfig(address=myAddr,netmask=netmask,mtu=200) + self.tun.ifconfig(address=myAddr, netmask=netmask, mtu=200) logging.debug(f"starting TUN reader, our IP address is {myAddr}") - self._rxThread = threading.Thread(target=self.__tunReader, args=(), daemon=True) + self._rxThread = threading.Thread( + target=self.__tunReader, args=(), daemon=True) self._rxThread.start() def onReceive(self, packet): - p = packet["decoded"]["data"]["payload"] + p = packet["decoded"]["payload"] if packet["from"] == self.iface.myInfo.my_node_num: logging.debug("Ignoring message we sent") else: - logging.debug(f"Received mesh tunnel message type={type(p)} len={len(p)}") + logging.debug( + f"Received mesh tunnel message type={type(p)} len={len(p)}") # we don't really need to check for filtering here (sender should have checked), but this provides # useful debug printing on types of packets received if not self._shouldFilterPacket(p): @@ -142,36 +151,43 @@ class Tunnel: srcaddr = p[12:16] destAddr = p[16:20] subheader = 20 - ignore = False # Assume we will be forwarding the packet + ignore = False # Assume we will be forwarding the packet if protocol in protocolBlacklist: ignore = True - logging.log(LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}") - elif protocol == 0x01: # ICMP + logging.log( + LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}") + elif protocol == 0x01: # ICMP icmpType = p[20] icmpCode = p[21] checksum = p[22:24] - logging.debug(f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}") + logging.debug( + f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}") # reply to pings (swap src and dest but keep rest of packet unchanged) #pingback = p[:12]+p[16:20]+p[12:16]+p[20:] - #tap.write(pingback) - elif protocol == 0x11: # UDP + # tap.write(pingback) + elif protocol == 0x11: # UDP srcport = readnet_u16(p, subheader) destport = readnet_u16(p, subheader + 2) if destport in udpBlacklist: ignore = True - logging.log(LOG_TRACE, f"ignoring blacklisted UDP port {destport}") + logging.log( + LOG_TRACE, f"ignoring blacklisted UDP port {destport}") else: - logging.debug(f"forwarding udp srcport={srcport}, destport={destport}") - elif protocol == 0x06: # TCP + logging.debug( + f"forwarding udp srcport={srcport}, destport={destport}") + elif protocol == 0x06: # TCP srcport = readnet_u16(p, subheader) destport = readnet_u16(p, subheader + 2) if destport in tcpBlacklist: ignore = True - logging.log(LOG_TRACE, f"ignoring blacklisted TCP port {destport}") + logging.log( + LOG_TRACE, f"ignoring blacklisted TCP port {destport}") else: - logging.debug(f"forwarding tcp srcport={srcport}, destport={destport}") + logging.debug( + f"forwarding tcp srcport={srcport}, destport={destport}") else: - logging.warning(f"forwarding unexpected protocol 0x{protocol:02x}, src={ipstr(srcaddr)}, dest={ipstr(destAddr)}") + logging.warning( + f"forwarding unexpected protocol 0x{protocol:02x}, src={ipstr(srcaddr)}, dest={ipstr(destAddr)}") return ignore @@ -207,10 +223,13 @@ class Tunnel: """Forward the provided IP packet into the mesh""" nodeId = self._ipToNodeId(destAddr) if nodeId is not None: - logging.debug(f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}") - self.iface.sendData(p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck = False) + logging.debug( + f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}") + self.iface.sendData( + p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck=False) else: - logging.warning(f"Dropping packet because no node found for destIP={ipstr(destAddr)}") + logging.warning( + f"Dropping packet because no node found for destIP={ipstr(destAddr)}") def close(self): self.tun.close()
    @@ -279,7 +298,7 @@ forward to our slow network

    def onTunnelReceive(packet, interface):
         """Callback for received tunneled messages from mesh
    -    
    +
         FIXME figure out how to do closures with methods in python"""
         tunnelInstance.onReceive(packet)
    @@ -318,7 +337,7 @@ subnet is used to construct our network number (normally 10.115.x.x)

    class Tunnel:
         """A TUN based IP tunnel over meshtastic"""
    -    
    +
         def __init__(self, iface, subnet=None, netmask="255.255.0.0"):
             """
             Constructor
    @@ -336,7 +355,8 @@ subnet is used to construct our network number (normally 10.115.x.x)

    global tunnelInstance tunnelInstance = self - logging.info("Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:") + logging.info( + "Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:") pub.subscribe(onTunnelReceive, "meshtastic.receive.data.IP_TUNNEL_APP") myAddr = self._nodeNumToIp(self.iface.myInfo.my_node_num) @@ -344,24 +364,26 @@ subnet is used to construct our network number (normally 10.115.x.x)

    for node in self.iface.nodes.values(): nodeId = node["user"]["id"] ip = self._nodeNumToIp(node["num"]) - logging.info(f"Node { nodeId } has IP address { ip }") + logging.info(f"Node { nodeId } has IP address { ip }") logging.debug("creating TUN device with MTU=200") # FIXME - figure out real max MTU, it should be 240 - the overhead bytes for SubPacket and Data from pytap2 import TapDevice self.tun = TapDevice(name="mesh") self.tun.up() - self.tun.ifconfig(address=myAddr,netmask=netmask,mtu=200) + self.tun.ifconfig(address=myAddr, netmask=netmask, mtu=200) logging.debug(f"starting TUN reader, our IP address is {myAddr}") - self._rxThread = threading.Thread(target=self.__tunReader, args=(), daemon=True) + self._rxThread = threading.Thread( + target=self.__tunReader, args=(), daemon=True) self._rxThread.start() def onReceive(self, packet): - p = packet["decoded"]["data"]["payload"] + p = packet["decoded"]["payload"] if packet["from"] == self.iface.myInfo.my_node_num: logging.debug("Ignoring message we sent") else: - logging.debug(f"Received mesh tunnel message type={type(p)} len={len(p)}") + logging.debug( + f"Received mesh tunnel message type={type(p)} len={len(p)}") # we don't really need to check for filtering here (sender should have checked), but this provides # useful debug printing on types of packets received if not self._shouldFilterPacket(p): @@ -373,36 +395,43 @@ subnet is used to construct our network number (normally 10.115.x.x)

    srcaddr = p[12:16] destAddr = p[16:20] subheader = 20 - ignore = False # Assume we will be forwarding the packet + ignore = False # Assume we will be forwarding the packet if protocol in protocolBlacklist: ignore = True - logging.log(LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}") - elif protocol == 0x01: # ICMP + logging.log( + LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}") + elif protocol == 0x01: # ICMP icmpType = p[20] icmpCode = p[21] checksum = p[22:24] - logging.debug(f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}") + logging.debug( + f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}") # reply to pings (swap src and dest but keep rest of packet unchanged) #pingback = p[:12]+p[16:20]+p[12:16]+p[20:] - #tap.write(pingback) - elif protocol == 0x11: # UDP + # tap.write(pingback) + elif protocol == 0x11: # UDP srcport = readnet_u16(p, subheader) destport = readnet_u16(p, subheader + 2) if destport in udpBlacklist: ignore = True - logging.log(LOG_TRACE, f"ignoring blacklisted UDP port {destport}") + logging.log( + LOG_TRACE, f"ignoring blacklisted UDP port {destport}") else: - logging.debug(f"forwarding udp srcport={srcport}, destport={destport}") - elif protocol == 0x06: # TCP + logging.debug( + f"forwarding udp srcport={srcport}, destport={destport}") + elif protocol == 0x06: # TCP srcport = readnet_u16(p, subheader) destport = readnet_u16(p, subheader + 2) if destport in tcpBlacklist: ignore = True - logging.log(LOG_TRACE, f"ignoring blacklisted TCP port {destport}") + logging.log( + LOG_TRACE, f"ignoring blacklisted TCP port {destport}") else: - logging.debug(f"forwarding tcp srcport={srcport}, destport={destport}") + logging.debug( + f"forwarding tcp srcport={srcport}, destport={destport}") else: - logging.warning(f"forwarding unexpected protocol 0x{protocol:02x}, src={ipstr(srcaddr)}, dest={ipstr(destAddr)}") + logging.warning( + f"forwarding unexpected protocol 0x{protocol:02x}, src={ipstr(srcaddr)}, dest={ipstr(destAddr)}") return ignore @@ -438,10 +467,13 @@ subnet is used to construct our network number (normally 10.115.x.x)

    """Forward the provided IP packet into the mesh""" nodeId = self._ipToNodeId(destAddr) if nodeId is not None: - logging.debug(f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}") - self.iface.sendData(p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck = False) + logging.debug( + f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}") + self.iface.sendData( + p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck=False) else: - logging.warning(f"Dropping packet because no node found for destIP={ipstr(destAddr)}") + logging.warning( + f"Dropping packet because no node found for destIP={ipstr(destAddr)}") def close(self): self.tun.close()
    @@ -471,11 +503,12 @@ subnet is used to construct our network number (normally 10.115.x.x)

    Expand source code
    def onReceive(self, packet):
    -    p = packet["decoded"]["data"]["payload"]
    +    p = packet["decoded"]["payload"]
         if packet["from"] == self.iface.myInfo.my_node_num:
             logging.debug("Ignoring message we sent")
         else:
    -        logging.debug(f"Received mesh tunnel message type={type(p)} len={len(p)}")
    +        logging.debug(
    +            f"Received mesh tunnel message type={type(p)} len={len(p)}")
             # we don't really need to check for filtering here (sender should have checked), but this provides
             # useful debug printing on types of packets received
             if not self._shouldFilterPacket(p):
    @@ -495,10 +528,13 @@ subnet is used to construct our network number (normally 10.115.x.x)

    """Forward the provided IP packet into the mesh""" nodeId = self._ipToNodeId(destAddr) if nodeId is not None: - logging.debug(f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}") - self.iface.sendData(p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck = False) + logging.debug( + f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}") + self.iface.sendData( + p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck=False) else: - logging.warning(f"Dropping packet because no node found for destIP={ipstr(destAddr)}")
    + logging.warning( + f"Dropping packet because no node found for destIP={ipstr(destAddr)}")
    diff --git a/docs/meshtastic/util.html b/docs/meshtastic/util.html index efc4a67..cec8525 100644 --- a/docs/meshtastic/util.html +++ b/docs/meshtastic/util.html @@ -34,6 +34,23 @@ import serial.tools.list_ports blacklistVids = dict.fromkeys([0x1366]) +def stripnl(s): + """remove newlines from a string""" + return str(s).replace("\n", " ") + + +def fixme(message): + raise Exception(f"FIXME: {message}") + + +def catchAndIgnore(reason, closure): + """Call a closure but if it throws an excpetion print it and continue""" + try: + closure() + except BaseException as ex: + logging.error(f"Exception thrown in {reason}: {ex}") + + def findPorts(): """Find all ports that might have meshtastic devices @@ -61,6 +78,23 @@ class dotdict(dict):

    Functions

    +
    +def catchAndIgnore(reason, closure) +
    +
    +

    Call a closure but if it throws an excpetion print it and continue

    +
    + +Expand source code + +
    def catchAndIgnore(reason, closure):
    +    """Call a closure but if it throws an excpetion print it and continue"""
    +    try:
    +        closure()
    +    except BaseException as ex:
    +        logging.error(f"Exception thrown in {reason}: {ex}")
    +
    +
    def findPorts()
    @@ -85,6 +119,33 @@ class dotdict(dict): return l
    +
    +def fixme(message) +
    +
    +
    +
    + +Expand source code + +
    def fixme(message):
    +    raise Exception(f"FIXME: {message}")
    +
    +
    +
    +def stripnl(s) +
    +
    +

    remove newlines from a string

    +
    + +Expand source code + +
    def stripnl(s):
    +    """remove newlines from a string"""
    +    return str(s).replace("\n", " ")
    +
    +
    @@ -127,7 +188,10 @@ class dotdict(dict):
  • Functions

  • Classes

    diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index bf3aa27..dd69d99 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -55,18 +55,29 @@ interface = meshtastic.SerialInterface() """ -import socket import pygatt import google.protobuf.json_format -import serial, threading, logging, sys, random, traceback, time, base64, platform -from . import mesh_pb2, portnums_pb2, util +import serial +import threading +import logging +import sys +import random +import traceback +import time +import base64 +import platform +import socket +from . import mesh_pb2, portnums_pb2, apponly_pb2, admin_pb2, environmental_measurement_pb2, remote_hardware_pb2, channel_pb2, radioconfig_pb2, util +from .util import fixme, catchAndIgnore, stripnl from pubsub import pub from dotmap import DotMap +from typing import * START1 = 0x94 START2 = 0xc3 HEADER_LEN = 4 MAX_TO_FROM_RADIO_SIZE = 512 +defaultHopLimit = 3 BROADCAST_ADDR = "^all" # A special ID that means broadcast @@ -79,7 +90,25 @@ MY_CONFIG_ID = 42 format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20 """ -OUR_APP_VERSION = 20120 +OUR_APP_VERSION = 20200 + + +class ResponseHandler(NamedTuple): + """A pending response callback, waiting for a response to one of our messages""" + # requestId: int - used only as a key + callback: Callable + # FIXME, add timestamp and age out old requests + + +class KnownProtocol(NamedTuple): + """Used to automatically decode known protocol payloads""" + name: str + # portnum: int, now a key + # If set, will be called to prase as a protocol buffer + protobufFactory: Callable = None + # If set, invoked as onReceive(interface, packet) + onReceive: Callable = None + class MeshInterface: """Interface class for meshtastic devices @@ -101,7 +130,10 @@ class MeshInterface: self.nodes = None # FIXME self.isConnected = threading.Event() self.noProto = noProto - random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it + self.myInfo = None # We don't have device info yet + self.responseHandlers = {} # A map from request ID to the handler + self.failure = None # If we've encountered a fatal exception it will be kept here + random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it self.currentPacketId = random.randint(0, 0xffffffff) self._startConfig() @@ -110,12 +142,18 @@ class MeshInterface: def __exit__(self, exc_type, exc_value, traceback): if exc_type is not None and exc_value is not None: - logging.error(f'An exception of type {exc_type} with value {exc_value} has occurred') + logging.error( + f'An exception of type {exc_type} with value {exc_value} has occurred') if traceback is not None: logging.error(f'Traceback: {traceback}') self.close() - def sendText(self, text, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False): + def sendText(self, text: AnyStr, + destinationId=BROADCAST_ADDR, + wantAck=False, + wantResponse=False, + hopLimit=defaultHopLimit, + onResponse=None): """Send a utf8 string to some other node, if the node has a display it will also be shown on the device. Arguments: @@ -125,13 +163,22 @@ class MeshInterface: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery) + wantResponse -- True if you want the service on the other side to send an application layer response Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ return self.sendData(text.encode("utf-8"), destinationId, - portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, wantAck=wantAck, wantResponse=wantResponse) + portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, + wantAck=wantAck, + wantResponse=wantResponse, + hopLimit=hopLimit, + onResponse=onResponse) - def sendData(self, data, destinationId=BROADCAST_ADDR, portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False, wantResponse=False): + def sendData(self, data, destinationId=BROADCAST_ADDR, + portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False, + wantResponse=False, + hopLimit=defaultHopLimit, + onResponse=None): """Send a data packet to some other node Keyword Arguments: @@ -139,20 +186,30 @@ class MeshInterface: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery) + wantResponse -- True if you want the service on the other side to send an application layer response + onResponse -- A closure of the form funct(packet), that will be called when a response packet arrives (or the transaction is NAKed due to non receipt) Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ if getattr(data, "SerializeToString", None): - logging.debug(f"Serializing protobuf as data: {data}") + logging.debug(f"Serializing protobuf as data: {stripnl(data)}") data = data.SerializeToString() if len(data) > mesh_pb2.Constants.DATA_PAYLOAD_LEN: raise Exception("Data payload too big") + + if portNum == portnums_pb2.PortNum.UNKNOWN_APP: # we are now more strict wrt port numbers + raise Exception("A non-zero port number must be specified") + meshPacket = mesh_pb2.MeshPacket() - meshPacket.decoded.data.payload = data - meshPacket.decoded.data.portnum = portNum + meshPacket.decoded.payload = data + meshPacket.decoded.portnum = portNum meshPacket.decoded.want_response = wantResponse - return self.sendPacket(meshPacket, destinationId, wantAck=wantAck) + + p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck, hopLimit=hopLimit) + if onResponse is not None: + self._addResponseHandler(p.id, onResponse) + return p def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False): """ @@ -179,18 +236,29 @@ class MeshInterface: timeSec = time.time() # returns unix timestamp in seconds p.time = int(timeSec) - return self.sendData(p, destinationId, portNum=portnums_pb2.PortNum.POSITION_APP, wantAck=wantAck, wantResponse=wantResponse) + return self.sendData(p, destinationId, + portNum=portnums_pb2.PortNum.POSITION_APP, + wantAck=wantAck, + wantResponse=wantResponse) - def sendPacket(self, meshPacket, destinationId=BROADCAST_ADDR, wantAck=False): + def _addResponseHandler(self, requestId, callback): + self.responseHandlers[requestId] = ResponseHandler(callback) + + def _sendPacket(self, meshPacket, + destinationId=BROADCAST_ADDR, + wantAck=False, hopLimit=defaultHopLimit): """Send a MeshPacket to the specified node (or if unspecified, broadcast). You probably don't want this - use sendData instead. - Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. + Returns the sent packet. The id field will be populated in this packet and + can be used to track future message acks/naks. """ - self._waitConnected() + + # We allow users to talk to the local node before we've completed the full connection flow... + if(self.myInfo is not None and destinationId != self.myInfo.my_node_num): + self._waitConnected() toRadio = mesh_pb2.ToRadio() - # FIXME add support for non broadcast addresses if destinationId is None: raise Exception("destinationId must not be None") @@ -203,6 +271,7 @@ class MeshInterface: meshPacket.to = nodeNum meshPacket.want_ack = wantAck + meshPacket.hop_limit = hopLimit # if the user hasn't set an ID for this packet (likely and recommended), we should pick a new unique ID # so the message can be tracked. @@ -210,10 +279,11 @@ class MeshInterface: meshPacket.id = self._generatePacketId() toRadio.packet.CopyFrom(meshPacket) + #logging.debug(f"Sending packet: {stripnl(meshPacket)}") self._sendToRadio(toRadio) return meshPacket - def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig')): + def waitForConfig(self, sleep=.1, maxsecs=20, attrs=('myInfo', 'nodes', 'radioConfig', 'channels')): """Block until radio config is received. Returns True if config has been received.""" for _ in range(int(maxsecs/sleep)): if all(map(lambda a: getattr(self, a, None), attrs)): @@ -226,11 +296,25 @@ class MeshInterface: if self.radioConfig == None: raise Exception("No RadioConfig has been read") - t = mesh_pb2.ToRadio() - t.set_radio.CopyFrom(self.radioConfig) - self._sendToRadio(t) + p = admin_pb2.AdminMessage() + p.set_radio.CopyFrom(self.radioConfig) + + self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) logging.debug("Wrote config") + def writeChannel(self, channelIndex): + """Write the current (edited) channel to the device""" + + p = admin_pb2.AdminMessage() + p.set_channel.CopyFrom(self.channels[channelIndex]) + + self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) + logging.debug("Wrote channel {channelIndex}") + def getMyNodeInfo(self): if self.myInfo is None: return None @@ -271,43 +355,66 @@ class MeshInterface: short_name = long_name[0] + long_name[1:].translate(trans) if len(short_name) < nChars: short_name = long_name[:nChars] - t = mesh_pb2.ToRadio() + + p = admin_pb2.AdminMessage() + if long_name is not None: - t.set_owner.long_name = long_name + p.set_owner.long_name = long_name if short_name is not None: short_name = short_name.strip() if len(short_name) > nChars: short_name = short_name[:nChars] - t.set_owner.short_name = short_name - self._sendToRadio(t) + p.set_owner.short_name = short_name + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True) @property def channelURL(self): """The sharable URL that describes the current channel """ - bytes = self.radioConfig.channel_settings.SerializeToString() + # Only keep the primary/secondary channels, assume primary is first + channelSet = apponly_pb2.ChannelSet() + for c in self.channels: + if c.role != channel_pb2.Channel.Role.DISABLED: + channelSet.settings.append(c.settings) + bytes = channelSet.SerializeToString() s = base64.urlsafe_b64encode(bytes).decode('ascii') - return f"https://www.meshtastic.org/c/#{s}" + return f"https://www.meshtastic.org/d/#{s}".replace("=", "") - def setURL(self, url, write=True): + def setURL(self, url): """Set mesh network URL""" if self.radioConfig == None: raise Exception("No RadioConfig has been read") - # URLs are of the form https://www.meshtastic.org/c/#{base64_channel_settings} + # URLs are of the form https://www.meshtastic.org/d/#{base64_channel_set} # Split on '/#' to find the base64 encoded channel settings splitURL = url.split("/#") decodedURL = base64.urlsafe_b64decode(splitURL[-1]) - self.radioConfig.channel_settings.ParseFromString(decodedURL) - if write: - self.writeConfig() + channelSet = apponly_pb2.ChannelSet() + channelSet.ParseFromString(decodedURL) + + i = 0 + for chs in channelSet.settings: + ch = channel_pb2.Channel() + ch.role = channel_pb2.Channel.Role.PRIMARY if i == 0 else channel_pb2.Channel.Role.SECONDARY + ch.index = i + ch.settings.CopyFrom(chs) + self.channels[ch.index] = ch + self.writeChannel(ch.index) + i = i + 1 def _waitConnected(self): """Block until the initial node db download is complete, or timeout and raise an exception""" - if not self.isConnected.wait(5.0): # timeout after 5 seconds + if not self.isConnected.wait(5.0): # timeout after 5 seconds raise Exception("Timed out waiting for connection completion") + # If we failed while connecting, raise the connection to the client + if self.failure: + raise self.failure + def _generatePacketId(self): """Get a new unique packet ID""" if self.currentPacketId is None: @@ -319,13 +426,15 @@ class MeshInterface: def _disconnected(self): """Called by subclasses to tell clients this interface has disconnected""" self.isConnected.clear() - pub.sendMessage("meshtastic.connection.lost", interface=self) + catchAndIgnore("disconnection publish", lambda: pub.sendMessage( + "meshtastic.connection.lost", interface=self)) def _connected(self): """Called by this class to tell clients we are now fully connected to a node """ self.isConnected.set() - pub.sendMessage("meshtastic.connection.established", interface=self) + catchAndIgnore("connection publish", lambda: pub.sendMessage( + "meshtastic.connection.established", interface=self)) def _startConfig(self): """Start device packets flowing""" @@ -333,6 +442,8 @@ class MeshInterface: self.nodes = {} # nodes keyed by ID self.nodesByNum = {} # nodes keyed by nodenum self.radioConfig = None + self.channels = None + self.partialChannels = [] # We keep our channels in a temp array until finished startConfig = mesh_pb2.ToRadio() startConfig.want_config_id = MY_CONFIG_ID # we don't use this value @@ -341,14 +452,74 @@ class MeshInterface: def _sendToRadio(self, toRadio): """Send a ToRadio protobuf to the device""" if self.noProto: - logging.warn(f"Not sending packet because protocol use is disabled by noProto") + logging.warn( + f"Not sending packet because protocol use is disabled by noProto") else: + #logging.debug(f"Sending toRadio: {stripnl(toRadio)}") self._sendToRadioImpl(toRadio) def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" logging.error(f"Subclass must provide toradio: {toRadio}") + def _handleConfigComplete(self): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings and channels + """ + self._requestSettings() + self._requestChannel(0) + + def _requestSettings(self): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings + """ + p = admin_pb2.AdminMessage() + p.get_radio_request = True + + def onResponse(p): + """A closure to handle the response packet""" + self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True, + wantResponse=True, + onResponse=onResponse) + + def _requestChannel(self, channelNum: int): + """ + Done with initial config messages, now send regular MeshPackets to ask for settings + """ + p = admin_pb2.AdminMessage() + p.get_channel_request = channelNum + 1 + logging.debug(f"Requesting channel {channelNum}") + + def onResponse(p): + """A closure to handle the response packet""" + c = p["decoded"]["admin"]["raw"].get_channel_response + self.partialChannels.append(c) + logging.debug(f"Received channel {stripnl(c)}") + index = c.index + + # for stress testing, we can always download all channels + fastChannelDownload = True + + # Once we see a response that has NO settings, assume we are at the end of channels and stop fetching + quitEarly = (c.role == channel_pb2.Channel.Role.DISABLED) and fastChannelDownload + + if quitEarly or index >= self.myInfo.max_channels - 1: + self.channels = self.partialChannels + # FIXME, the following should only be called after we have settings and channels + self._connected() # Tell everone else we are ready to go + else: + self._requestChannel(index + 1) + + return self.sendData(p, self.myInfo.my_node_num, + portNum=portnums_pb2.PortNum.ADMIN_APP, + wantAck=True, + wantResponse=True, + onResponse=onResponse) + def _handleFromRadio(self, fromRadioBytes): """ Handle a packet that arrived from the radio(update model and publish events) @@ -357,28 +528,41 @@ class MeshInterface: fromRadio = mesh_pb2.FromRadio() fromRadio.ParseFromString(fromRadioBytes) asDict = google.protobuf.json_format.MessageToDict(fromRadio) - logging.debug(f"Received: {asDict}") if fromRadio.HasField("my_info"): self.myInfo = fromRadio.my_info + logging.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}") + + failmsg = None + # Check for app too old if self.myInfo.min_app_version > OUR_APP_VERSION: - raise Exception( - "This device needs a newer python client, please \"pip install --upgrade meshtastic\"") - # start assigning our packet IDs from the opposite side of where our local device is assigning them - elif fromRadio.HasField("radio"): - self.radioConfig = fromRadio.radio + failmsg = "This device needs a newer python client, please \"pip install --upgrade meshtastic\". For more information see https://tinyurl.com/5bjsxu32" + + # check for firmware too old + if self.myInfo.max_channels == 0: + failmsg = "This version of meshtastic-python requires device firmware version 1.2 or later. For more information see https://tinyurl.com/5bjsxu32" + + if failmsg: + self.failure = Exception(failmsg) + self.isConnected.set() # let waitConnected return this exception + self.close() + elif fromRadio.HasField("node_info"): node = asDict["nodeInfo"] try: self._fixupPosition(node["position"]) except: logging.debug("Node without position") + + logging.debug(f"Received nodeinfo: {node}") + self.nodesByNum[node["num"]] = node if "user" in node: # Some nodes might not have user/ids assigned yet self.nodes[node["user"]["id"]] = node - pub.sendMessage("meshtastic.node.updated", node=node, interface=self) + pub.sendMessage("meshtastic.node.updated", + node=node, interface=self) elif fromRadio.config_complete_id == MY_CONFIG_ID: # we ignore the config_complete_id, it is unneeded for our stream API fromRadio.config_complete_id - self._connected() + self._handleConfigComplete() elif fromRadio.HasField("packet"): self._handlePacketFromRadio(fromRadio.packet) elif fromRadio.rebooted: @@ -441,6 +625,20 @@ class MeshInterface: """ asDict = google.protobuf.json_format.MessageToDict(meshPacket) + + # We normally decompose the payload into a dictionary so that the client + # doesn't need to understand protobufs. But advanced clients might + # want the raw protobuf, so we provide it in "raw" + asDict["raw"] = meshPacket + + # from might be missing if the nodenum was zero. + if not "from" in asDict: + asDict["from"] = 0 + logging.error(f"Device returned a packet we sent, ignoring: {stripnl(asDict)}") + return + if not "to" in asDict: + asDict["to"] = 0 + # /add fromId and toId fields based on the node ID asDict["fromId"] = self._nodeNumToId(asDict["from"]) asDict["toId"] = self._nodeNumToId(asDict["to"]) @@ -449,68 +647,59 @@ class MeshInterface: # asObj = DotMap(asDict) topic = "meshtastic.receive" # Generic unknown packet type - # Warn users if firmware doesn't use new portnum based data encodings - # But do not crash, because the lib will still basically work and ignore those packet types - if meshPacket.decoded.HasField("user") or meshPacket.decoded.HasField("position"): - logging.warn("Ignoring old position/user message. Recommend you update firmware to 1.1.20 or later") + decoded = asDict["decoded"] + # The default MessageToDict converts byte arrays into base64 strings. + # We don't want that - it messes up data payload. So slam in the correct + # byte array. + decoded["payload"] = meshPacket.decoded.payload - if meshPacket.decoded.HasField("data"): + # UNKNOWN_APP is the default protobuf portnum value, and therefore if not set it will not be populated at all + # to make API usage easier, set it to prevent confusion + if not "portnum" in decoded: + decoded["portnum"] = portnums_pb2.PortNum.Name( + portnums_pb2.PortNum.UNKNOWN_APP) - # The default MessageToDict converts byte arrays into base64 strings. - # We don't want that - it messes up data payload. So slam in the correct - # byte array. - asDict["decoded"]["data"]["payload"] = meshPacket.decoded.data.payload + portnum = decoded["portnum"] - # UNKNOWN_APP is the default protobuf portnum value, and therefore if not set it will not be populated at all - # to make API usage easier, set it to prevent confusion - if not "portnum" in asDict["decoded"]["data"]: - asDict["decoded"]["data"]["portnum"] = portnums_pb2.PortNum.Name(portnums_pb2.PortNum.UNKNOWN_APP) + topic = f"meshtastic.receive.data.{portnum}" - portnum = asDict["decoded"]["data"]["portnum"] + # decode position protobufs and update nodedb, provide decoded version as "position" in the published msg + # move the following into a 'decoders' API that clients could register? + portNumInt = meshPacket.decoded.portnum # we want portnum as an int + handler = protocols.get(portNumInt) + # The decoded protobuf as a dictionary (if we understand this message) + p = None + if handler is not None: + topic = f"meshtastic.receive.{handler.name}" - topic = f"meshtastic.receive.data.{portnum}" - - # For text messages, we go ahead and decode the text to ascii for our users - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.TEXT_MESSAGE_APP): - topic = "meshtastic.receive.text" - - # We don't throw if the utf8 is invalid in the text message. Instead we just don't populate - # the decoded.data.text and we log an error message. This at least allows some delivery to - # the app and the app can deal with the missing decoded representation. - # - # Usually btw this problem is caused by apps sending binary data but setting the payload type to - # text. - try: - asDict["decoded"]["data"]["text"] = meshPacket.decoded.data.payload.decode("utf-8") - except Exception as ex: - logging.error(f"Malformatted utf8 in text message: {ex}") - - # decode position protobufs and update nodedb, provide decoded version as "position" in the published msg - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.POSITION_APP): - topic = "meshtastic.receive.position" - pb = mesh_pb2.Position() - pb.ParseFromString(meshPacket.decoded.data.payload) + # Convert to protobuf if possible + if handler.protobufFactory is not None: + pb = handler.protobufFactory() + pb.ParseFromString(meshPacket.decoded.payload) p = google.protobuf.json_format.MessageToDict(pb) - self._fixupPosition(p) - asDict["decoded"]["data"]["position"] = p - # update node DB as needed - self._getOrCreateByNum(asDict["from"])["position"] = p + asDict["decoded"][handler.name] = p + # Also provide the protobuf raw + asDict["decoded"][handler.name]["raw"] = pb - # decode user protobufs and update nodedb, provide decoded version as "position" in the published msg - if portnum == portnums_pb2.PortNum.Name(portnums_pb2.PortNum.NODEINFO_APP): - topic = "meshtastic.receive.user" - pb = mesh_pb2.User() - pb.ParseFromString(meshPacket.decoded.data.payload) - u = google.protobuf.json_format.MessageToDict(pb) - asDict["decoded"]["data"]["user"] = u - # update node DB as needed - n = self._getOrCreateByNum(asDict["from"]) - n["user"] = u - # We now have a node ID, make sure it is uptodate in that table - self.nodes[u["id"]] = n + # Call specialized onReceive if necessary + if handler.onReceive is not None: + handler.onReceive(self, asDict) - logging.debug(f"Publishing topic {topic}") - pub.sendMessage(topic, packet=asDict, interface=self) + # Is this message in response to a request, if so, look for a handler + requestId = decoded.get("requestId") + if requestId is not None: + # We ignore ACK packets, but send NAKs and data responses to the handlers + routing = decoded.get("routing") + isAck = routing is not None and ("errorReason" not in routing) + if not isAck: + # we keep the responseHandler in dict until we get a non ack + handler = self.responseHandlers.pop(requestId, None) + if handler is not None: + handler.callback(asDict) + + logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ") + catchAndIgnore(f"publishing {topic}", lambda: pub.sendMessage( + topic, packet=asDict, interface=self)) # Our standard BLE characteristics @@ -541,7 +730,7 @@ class BLEInterface(MeshInterface): def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" - logging.debug(f"Sending: {toRadio}") + # logging.debug(f"Sending: {stripnl(toRadio)}") b = toRadio.SerializeToString() self.device.char_write(TORADIO_UUID, b) @@ -599,7 +788,7 @@ class StreamInterface(MeshInterface): time.sleep(0.1) # wait 100ms to give device time to start running self._rxThread.start() - if not self.noProto: # Wait for the db download if using the protocol + if not self.noProto: # Wait for the db download if using the protocol self._waitConnected() def _disconnected(self): @@ -621,7 +810,7 @@ class StreamInterface(MeshInterface): def _sendToRadioImpl(self, toRadio): """Send a ToRadio protobuf to the device""" - logging.debug(f"Sending: {toRadio}") + logging.debug(f"Sending: {stripnl(toRadio)}") b = toRadio.SerializeToString() bufLen = len(b) # We convert into a string, because the TCP code doesn't work with byte arrays @@ -685,13 +874,16 @@ class StreamInterface(MeshInterface): # logging.debug(f"timeout") pass except serial.SerialException as ex: - if not self._wantExit: # We might intentionally get an exception during shutdown - logging.warn(f"Meshtastic serial port disconnected, disconnecting... {ex}") + if not self._wantExit: # We might intentionally get an exception during shutdown + logging.warn( + f"Meshtastic serial port disconnected, disconnecting... {ex}") except OSError as ex: - if not self._wantExit: # We might intentionally get an exception during shutdown - logging.error(f"Unexpected OSError, terminating meshtastic reader... {ex}") + if not self._wantExit: # We might intentionally get an exception during shutdown + logging.error( + f"Unexpected OSError, terminating meshtastic reader... {ex}") except Exception as ex: - logging.error(f"Unexpected exception, terminating meshtastic reader... {ex}") + logging.error( + f"Unexpected exception, terminating meshtastic reader... {ex}") finally: logging.debug("reader is exiting") self._disconnected() @@ -739,10 +931,11 @@ class SerialInterface(StreamInterface): StreamInterface.__init__( self, debugOut=debugOut, noProto=noProto, connectNow=connectNow) + class TCPInterface(StreamInterface): """Interface class for meshtastic devices over a TCP link""" - def __init__(self, hostname, debugOut=None, noProto=False, connectNow=True, portNumber=4403): + def __init__(self, hostname: AnyStr, debugOut=None, noProto=False, connectNow=True, portNumber=4403): """Constructor, opens a connection to a specified IP address/hostname Keyword Arguments: @@ -765,9 +958,9 @@ class TCPInterface(StreamInterface): def close(self): """Close a connection to the device""" logging.debug("Closing TCP stream") - # Sometimes the socket read might be blocked in the reader thread. Therefore we force the shutdown by closing + # Sometimes the socket read might be blocked in the reader thread. Therefore we force the shutdown by closing # the socket here - self._wantExit = True + self._wantExit = True if not self.socket is None: self.socket.shutdown(socket.SHUT_RDWR) self.socket.close() @@ -780,3 +973,50 @@ class TCPInterface(StreamInterface): def _readBytes(self, len): """Read an array of bytes from our stream""" return self.socket.recv(len) + + +def _onTextReceive(iface, asDict): + """Special text auto parsing for received messages""" + # We don't throw if the utf8 is invalid in the text message. Instead we just don't populate + # the decoded.data.text and we log an error message. This at least allows some delivery to + # the app and the app can deal with the missing decoded representation. + # + # Usually btw this problem is caused by apps sending binary data but setting the payload type to + # text. + try: + asBytes = asDict["decoded"]["payload"] + asDict["decoded"]["text"] = asBytes.decode("utf-8") + except Exception as ex: + logging.error(f"Malformatted utf8 in text message: {ex}") + + +def _onPositionReceive(iface, asDict): + """Special auto parsing for received messages""" + p = asDict["decoded"]["position"] + iface._fixupPosition(p) + # update node DB as needed + iface._getOrCreateByNum(asDict["from"])["position"] = p + + +def _onNodeInfoReceive(iface, asDict): + """Special auto parsing for received messages""" + p = asDict["decoded"]["user"] + # decode user protobufs and update nodedb, provide decoded version as "position" in the published msg + # update node DB as needed + n = iface._getOrCreateByNum(asDict["from"]) + n["user"] = p + # We now have a node ID, make sure it is uptodate in that table + iface.nodes[p["id"]] = n + + +"""Well known message payloads can register decoders for automatic protobuf parsing""" +protocols = { + portnums_pb2.PortNum.TEXT_MESSAGE_APP: KnownProtocol("text", onReceive=_onTextReceive), + portnums_pb2.PortNum.POSITION_APP: KnownProtocol("position", mesh_pb2.Position, _onPositionReceive), + portnums_pb2.PortNum.NODEINFO_APP: KnownProtocol("user", mesh_pb2.User, _onNodeInfoReceive), + portnums_pb2.PortNum.ADMIN_APP: KnownProtocol("admin", admin_pb2.AdminMessage), + portnums_pb2.PortNum.ROUTING_APP: KnownProtocol("routing", mesh_pb2.Routing), + portnums_pb2.PortNum.ENVIRONMENTAL_MEASUREMENT_APP: KnownProtocol("environmental", environmental_measurement_pb2.EnvironmentalMeasurement), + portnums_pb2.PortNum.REMOTE_HARDWARE_APP: KnownProtocol( + "remotehw", remote_hardware_pb2.HardwareMessage) +} diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index c1c6a51..617fe1c 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -1,13 +1,22 @@ #!python3 -import argparse, platform, logging, sys, codecs, base64 +import argparse +import platform +import logging +import sys +import codecs +import base64 from . import SerialInterface, TCPInterface, BLEInterface, test, remote_hardware from pubsub import pub -from . import mesh_pb2, portnums_pb2 +from . import mesh_pb2, portnums_pb2, channel_pb2 +from .util import stripnl import google.protobuf.json_format import pyqrcode import traceback import pkg_resources +from datetime import datetime +from easy_table import EasyTable +from google.protobuf.json_format import MessageToJson """We only import the tunnel code if we are on a platform that can run it""" have_tunnel = platform.system() == 'Linux' @@ -18,19 +27,22 @@ args = None """The parser for arguments""" parser = argparse.ArgumentParser() +channelIndex = 0 + + def onReceive(packet, interface): """Callback invoked when a packet arrives""" - logging.debug(f"Received: {packet}") - try: + d = packet.get('decoded') + # Exit once we receive a reply - if args.sendtext and packet["to"] == interface.myInfo.my_node_num: + if args.sendtext and packet["to"] == interface.myInfo.my_node_num and d["portnum"] == portnums_pb2.PortNum.TEXT_MESSAGE_APP: interface.close() # after running command then exit # Reply to every received message with some stats if args.reply: - if packet['decoded']['data'] is not None: - msg = packet['decoded']['data']['text'] + msg = d.get('text') + if msg: #shortName = packet['decoded']['data']['shortName'] rxSnr = packet['rxSnr'] hopLimit = packet['hopLimit'] @@ -52,6 +64,7 @@ def onConnection(interface, topic=pub.AUTO_TOPIC): trueTerms = {"t", "true", "yes"} falseTerms = {"f", "false", "no"} + def fromStr(valstr): """try to parse as int, float or bool (and fallback to a string as last resort) @@ -61,7 +74,8 @@ def fromStr(valstr): valstr (string): A user provided string """ if(valstr.startswith('0x')): - val = bytes.fromhex(valstr[2:]) # if needed convert to string with asBytes.decode('utf-8') + # if needed convert to string with asBytes.decode('utf-8') + val = bytes.fromhex(valstr[2:]) elif valstr in trueTerms: val = True elif valstr in falseTerms: @@ -81,56 +95,58 @@ def fromStr(valstr): never = 0xffffffff oneday = 24 * 60 * 60 +# Returns formatted value -def setRouter(interface, on): - """Turn router mode on or off""" - prefs = interface.radioConfig.preferences - if on: - print("Setting router mode") - prefs.is_router = True +def formatFloat(value, formatStr="{:.2f}", unit="", default="N/A"): + return formatStr.format(value)+unit if value else default - # FIXME as of 1.1.24 of the device code, the following is all deprecated. After that release - # has been out a while, just set is_router and warn the user about deprecation - # - prefs.is_low_power = True - prefs.gps_operation = mesh_pb2.GpsOpMobile +# Returns Last Heard Time in human readable format - # FIXME - after tuning, move these params into the on-device defaults based on is_router and is_low_power - # prefs.position_broadcast_secs = FIXME possibly broadcast only once an hr - prefs.wait_bluetooth_secs = 1 # Don't stay in bluetooth mode - prefs.screen_on_secs = 60 # default to only keep screen & bluetooth on for one minute - prefs.mesh_sds_timeout_secs = never - prefs.phone_sds_timeout_sec = never - # try to stay in light sleep one full day, then briefly wake and sleep again +def getLH(ts, default="N/A"): + return datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') if ts else default - prefs.ls_secs = oneday +# Print Nodes - # if a message wakes us from light sleep, stay awake for 10 secs in hopes of other processing - prefs.min_wake_secs = 10 - # allow up to five minutes for each new GPS lock attempt - prefs.gps_attempt_time = 300 +def printNodes(nodes): + # Create the table and define the structure + table = EasyTable("Nodes") + table.setCorners("/", "\\", "\\", "/") + table.setOuterStructure("|", "-") + table.setInnerStructure("|", "-", "+") - # get a new GPS position once per day - prefs.gps_update_interval = oneday + tableData = [] + for node in nodes: + # aux var to get not defined keys + LH = getLH(node['position'].get("time")) + lat = formatFloat(node['position'].get("latitude"), "{:.4f}", "°") + lon = formatFloat(node['position'].get("longitude"), "{:.4f}", "°") + alt = formatFloat(node['position'].get("altitude"), "{:.0f}", " m") + batt = formatFloat(node['position'].get("batteryLevel"), "{:.2f}", "%") + snr = formatFloat(node.get("snr"), "{:.2f}", " dB") + tableData.append({"User": node['user']['longName'], + "Position": "Lat:"+lat+", Lon:"+lon+", Alt:"+alt, + "Battery": batt, "SNR": snr, "LastHeard": LH}) + table.setData(tableData) + table.displayTable() - else: - print("Unsetting router mode") - prefs.is_router = False - prefs.is_low_power = False - prefs.gps_operation = mesh_pb2.GpsOpUnset - # Set defaults - prefs.wait_bluetooth_secs = 0 - prefs.screen_on_secs = 0 - prefs.mesh_sds_timeout_secs = 0 - prefs.phone_sds_timeout_sec = 0 - prefs.ls_secs = 0 - prefs.min_wake_secs = 0 - prefs.gps_attempt_time = 0 - prefs.gps_update_interval = 0 +def setPref(attributes, name, valStr): + """Set a channel or preferences value""" + val = fromStr(valStr) + try: + try: + setattr(attributes, name, val) + except TypeError as ex: + # The setter didn't like our arg type guess try again as a string + setattr(attributes, name, valStr) + + # succeeded! + print(f"Set {name} to {valStr}") + except Exception as ex: + print(f"Can't set {name} due to {ex}") def onConnected(interface): @@ -194,7 +210,8 @@ def onConnected(interface): for wrpair in (args.gpiowrb or []): bitmask |= 1 << int(wrpair[0]) bitval |= int(wrpair[1]) << int(wrpair[0]) - print(f"Writing GPIO mask 0x{bitmask:x} with value 0x{bitval:x} to {args.dest}") + print( + f"Writing GPIO mask 0x{bitmask:x} with value 0x{bitval:x} to {args.dest}") rhc.writeGPIOs(args.dest, bitmask, bitval) if args.gpiord: @@ -205,73 +222,74 @@ def onConnected(interface): if args.gpiowatch: bitmask = int(args.gpiowatch) print(f"Watching GPIO mask 0x{bitmask:x} from {args.dest}") - rhc.watchGPIOs(args.dest, bitmask) + rhc.watchGPIOs(args.dest, bitmask) - if args.set or args.setstr or args.setchan or args.setch_longslow or args.setch_shortfast \ - or args.seturl or args.router != None: + # handle settings + if args.set: closeNow = True - def setPref(attributes, name, valStr): - """Set a preferences value""" - val = fromStr(valStr) - try: - try: - setattr(attributes, name, val) - except TypeError as ex: - # The setter didn't like our arg type guess try again as a string - setattr(attributes, name, valStr) - - # succeeded! - print(f"Set {name} to {valStr}") - except Exception as ex: - print(f"Can't set {name} due to {ex}") - - def setSimpleChannel(modem_config): - """Set one of the simple modem_config only based channels""" - ch = mesh_pb2.ChannelSettings() - ch.modem_config = modem_config - ch.psk = bytes([1]) # Use default channel psk 1 - interface.radioConfig.channel_settings.CopyFrom(ch) - - if args.router != None: - setRouter(interface, args.router) - # Handle the int/float/bool arguments - for pref in (args.set or []): + for pref in args.set: setPref( prefs, pref[0], pref[1]) - # Handle the string arguments - for pref in (args.setstr or []): - setPref(prefs, pref[0], pref[1]) + print("Writing modified preferences to device") + interface.writeConfig() + + if args.seturl: + closeNow = True + interface.setURL(args.seturl) + + # handle changing channels + if args.setchan or args.setch_longslow or args.setch_shortfast \ + or args.seturl != None: + closeNow = True + + ch = interface.channels[channelIndex] + + def setSimpleChannel(modem_config): + """Set one of the simple modem_config only based channels""" + + # Completely new channel settings + chs = channel_pb2.ChannelSettings() + chs.modem_config = modem_config + chs.psk = bytes([1]) # Use default channel psk 1 + + ch.settings.CopyFrom(chs) # handle the simple channel set commands if args.setch_longslow: - setSimpleChannel(mesh_pb2.ChannelSettings.ModemConfig.Bw125Cr48Sf4096) + setSimpleChannel( + channel_pb2.ChannelSettings.ModemConfig.Bw125Cr48Sf4096) if args.setch_shortfast: - setSimpleChannel(mesh_pb2.ChannelSettings.ModemConfig.Bw500Cr45Sf128) + setSimpleChannel( + channel_pb2.ChannelSettings.ModemConfig.Bw500Cr45Sf128) # Handle the channel settings for pref in (args.setchan or []): - setPref(interface.radioConfig.channel_settings, - pref[0], pref[1]) + setPref(ch.settings, pref[0], pref[1]) - # Handle set URL - if args.seturl: - interface.setURL(args.seturl, False) - - print("Writing modified preferences to device") - interface.writeConfig() + print("Writing modified channels to device") + interface.writeChannel(channelIndex) if args.info: closeNow = True print(interface.myInfo) print(interface.radioConfig) - print(f"Channel URL {interface.channelURL}") + print("Channels:") + for c in interface.channels: + if c.role != channel_pb2.Channel.Role.DISABLED: + cStr = MessageToJson(c.settings).replace("\n", "") + print(f" {channel_pb2.Channel.Role.Name(c.role)} {cStr}") + print(f"\nChannel URL {interface.channelURL}") print("Nodes in mesh:") for n in interface.nodes.values(): - print(n) + print(stripnl(n)) + + if args.nodes: + closeNow = True + printNodes(interface.nodes.values()) if args.qr: closeNow = True @@ -279,11 +297,12 @@ def onConnected(interface): url = pyqrcode.create(interface.channelURL) print(url.terminal()) - if have_tunnel and args.tunnel : + if have_tunnel and args.tunnel: from . import tunnel - closeNow = False # Even if others said we could close, stay open if the user asked for a tunnel + # Even if others said we could close, stay open if the user asked for a tunnel + closeNow = False tunnel.Tunnel(interface, subnet=args.tunnel_net) - + except Exception as ex: print(ex) @@ -316,15 +335,18 @@ def common(): args.destOrAll = "^all" if not args.seriallog: - if args.info or args.set or args.seturl or args.setowner or args.setlat or args.setlon or \ + if args.info or args.nodes or args.set or args.seturl or args.setowner or args.setlat or args.setlon or \ args.settime or \ - args.setch_longslow or args.setch_shortfast or args.setstr or args.setchan or args.sendtext or \ - args.router != None or args.qr: + args.setch_longslow or args.setch_shortfast or args.setchan or args.sendtext or \ + args.qr: args.seriallog = "none" # assume no debug output in this case else: args.seriallog = "stdout" # default to stdout - if args.test: + if args.router != None: + logging.error( + '--set-router has been deprecated. Use "--set router true" or "--set router false" instead') + elif args.test: test.testAll() else: if args.seriallog == "stdout": @@ -347,6 +369,7 @@ def common(): client = SerialInterface( args.port, debugOut=logfile, noProto=args.noproto) + def initParser(): global parser, args @@ -367,14 +390,14 @@ def initParser(): parser.add_argument("--info", help="Read and display the radio config information", action="store_true") + parser.add_argument("--nodes", help="Print Node List in a pretty formatted table", + action="store_true") + parser.add_argument("--qr", help="Display the QR code that corresponds to the current channel", action="store_true") parser.add_argument( - "--set", help="Set a numeric preferences field", nargs=2, action='append') - - parser.add_argument( - "--setstr", help="Set a string preferences field", nargs=2, action='append') + "--set", help="Set a preferences field", nargs=2, action='append') parser.add_argument( "--setchan", help="Set a channel parameter", nargs=2, action='append') @@ -400,7 +423,7 @@ def initParser(): parser.add_argument( "--sendping", help="Send a ping message (which requests a reply)", action="store_true") - #parser.add_argument( + # parser.add_argument( # "--repeat", help="Normally the send commands send only one message, use this option to request repeated sends") parser.add_argument( @@ -441,27 +464,30 @@ def initParser(): action="store_true") parser.add_argument('--set-router', dest='router', - action='store_true', help="Turns on router mode") + action='store_true', help="Deprecated, use --set router true instead") parser.add_argument('--unset-router', dest='router', - action='store_false', help="Turns off router mode") + action='store_false', help="Deprecated, use --set router false instead") if have_tunnel: parser.add_argument('--tunnel', - action='store_true', help="Create a TUN tunnel device for forwarding IP packets over the mesh") + action='store_true', help="Create a TUN tunnel device for forwarding IP packets over the mesh") parser.add_argument( "--subnet", dest='tunnel_net', help="Read from a GPIO mask", default=None) parser.set_defaults(router=None) - parser.add_argument('--version', action='version', version=f"{pkg_resources.require('meshtastic')[0].version}") + parser.add_argument('--version', action='version', + version=f"{pkg_resources.require('meshtastic')[0].version}") args = parser.parse_args() + def main(): """Perform command line meshtastic operations""" initParser() common() + def tunnelMain(): """Run a meshtastic IP tunnel""" global args @@ -469,5 +495,6 @@ def tunnelMain(): args.tunnel = True common() + if __name__ == "__main__": main() diff --git a/meshtastic/admin_pb2.py b/meshtastic/admin_pb2.py new file mode 100644 index 0000000..fe6ca5c --- /dev/null +++ b/meshtastic/admin_pb2.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: admin.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from . import mesh_pb2 as mesh__pb2 +from . import radioconfig_pb2 as radioconfig__pb2 +from . import channel_pb2 as channel__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='admin.proto', + package='', + syntax='proto3', + serialized_options=b'\n\023com.geeksville.meshB\013AdminProtosH\003', + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x0b\x61\x64min.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\x1a\rchannel.proto\"\x8b\x02\n\x0c\x41\x64minMessage\x12!\n\tset_radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1a\n\tset_owner\x18\x02 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18\x03 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_radio_request\x18\x04 \x01(\x08H\x00\x12*\n\x12get_radio_response\x18\x05 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1d\n\x13get_channel_request\x18\x06 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x07 \x01(\x0b\x32\x08.ChannelH\x00\x42\t\n\x07variantB$\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03\x62\x06proto3' + , + dependencies=[mesh__pb2.DESCRIPTOR,radioconfig__pb2.DESCRIPTOR,channel__pb2.DESCRIPTOR,]) + + + + +_ADMINMESSAGE = _descriptor.Descriptor( + name='AdminMessage', + full_name='AdminMessage', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='set_radio', full_name='AdminMessage.set_radio', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='set_owner', full_name='AdminMessage.set_owner', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='set_channel', full_name='AdminMessage.set_channel', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='get_radio_request', full_name='AdminMessage.get_radio_request', index=3, + number=4, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='get_radio_response', full_name='AdminMessage.get_radio_response', index=4, + number=5, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='get_channel_request', full_name='AdminMessage.get_channel_request', index=5, + number=6, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='get_channel_response', full_name='AdminMessage.get_channel_response', index=6, + number=7, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + _descriptor.OneofDescriptor( + name='variant', full_name='AdminMessage.variant', + index=0, containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[]), + ], + serialized_start=62, + serialized_end=329, +) + +_ADMINMESSAGE.fields_by_name['set_radio'].message_type = radioconfig__pb2._RADIOCONFIG +_ADMINMESSAGE.fields_by_name['set_owner'].message_type = mesh__pb2._USER +_ADMINMESSAGE.fields_by_name['set_channel'].message_type = channel__pb2._CHANNEL +_ADMINMESSAGE.fields_by_name['get_radio_response'].message_type = radioconfig__pb2._RADIOCONFIG +_ADMINMESSAGE.fields_by_name['get_channel_response'].message_type = channel__pb2._CHANNEL +_ADMINMESSAGE.oneofs_by_name['variant'].fields.append( + _ADMINMESSAGE.fields_by_name['set_radio']) +_ADMINMESSAGE.fields_by_name['set_radio'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] +_ADMINMESSAGE.oneofs_by_name['variant'].fields.append( + _ADMINMESSAGE.fields_by_name['set_owner']) +_ADMINMESSAGE.fields_by_name['set_owner'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] +_ADMINMESSAGE.oneofs_by_name['variant'].fields.append( + _ADMINMESSAGE.fields_by_name['set_channel']) +_ADMINMESSAGE.fields_by_name['set_channel'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] +_ADMINMESSAGE.oneofs_by_name['variant'].fields.append( + _ADMINMESSAGE.fields_by_name['get_radio_request']) +_ADMINMESSAGE.fields_by_name['get_radio_request'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] +_ADMINMESSAGE.oneofs_by_name['variant'].fields.append( + _ADMINMESSAGE.fields_by_name['get_radio_response']) +_ADMINMESSAGE.fields_by_name['get_radio_response'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] +_ADMINMESSAGE.oneofs_by_name['variant'].fields.append( + _ADMINMESSAGE.fields_by_name['get_channel_request']) +_ADMINMESSAGE.fields_by_name['get_channel_request'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] +_ADMINMESSAGE.oneofs_by_name['variant'].fields.append( + _ADMINMESSAGE.fields_by_name['get_channel_response']) +_ADMINMESSAGE.fields_by_name['get_channel_response'].containing_oneof = _ADMINMESSAGE.oneofs_by_name['variant'] +DESCRIPTOR.message_types_by_name['AdminMessage'] = _ADMINMESSAGE +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +AdminMessage = _reflection.GeneratedProtocolMessageType('AdminMessage', (_message.Message,), { + 'DESCRIPTOR' : _ADMINMESSAGE, + '__module__' : 'admin_pb2' + # @@protoc_insertion_point(class_scope:AdminMessage) + }) +_sym_db.RegisterMessage(AdminMessage) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/apponly_pb2.py b/meshtastic/apponly_pb2.py index b61e850..b4a865f 100644 --- a/meshtastic/apponly_pb2.py +++ b/meshtastic/apponly_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: apponly.proto - +"""Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -12,16 +12,18 @@ _sym_db = _symbol_database.Default() from . import mesh_pb2 as mesh__pb2 +from . import channel_pb2 as channel__pb2 DESCRIPTOR = _descriptor.FileDescriptor( name='apponly.proto', package='', syntax='proto3', - serialized_options=b'\n\023com.geeksville.meshB\007AppOnlyH\003', - serialized_pb=b'\n\rapponly.proto\x1a\nmesh.proto\"V\n\x0fServiceEnvelope\x12\x1b\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\tB \n\x13\x63om.geeksville.meshB\x07\x41ppOnlyH\x03\x62\x06proto3' + serialized_options=b'\n\023com.geeksville.meshB\rAppOnlyProtosH\003', + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\rapponly.proto\x1a\nmesh.proto\x1a\rchannel.proto\"V\n\x0fServiceEnvelope\x12\x1b\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"0\n\nChannelSet\x12\"\n\x08settings\x18\x01 \x03(\x0b\x32\x10.ChannelSettingsB&\n\x13\x63om.geeksville.meshB\rAppOnlyProtosH\x03\x62\x06proto3' , - dependencies=[mesh__pb2.DESCRIPTOR,]) + dependencies=[mesh__pb2.DESCRIPTOR,channel__pb2.DESCRIPTOR,]) @@ -32,6 +34,7 @@ _SERVICEENVELOPE = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='packet', full_name='ServiceEnvelope.packet', index=0, @@ -39,21 +42,21 @@ _SERVICEENVELOPE = _descriptor.Descriptor( has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='channel_id', full_name='ServiceEnvelope.channel_id', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='gateway_id', full_name='ServiceEnvelope.gateway_id', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -66,12 +69,46 @@ _SERVICEENVELOPE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=29, - serialized_end=115, + serialized_start=44, + serialized_end=130, +) + + +_CHANNELSET = _descriptor.Descriptor( + name='ChannelSet', + full_name='ChannelSet', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='settings', full_name='ChannelSet.settings', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=132, + serialized_end=180, ) _SERVICEENVELOPE.fields_by_name['packet'].message_type = mesh__pb2._MESHPACKET +_CHANNELSET.fields_by_name['settings'].message_type = channel__pb2._CHANNELSETTINGS DESCRIPTOR.message_types_by_name['ServiceEnvelope'] = _SERVICEENVELOPE +DESCRIPTOR.message_types_by_name['ChannelSet'] = _CHANNELSET _sym_db.RegisterFileDescriptor(DESCRIPTOR) ServiceEnvelope = _reflection.GeneratedProtocolMessageType('ServiceEnvelope', (_message.Message,), { @@ -81,6 +118,13 @@ ServiceEnvelope = _reflection.GeneratedProtocolMessageType('ServiceEnvelope', (_ }) _sym_db.RegisterMessage(ServiceEnvelope) +ChannelSet = _reflection.GeneratedProtocolMessageType('ChannelSet', (_message.Message,), { + 'DESCRIPTOR' : _CHANNELSET, + '__module__' : 'apponly_pb2' + # @@protoc_insertion_point(class_scope:ChannelSet) + }) +_sym_db.RegisterMessage(ChannelSet) + DESCRIPTOR._options = None # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/channel_pb2.py b/meshtastic/channel_pb2.py new file mode 100644 index 0000000..2b1d8a6 --- /dev/null +++ b/meshtastic/channel_pb2.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: channel.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='channel.proto', + package='', + syntax='proto3', + serialized_options=b'\n\023com.geeksville.meshB\rChannelProtosH\003', + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\rchannel.proto\"\xe6\x02\n\x0f\x43hannelSettings\x12\x10\n\x08tx_power\x18\x01 \x01(\x05\x12\x32\n\x0cmodem_config\x18\x03 \x01(\x0e\x32\x1c.ChannelSettings.ModemConfig\x12\x11\n\tbandwidth\x18\x06 \x01(\r\x12\x15\n\rspread_factor\x18\x07 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x08 \x01(\r\x12\x13\n\x0b\x63hannel_num\x18\t \x01(\r\x12\x0b\n\x03psk\x18\x04 \x01(\x0c\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\n\n\x02id\x18\n \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x10 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x11 \x01(\x08\"`\n\x0bModemConfig\x12\x12\n\x0e\x42w125Cr45Sf128\x10\x00\x12\x12\n\x0e\x42w500Cr45Sf128\x10\x01\x12\x14\n\x10\x42w31_25Cr48Sf512\x10\x02\x12\x13\n\x0f\x42w125Cr48Sf4096\x10\x03\"\x8b\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\r\x12\"\n\x08settings\x18\x02 \x01(\x0b\x32\x10.ChannelSettings\x12\x1b\n\x04role\x18\x03 \x01(\x0e\x32\r.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42&\n\x13\x63om.geeksville.meshB\rChannelProtosH\x03\x62\x06proto3' +) + + + +_CHANNELSETTINGS_MODEMCONFIG = _descriptor.EnumDescriptor( + name='ModemConfig', + full_name='ChannelSettings.ModemConfig', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='Bw125Cr45Sf128', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='Bw500Cr45Sf128', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='Bw31_25Cr48Sf512', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='Bw125Cr48Sf4096', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=280, + serialized_end=376, +) +_sym_db.RegisterEnumDescriptor(_CHANNELSETTINGS_MODEMCONFIG) + +_CHANNEL_ROLE = _descriptor.EnumDescriptor( + name='Role', + full_name='Channel.Role', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='DISABLED', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PRIMARY', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='SECONDARY', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=470, + serialized_end=518, +) +_sym_db.RegisterEnumDescriptor(_CHANNEL_ROLE) + + +_CHANNELSETTINGS = _descriptor.Descriptor( + name='ChannelSettings', + full_name='ChannelSettings', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='tx_power', full_name='ChannelSettings.tx_power', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='modem_config', full_name='ChannelSettings.modem_config', index=1, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='bandwidth', full_name='ChannelSettings.bandwidth', index=2, + number=6, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='spread_factor', full_name='ChannelSettings.spread_factor', index=3, + number=7, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='coding_rate', full_name='ChannelSettings.coding_rate', index=4, + number=8, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='channel_num', full_name='ChannelSettings.channel_num', index=5, + number=9, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='psk', full_name='ChannelSettings.psk', index=6, + number=4, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='name', full_name='ChannelSettings.name', index=7, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='id', full_name='ChannelSettings.id', index=8, + number=10, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uplink_enabled', full_name='ChannelSettings.uplink_enabled', index=9, + number=16, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='downlink_enabled', full_name='ChannelSettings.downlink_enabled', index=10, + number=17, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _CHANNELSETTINGS_MODEMCONFIG, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=18, + serialized_end=376, +) + + +_CHANNEL = _descriptor.Descriptor( + name='Channel', + full_name='Channel', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='index', full_name='Channel.index', index=0, + number=1, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='settings', full_name='Channel.settings', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='role', full_name='Channel.role', index=2, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _CHANNEL_ROLE, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=379, + serialized_end=518, +) + +_CHANNELSETTINGS.fields_by_name['modem_config'].enum_type = _CHANNELSETTINGS_MODEMCONFIG +_CHANNELSETTINGS_MODEMCONFIG.containing_type = _CHANNELSETTINGS +_CHANNEL.fields_by_name['settings'].message_type = _CHANNELSETTINGS +_CHANNEL.fields_by_name['role'].enum_type = _CHANNEL_ROLE +_CHANNEL_ROLE.containing_type = _CHANNEL +DESCRIPTOR.message_types_by_name['ChannelSettings'] = _CHANNELSETTINGS +DESCRIPTOR.message_types_by_name['Channel'] = _CHANNEL +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +ChannelSettings = _reflection.GeneratedProtocolMessageType('ChannelSettings', (_message.Message,), { + 'DESCRIPTOR' : _CHANNELSETTINGS, + '__module__' : 'channel_pb2' + # @@protoc_insertion_point(class_scope:ChannelSettings) + }) +_sym_db.RegisterMessage(ChannelSettings) + +Channel = _reflection.GeneratedProtocolMessageType('Channel', (_message.Message,), { + 'DESCRIPTOR' : _CHANNEL, + '__module__' : 'channel_pb2' + # @@protoc_insertion_point(class_scope:Channel) + }) +_sym_db.RegisterMessage(Channel) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/deviceonly_pb2.py b/meshtastic/deviceonly_pb2.py index e1f110a..d5c34ec 100644 --- a/meshtastic/deviceonly_pb2.py +++ b/meshtastic/deviceonly_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: deviceonly.proto - +"""Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -12,6 +12,8 @@ _sym_db = _symbol_database.Default() from . import mesh_pb2 as mesh__pb2 +from . import radioconfig_pb2 as radioconfig__pb2 +from . import channel_pb2 as channel__pb2 DESCRIPTOR = _descriptor.FileDescriptor( @@ -19,9 +21,10 @@ DESCRIPTOR = _descriptor.FileDescriptor( package='', syntax='proto3', serialized_options=b'\n\023com.geeksville.meshB\nDeviceOnlyH\003', - serialized_pb=b'\n\x10\x64\x65viceonly.proto\x1a\nmesh.proto\"\xab\x02\n\x0b\x44\x65viceState\x12\x1b\n\x05radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfig\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\x1a\n\x07node_db\x18\x04 \x03(\x0b\x32\t.NodeInfo\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07no_save\x18\t \x01(\x08\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\x12,\n\x12secondary_channels\x18\x0c \x03(\x0b\x32\x10.ChannelSettingsB#\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03\x62\x06proto3' + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x10\x64\x65viceonly.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\x1a\rchannel.proto\"\x9f\x02\n\x0b\x44\x65viceState\x12\x1b\n\x05radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfig\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\x1a\n\x07node_db\x18\x04 \x03(\x0b\x32\t.NodeInfo\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07no_save\x18\t \x01(\x08\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\x12\x1a\n\x08\x63hannels\x18\r \x03(\x0b\x32\x08.ChannelJ\x04\x08\x0c\x10\rB#\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03\x62\x06proto3' , - dependencies=[mesh__pb2.DESCRIPTOR,]) + dependencies=[mesh__pb2.DESCRIPTOR,radioconfig__pb2.DESCRIPTOR,channel__pb2.DESCRIPTOR,]) @@ -32,6 +35,7 @@ _DEVICESTATE = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='radio', full_name='DeviceState.radio', index=0, @@ -39,70 +43,70 @@ _DEVICESTATE = _descriptor.Descriptor( has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='my_node', full_name='DeviceState.my_node', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='owner', full_name='DeviceState.owner', index=2, number=3, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='node_db', full_name='DeviceState.node_db', index=3, number=4, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='receive_queue', full_name='DeviceState.receive_queue', index=4, number=5, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='version', full_name='DeviceState.version', index=5, number=8, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='rx_text_message', full_name='DeviceState.rx_text_message', index=6, number=7, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='no_save', full_name='DeviceState.no_save', index=7, number=9, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='did_gps_reset', full_name='DeviceState.did_gps_reset', index=8, number=11, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='secondary_channels', full_name='DeviceState.secondary_channels', index=9, - number=12, type=11, cpp_type=10, label=3, + name='channels', full_name='DeviceState.channels', index=9, + number=13, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -115,17 +119,17 @@ _DEVICESTATE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=33, - serialized_end=332, + serialized_start=67, + serialized_end=354, ) -_DEVICESTATE.fields_by_name['radio'].message_type = mesh__pb2._RADIOCONFIG +_DEVICESTATE.fields_by_name['radio'].message_type = radioconfig__pb2._RADIOCONFIG _DEVICESTATE.fields_by_name['my_node'].message_type = mesh__pb2._MYNODEINFO _DEVICESTATE.fields_by_name['owner'].message_type = mesh__pb2._USER _DEVICESTATE.fields_by_name['node_db'].message_type = mesh__pb2._NODEINFO _DEVICESTATE.fields_by_name['receive_queue'].message_type = mesh__pb2._MESHPACKET _DEVICESTATE.fields_by_name['rx_text_message'].message_type = mesh__pb2._MESHPACKET -_DEVICESTATE.fields_by_name['secondary_channels'].message_type = mesh__pb2._CHANNELSETTINGS +_DEVICESTATE.fields_by_name['channels'].message_type = channel__pb2._CHANNEL DESCRIPTOR.message_types_by_name['DeviceState'] = _DEVICESTATE _sym_db.RegisterFileDescriptor(DESCRIPTOR) diff --git a/meshtastic/environmental_measurement_pb2.py b/meshtastic/environmental_measurement_pb2.py new file mode 100644 index 0000000..b502db8 --- /dev/null +++ b/meshtastic/environmental_measurement_pb2.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: environmental_measurement.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='environmental_measurement.proto', + package='', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x1f\x65nvironmental_measurement.proto\"g\n\x18\x45nvironmentalMeasurement\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x62\x06proto3' +) + + + + +_ENVIRONMENTALMEASUREMENT = _descriptor.Descriptor( + name='EnvironmentalMeasurement', + full_name='EnvironmentalMeasurement', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='temperature', full_name='EnvironmentalMeasurement.temperature', index=0, + number=1, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='relative_humidity', full_name='EnvironmentalMeasurement.relative_humidity', index=1, + number=2, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='barometric_pressure', full_name='EnvironmentalMeasurement.barometric_pressure', index=2, + number=3, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=35, + serialized_end=138, +) + +DESCRIPTOR.message_types_by_name['EnvironmentalMeasurement'] = _ENVIRONMENTALMEASUREMENT +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +EnvironmentalMeasurement = _reflection.GeneratedProtocolMessageType('EnvironmentalMeasurement', (_message.Message,), { + 'DESCRIPTOR' : _ENVIRONMENTALMEASUREMENT, + '__module__' : 'environmental_measurement_pb2' + # @@protoc_insertion_point(class_scope:EnvironmentalMeasurement) + }) +_sym_db.RegisterMessage(EnvironmentalMeasurement) + + +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/mesh_pb2.py b/meshtastic/mesh_pb2.py index 8a9b0c2..488f536 100644 --- a/meshtastic/mesh_pb2.py +++ b/meshtastic/mesh_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: mesh.proto - +"""Generated protocol buffer code.""" from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message @@ -20,361 +20,100 @@ DESCRIPTOR = _descriptor.FileDescriptor( package='', syntax='proto3', serialized_options=b'\n\023com.geeksville.meshB\nMeshProtosH\003', - serialized_pb=b'\n\nmesh.proto\x1a\x0eportnums.proto\"j\n\x08Position\x12\x12\n\nlatitude_i\x18\x07 \x01(\x11\x12\x13\n\x0blongitude_i\x18\x08 \x01(\x11\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x15\n\rbattery_level\x18\x04 \x01(\x05\x12\x0c\n\x04time\x18\t \x01(\x07\"2\n\x04\x44\x61ta\x12\x19\n\x07portnum\x18\x01 \x01(\x0e\x32\x08.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"J\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x0f\n\x07macaddr\x18\x04 \x01(\x0c\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x02 \x03(\x05\"\xeb\x02\n\tSubPacket\x12\x15\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x05.DataH\x00\x12(\n\rroute_request\x18\x06 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0broute_reply\x18\x07 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12$\n\x0c\x65rror_reason\x18\r \x01(\x0e\x32\x0c.ErrorReasonH\x00\x12!\n\x08position\x18\x01 \x01(\x0b\x32\t.PositionB\x02\x18\x01H\x00\x12\x19\n\x04user\x18\x04 \x01(\x0b\x32\x05.UserB\x02\x18\x01H\x00\x12\x15\n\rwant_response\x18\x05 \x01(\x08\x12\x14\n\nsuccess_id\x18\n \x01(\rH\x01\x12\x11\n\x07\x66\x61il_id\x18\x0b \x01(\rH\x01\x12\x0c\n\x04\x64\x65st\x18\t \x01(\r\x12\x0e\n\x06source\x18\x0c \x01(\r\x12\x13\n\x0boriginal_id\x18\x02 \x01(\rB\x10\n\x0epayloadVariantB\x0c\n\nackVariant\"\xd5\x01\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\r\x12\n\n\x02to\x18\x02 \x01(\r\x12\x15\n\rchannel_index\x18\x04 \x01(\r\x12\x1d\n\x07\x64\x65\x63oded\x18\x03 \x01(\x0b\x32\n.SubPacketH\x00\x12\x13\n\tencrypted\x18\x08 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\r\x12\x0f\n\x07rx_time\x18\t \x01(\x07\x12\x0e\n\x06rx_snr\x18\x07 \x01(\x02\x12\x11\n\thop_limit\x18\n \x01(\r\x12\x10\n\x08want_ack\x18\x0b \x01(\x08\x42\x10\n\x0epayloadVariant\"\xe6\x02\n\x0f\x43hannelSettings\x12\x10\n\x08tx_power\x18\x01 \x01(\x05\x12\x32\n\x0cmodem_config\x18\x03 \x01(\x0e\x32\x1c.ChannelSettings.ModemConfig\x12\x11\n\tbandwidth\x18\x06 \x01(\r\x12\x15\n\rspread_factor\x18\x07 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x08 \x01(\r\x12\x13\n\x0b\x63hannel_num\x18\t \x01(\r\x12\x0b\n\x03psk\x18\x04 \x01(\x0c\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\n\n\x02id\x18\n \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x10 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x11 \x01(\x08\"`\n\x0bModemConfig\x12\x12\n\x0e\x42w125Cr45Sf128\x10\x00\x12\x12\n\x0e\x42w500Cr45Sf128\x10\x01\x12\x14\n\x10\x42w31_25Cr48Sf512\x10\x02\x12\x13\n\x0f\x42w125Cr48Sf4096\x10\x03\"\x82\x0b\n\x0bRadioConfig\x12\x31\n\x0bpreferences\x18\x01 \x01(\x0b\x32\x1c.RadioConfig.UserPreferences\x12.\n\x10\x63hannel_settings\x18\x02 \x01(\x0b\x32\x10.ChannelSettingsB\x02\x18\x01\x1a\x8f\n\n\x0fUserPreferences\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12\x1b\n\x13send_owner_interval\x18\x02 \x01(\r\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x16\n\x0escreen_on_secs\x18\x05 \x01(\r\x12\x1a\n\x12phone_timeout_secs\x18\x06 \x01(\r\x12\x1d\n\x15phone_sds_timeout_sec\x18\x07 \x01(\r\x12\x1d\n\x15mesh_sds_timeout_secs\x18\x08 \x01(\r\x12\x10\n\x08sds_secs\x18\t \x01(\r\x12\x0f\n\x07ls_secs\x18\n \x01(\r\x12\x15\n\rmin_wake_secs\x18\x0b \x01(\r\x12\x11\n\twifi_ssid\x18\x0c \x01(\t\x12\x15\n\rwifi_password\x18\r \x01(\t\x12\x14\n\x0cwifi_ap_mode\x18\x0e \x01(\x08\x12\x1b\n\x06region\x18\x0f \x01(\x0e\x32\x0b.RegionCode\x12&\n\x0e\x63harge_current\x18\x10 \x01(\x0e\x32\x0e.ChargeCurrent\x12\x11\n\tis_router\x18% \x01(\x08\x12\x14\n\x0cis_low_power\x18& \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\' \x01(\x08\x12\x15\n\rfactory_reset\x18\x64 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x65 \x01(\x08\x12(\n\x0elocation_share\x18 \x01(\x0e\x32\x10.LocationSharing\x12$\n\rgps_operation\x18! \x01(\x0e\x32\r.GpsOperation\x12\x1b\n\x13gps_update_interval\x18\" \x01(\r\x12\x18\n\x10gps_attempt_time\x18$ \x01(\r\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x1c\n\x14serialplugin_enabled\x18x \x01(\x08\x12\x19\n\x11serialplugin_echo\x18y \x01(\x08\x12\x18\n\x10serialplugin_rxd\x18z \x01(\r\x12\x18\n\x10serialplugin_txd\x18{ \x01(\r\x12\x1c\n\x14serialplugin_timeout\x18| \x01(\r\x12\x19\n\x11serialplugin_mode\x18} \x01(\r\x12\'\n\x1f\x65xt_notification_plugin_enabled\x18~ \x01(\x08\x12)\n!ext_notification_plugin_output_ms\x18\x7f \x01(\r\x12\'\n\x1e\x65xt_notification_plugin_output\x18\x80\x01 \x01(\r\x12\'\n\x1e\x65xt_notification_plugin_active\x18\x81\x01 \x01(\x08\x12.\n%ext_notification_plugin_alert_message\x18\x82\x01 \x01(\x08\x12+\n\"ext_notification_plugin_alert_bell\x18\x83\x01 \x01(\x08\x12\"\n\x19range_test_plugin_enabled\x18\x84\x01 \x01(\x08\x12!\n\x18range_test_plugin_sender\x18\x85\x01 \x01(\r\x12\x1f\n\x16range_test_plugin_save\x18\x86\x01 \x01(\x08\x12%\n\x1cstore_forward_plugin_enabled\x18\x88\x01 \x01(\x08\x12%\n\x1cstore_forward_plugin_records\x18\x89\x01 \x01(\r\"h\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1b\n\x08position\x18\x03 \x01(\x0b\x32\t.Position\x12\x0b\n\x03snr\x18\x07 \x01(\x02\x12\x10\n\x08next_hop\x18\x05 \x01(\r\"\xd9\x02\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x0f\n\x07has_gps\x18\x02 \x01(\x08\x12\x14\n\x0cnum_channels\x18\x03 \x01(\x05\x12\x0e\n\x06region\x18\x04 \x01(\t\x12\x10\n\x08hw_model\x18\x05 \x01(\t\x12\x18\n\x10\x66irmware_version\x18\x06 \x01(\t\x12&\n\nerror_code\x18\x07 \x01(\x0e\x32\x12.CriticalErrorCode\x12\x15\n\rerror_address\x18\x08 \x01(\r\x12\x13\n\x0b\x65rror_count\x18\t \x01(\r\x12\x16\n\x0epacket_id_bits\x18\n \x01(\r\x12\x19\n\x11\x63urrent_packet_id\x18\x0b \x01(\r\x12\x15\n\rnode_num_bits\x18\x0c \x01(\r\x12\x1c\n\x14message_timeout_msec\x18\r \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0e \x01(\r\"\xb5\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x1f\n\x05level\x18\x04 \x01(\x0e\x32\x10.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"\xa1\x02\n\tFromRadio\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1d\n\x06packet\x18\x02 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x1e\n\x07my_info\x18\x03 \x01(\x0b\x32\x0b.MyNodeInfoH\x00\x12\x1e\n\tnode_info\x18\x04 \x01(\x0b\x32\t.NodeInfoH\x00\x12\x1d\n\x05radio\x18\x06 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12 \n\nlog_record\x18\x07 \x01(\x0b\x32\n.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x08 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\t \x01(\x08H\x00\x12#\n\x07\x63hannel\x18\n \x01(\x0b\x32\x10.ChannelSettingsH\x00\x42\x10\n\x0epayloadVariant\"\xbc\x01\n\x07ToRadio\x12\x1d\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x64 \x01(\rH\x00\x12!\n\tset_radio\x18\x65 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1a\n\tset_owner\x18\x66 \x01(\x0b\x32\x05.UserH\x00\x12\'\n\x0bset_channel\x18g \x01(\x0b\x32\x10.ChannelSettingsH\x00\x42\x10\n\x0epayloadVariant*e\n\x0b\x45rrorReason\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05*.\n\tConstants\x12\n\n\x06Unused\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xf0\x01*^\n\nRegionCode\x12\t\n\x05Unset\x10\x00\x12\x06\n\x02US\x10\x01\x12\t\n\x05\x45U433\x10\x02\x12\t\n\x05\x45U865\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08*\xd1\x01\n\rChargeCurrent\x12\x0b\n\x07MAUnset\x10\x00\x12\t\n\x05MA100\x10\x01\x12\t\n\x05MA190\x10\x02\x12\t\n\x05MA280\x10\x03\x12\t\n\x05MA360\x10\x04\x12\t\n\x05MA450\x10\x05\x12\t\n\x05MA550\x10\x06\x12\t\n\x05MA630\x10\x07\x12\t\n\x05MA700\x10\x08\x12\t\n\x05MA780\x10\t\x12\t\n\x05MA880\x10\n\x12\t\n\x05MA960\x10\x0b\x12\n\n\x06MA1000\x10\x0c\x12\n\n\x06MA1080\x10\r\x12\n\n\x06MA1160\x10\x0e\x12\n\n\x06MA1240\x10\x0f\x12\n\n\x06MA1320\x10\x10*j\n\x0cGpsOperation\x12\x0e\n\nGpsOpUnset\x10\x00\x12\x13\n\x0fGpsOpStationary\x10\x01\x12\x0f\n\x0bGpsOpMobile\x10\x02\x12\x11\n\rGpsOpTimeOnly\x10\x03\x12\x11\n\rGpsOpDisabled\x10\x04*@\n\x0fLocationSharing\x12\x0c\n\x08LocUnset\x10\x00\x12\x0e\n\nLocEnabled\x10\x01\x12\x0f\n\x0bLocDisabled\x10\x02*\xaf\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04None\x10\x00\x12\x0e\n\nTxWatchdog\x10\x01\x12\x12\n\x0eSleepEnterWait\x10\x02\x12\x0b\n\x07NoRadio\x10\x03\x12\x0f\n\x0bUnspecified\x10\x04\x12\x13\n\x0fUBloxInitFailed\x10\x05\x12\x0c\n\x08NoAXP192\x10\x06\x12\x17\n\x13InvalidRadioSetting\x10\x07\x12\x12\n\x0eTransmitFailed\x10\x08\x42#\n\x13\x63om.geeksville.meshB\nMeshProtosH\x03\x62\x06proto3' + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\nmesh.proto\x1a\x0eportnums.proto\"v\n\x08Position\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\x15\n\rbattery_level\x18\x04 \x01(\x05\x12\x0c\n\x04time\x18\t \x01(\x07J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\t\"J\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x0f\n\x07macaddr\x18\x04 \x01(\x0c\"\x1f\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x02 \x03(\x07\"\x8e\x02\n\x07Routing\x12(\n\rroute_request\x18\x01 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0broute_reply\x18\x02 \x01(\x0b\x32\x0f.RouteDiscoveryH\x00\x12&\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\x0e.Routing.ErrorH\x00\"~\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x42\t\n\x07variant\"{\n\x04\x44\x61ta\x12\x19\n\x07portnum\x18\x01 \x01(\x0e\x32\x08.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\"\xcf\x02\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12\x18\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x05.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\n \x01(\r\x12\x10\n\x08want_ack\x18\x0b \x01(\x08\x12&\n\x08priority\x18\x0c \x01(\x0e\x32\x14.MeshPacket.Priority\"[\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\x42\x10\n\x0epayloadVariant\"h\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1b\n\x08position\x18\x03 \x01(\x0b\x32\t.Position\x12\x0b\n\x03snr\x18\x07 \x01(\x02\x12\x10\n\x08next_hop\x18\x05 \x01(\r\"\xa6\x02\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x0f\n\x07has_gps\x18\x02 \x01(\x08\x12\x11\n\tnum_bands\x18\x03 \x01(\r\x12\x14\n\x0cmax_channels\x18\x0f \x01(\r\x12\x12\n\x06region\x18\x04 \x01(\tB\x02\x18\x01\x12\x10\n\x08hw_model\x18\x05 \x01(\t\x12\x18\n\x10\x66irmware_version\x18\x06 \x01(\t\x12&\n\nerror_code\x18\x07 \x01(\x0e\x32\x12.CriticalErrorCode\x12\x15\n\rerror_address\x18\x08 \x01(\r\x12\x13\n\x0b\x65rror_count\x18\t \x01(\r\x12\x1c\n\x14message_timeout_msec\x18\r \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0e \x01(\r\"\xb5\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x1f\n\x05level\x18\x04 \x01(\x0e\x32\x10.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"\xe9\x01\n\tFromRadio\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x1d\n\x06packet\x18\x0b \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x1e\n\x07my_info\x18\x03 \x01(\x0b\x32\x0b.MyNodeInfoH\x00\x12\x1e\n\tnode_info\x18\x04 \x01(\x0b\x32\t.NodeInfoH\x00\x12 \n\nlog_record\x18\x07 \x01(\x0b\x32\n.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x08 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\t \x01(\x08H\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x02\x10\x03J\x04\x08\x06\x10\x07\"l\n\x07ToRadio\x12\x1d\n\x06packet\x18\x02 \x01(\x0b\x32\x0b.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x64 \x01(\rH\x00\x42\x10\n\x0epayloadVariantJ\x04\x08\x01\x10\x02J\x04\x08\x65\x10\x66J\x04\x08\x66\x10gJ\x04\x08g\x10h*.\n\tConstants\x12\n\n\x06Unused\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xf0\x01*\xaf\x01\n\x11\x43riticalErrorCode\x12\x08\n\x04None\x10\x00\x12\x0e\n\nTxWatchdog\x10\x01\x12\x12\n\x0eSleepEnterWait\x10\x02\x12\x0b\n\x07NoRadio\x10\x03\x12\x0f\n\x0bUnspecified\x10\x04\x12\x13\n\x0fUBloxInitFailed\x10\x05\x12\x0c\n\x08NoAXP192\x10\x06\x12\x17\n\x13InvalidRadioSetting\x10\x07\x12\x12\n\x0eTransmitFailed\x10\x08\x42#\n\x13\x63om.geeksville.meshB\nMeshProtosH\x03\x62\x06proto3' , dependencies=[portnums__pb2.DESCRIPTOR,]) -_ERRORREASON = _descriptor.EnumDescriptor( - name='ErrorReason', - full_name='ErrorReason', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='NONE', index=0, number=0, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NO_ROUTE', index=1, number=1, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='GOT_NAK', index=2, number=2, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='TIMEOUT', index=3, number=3, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='NO_INTERFACE', index=4, number=4, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MAX_RETRANSMIT', index=5, number=5, - serialized_options=None, - type=None), - ], - containing_type=None, - serialized_options=None, - serialized_start=3776, - serialized_end=3877, -) -_sym_db.RegisterEnumDescriptor(_ERRORREASON) - -ErrorReason = enum_type_wrapper.EnumTypeWrapper(_ERRORREASON) _CONSTANTS = _descriptor.EnumDescriptor( name='Constants', full_name='Constants', filename=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, values=[ _descriptor.EnumValueDescriptor( name='Unused', index=0, number=0, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='DATA_PAYLOAD_LEN', index=1, number=240, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), ], containing_type=None, serialized_options=None, - serialized_start=3879, - serialized_end=3925, + serialized_start=1928, + serialized_end=1974, ) _sym_db.RegisterEnumDescriptor(_CONSTANTS) Constants = enum_type_wrapper.EnumTypeWrapper(_CONSTANTS) -_REGIONCODE = _descriptor.EnumDescriptor( - name='RegionCode', - full_name='RegionCode', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='Unset', index=0, number=0, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='US', index=1, number=1, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='EU433', index=2, number=2, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='EU865', index=3, number=3, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='CN', index=4, number=4, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='JP', index=5, number=5, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ANZ', index=6, number=6, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='KR', index=7, number=7, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='TW', index=8, number=8, - serialized_options=None, - type=None), - ], - containing_type=None, - serialized_options=None, - serialized_start=3927, - serialized_end=4021, -) -_sym_db.RegisterEnumDescriptor(_REGIONCODE) - -RegionCode = enum_type_wrapper.EnumTypeWrapper(_REGIONCODE) -_CHARGECURRENT = _descriptor.EnumDescriptor( - name='ChargeCurrent', - full_name='ChargeCurrent', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='MAUnset', index=0, number=0, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA100', index=1, number=1, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA190', index=2, number=2, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA280', index=3, number=3, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA360', index=4, number=4, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA450', index=5, number=5, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA550', index=6, number=6, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA630', index=7, number=7, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA700', index=8, number=8, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA780', index=9, number=9, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA880', index=10, number=10, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA960', index=11, number=11, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA1000', index=12, number=12, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA1080', index=13, number=13, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA1160', index=14, number=14, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA1240', index=15, number=15, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='MA1320', index=16, number=16, - serialized_options=None, - type=None), - ], - containing_type=None, - serialized_options=None, - serialized_start=4024, - serialized_end=4233, -) -_sym_db.RegisterEnumDescriptor(_CHARGECURRENT) - -ChargeCurrent = enum_type_wrapper.EnumTypeWrapper(_CHARGECURRENT) -_GPSOPERATION = _descriptor.EnumDescriptor( - name='GpsOperation', - full_name='GpsOperation', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='GpsOpUnset', index=0, number=0, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='GpsOpStationary', index=1, number=1, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='GpsOpMobile', index=2, number=2, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='GpsOpTimeOnly', index=3, number=3, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='GpsOpDisabled', index=4, number=4, - serialized_options=None, - type=None), - ], - containing_type=None, - serialized_options=None, - serialized_start=4235, - serialized_end=4341, -) -_sym_db.RegisterEnumDescriptor(_GPSOPERATION) - -GpsOperation = enum_type_wrapper.EnumTypeWrapper(_GPSOPERATION) -_LOCATIONSHARING = _descriptor.EnumDescriptor( - name='LocationSharing', - full_name='LocationSharing', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='LocUnset', index=0, number=0, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='LocEnabled', index=1, number=1, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='LocDisabled', index=2, number=2, - serialized_options=None, - type=None), - ], - containing_type=None, - serialized_options=None, - serialized_start=4343, - serialized_end=4407, -) -_sym_db.RegisterEnumDescriptor(_LOCATIONSHARING) - -LocationSharing = enum_type_wrapper.EnumTypeWrapper(_LOCATIONSHARING) _CRITICALERRORCODE = _descriptor.EnumDescriptor( name='CriticalErrorCode', full_name='CriticalErrorCode', filename=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, values=[ _descriptor.EnumValueDescriptor( name='None', index=0, number=0, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='TxWatchdog', index=1, number=1, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='SleepEnterWait', index=2, number=2, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='NoRadio', index=3, number=3, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='Unspecified', index=4, number=4, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='UBloxInitFailed', index=5, number=5, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='NoAXP192', index=6, number=6, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='InvalidRadioSetting', index=7, number=7, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='TransmitFailed', index=8, number=8, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), ], containing_type=None, serialized_options=None, - serialized_start=4410, - serialized_end=4585, + serialized_start=1977, + serialized_end=2152, ) _sym_db.RegisterEnumDescriptor(_CRITICALERRORCODE) CriticalErrorCode = enum_type_wrapper.EnumTypeWrapper(_CRITICALERRORCODE) -NONE = 0 -NO_ROUTE = 1 -GOT_NAK = 2 -TIMEOUT = 3 -NO_INTERFACE = 4 -MAX_RETRANSMIT = 5 Unused = 0 DATA_PAYLOAD_LEN = 240 -Unset = 0 -US = 1 -EU433 = 2 -EU865 = 3 -CN = 4 -JP = 5 -ANZ = 6 -KR = 7 -TW = 8 -MAUnset = 0 -MA100 = 1 -MA190 = 2 -MA280 = 3 -MA360 = 4 -MA450 = 5 -MA550 = 6 -MA630 = 7 -MA700 = 8 -MA780 = 9 -MA880 = 10 -MA960 = 11 -MA1000 = 12 -MA1080 = 13 -MA1160 = 14 -MA1240 = 15 -MA1320 = 16 -GpsOpUnset = 0 -GpsOpStationary = 1 -GpsOpMobile = 2 -GpsOpTimeOnly = 3 -GpsOpDisabled = 4 -LocUnset = 0 -LocEnabled = 1 -LocDisabled = 2 globals()['None'] = 0 TxWatchdog = 1 SleepEnterWait = 2 @@ -386,75 +125,158 @@ InvalidRadioSetting = 7 TransmitFailed = 8 -_CHANNELSETTINGS_MODEMCONFIG = _descriptor.EnumDescriptor( - name='ModemConfig', - full_name='ChannelSettings.ModemConfig', +_ROUTING_ERROR = _descriptor.EnumDescriptor( + name='Error', + full_name='Routing.Error', filename=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, values=[ _descriptor.EnumValueDescriptor( - name='Bw125Cr45Sf128', index=0, number=0, + name='NONE', index=0, number=0, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='Bw500Cr45Sf128', index=1, number=1, + name='NO_ROUTE', index=1, number=1, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='Bw31_25Cr48Sf512', index=2, number=2, + name='GOT_NAK', index=2, number=2, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='Bw125Cr48Sf4096', index=3, number=3, + name='TIMEOUT', index=3, number=3, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='NO_INTERFACE', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MAX_RETRANSMIT', index=5, number=5, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='NO_CHANNEL', index=6, number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TOO_LARGE', index=7, number=7, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), ], containing_type=None, serialized_options=None, - serialized_start=1144, - serialized_end=1240, + serialized_start=393, + serialized_end=519, ) -_sym_db.RegisterEnumDescriptor(_CHANNELSETTINGS_MODEMCONFIG) +_sym_db.RegisterEnumDescriptor(_ROUTING_ERROR) + +_MESHPACKET_PRIORITY = _descriptor.EnumDescriptor( + name='Priority', + full_name='MeshPacket.Priority', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='UNSET', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MIN', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='BACKGROUND', index=2, number=10, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='DEFAULT', index=3, number=64, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RELIABLE', index=4, number=70, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ACK', index=5, number=120, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MAX', index=6, number=127, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=884, + serialized_end=975, +) +_sym_db.RegisterEnumDescriptor(_MESHPACKET_PRIORITY) _LOGRECORD_LEVEL = _descriptor.EnumDescriptor( name='Level', full_name='LogRecord.Level', filename=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, values=[ _descriptor.EnumValueDescriptor( name='UNSET', index=0, number=0, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='CRITICAL', index=1, number=50, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='ERROR', index=2, number=40, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='WARNING', index=3, number=30, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='INFO', index=4, number=20, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='DEBUG', index=5, number=10, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='TRACE', index=6, number=5, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), ], containing_type=None, serialized_options=None, - serialized_start=3203, - serialized_end=3291, + serialized_start=1492, + serialized_end=1580, ) _sym_db.RegisterEnumDescriptor(_LOGRECORD_LEVEL) @@ -465,42 +287,43 @@ _POSITION = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='latitude_i', full_name='Position.latitude_i', index=0, - number=7, type=17, cpp_type=1, label=1, + number=1, type=15, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='longitude_i', full_name='Position.longitude_i', index=1, - number=8, type=17, cpp_type=1, label=1, + number=2, type=15, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='altitude', full_name='Position.altitude', index=2, number=3, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='battery_level', full_name='Position.battery_level', index=3, number=4, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='time', full_name='Position.time', index=4, number=9, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -514,45 +337,7 @@ _POSITION = _descriptor.Descriptor( oneofs=[ ], serialized_start=30, - serialized_end=136, -) - - -_DATA = _descriptor.Descriptor( - name='Data', - full_name='Data', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='portnum', full_name='Data.portnum', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='payload', full_name='Data.payload', index=1, - number=2, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=b"", - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=138, - serialized_end=188, + serialized_end=148, ) @@ -562,6 +347,7 @@ _USER = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='id', full_name='User.id', index=0, @@ -569,28 +355,28 @@ _USER = _descriptor.Descriptor( has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='long_name', full_name='User.long_name', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='short_name', full_name='User.short_name', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='macaddr', full_name='User.macaddr', index=3, number=4, type=12, cpp_type=9, label=1, has_default_value=False, default_value=b"", message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -603,8 +389,8 @@ _USER = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=190, - serialized_end=264, + serialized_start=150, + serialized_end=224, ) @@ -614,14 +400,15 @@ _ROUTEDISCOVERY = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='route', full_name='RouteDiscovery.route', index=0, - number=2, type=5, cpp_type=1, label=3, + number=2, type=7, cpp_type=3, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -634,102 +421,113 @@ _ROUTEDISCOVERY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=266, - serialized_end=297, + serialized_start=226, + serialized_end=257, ) -_SUBPACKET = _descriptor.Descriptor( - name='SubPacket', - full_name='SubPacket', +_ROUTING = _descriptor.Descriptor( + name='Routing', + full_name='Routing', filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( - name='data', full_name='SubPacket.data', index=0, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='route_request', full_name='SubPacket.route_request', index=1, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='route_reply', full_name='SubPacket.route_reply', index=2, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='error_reason', full_name='SubPacket.error_reason', index=3, - number=13, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='position', full_name='SubPacket.position', index=4, + name='route_request', full_name='Routing.route_request', index=0, number=1, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=b'\030\001', file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='user', full_name='SubPacket.user', index=5, - number=4, type=11, cpp_type=10, label=1, + name='route_reply', full_name='Routing.route_reply', index=1, + number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=b'\030\001', file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='want_response', full_name='SubPacket.want_response', index=6, - number=5, type=8, cpp_type=7, label=1, + name='error_reason', full_name='Routing.error_reason', index=2, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _ROUTING_ERROR, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + _descriptor.OneofDescriptor( + name='variant', full_name='Routing.variant', + index=0, containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[]), + ], + serialized_start=260, + serialized_end=530, +) + + +_DATA = _descriptor.Descriptor( + name='Data', + full_name='Data', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='portnum', full_name='Data.portnum', index=0, + number=1, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='payload', full_name='Data.payload', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='want_response', full_name='Data.want_response', index=2, + number=3, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='success_id', full_name='SubPacket.success_id', index=7, - number=10, type=13, cpp_type=3, label=1, + name='dest', full_name='Data.dest', index=3, + number=4, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='fail_id', full_name='SubPacket.fail_id', index=8, - number=11, type=13, cpp_type=3, label=1, + name='source', full_name='Data.source', index=4, + number=5, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='dest', full_name='SubPacket.dest', index=9, - number=9, type=13, cpp_type=3, label=1, + name='request_id', full_name='Data.request_id', index=5, + number=6, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='source', full_name='SubPacket.source', index=10, - number=12, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='original_id', full_name='SubPacket.original_id', index=11, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -741,15 +539,9 @@ _SUBPACKET = _descriptor.Descriptor( syntax='proto3', extension_ranges=[], oneofs=[ - _descriptor.OneofDescriptor( - name='payloadVariant', full_name='SubPacket.payloadVariant', - index=0, containing_type=None, fields=[]), - _descriptor.OneofDescriptor( - name='ackVariant', full_name='SubPacket.ackVariant', - index=1, containing_type=None, fields=[]), ], - serialized_start=300, - serialized_end=663, + serialized_start=532, + serialized_end=655, ) @@ -759,82 +551,91 @@ _MESHPACKET = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='from', full_name='MeshPacket.from', index=0, - number=1, type=13, cpp_type=3, label=1, + number=1, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='to', full_name='MeshPacket.to', index=1, - number=2, type=13, cpp_type=3, label=1, + number=2, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='channel_index', full_name='MeshPacket.channel_index', index=2, - number=4, type=13, cpp_type=3, label=1, + name='channel', full_name='MeshPacket.channel', index=2, + number=3, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='decoded', full_name='MeshPacket.decoded', index=3, - number=3, type=11, cpp_type=10, label=1, + number=4, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='encrypted', full_name='MeshPacket.encrypted', index=4, - number=8, type=12, cpp_type=9, label=1, + number=5, type=12, cpp_type=9, label=1, has_default_value=False, default_value=b"", message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='id', full_name='MeshPacket.id', index=5, - number=6, type=13, cpp_type=3, label=1, + number=6, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='rx_time', full_name='MeshPacket.rx_time', index=6, - number=9, type=7, cpp_type=3, label=1, + number=7, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='rx_snr', full_name='MeshPacket.rx_snr', index=7, - number=7, type=2, cpp_type=6, label=1, + number=8, type=2, cpp_type=6, label=1, has_default_value=False, default_value=float(0), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='hop_limit', full_name='MeshPacket.hop_limit', index=8, number=10, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='want_ack', full_name='MeshPacket.want_ack', index=9, number=11, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='priority', full_name='MeshPacket.priority', index=10, + number=12, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], nested_types=[], enum_types=[ + _MESHPACKET_PRIORITY, ], serialized_options=None, is_extendable=False, @@ -843,467 +644,12 @@ _MESHPACKET = _descriptor.Descriptor( oneofs=[ _descriptor.OneofDescriptor( name='payloadVariant', full_name='MeshPacket.payloadVariant', - index=0, containing_type=None, fields=[]), + index=0, containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[]), ], - serialized_start=666, - serialized_end=879, -) - - -_CHANNELSETTINGS = _descriptor.Descriptor( - name='ChannelSettings', - full_name='ChannelSettings', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='tx_power', full_name='ChannelSettings.tx_power', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='modem_config', full_name='ChannelSettings.modem_config', index=1, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='bandwidth', full_name='ChannelSettings.bandwidth', index=2, - number=6, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='spread_factor', full_name='ChannelSettings.spread_factor', index=3, - number=7, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='coding_rate', full_name='ChannelSettings.coding_rate', index=4, - number=8, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='channel_num', full_name='ChannelSettings.channel_num', index=5, - number=9, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='psk', full_name='ChannelSettings.psk', index=6, - number=4, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=b"", - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='ChannelSettings.name', index=7, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='id', full_name='ChannelSettings.id', index=8, - number=10, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='uplink_enabled', full_name='ChannelSettings.uplink_enabled', index=9, - number=16, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='downlink_enabled', full_name='ChannelSettings.downlink_enabled', index=10, - number=17, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _CHANNELSETTINGS_MODEMCONFIG, - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=882, - serialized_end=1240, -) - - -_RADIOCONFIG_USERPREFERENCES = _descriptor.Descriptor( - name='UserPreferences', - full_name='RadioConfig.UserPreferences', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='position_broadcast_secs', full_name='RadioConfig.UserPreferences.position_broadcast_secs', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='send_owner_interval', full_name='RadioConfig.UserPreferences.send_owner_interval', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='wait_bluetooth_secs', full_name='RadioConfig.UserPreferences.wait_bluetooth_secs', index=2, - number=4, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='screen_on_secs', full_name='RadioConfig.UserPreferences.screen_on_secs', index=3, - number=5, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='phone_timeout_secs', full_name='RadioConfig.UserPreferences.phone_timeout_secs', index=4, - number=6, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='phone_sds_timeout_sec', full_name='RadioConfig.UserPreferences.phone_sds_timeout_sec', index=5, - number=7, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='mesh_sds_timeout_secs', full_name='RadioConfig.UserPreferences.mesh_sds_timeout_secs', index=6, - number=8, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='sds_secs', full_name='RadioConfig.UserPreferences.sds_secs', index=7, - number=9, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ls_secs', full_name='RadioConfig.UserPreferences.ls_secs', index=8, - number=10, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='min_wake_secs', full_name='RadioConfig.UserPreferences.min_wake_secs', index=9, - number=11, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='wifi_ssid', full_name='RadioConfig.UserPreferences.wifi_ssid', index=10, - number=12, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='wifi_password', full_name='RadioConfig.UserPreferences.wifi_password', index=11, - number=13, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='wifi_ap_mode', full_name='RadioConfig.UserPreferences.wifi_ap_mode', index=12, - number=14, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='region', full_name='RadioConfig.UserPreferences.region', index=13, - number=15, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='charge_current', full_name='RadioConfig.UserPreferences.charge_current', index=14, - number=16, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_router', full_name='RadioConfig.UserPreferences.is_router', index=15, - number=37, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_low_power', full_name='RadioConfig.UserPreferences.is_low_power', index=16, - number=38, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='fixed_position', full_name='RadioConfig.UserPreferences.fixed_position', index=17, - number=39, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='factory_reset', full_name='RadioConfig.UserPreferences.factory_reset', index=18, - number=100, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='debug_log_enabled', full_name='RadioConfig.UserPreferences.debug_log_enabled', index=19, - number=101, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='location_share', full_name='RadioConfig.UserPreferences.location_share', index=20, - number=32, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='gps_operation', full_name='RadioConfig.UserPreferences.gps_operation', index=21, - number=33, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='gps_update_interval', full_name='RadioConfig.UserPreferences.gps_update_interval', index=22, - number=34, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='gps_attempt_time', full_name='RadioConfig.UserPreferences.gps_attempt_time', index=23, - number=36, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ignore_incoming', full_name='RadioConfig.UserPreferences.ignore_incoming', index=24, - number=103, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='serialplugin_enabled', full_name='RadioConfig.UserPreferences.serialplugin_enabled', index=25, - number=120, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='serialplugin_echo', full_name='RadioConfig.UserPreferences.serialplugin_echo', index=26, - number=121, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='serialplugin_rxd', full_name='RadioConfig.UserPreferences.serialplugin_rxd', index=27, - number=122, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='serialplugin_txd', full_name='RadioConfig.UserPreferences.serialplugin_txd', index=28, - number=123, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='serialplugin_timeout', full_name='RadioConfig.UserPreferences.serialplugin_timeout', index=29, - number=124, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='serialplugin_mode', full_name='RadioConfig.UserPreferences.serialplugin_mode', index=30, - number=125, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ext_notification_plugin_enabled', full_name='RadioConfig.UserPreferences.ext_notification_plugin_enabled', index=31, - number=126, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ext_notification_plugin_output_ms', full_name='RadioConfig.UserPreferences.ext_notification_plugin_output_ms', index=32, - number=127, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ext_notification_plugin_output', full_name='RadioConfig.UserPreferences.ext_notification_plugin_output', index=33, - number=128, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ext_notification_plugin_active', full_name='RadioConfig.UserPreferences.ext_notification_plugin_active', index=34, - number=129, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ext_notification_plugin_alert_message', full_name='RadioConfig.UserPreferences.ext_notification_plugin_alert_message', index=35, - number=130, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='ext_notification_plugin_alert_bell', full_name='RadioConfig.UserPreferences.ext_notification_plugin_alert_bell', index=36, - number=131, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='range_test_plugin_enabled', full_name='RadioConfig.UserPreferences.range_test_plugin_enabled', index=37, - number=132, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='range_test_plugin_sender', full_name='RadioConfig.UserPreferences.range_test_plugin_sender', index=38, - number=133, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='range_test_plugin_save', full_name='RadioConfig.UserPreferences.range_test_plugin_save', index=39, - number=134, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='store_forward_plugin_enabled', full_name='RadioConfig.UserPreferences.store_forward_plugin_enabled', index=40, - number=136, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='store_forward_plugin_records', full_name='RadioConfig.UserPreferences.store_forward_plugin_records', index=41, - number=137, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1358, - serialized_end=2653, -) - -_RADIOCONFIG = _descriptor.Descriptor( - name='RadioConfig', - full_name='RadioConfig', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='preferences', full_name='RadioConfig.preferences', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='channel_settings', full_name='RadioConfig.channel_settings', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\030\001', file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[_RADIOCONFIG_USERPREFERENCES, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1243, - serialized_end=2653, + serialized_start=658, + serialized_end=993, ) @@ -1313,6 +659,7 @@ _NODEINFO = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='num', full_name='NodeInfo.num', index=0, @@ -1320,35 +667,35 @@ _NODEINFO = _descriptor.Descriptor( has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='user', full_name='NodeInfo.user', index=1, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='position', full_name='NodeInfo.position', index=2, number=3, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='snr', full_name='NodeInfo.snr', index=3, number=7, type=2, cpp_type=6, label=1, has_default_value=False, default_value=float(0), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='next_hop', full_name='NodeInfo.next_hop', index=4, number=5, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -1361,8 +708,8 @@ _NODEINFO = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2655, - serialized_end=2759, + serialized_start=995, + serialized_end=1099, ) @@ -1372,6 +719,7 @@ _MYNODEINFO = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='my_node_num', full_name='MyNodeInfo.my_node_num', index=0, @@ -1379,98 +727,84 @@ _MYNODEINFO = _descriptor.Descriptor( has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='has_gps', full_name='MyNodeInfo.has_gps', index=1, number=2, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='num_channels', full_name='MyNodeInfo.num_channels', index=2, - number=3, type=5, cpp_type=1, label=1, + name='num_bands', full_name='MyNodeInfo.num_bands', index=2, + number=3, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='region', full_name='MyNodeInfo.region', index=3, + name='max_channels', full_name='MyNodeInfo.max_channels', index=3, + number=15, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='region', full_name='MyNodeInfo.region', index=4, number=4, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=b'\030\001', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='hw_model', full_name='MyNodeInfo.hw_model', index=4, + name='hw_model', full_name='MyNodeInfo.hw_model', index=5, number=5, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='firmware_version', full_name='MyNodeInfo.firmware_version', index=5, + name='firmware_version', full_name='MyNodeInfo.firmware_version', index=6, number=6, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='error_code', full_name='MyNodeInfo.error_code', index=6, + name='error_code', full_name='MyNodeInfo.error_code', index=7, number=7, type=14, cpp_type=8, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='error_address', full_name='MyNodeInfo.error_address', index=7, + name='error_address', full_name='MyNodeInfo.error_address', index=8, number=8, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='error_count', full_name='MyNodeInfo.error_count', index=8, + name='error_count', full_name='MyNodeInfo.error_count', index=9, number=9, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='packet_id_bits', full_name='MyNodeInfo.packet_id_bits', index=9, - number=10, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='current_packet_id', full_name='MyNodeInfo.current_packet_id', index=10, - number=11, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='node_num_bits', full_name='MyNodeInfo.node_num_bits', index=11, - number=12, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='message_timeout_msec', full_name='MyNodeInfo.message_timeout_msec', index=12, + name='message_timeout_msec', full_name='MyNodeInfo.message_timeout_msec', index=10, number=13, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='min_app_version', full_name='MyNodeInfo.min_app_version', index=13, + name='min_app_version', full_name='MyNodeInfo.min_app_version', index=11, number=14, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -1483,8 +817,8 @@ _MYNODEINFO = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2762, - serialized_end=3107, + serialized_start=1102, + serialized_end=1396, ) @@ -1494,6 +828,7 @@ _LOGRECORD = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='message', full_name='LogRecord.message', index=0, @@ -1501,28 +836,28 @@ _LOGRECORD = _descriptor.Descriptor( has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='time', full_name='LogRecord.time', index=1, number=2, type=7, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='source', full_name='LogRecord.source', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='level', full_name='LogRecord.level', index=3, number=4, type=14, cpp_type=8, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -1536,8 +871,8 @@ _LOGRECORD = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3110, - serialized_end=3291, + serialized_start=1399, + serialized_end=1580, ) @@ -1547,6 +882,7 @@ _FROMRADIO = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='num', full_name='FromRadio.num', index=0, @@ -1554,63 +890,49 @@ _FROMRADIO = _descriptor.Descriptor( has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='packet', full_name='FromRadio.packet', index=1, - number=2, type=11, cpp_type=10, label=1, + number=11, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='my_info', full_name='FromRadio.my_info', index=2, number=3, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='node_info', full_name='FromRadio.node_info', index=3, number=4, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='radio', full_name='FromRadio.radio', index=4, - number=6, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='log_record', full_name='FromRadio.log_record', index=5, + name='log_record', full_name='FromRadio.log_record', index=4, number=7, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='config_complete_id', full_name='FromRadio.config_complete_id', index=6, + name='config_complete_id', full_name='FromRadio.config_complete_id', index=5, number=8, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='rebooted', full_name='FromRadio.rebooted', index=7, + name='rebooted', full_name='FromRadio.rebooted', index=6, number=9, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='channel', full_name='FromRadio.channel', index=8, - number=10, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -1624,10 +946,12 @@ _FROMRADIO = _descriptor.Descriptor( oneofs=[ _descriptor.OneofDescriptor( name='payloadVariant', full_name='FromRadio.payloadVariant', - index=0, containing_type=None, fields=[]), + index=0, containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[]), ], - serialized_start=3294, - serialized_end=3583, + serialized_start=1583, + serialized_end=1816, ) @@ -1637,42 +961,22 @@ _TORADIO = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='packet', full_name='ToRadio.packet', index=0, - number=1, type=11, cpp_type=10, label=1, + number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='want_config_id', full_name='ToRadio.want_config_id', index=1, number=100, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='set_radio', full_name='ToRadio.set_radio', index=2, - number=101, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='set_owner', full_name='ToRadio.set_owner', index=3, - number=102, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='set_channel', full_name='ToRadio.set_channel', index=4, - number=103, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -1686,59 +990,37 @@ _TORADIO = _descriptor.Descriptor( oneofs=[ _descriptor.OneofDescriptor( name='payloadVariant', full_name='ToRadio.payloadVariant', - index=0, containing_type=None, fields=[]), + index=0, containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[]), ], - serialized_start=3586, - serialized_end=3774, + serialized_start=1818, + serialized_end=1926, ) +_ROUTING.fields_by_name['route_request'].message_type = _ROUTEDISCOVERY +_ROUTING.fields_by_name['route_reply'].message_type = _ROUTEDISCOVERY +_ROUTING.fields_by_name['error_reason'].enum_type = _ROUTING_ERROR +_ROUTING_ERROR.containing_type = _ROUTING +_ROUTING.oneofs_by_name['variant'].fields.append( + _ROUTING.fields_by_name['route_request']) +_ROUTING.fields_by_name['route_request'].containing_oneof = _ROUTING.oneofs_by_name['variant'] +_ROUTING.oneofs_by_name['variant'].fields.append( + _ROUTING.fields_by_name['route_reply']) +_ROUTING.fields_by_name['route_reply'].containing_oneof = _ROUTING.oneofs_by_name['variant'] +_ROUTING.oneofs_by_name['variant'].fields.append( + _ROUTING.fields_by_name['error_reason']) +_ROUTING.fields_by_name['error_reason'].containing_oneof = _ROUTING.oneofs_by_name['variant'] _DATA.fields_by_name['portnum'].enum_type = portnums__pb2._PORTNUM -_SUBPACKET.fields_by_name['data'].message_type = _DATA -_SUBPACKET.fields_by_name['route_request'].message_type = _ROUTEDISCOVERY -_SUBPACKET.fields_by_name['route_reply'].message_type = _ROUTEDISCOVERY -_SUBPACKET.fields_by_name['error_reason'].enum_type = _ERRORREASON -_SUBPACKET.fields_by_name['position'].message_type = _POSITION -_SUBPACKET.fields_by_name['user'].message_type = _USER -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append( - _SUBPACKET.fields_by_name['data']) -_SUBPACKET.fields_by_name['data'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant'] -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append( - _SUBPACKET.fields_by_name['route_request']) -_SUBPACKET.fields_by_name['route_request'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant'] -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append( - _SUBPACKET.fields_by_name['route_reply']) -_SUBPACKET.fields_by_name['route_reply'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant'] -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append( - _SUBPACKET.fields_by_name['error_reason']) -_SUBPACKET.fields_by_name['error_reason'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant'] -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append( - _SUBPACKET.fields_by_name['position']) -_SUBPACKET.fields_by_name['position'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant'] -_SUBPACKET.oneofs_by_name['payloadVariant'].fields.append( - _SUBPACKET.fields_by_name['user']) -_SUBPACKET.fields_by_name['user'].containing_oneof = _SUBPACKET.oneofs_by_name['payloadVariant'] -_SUBPACKET.oneofs_by_name['ackVariant'].fields.append( - _SUBPACKET.fields_by_name['success_id']) -_SUBPACKET.fields_by_name['success_id'].containing_oneof = _SUBPACKET.oneofs_by_name['ackVariant'] -_SUBPACKET.oneofs_by_name['ackVariant'].fields.append( - _SUBPACKET.fields_by_name['fail_id']) -_SUBPACKET.fields_by_name['fail_id'].containing_oneof = _SUBPACKET.oneofs_by_name['ackVariant'] -_MESHPACKET.fields_by_name['decoded'].message_type = _SUBPACKET +_MESHPACKET.fields_by_name['decoded'].message_type = _DATA +_MESHPACKET.fields_by_name['priority'].enum_type = _MESHPACKET_PRIORITY +_MESHPACKET_PRIORITY.containing_type = _MESHPACKET _MESHPACKET.oneofs_by_name['payloadVariant'].fields.append( _MESHPACKET.fields_by_name['decoded']) _MESHPACKET.fields_by_name['decoded'].containing_oneof = _MESHPACKET.oneofs_by_name['payloadVariant'] _MESHPACKET.oneofs_by_name['payloadVariant'].fields.append( _MESHPACKET.fields_by_name['encrypted']) _MESHPACKET.fields_by_name['encrypted'].containing_oneof = _MESHPACKET.oneofs_by_name['payloadVariant'] -_CHANNELSETTINGS.fields_by_name['modem_config'].enum_type = _CHANNELSETTINGS_MODEMCONFIG -_CHANNELSETTINGS_MODEMCONFIG.containing_type = _CHANNELSETTINGS -_RADIOCONFIG_USERPREFERENCES.fields_by_name['region'].enum_type = _REGIONCODE -_RADIOCONFIG_USERPREFERENCES.fields_by_name['charge_current'].enum_type = _CHARGECURRENT -_RADIOCONFIG_USERPREFERENCES.fields_by_name['location_share'].enum_type = _LOCATIONSHARING -_RADIOCONFIG_USERPREFERENCES.fields_by_name['gps_operation'].enum_type = _GPSOPERATION -_RADIOCONFIG_USERPREFERENCES.containing_type = _RADIOCONFIG -_RADIOCONFIG.fields_by_name['preferences'].message_type = _RADIOCONFIG_USERPREFERENCES -_RADIOCONFIG.fields_by_name['channel_settings'].message_type = _CHANNELSETTINGS _NODEINFO.fields_by_name['user'].message_type = _USER _NODEINFO.fields_by_name['position'].message_type = _POSITION _MYNODEINFO.fields_by_name['error_code'].enum_type = _CRITICALERRORCODE @@ -1747,9 +1029,7 @@ _LOGRECORD_LEVEL.containing_type = _LOGRECORD _FROMRADIO.fields_by_name['packet'].message_type = _MESHPACKET _FROMRADIO.fields_by_name['my_info'].message_type = _MYNODEINFO _FROMRADIO.fields_by_name['node_info'].message_type = _NODEINFO -_FROMRADIO.fields_by_name['radio'].message_type = _RADIOCONFIG _FROMRADIO.fields_by_name['log_record'].message_type = _LOGRECORD -_FROMRADIO.fields_by_name['channel'].message_type = _CHANNELSETTINGS _FROMRADIO.oneofs_by_name['payloadVariant'].fields.append( _FROMRADIO.fields_by_name['packet']) _FROMRADIO.fields_by_name['packet'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant'] @@ -1759,9 +1039,6 @@ _FROMRADIO.fields_by_name['my_info'].containing_oneof = _FROMRADIO.oneofs_by_nam _FROMRADIO.oneofs_by_name['payloadVariant'].fields.append( _FROMRADIO.fields_by_name['node_info']) _FROMRADIO.fields_by_name['node_info'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant'] -_FROMRADIO.oneofs_by_name['payloadVariant'].fields.append( - _FROMRADIO.fields_by_name['radio']) -_FROMRADIO.fields_by_name['radio'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant'] _FROMRADIO.oneofs_by_name['payloadVariant'].fields.append( _FROMRADIO.fields_by_name['log_record']) _FROMRADIO.fields_by_name['log_record'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant'] @@ -1771,47 +1048,25 @@ _FROMRADIO.fields_by_name['config_complete_id'].containing_oneof = _FROMRADIO.on _FROMRADIO.oneofs_by_name['payloadVariant'].fields.append( _FROMRADIO.fields_by_name['rebooted']) _FROMRADIO.fields_by_name['rebooted'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant'] -_FROMRADIO.oneofs_by_name['payloadVariant'].fields.append( - _FROMRADIO.fields_by_name['channel']) -_FROMRADIO.fields_by_name['channel'].containing_oneof = _FROMRADIO.oneofs_by_name['payloadVariant'] _TORADIO.fields_by_name['packet'].message_type = _MESHPACKET -_TORADIO.fields_by_name['set_radio'].message_type = _RADIOCONFIG -_TORADIO.fields_by_name['set_owner'].message_type = _USER -_TORADIO.fields_by_name['set_channel'].message_type = _CHANNELSETTINGS _TORADIO.oneofs_by_name['payloadVariant'].fields.append( _TORADIO.fields_by_name['packet']) _TORADIO.fields_by_name['packet'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant'] _TORADIO.oneofs_by_name['payloadVariant'].fields.append( _TORADIO.fields_by_name['want_config_id']) _TORADIO.fields_by_name['want_config_id'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant'] -_TORADIO.oneofs_by_name['payloadVariant'].fields.append( - _TORADIO.fields_by_name['set_radio']) -_TORADIO.fields_by_name['set_radio'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant'] -_TORADIO.oneofs_by_name['payloadVariant'].fields.append( - _TORADIO.fields_by_name['set_owner']) -_TORADIO.fields_by_name['set_owner'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant'] -_TORADIO.oneofs_by_name['payloadVariant'].fields.append( - _TORADIO.fields_by_name['set_channel']) -_TORADIO.fields_by_name['set_channel'].containing_oneof = _TORADIO.oneofs_by_name['payloadVariant'] DESCRIPTOR.message_types_by_name['Position'] = _POSITION -DESCRIPTOR.message_types_by_name['Data'] = _DATA DESCRIPTOR.message_types_by_name['User'] = _USER DESCRIPTOR.message_types_by_name['RouteDiscovery'] = _ROUTEDISCOVERY -DESCRIPTOR.message_types_by_name['SubPacket'] = _SUBPACKET +DESCRIPTOR.message_types_by_name['Routing'] = _ROUTING +DESCRIPTOR.message_types_by_name['Data'] = _DATA DESCRIPTOR.message_types_by_name['MeshPacket'] = _MESHPACKET -DESCRIPTOR.message_types_by_name['ChannelSettings'] = _CHANNELSETTINGS -DESCRIPTOR.message_types_by_name['RadioConfig'] = _RADIOCONFIG DESCRIPTOR.message_types_by_name['NodeInfo'] = _NODEINFO DESCRIPTOR.message_types_by_name['MyNodeInfo'] = _MYNODEINFO DESCRIPTOR.message_types_by_name['LogRecord'] = _LOGRECORD DESCRIPTOR.message_types_by_name['FromRadio'] = _FROMRADIO DESCRIPTOR.message_types_by_name['ToRadio'] = _TORADIO -DESCRIPTOR.enum_types_by_name['ErrorReason'] = _ERRORREASON DESCRIPTOR.enum_types_by_name['Constants'] = _CONSTANTS -DESCRIPTOR.enum_types_by_name['RegionCode'] = _REGIONCODE -DESCRIPTOR.enum_types_by_name['ChargeCurrent'] = _CHARGECURRENT -DESCRIPTOR.enum_types_by_name['GpsOperation'] = _GPSOPERATION -DESCRIPTOR.enum_types_by_name['LocationSharing'] = _LOCATIONSHARING DESCRIPTOR.enum_types_by_name['CriticalErrorCode'] = _CRITICALERRORCODE _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -1822,13 +1077,6 @@ Position = _reflection.GeneratedProtocolMessageType('Position', (_message.Messag }) _sym_db.RegisterMessage(Position) -Data = _reflection.GeneratedProtocolMessageType('Data', (_message.Message,), { - 'DESCRIPTOR' : _DATA, - '__module__' : 'mesh_pb2' - # @@protoc_insertion_point(class_scope:Data) - }) -_sym_db.RegisterMessage(Data) - User = _reflection.GeneratedProtocolMessageType('User', (_message.Message,), { 'DESCRIPTOR' : _USER, '__module__' : 'mesh_pb2' @@ -1843,12 +1091,19 @@ RouteDiscovery = _reflection.GeneratedProtocolMessageType('RouteDiscovery', (_me }) _sym_db.RegisterMessage(RouteDiscovery) -SubPacket = _reflection.GeneratedProtocolMessageType('SubPacket', (_message.Message,), { - 'DESCRIPTOR' : _SUBPACKET, +Routing = _reflection.GeneratedProtocolMessageType('Routing', (_message.Message,), { + 'DESCRIPTOR' : _ROUTING, '__module__' : 'mesh_pb2' - # @@protoc_insertion_point(class_scope:SubPacket) + # @@protoc_insertion_point(class_scope:Routing) }) -_sym_db.RegisterMessage(SubPacket) +_sym_db.RegisterMessage(Routing) + +Data = _reflection.GeneratedProtocolMessageType('Data', (_message.Message,), { + 'DESCRIPTOR' : _DATA, + '__module__' : 'mesh_pb2' + # @@protoc_insertion_point(class_scope:Data) + }) +_sym_db.RegisterMessage(Data) MeshPacket = _reflection.GeneratedProtocolMessageType('MeshPacket', (_message.Message,), { 'DESCRIPTOR' : _MESHPACKET, @@ -1857,28 +1112,6 @@ MeshPacket = _reflection.GeneratedProtocolMessageType('MeshPacket', (_message.Me }) _sym_db.RegisterMessage(MeshPacket) -ChannelSettings = _reflection.GeneratedProtocolMessageType('ChannelSettings', (_message.Message,), { - 'DESCRIPTOR' : _CHANNELSETTINGS, - '__module__' : 'mesh_pb2' - # @@protoc_insertion_point(class_scope:ChannelSettings) - }) -_sym_db.RegisterMessage(ChannelSettings) - -RadioConfig = _reflection.GeneratedProtocolMessageType('RadioConfig', (_message.Message,), { - - 'UserPreferences' : _reflection.GeneratedProtocolMessageType('UserPreferences', (_message.Message,), { - 'DESCRIPTOR' : _RADIOCONFIG_USERPREFERENCES, - '__module__' : 'mesh_pb2' - # @@protoc_insertion_point(class_scope:RadioConfig.UserPreferences) - }) - , - 'DESCRIPTOR' : _RADIOCONFIG, - '__module__' : 'mesh_pb2' - # @@protoc_insertion_point(class_scope:RadioConfig) - }) -_sym_db.RegisterMessage(RadioConfig) -_sym_db.RegisterMessage(RadioConfig.UserPreferences) - NodeInfo = _reflection.GeneratedProtocolMessageType('NodeInfo', (_message.Message,), { 'DESCRIPTOR' : _NODEINFO, '__module__' : 'mesh_pb2' @@ -1916,7 +1149,5 @@ _sym_db.RegisterMessage(ToRadio) DESCRIPTOR._options = None -_SUBPACKET.fields_by_name['position']._options = None -_SUBPACKET.fields_by_name['user']._options = None -_RADIOCONFIG.fields_by_name['channel_settings']._options = None +_MYNODEINFO.fields_by_name['region']._options = None # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/portnums_pb2.py b/meshtastic/portnums_pb2.py index 171a206..f677cd1 100644 --- a/meshtastic/portnums_pb2.py +++ b/meshtastic/portnums_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: portnums.proto - +"""Generated protocol buffer code.""" from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message @@ -19,7 +19,8 @@ DESCRIPTOR = _descriptor.FileDescriptor( package='', syntax='proto3', serialized_options=b'\n\023com.geeksville.meshB\010PortnumsH\003', - serialized_pb=b'\n\x0eportnums.proto*\xdd\x01\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x42!\n\x13\x63om.geeksville.meshB\x08PortnumsH\x03\x62\x06proto3' + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x0eportnums.proto*\xbe\x02\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12!\n\x1d\x45NVIRONMENTAL_MEASUREMENT_APP\x10\x43\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42!\n\x13\x63om.geeksville.meshB\x08PortnumsH\x03\x62\x06proto3' ) _PORTNUM = _descriptor.EnumDescriptor( @@ -27,56 +28,93 @@ _PORTNUM = _descriptor.EnumDescriptor( full_name='PortNum', filename=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, values=[ _descriptor.EnumValueDescriptor( name='UNKNOWN_APP', index=0, number=0, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='TEXT_MESSAGE_APP', index=1, number=1, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='REMOTE_HARDWARE_APP', index=2, number=2, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='POSITION_APP', index=3, number=3, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='NODEINFO_APP', index=4, number=4, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='REPLY_APP', index=5, number=32, + name='ROUTING_APP', index=5, number=5, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='IP_TUNNEL_APP', index=6, number=33, + name='ADMIN_APP', index=6, number=6, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='SERIAL_APP', index=7, number=64, + name='REPLY_APP', index=7, number=32, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='STORE_FORWARD_APP', index=8, number=65, + name='IP_TUNNEL_APP', index=8, number=33, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='PRIVATE_APP', index=9, number=256, + name='SERIAL_APP', index=9, number=64, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( - name='ATAK_FORWARDER', index=10, number=257, + name='STORE_FORWARD_APP', index=10, number=65, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RANGE_TEST_APP', index=11, number=66, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ENVIRONMENTAL_MEASUREMENT_APP', index=12, number=67, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PRIVATE_APP', index=13, number=256, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ATAK_FORWARDER', index=14, number=257, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MAX', index=15, number=511, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), ], containing_type=None, serialized_options=None, serialized_start=19, - serialized_end=240, + serialized_end=337, ) _sym_db.RegisterEnumDescriptor(_PORTNUM) @@ -86,12 +124,17 @@ TEXT_MESSAGE_APP = 1 REMOTE_HARDWARE_APP = 2 POSITION_APP = 3 NODEINFO_APP = 4 +ROUTING_APP = 5 +ADMIN_APP = 6 REPLY_APP = 32 IP_TUNNEL_APP = 33 SERIAL_APP = 64 STORE_FORWARD_APP = 65 +RANGE_TEST_APP = 66 +ENVIRONMENTAL_MEASUREMENT_APP = 67 PRIVATE_APP = 256 ATAK_FORWARDER = 257 +MAX = 511 DESCRIPTOR.enum_types_by_name['PortNum'] = _PORTNUM diff --git a/meshtastic/radioconfig_pb2.py b/meshtastic/radioconfig_pb2.py new file mode 100644 index 0000000..f66b4b0 --- /dev/null +++ b/meshtastic/radioconfig_pb2.py @@ -0,0 +1,761 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: radioconfig.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='radioconfig.proto', + package='', + syntax='proto3', + serialized_options=b'\n\023com.geeksville.meshB\021RadioConfigProtosH\003', + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x11radioconfig.proto\"\xa5\x0f\n\x0bRadioConfig\x12\x31\n\x0bpreferences\x18\x01 \x01(\x0b\x32\x1c.RadioConfig.UserPreferences\x1a\xe2\x0e\n\x0fUserPreferences\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12\x1b\n\x13send_owner_interval\x18\x02 \x01(\r\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x16\n\x0escreen_on_secs\x18\x05 \x01(\r\x12\x1a\n\x12phone_timeout_secs\x18\x06 \x01(\r\x12\x1d\n\x15phone_sds_timeout_sec\x18\x07 \x01(\r\x12\x1d\n\x15mesh_sds_timeout_secs\x18\x08 \x01(\r\x12\x10\n\x08sds_secs\x18\t \x01(\r\x12\x0f\n\x07ls_secs\x18\n \x01(\r\x12\x15\n\rmin_wake_secs\x18\x0b \x01(\r\x12\x11\n\twifi_ssid\x18\x0c \x01(\t\x12\x15\n\rwifi_password\x18\r \x01(\t\x12\x14\n\x0cwifi_ap_mode\x18\x0e \x01(\x08\x12\x1b\n\x06region\x18\x0f \x01(\x0e\x32\x0b.RegionCode\x12&\n\x0e\x63harge_current\x18\x10 \x01(\x0e\x32\x0e.ChargeCurrent\x12\x11\n\tis_router\x18% \x01(\x08\x12\x14\n\x0cis_low_power\x18& \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\' \x01(\x08\x12\x15\n\rfactory_reset\x18\x64 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x65 \x01(\x08\x12(\n\x0elocation_share\x18 \x01(\x0e\x32\x10.LocationSharing\x12$\n\rgps_operation\x18! \x01(\x0e\x32\r.GpsOperation\x12\x1b\n\x13gps_update_interval\x18\" \x01(\r\x12\x18\n\x10gps_attempt_time\x18$ \x01(\r\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x1c\n\x14serialplugin_enabled\x18x \x01(\x08\x12\x19\n\x11serialplugin_echo\x18y \x01(\x08\x12\x18\n\x10serialplugin_rxd\x18z \x01(\r\x12\x18\n\x10serialplugin_txd\x18{ \x01(\r\x12\x1c\n\x14serialplugin_timeout\x18| \x01(\r\x12\x19\n\x11serialplugin_mode\x18} \x01(\r\x12\'\n\x1f\x65xt_notification_plugin_enabled\x18~ \x01(\x08\x12)\n!ext_notification_plugin_output_ms\x18\x7f \x01(\r\x12\'\n\x1e\x65xt_notification_plugin_output\x18\x80\x01 \x01(\r\x12\'\n\x1e\x65xt_notification_plugin_active\x18\x81\x01 \x01(\x08\x12.\n%ext_notification_plugin_alert_message\x18\x82\x01 \x01(\x08\x12+\n\"ext_notification_plugin_alert_bell\x18\x83\x01 \x01(\x08\x12\"\n\x19range_test_plugin_enabled\x18\x84\x01 \x01(\x08\x12!\n\x18range_test_plugin_sender\x18\x85\x01 \x01(\r\x12\x1f\n\x16range_test_plugin_save\x18\x86\x01 \x01(\x08\x12%\n\x1cstore_forward_plugin_enabled\x18\x88\x01 \x01(\x08\x12%\n\x1cstore_forward_plugin_records\x18\x89\x01 \x01(\r\x12=\n4environmental_measurement_plugin_measurement_enabled\x18\x8c\x01 \x01(\x08\x12\x38\n/environmental_measurement_plugin_screen_enabled\x18\x8d\x01 \x01(\x08\x12\x44\n;environmental_measurement_plugin_read_error_count_threshold\x18\x8e\x01 \x01(\r\x12\x39\n0environmental_measurement_plugin_update_interval\x18\x8f\x01 \x01(\r\x12;\n2environmental_measurement_plugin_recovery_interval\x18\x90\x01 \x01(\r\x12;\n2environmental_measurement_plugin_display_farenheit\x18\x91\x01 \x01(\x08\x12v\n,environmental_measurement_plugin_sensor_type\x18\x92\x01 \x01(\x0e\x32?.RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType\x12\x34\n+environmental_measurement_plugin_sensor_pin\x18\x93\x01 \x01(\r\"/\n\"EnvironmentalMeasurementSensorType\x12\t\n\x05\x44HT11\x10\x00*f\n\nRegionCode\x12\t\n\x05Unset\x10\x00\x12\x06\n\x02US\x10\x01\x12\t\n\x05\x45U433\x10\x02\x12\t\n\x05\x45U865\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t*\xd1\x01\n\rChargeCurrent\x12\x0b\n\x07MAUnset\x10\x00\x12\t\n\x05MA100\x10\x01\x12\t\n\x05MA190\x10\x02\x12\t\n\x05MA280\x10\x03\x12\t\n\x05MA360\x10\x04\x12\t\n\x05MA450\x10\x05\x12\t\n\x05MA550\x10\x06\x12\t\n\x05MA630\x10\x07\x12\t\n\x05MA700\x10\x08\x12\t\n\x05MA780\x10\t\x12\t\n\x05MA880\x10\n\x12\t\n\x05MA960\x10\x0b\x12\n\n\x06MA1000\x10\x0c\x12\n\n\x06MA1080\x10\r\x12\n\n\x06MA1160\x10\x0e\x12\n\n\x06MA1240\x10\x0f\x12\n\n\x06MA1320\x10\x10*j\n\x0cGpsOperation\x12\x0e\n\nGpsOpUnset\x10\x00\x12\x13\n\x0fGpsOpStationary\x10\x01\x12\x0f\n\x0bGpsOpMobile\x10\x02\x12\x11\n\rGpsOpTimeOnly\x10\x03\x12\x11\n\rGpsOpDisabled\x10\x04*@\n\x0fLocationSharing\x12\x0c\n\x08LocUnset\x10\x00\x12\x0e\n\nLocEnabled\x10\x01\x12\x0f\n\x0bLocDisabled\x10\x02\x42*\n\x13\x63om.geeksville.meshB\x11RadioConfigProtosH\x03\x62\x06proto3' +) + +_REGIONCODE = _descriptor.EnumDescriptor( + name='RegionCode', + full_name='RegionCode', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='Unset', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='US', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EU433', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EU865', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='CN', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='JP', index=5, number=5, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ANZ', index=6, number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='KR', index=7, number=7, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TW', index=8, number=8, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RU', index=9, number=9, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=1981, + serialized_end=2083, +) +_sym_db.RegisterEnumDescriptor(_REGIONCODE) + +RegionCode = enum_type_wrapper.EnumTypeWrapper(_REGIONCODE) +_CHARGECURRENT = _descriptor.EnumDescriptor( + name='ChargeCurrent', + full_name='ChargeCurrent', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='MAUnset', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA100', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA190', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA280', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA360', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA450', index=5, number=5, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA550', index=6, number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA630', index=7, number=7, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA700', index=8, number=8, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA780', index=9, number=9, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA880', index=10, number=10, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA960', index=11, number=11, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA1000', index=12, number=12, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA1080', index=13, number=13, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA1160', index=14, number=14, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA1240', index=15, number=15, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='MA1320', index=16, number=16, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=2086, + serialized_end=2295, +) +_sym_db.RegisterEnumDescriptor(_CHARGECURRENT) + +ChargeCurrent = enum_type_wrapper.EnumTypeWrapper(_CHARGECURRENT) +_GPSOPERATION = _descriptor.EnumDescriptor( + name='GpsOperation', + full_name='GpsOperation', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='GpsOpUnset', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='GpsOpStationary', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='GpsOpMobile', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='GpsOpTimeOnly', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='GpsOpDisabled', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=2297, + serialized_end=2403, +) +_sym_db.RegisterEnumDescriptor(_GPSOPERATION) + +GpsOperation = enum_type_wrapper.EnumTypeWrapper(_GPSOPERATION) +_LOCATIONSHARING = _descriptor.EnumDescriptor( + name='LocationSharing', + full_name='LocationSharing', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='LocUnset', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LocEnabled', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LocDisabled', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=2405, + serialized_end=2469, +) +_sym_db.RegisterEnumDescriptor(_LOCATIONSHARING) + +LocationSharing = enum_type_wrapper.EnumTypeWrapper(_LOCATIONSHARING) +Unset = 0 +US = 1 +EU433 = 2 +EU865 = 3 +CN = 4 +JP = 5 +ANZ = 6 +KR = 7 +TW = 8 +RU = 9 +MAUnset = 0 +MA100 = 1 +MA190 = 2 +MA280 = 3 +MA360 = 4 +MA450 = 5 +MA550 = 6 +MA630 = 7 +MA700 = 8 +MA780 = 9 +MA880 = 10 +MA960 = 11 +MA1000 = 12 +MA1080 = 13 +MA1160 = 14 +MA1240 = 15 +MA1320 = 16 +GpsOpUnset = 0 +GpsOpStationary = 1 +GpsOpMobile = 2 +GpsOpTimeOnly = 3 +GpsOpDisabled = 4 +LocUnset = 0 +LocEnabled = 1 +LocDisabled = 2 + + +_RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE = _descriptor.EnumDescriptor( + name='EnvironmentalMeasurementSensorType', + full_name='RadioConfig.UserPreferences.EnvironmentalMeasurementSensorType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='DHT11', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=1932, + serialized_end=1979, +) +_sym_db.RegisterEnumDescriptor(_RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE) + + +_RADIOCONFIG_USERPREFERENCES = _descriptor.Descriptor( + name='UserPreferences', + full_name='RadioConfig.UserPreferences', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='position_broadcast_secs', full_name='RadioConfig.UserPreferences.position_broadcast_secs', index=0, + number=1, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='send_owner_interval', full_name='RadioConfig.UserPreferences.send_owner_interval', index=1, + number=2, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='wait_bluetooth_secs', full_name='RadioConfig.UserPreferences.wait_bluetooth_secs', index=2, + number=4, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='screen_on_secs', full_name='RadioConfig.UserPreferences.screen_on_secs', index=3, + number=5, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='phone_timeout_secs', full_name='RadioConfig.UserPreferences.phone_timeout_secs', index=4, + number=6, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='phone_sds_timeout_sec', full_name='RadioConfig.UserPreferences.phone_sds_timeout_sec', index=5, + number=7, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='mesh_sds_timeout_secs', full_name='RadioConfig.UserPreferences.mesh_sds_timeout_secs', index=6, + number=8, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sds_secs', full_name='RadioConfig.UserPreferences.sds_secs', index=7, + number=9, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ls_secs', full_name='RadioConfig.UserPreferences.ls_secs', index=8, + number=10, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='min_wake_secs', full_name='RadioConfig.UserPreferences.min_wake_secs', index=9, + number=11, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='wifi_ssid', full_name='RadioConfig.UserPreferences.wifi_ssid', index=10, + number=12, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='wifi_password', full_name='RadioConfig.UserPreferences.wifi_password', index=11, + number=13, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='wifi_ap_mode', full_name='RadioConfig.UserPreferences.wifi_ap_mode', index=12, + number=14, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='region', full_name='RadioConfig.UserPreferences.region', index=13, + number=15, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='charge_current', full_name='RadioConfig.UserPreferences.charge_current', index=14, + number=16, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='is_router', full_name='RadioConfig.UserPreferences.is_router', index=15, + number=37, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='is_low_power', full_name='RadioConfig.UserPreferences.is_low_power', index=16, + number=38, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='fixed_position', full_name='RadioConfig.UserPreferences.fixed_position', index=17, + number=39, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='factory_reset', full_name='RadioConfig.UserPreferences.factory_reset', index=18, + number=100, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='debug_log_enabled', full_name='RadioConfig.UserPreferences.debug_log_enabled', index=19, + number=101, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='location_share', full_name='RadioConfig.UserPreferences.location_share', index=20, + number=32, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='gps_operation', full_name='RadioConfig.UserPreferences.gps_operation', index=21, + number=33, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='gps_update_interval', full_name='RadioConfig.UserPreferences.gps_update_interval', index=22, + number=34, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='gps_attempt_time', full_name='RadioConfig.UserPreferences.gps_attempt_time', index=23, + number=36, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ignore_incoming', full_name='RadioConfig.UserPreferences.ignore_incoming', index=24, + number=103, type=13, cpp_type=3, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='serialplugin_enabled', full_name='RadioConfig.UserPreferences.serialplugin_enabled', index=25, + number=120, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='serialplugin_echo', full_name='RadioConfig.UserPreferences.serialplugin_echo', index=26, + number=121, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='serialplugin_rxd', full_name='RadioConfig.UserPreferences.serialplugin_rxd', index=27, + number=122, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='serialplugin_txd', full_name='RadioConfig.UserPreferences.serialplugin_txd', index=28, + number=123, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='serialplugin_timeout', full_name='RadioConfig.UserPreferences.serialplugin_timeout', index=29, + number=124, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='serialplugin_mode', full_name='RadioConfig.UserPreferences.serialplugin_mode', index=30, + number=125, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ext_notification_plugin_enabled', full_name='RadioConfig.UserPreferences.ext_notification_plugin_enabled', index=31, + number=126, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ext_notification_plugin_output_ms', full_name='RadioConfig.UserPreferences.ext_notification_plugin_output_ms', index=32, + number=127, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ext_notification_plugin_output', full_name='RadioConfig.UserPreferences.ext_notification_plugin_output', index=33, + number=128, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ext_notification_plugin_active', full_name='RadioConfig.UserPreferences.ext_notification_plugin_active', index=34, + number=129, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ext_notification_plugin_alert_message', full_name='RadioConfig.UserPreferences.ext_notification_plugin_alert_message', index=35, + number=130, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ext_notification_plugin_alert_bell', full_name='RadioConfig.UserPreferences.ext_notification_plugin_alert_bell', index=36, + number=131, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='range_test_plugin_enabled', full_name='RadioConfig.UserPreferences.range_test_plugin_enabled', index=37, + number=132, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='range_test_plugin_sender', full_name='RadioConfig.UserPreferences.range_test_plugin_sender', index=38, + number=133, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='range_test_plugin_save', full_name='RadioConfig.UserPreferences.range_test_plugin_save', index=39, + number=134, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='store_forward_plugin_enabled', full_name='RadioConfig.UserPreferences.store_forward_plugin_enabled', index=40, + number=136, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='store_forward_plugin_records', full_name='RadioConfig.UserPreferences.store_forward_plugin_records', index=41, + number=137, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='environmental_measurement_plugin_measurement_enabled', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_measurement_enabled', index=42, + number=140, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='environmental_measurement_plugin_screen_enabled', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_screen_enabled', index=43, + number=141, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='environmental_measurement_plugin_read_error_count_threshold', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_read_error_count_threshold', index=44, + number=142, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='environmental_measurement_plugin_update_interval', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_update_interval', index=45, + number=143, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='environmental_measurement_plugin_recovery_interval', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_recovery_interval', index=46, + number=144, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='environmental_measurement_plugin_display_farenheit', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_display_farenheit', index=47, + number=145, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='environmental_measurement_plugin_sensor_type', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_sensor_type', index=48, + number=146, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='environmental_measurement_plugin_sensor_pin', full_name='RadioConfig.UserPreferences.environmental_measurement_plugin_sensor_pin', index=49, + number=147, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=89, + serialized_end=1979, +) + +_RADIOCONFIG = _descriptor.Descriptor( + name='RadioConfig', + full_name='RadioConfig', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='preferences', full_name='RadioConfig.preferences', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_RADIOCONFIG_USERPREFERENCES, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=22, + serialized_end=1979, +) + +_RADIOCONFIG_USERPREFERENCES.fields_by_name['region'].enum_type = _REGIONCODE +_RADIOCONFIG_USERPREFERENCES.fields_by_name['charge_current'].enum_type = _CHARGECURRENT +_RADIOCONFIG_USERPREFERENCES.fields_by_name['location_share'].enum_type = _LOCATIONSHARING +_RADIOCONFIG_USERPREFERENCES.fields_by_name['gps_operation'].enum_type = _GPSOPERATION +_RADIOCONFIG_USERPREFERENCES.fields_by_name['environmental_measurement_plugin_sensor_type'].enum_type = _RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE +_RADIOCONFIG_USERPREFERENCES.containing_type = _RADIOCONFIG +_RADIOCONFIG_USERPREFERENCES_ENVIRONMENTALMEASUREMENTSENSORTYPE.containing_type = _RADIOCONFIG_USERPREFERENCES +_RADIOCONFIG.fields_by_name['preferences'].message_type = _RADIOCONFIG_USERPREFERENCES +DESCRIPTOR.message_types_by_name['RadioConfig'] = _RADIOCONFIG +DESCRIPTOR.enum_types_by_name['RegionCode'] = _REGIONCODE +DESCRIPTOR.enum_types_by_name['ChargeCurrent'] = _CHARGECURRENT +DESCRIPTOR.enum_types_by_name['GpsOperation'] = _GPSOPERATION +DESCRIPTOR.enum_types_by_name['LocationSharing'] = _LOCATIONSHARING +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +RadioConfig = _reflection.GeneratedProtocolMessageType('RadioConfig', (_message.Message,), { + + 'UserPreferences' : _reflection.GeneratedProtocolMessageType('UserPreferences', (_message.Message,), { + 'DESCRIPTOR' : _RADIOCONFIG_USERPREFERENCES, + '__module__' : 'radioconfig_pb2' + # @@protoc_insertion_point(class_scope:RadioConfig.UserPreferences) + }) + , + 'DESCRIPTOR' : _RADIOCONFIG, + '__module__' : 'radioconfig_pb2' + # @@protoc_insertion_point(class_scope:RadioConfig) + }) +_sym_db.RegisterMessage(RadioConfig) +_sym_db.RegisterMessage(RadioConfig.UserPreferences) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/remote_hardware_pb2.py b/meshtastic/remote_hardware_pb2.py index 31052e0..ee6a78e 100644 --- a/meshtastic/remote_hardware_pb2.py +++ b/meshtastic/remote_hardware_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: remote_hardware.proto - +"""Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -18,6 +18,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( package='', syntax='proto3', serialized_options=b'\n\023com.geeksville.meshB\016RemoteHardwareH\003', + create_key=_descriptor._internal_create_key, serialized_pb=b'\n\x15remote_hardware.proto\"\xca\x01\n\x0fHardwareMessage\x12\"\n\x03typ\x18\x01 \x01(\x0e\x32\x15.HardwareMessage.Type\x12\x11\n\tgpio_mask\x18\x02 \x01(\x04\x12\x12\n\ngpio_value\x18\x03 \x01(\x04\"l\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0f\n\x0bWRITE_GPIOS\x10\x01\x12\x0f\n\x0bWATCH_GPIOS\x10\x02\x12\x11\n\rGPIOS_CHANGED\x10\x03\x12\x0e\n\nREAD_GPIOS\x10\x04\x12\x14\n\x10READ_GPIOS_REPLY\x10\x05\x42\'\n\x13\x63om.geeksville.meshB\x0eRemoteHardwareH\x03\x62\x06proto3' ) @@ -28,31 +29,38 @@ _HARDWAREMESSAGE_TYPE = _descriptor.EnumDescriptor( full_name='HardwareMessage.Type', filename=None, file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, values=[ _descriptor.EnumValueDescriptor( name='UNSET', index=0, number=0, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='WRITE_GPIOS', index=1, number=1, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='WATCH_GPIOS', index=2, number=2, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='GPIOS_CHANGED', index=3, number=3, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='READ_GPIOS', index=4, number=4, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), _descriptor.EnumValueDescriptor( name='READ_GPIOS_REPLY', index=5, number=5, serialized_options=None, - type=None), + type=None, + create_key=_descriptor._internal_create_key), ], containing_type=None, serialized_options=None, @@ -68,6 +76,7 @@ _HARDWAREMESSAGE = _descriptor.Descriptor( filename=None, file=DESCRIPTOR, containing_type=None, + create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( name='typ', full_name='HardwareMessage.typ', index=0, @@ -75,21 +84,21 @@ _HARDWAREMESSAGE = _descriptor.Descriptor( has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='gpio_mask', full_name='HardwareMessage.gpio_mask', index=1, number=2, type=4, cpp_type=4, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( name='gpio_value', full_name='HardwareMessage.gpio_value', index=2, number=3, type=4, cpp_type=4, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], diff --git a/meshtastic/test.py b/meshtastic/test.py index 142d56f..dee1a3c 100644 --- a/meshtastic/test.py +++ b/meshtastic/test.py @@ -19,18 +19,21 @@ testNumber = 0 sendingInterface = None + def onReceive(packet, interface): """Callback invoked when a packet arrives""" if sendingInterface == interface: - print("Ignoring sending interface") + pass + # print("Ignoring sending interface") else: - print(f"From {interface.stream.port}: {packet}") + # print(f"From {interface.stream.port}: {packet}") p = DotMap(packet) - if p.decoded.data.portnum == "TEXT_MESSAGE_APP": + if p.decoded.portnum == "TEXT_MESSAGE_APP": # We only care a about clear text packets receivedPackets.append(p) + def onNode(node): """Callback invoked when the node DB changes""" print(f"Node changed: {node}") @@ -42,7 +45,7 @@ def subscribe(): pub.subscribe(onNode, "meshtastic.node") -def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False): +def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False, wantAck=False): """ Sends one test packet between two nodes and then returns success or failure @@ -62,8 +65,7 @@ def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False): else: toNode = toInterface.myInfo.my_node_num - logging.info(f"Sending test packet from {fromNode} to {toNode}") - wantAck = False # Don't want any sort of reliaible sending + logging.debug(f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}") global sendingInterface sendingInterface = fromInterface if not asBinary: @@ -71,15 +73,15 @@ def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False): else: fromInterface.sendData((f"Binary {testNumber}").encode( "utf-8"), toNode, wantAck=wantAck) - for sec in range(45): # max of 45 secs before we timeout + for sec in range(60): # max of 60 secs before we timeout time.sleep(1) if (len(receivedPackets) >= 1): return True - return False # Failed to send + return False # Failed to send -def testThread(numTests=50): - logging.info("Found devices, starting tests...") +def runTests(numTests=50, wantAck=False, maxFailures=0): + logging.info(f"Running {numTests} tests with wantAck={wantAck}") numFail = 0 numSuccess = 0 for i in range(numTests): @@ -88,32 +90,45 @@ def testThread(numTests=50): isBroadcast = True # asBinary=(i % 2 == 0) success = testSend( - interfaces[0], interfaces[1], isBroadcast, asBinary = False) + interfaces[0], interfaces[1], isBroadcast, asBinary=False, wantAck=wantAck) if not success: numFail = numFail + 1 logging.error( f"Test failed, expected packet not received ({numFail} failures so far)") else: numSuccess = numSuccess + 1 - logging.info(f"Test succeeded ({numSuccess} successes so far)") + logging.info( + f"Test succeeded {numSuccess} successes {numFail} failures so far") - if numFail >= 3: - for i in interfaces: - i.close() - return + #if numFail >= 3: + # for i in interfaces: + # i.close() + # return time.sleep(1) + if numFail > maxFailures: + logging.error("Too many failures! Test failed!") + + return numFail + +def testThread(numTests=50): + logging.info("Found devices, starting tests...") + runTests(numTests, wantAck=True) + runTests(numTests, wantAck=False, maxFailures=5) # Allow a few dropped packets + def onConnection(topic=pub.AUTO_TOPIC): """Callback invoked when we connect/disconnect from a radio""" print(f"Connection changed: {topic.getName()}") + def openDebugLog(portName): debugname = "log" + portName.replace("/", "_") logging.info(f"Writing serial debugging to {debugname}") return open(debugname, 'w+', buffering=1) + def testAll(): """ Run a series of tests using devices we can find. @@ -136,4 +151,3 @@ def testAll(): for i in interfaces: i.close() - diff --git a/meshtastic/tunnel.py b/meshtastic/tunnel.py index d897a92..0aa9dc0 100644 --- a/meshtastic/tunnel.py +++ b/meshtastic/tunnel.py @@ -6,7 +6,7 @@ # sudo bin/run.sh --port /dev/ttyUSB0 --setch-shortfast # sudo bin/run.sh --port /dev/ttyUSB0 --tunnel --debug # ssh -Y root@192.168.10.151 (or dietpi), default password p -# ncat -e /bin/cat -k -u -l 1235 +# ncat -e /bin/cat -k -u -l 1235 # ncat -u 10.115.64.152 1235 # ping -c 1 -W 20 10.115.64.152 # ping -i 30 -W 30 10.115.64.152 @@ -15,7 +15,8 @@ from . import portnums_pb2 from pubsub import pub -import logging, threading +import logging +import threading # A new non standard log level that is lower level than DEBUG LOG_TRACE = 5 @@ -26,8 +27,8 @@ tunnelInstance = None """A list of chatty UDP services we should never accidentally forward to our slow network""" udpBlacklist = { - 1900, # SSDP - 5353, # multicast DNS + 1900, # SSDP + 5353, # multicast DNS } """A list of TCP services to block""" @@ -35,31 +36,36 @@ tcpBlacklist = {} """A list of protocols we ignore""" protocolBlacklist = { - 0x02, # IGMP - 0x80, # Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment + 0x02, # IGMP + 0x80, # Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment } + def hexstr(barray): """Print a string of hex digits""" return ":".join('{:02x}'.format(x) for x in barray) + def ipstr(barray): """Print a string of ip digits""" return ".".join('{}'.format(x) for x in barray) + def readnet_u16(p, offset): """Read big endian u16 (network byte order)""" return p[offset] * 256 + p[offset + 1] + def onTunnelReceive(packet, interface): """Callback for received tunneled messages from mesh - + FIXME figure out how to do closures with methods in python""" tunnelInstance.onReceive(packet) + class Tunnel: """A TUN based IP tunnel over meshtastic""" - + def __init__(self, iface, subnet=None, netmask="255.255.0.0"): """ Constructor @@ -77,7 +83,8 @@ class Tunnel: global tunnelInstance tunnelInstance = self - logging.info("Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:") + logging.info( + "Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:") pub.subscribe(onTunnelReceive, "meshtastic.receive.data.IP_TUNNEL_APP") myAddr = self._nodeNumToIp(self.iface.myInfo.my_node_num) @@ -85,24 +92,26 @@ class Tunnel: for node in self.iface.nodes.values(): nodeId = node["user"]["id"] ip = self._nodeNumToIp(node["num"]) - logging.info(f"Node { nodeId } has IP address { ip }") + logging.info(f"Node { nodeId } has IP address { ip }") logging.debug("creating TUN device with MTU=200") # FIXME - figure out real max MTU, it should be 240 - the overhead bytes for SubPacket and Data from pytap2 import TapDevice self.tun = TapDevice(name="mesh") self.tun.up() - self.tun.ifconfig(address=myAddr,netmask=netmask,mtu=200) + self.tun.ifconfig(address=myAddr, netmask=netmask, mtu=200) logging.debug(f"starting TUN reader, our IP address is {myAddr}") - self._rxThread = threading.Thread(target=self.__tunReader, args=(), daemon=True) + self._rxThread = threading.Thread( + target=self.__tunReader, args=(), daemon=True) self._rxThread.start() def onReceive(self, packet): - p = packet["decoded"]["data"]["payload"] + p = packet["decoded"]["payload"] if packet["from"] == self.iface.myInfo.my_node_num: logging.debug("Ignoring message we sent") else: - logging.debug(f"Received mesh tunnel message type={type(p)} len={len(p)}") + logging.debug( + f"Received mesh tunnel message type={type(p)} len={len(p)}") # we don't really need to check for filtering here (sender should have checked), but this provides # useful debug printing on types of packets received if not self._shouldFilterPacket(p): @@ -114,36 +123,43 @@ class Tunnel: srcaddr = p[12:16] destAddr = p[16:20] subheader = 20 - ignore = False # Assume we will be forwarding the packet + ignore = False # Assume we will be forwarding the packet if protocol in protocolBlacklist: ignore = True - logging.log(LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}") - elif protocol == 0x01: # ICMP + logging.log( + LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}") + elif protocol == 0x01: # ICMP icmpType = p[20] icmpCode = p[21] checksum = p[22:24] - logging.debug(f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}") + logging.debug( + f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}") # reply to pings (swap src and dest but keep rest of packet unchanged) #pingback = p[:12]+p[16:20]+p[12:16]+p[20:] - #tap.write(pingback) - elif protocol == 0x11: # UDP + # tap.write(pingback) + elif protocol == 0x11: # UDP srcport = readnet_u16(p, subheader) destport = readnet_u16(p, subheader + 2) if destport in udpBlacklist: ignore = True - logging.log(LOG_TRACE, f"ignoring blacklisted UDP port {destport}") + logging.log( + LOG_TRACE, f"ignoring blacklisted UDP port {destport}") else: - logging.debug(f"forwarding udp srcport={srcport}, destport={destport}") - elif protocol == 0x06: # TCP + logging.debug( + f"forwarding udp srcport={srcport}, destport={destport}") + elif protocol == 0x06: # TCP srcport = readnet_u16(p, subheader) destport = readnet_u16(p, subheader + 2) if destport in tcpBlacklist: ignore = True - logging.log(LOG_TRACE, f"ignoring blacklisted TCP port {destport}") + logging.log( + LOG_TRACE, f"ignoring blacklisted TCP port {destport}") else: - logging.debug(f"forwarding tcp srcport={srcport}, destport={destport}") + logging.debug( + f"forwarding tcp srcport={srcport}, destport={destport}") else: - logging.warning(f"forwarding unexpected protocol 0x{protocol:02x}, src={ipstr(srcaddr)}, dest={ipstr(destAddr)}") + logging.warning( + f"forwarding unexpected protocol 0x{protocol:02x}, src={ipstr(srcaddr)}, dest={ipstr(destAddr)}") return ignore @@ -179,14 +195,13 @@ class Tunnel: """Forward the provided IP packet into the mesh""" nodeId = self._ipToNodeId(destAddr) if nodeId is not None: - logging.debug(f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}") - self.iface.sendData(p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck = False) + logging.debug( + f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}") + self.iface.sendData( + p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck=False) else: - logging.warning(f"Dropping packet because no node found for destIP={ipstr(destAddr)}") + logging.warning( + f"Dropping packet because no node found for destIP={ipstr(destAddr)}") def close(self): self.tun.close() - - - - diff --git a/meshtastic/util.py b/meshtastic/util.py index d384897..1b062e3 100644 --- a/meshtastic/util.py +++ b/meshtastic/util.py @@ -7,6 +7,23 @@ import serial.tools.list_ports blacklistVids = dict.fromkeys([0x1366]) +def stripnl(s): + """remove newlines from a string""" + return str(s).replace("\n", " ") + + +def fixme(message): + raise Exception(f"FIXME: {message}") + + +def catchAndIgnore(reason, closure): + """Call a closure but if it throws an excpetion print it and continue""" + try: + closure() + except BaseException as ex: + logging.error(f"Exception thrown in {reason}: {ex}") + + def findPorts(): """Find all ports that might have meshtastic devices diff --git a/proto b/proto index 8492e40..7c025b9 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 8492e4030ad928ee5fc97f8ead95325dba7f9492 +Subproject commit 7c025b9a4d54bb410ec17ee653122861b413f177 diff --git a/setup.py b/setup.py index 7f01ed4..03363ee 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ with open("README.md", "r") as fh: # This call to setup() does all the work setup( name="meshtastic", - version="1.1.45", + version="1.2.6", description="Python API & client shell for talking to Meshtastic devices", long_description=long_description, long_description_content_type="text/markdown", @@ -29,7 +29,7 @@ setup( include_package_data=True, install_requires=["pyserial>=3.4", "protobuf>=3.13.0", "pypubsub>=4.0.3", "dotmap>=1.3.14", "pexpect>=4.6.0", "pyqrcode>=1.2.1", - "pygatt>=4.0.5"], + "pygatt>=4.0.5", "easy-table==0.0.4"], extras_require={ 'tunnel': ["pytap2>=2.0.0"] },