mirror of
https://github.com/meshtastic/python.git
synced 2026-05-19 14:01:09 -04:00
Merge branch 'master' into Feature-requested-20210218
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
#!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
|
||||
@@ -11,6 +17,7 @@ import pkg_resources
|
||||
from datetime import datetime
|
||||
import timeago
|
||||
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'
|
||||
@@ -21,19 +28,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']
|
||||
@@ -55,6 +65,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)
|
||||
|
||||
@@ -64,7 +75,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:
|
||||
@@ -84,63 +96,15 @@ def fromStr(valstr):
|
||||
never = 0xffffffff
|
||||
oneday = 24 * 60 * 60
|
||||
|
||||
|
||||
def setRouter(interface, on):
|
||||
"""Turn router mode on or off"""
|
||||
prefs = interface.radioConfig.preferences
|
||||
if on:
|
||||
print("Setting router mode")
|
||||
|
||||
prefs.is_router = True
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
prefs.ls_secs = oneday
|
||||
|
||||
# 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
|
||||
|
||||
# get a new GPS position once per day
|
||||
prefs.gps_update_interval = oneday
|
||||
|
||||
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
|
||||
# Returns formatted value
|
||||
|
||||
|
||||
#Returns formatted value
|
||||
def formatFloat(value, formatStr="{:.2f}", unit="", default="N/A"):
|
||||
return formatStr.format(value)+unit if value else default
|
||||
|
||||
#Returns Last Heard Time in human readable format
|
||||
# Returns Last Heard Time in human readable format
|
||||
|
||||
|
||||
def getLH(ts, default="N/A"):
|
||||
return datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') if ts else default
|
||||
|
||||
@@ -182,6 +146,23 @@ def printNodes(nodes, myId):
|
||||
|
||||
table.displayTable()
|
||||
|
||||
|
||||
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):
|
||||
"""Callback invoked when we connect to a radio"""
|
||||
closeNow = False # Should we drop the connection after we finish?
|
||||
@@ -243,7 +224,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:
|
||||
@@ -254,73 +236,70 @@ 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
|
||||
@@ -332,9 +311,10 @@ 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:
|
||||
@@ -344,6 +324,7 @@ def onConnected(interface):
|
||||
if (not args.seriallog) and closeNow:
|
||||
interface.close() # after running command then exit
|
||||
|
||||
|
||||
def onNode(node):
|
||||
"""Callback invoked when the node DB changes"""
|
||||
print(f"Node changed: {node}")
|
||||
@@ -370,13 +351,16 @@ def common():
|
||||
if not args.seriallog:
|
||||
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":
|
||||
@@ -399,6 +383,7 @@ def common():
|
||||
client = SerialInterface(
|
||||
args.port, debugOut=logfile, noProto=args.noproto)
|
||||
|
||||
|
||||
def initParser():
|
||||
global parser, args
|
||||
|
||||
@@ -419,17 +404,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",
|
||||
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')
|
||||
@@ -455,7 +437,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(
|
||||
@@ -496,27 +478,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
|
||||
@@ -524,5 +509,6 @@ def tunnelMain():
|
||||
args.tunnel = True
|
||||
common()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
148
meshtastic/admin_pb2.py
Normal file
148
meshtastic/admin_pb2.py
Normal file
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
267
meshtastic/channel_pb2.py
Normal file
267
meshtastic/channel_pb2.py
Normal file
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
|
||||
84
meshtastic/environmental_measurement_pb2.py
Normal file
84
meshtastic/environmental_measurement_pb2.py
Normal file
@@ -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)
|
||||
File diff suppressed because one or more lines are too long
@@ -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*\xf1\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\x12\n\x0eRANGE_TEST_APP\x10\x42\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,60 +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='RANGE_TEST_APP', index=9, number=66,
|
||||
name='SERIAL_APP', index=9, number=64,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='PRIVATE_APP', index=10, number=256,
|
||||
name='STORE_FORWARD_APP', index=10, number=65,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
type=None,
|
||||
create_key=_descriptor._internal_create_key),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ATAK_FORWARDER', index=11, number=257,
|
||||
name='RANGE_TEST_APP', index=11, number=66,
|
||||
serialized_options=None,
|
||||
type=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=260,
|
||||
serialized_end=337,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_PORTNUM)
|
||||
|
||||
@@ -90,13 +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
|
||||
|
||||
761
meshtastic/radioconfig_pb2.py
Normal file
761
meshtastic/radioconfig_pb2.py
Normal file
@@ -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)
|
||||
@@ -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=[
|
||||
],
|
||||
|
||||
@@ -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 ({numFail} failures) 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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user