piermesh/src/Sponge/base.py

150 lines
5.2 KiB
Python
Raw Normal View History

2024-07-29 03:47:27 +00:00
import msgpack
2024-07-28 11:21:15 +00:00
import traceback
2024-08-01 01:00:46 +00:00
from Packets.Message import Message
2024-07-29 03:47:27 +00:00
import Sponge.Protocols.bubble
import Sponge.Protocols.map
import Sponge.Protocols.catch
import Sponge.Protocols.cryptography
2024-07-28 11:21:15 +00:00
class Filter:
2024-08-01 01:00:46 +00:00
"""
Packet filtering orchestration
2024-08-01 22:03:59 +00:00
`🔗 Source <https://git.utopic.work/PierMesh/piermesh/src/branch/main/Sponge/base.py>`__
2024-08-01 21:09:50 +00:00
2024-08-01 01:00:46 +00:00
cLog
Reference to `run.Node.cLog` for logging
cache: Daisy.Cache.Cache
Reference to our Daisy Cache instance
completed: list
List of completed messages IDs
todo
Reference to list of actions to do in the Node
onodeID
PierMesh node ID
"""
2024-07-28 11:21:15 +00:00
def __init__(self, cache, onodeID, todo, cLog):
self.cLog = cLog
self.cache = cache
2024-07-29 03:47:27 +00:00
"""
Messages is temporary storage for unfinished messages
"""
2024-07-28 11:21:15 +00:00
self.messages = {}
self.completed = []
self.todo = todo
self.onodeID = onodeID
2024-08-01 01:00:46 +00:00
def mCheck(self, payload: bytes):
"""
Check if payload bytes are msgpack encoded, otherwise skip
"""
2024-07-28 11:21:15 +00:00
try:
msgpack.loads(payload)
return True
except Exception as e:
self.cLog(20, "Not msgpack encoded, skipping")
return False
def selfCheck(self, packet):
2024-08-01 01:00:46 +00:00
"""
Check if this is a self packet, if so skip
"""
2024-07-28 11:21:15 +00:00
if packet["fromId"] == packet["toId"]:
self.cLog(20, "Self packet, ignored")
return False
else:
return True
2024-08-01 01:00:46 +00:00
async def protoMap(self, protocolID: int):
"""
Get protocol from protocol ID using the mlookup table
"""
2024-07-28 11:21:15 +00:00
protocolID = str(protocolID).zfill(6)
return self.cache.get("mlookup").get()[protocolID]
2024-08-01 01:00:46 +00:00
async def protoRoute(self, completeMessage: dict):
2024-07-28 11:21:15 +00:00
"""
2024-08-01 01:00:46 +00:00
Route message to proper protocol handler
2024-07-28 11:21:15 +00:00
"""
m = completeMessage
2024-08-01 01:00:46 +00:00
"""
Shorthand reference completeMessage for ease
"""
2024-07-28 11:21:15 +00:00
sender = m["sender"]
senderDisplay = m["senderDisplayName"]
recipient = m["recipient"]
recipientNode = m["recipientNode"]
# TODO: Fix packets to use class
protocol = await self.protoMap(m["packetsClass"])
self.cLog(20, "Protocol: " + protocol)
if protocol == "bubble":
2024-07-29 03:47:27 +00:00
await Sponge.Protocols.bubble.filter(
2024-07-28 11:21:15 +00:00
m, recipient, recipientNode, self.onodeID, self.todo
)
elif protocol == "map":
2024-07-29 03:47:27 +00:00
await Sponge.Protocols.map.filter(m, self.todo)
2024-07-28 11:21:15 +00:00
elif protocol == "catch":
2024-07-29 03:47:27 +00:00
await Sponge.Protocols.catch.filter(m, recipient, recipientNode, self.todo)
2024-07-28 11:21:15 +00:00
elif protocol == "cryptography":
2024-07-29 03:47:27 +00:00
await Sponge.Protocols.cryptography.filter(
2024-07-28 11:21:15 +00:00
completeMessage, recipientNode, self.todo
)
else:
self.cLog(30, "Cant route, no protocol")
async def sieve(self, packet):
2024-08-01 01:00:46 +00:00
"""
Base filtering logic, takes a single MeshTastic packet
"""
2024-07-28 11:21:15 +00:00
p = packet["decoded"]["payload"]
if self.selfCheck(packet) and self.mCheck(p):
try:
p = msgpack.loads(p)
self.cLog(20, p)
packetsID = p["packetsID"]
packetsClass = p["packetsClass"]
if packetsID == 0:
self.cLog(20, "Single packet")
# Do sp handling
pass
if packetsID in self.completed:
raise ValueError("Message already completed")
if not (packetsID in self.messages):
self.messages[packetsID] = {
"packetCount": p["packetCount"],
"data": [],
"finished": False,
"dataOrder": [],
}
if "wantFullResponse" in p.keys():
for k in p.keys():
if k != "data":
self.messages[packetsID][k] = p[k]
elif not p["packetNumber"] in self.messages[packetsID]["dataOrder"]:
self.messages[packetsID]["data"].append(p["data"])
self.messages[packetsID]["dataOrder"].append(p["packetNumber"])
if (len(self.messages[packetsID]["data"])) >= (
self.messages[packetsID]["packetCount"] - 1
) and ("wantFullResponse" in self.messages[packetsID].keys()):
self.cLog(20, "Finished receiving for message " + str(packetsID))
self.messages[packetsID]["finished"] = True
if self.messages[packetsID]["wantFullResponse"] != False:
# TO DO: implement loop
# responseLoop(packets_id)
pass
completeMessage = self.messages[packetsID]
2024-08-01 21:09:50 +00:00
completeMessage["data"] = Message.reassemble(None, completeMessage)
2024-07-28 11:21:15 +00:00
del self.messages[packetsID]
self.completed.append(packetsID)
self.cLog(20, "Assembly completed, routing")
await self.protoRoute(completeMessage)
2024-08-01 21:09:50 +00:00
except Exception:
self.cLog(30, traceback.format_exc())