![PierMesh logo](https://git.utopic.work/PierMesh/piermesh/raw/branch/main/piermeshicon.png) # PierMesh documentation # Contents: * [run: PierMesh service runner](/PierMesh/piermesh/src/branch/main/docs/run.md) * [`Node`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node) * [`Node.toLog`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.toLog) * [`Node.actions`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.actions) * [`Node.todo`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.todo) * [`Node.network`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.network) * [`Node.catch`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.catch) * [`Node.cache`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.cache) * [`Node.nodeInfo`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.nodeInfo) * [`Node.onodeID`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.onodeID) * [`Node.oTransceiver`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.oTransceiver) * [`Node.processed`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.processed) * [`Node.proc`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.proc) * [`Node.mTasks`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.mTasks) * [`Node.action_initNodeDH()`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.action_initNodeDH) * [`Node.action_keyDeriveDH()`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.action_keyDeriveDH) * [`Node.action_map()`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.action_map) * [`Node.action_sendCatch()`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.action_sendCatch) * [`Node.action_sendToPeer()`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.action_sendToPeer) * [`Node.cLog()`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.cLog) * [`Node.spongeListen()`](/PierMesh/piermesh/src/branch/main/docs/run.md#run.Node.spongeListen) * [ui: TUI application](/PierMesh/piermesh/src/branch/main/docs/ui.md) * [`TUI`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI) * [`TUI.visibleLogo`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.visibleLogo) * [`TUI.nodeOb`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.nodeOb) * [`TUI.done`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.done) * [`TUI.CSS_PATH`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.CSS_PATH) * [`TUI.action_quitFull()`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.action_quitFull) * [`TUI.action_toggleFullscreen()`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.action_toggleFullscreen) * [`TUI.compose()`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.compose) * [`TUI.do_set_cpu_percent()`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.do_set_cpu_percent) * [`TUI.do_set_mem()`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.do_set_mem) * [`TUI.do_write_line()`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.do_write_line) * [`TUI.on_mount()`](/PierMesh/piermesh/src/branch/main/docs/ui.md#ui.TUI.on_mount) * [Network: Network map representation](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md) * [`Network`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network) * [`Network.omap`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.omap) * [`Network.imap`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.imap) * [`Network.emaps`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.emaps) * [`Network.lookup`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.lookup) * [`Network.addLookup()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.addLookup) * [`Network.addie()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.addie) * [`Network.addin()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.addin) * [`Network.addoe()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.addoe) * [`Network.addon()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.addon) * [`Network.doLookup()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.doLookup) * [`Network.export()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.export) * [`Network.path`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.path) * [`Network.getRoute()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.getRoute) * [`Network.mimport()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.mimport) * [`Network.render()`](/PierMesh/piermesh/src/branch/main/docs/Siph/map.md#Siph.map.Network.render) * [hopper: Small internet interop utilities](/PierMesh/piermesh/src/branch/main/docs/Components/hopper.md) * [`get()`](/PierMesh/piermesh/src/branch/main/docs/Components/hopper.md#Components.hopper.get) * [`post()`](/PierMesh/piermesh/src/branch/main/docs/Components/hopper.md#Components.hopper.post) * [Daisy based cache](/PierMesh/piermesh/src/branch/main/docs/Daisy/Cache.md) * [`Cache`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Cache.md#Daisy.Cache.Cache) * [`Cache.create()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Cache.md#Daisy.Cache.Cache.create) * [`Cache.get()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Cache.md#Daisy.Cache.Cache.get) * [`Cache.refresh()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Cache.md#Daisy.Cache.Cache.refresh) * [`Cache.search()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Cache.md#Daisy.Cache.Cache.search) * [Daisy Catch cache](/PierMesh/piermesh/src/branch/main/docs/Daisy/Catch.md) * [`Catch`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Catch.md#Daisy.Catch.Catch) * [`Catch.get()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Catch.md#Daisy.Catch.Catch.get) * [`Catch.sget()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Catch.md#Daisy.Catch.Catch.sget) * [Daisy](/PierMesh/piermesh/src/branch/main/docs/Daisy/Daisy.md) * [`Daisy`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Daisy.md#Daisy.Daisy.Daisy) * [`Daisy.filepath`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Daisy.md#Daisy.Daisy.Daisy.filepath) * [`Daisy.msg`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Daisy.md#Daisy.Daisy.Daisy.msg) * [`Daisy.get()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Daisy.md#Daisy.Daisy.Daisy.get) * [`Daisy.read()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Daisy.md#Daisy.Daisy.Daisy.read) * [`Daisy.sublist()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Daisy.md#Daisy.Daisy.Daisy.sublist) * [`Daisy.write()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Daisy.md#Daisy.Daisy.Daisy.write) * [Soil: Daisy signal management](/PierMesh/piermesh/src/branch/main/docs/Daisy/Soil.md) * [`Compound`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Soil.md#Daisy.Soil.Compound) * [`Compound.on_any_event()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Soil.md#Daisy.Soil.Compound.on_any_event) * [Store: Daisy key value store](/PierMesh/piermesh/src/branch/main/docs/Daisy/Store.md) * [`Store`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Store.md#Daisy.Store.Store) * [`Store.getRecord()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Store.md#Daisy.Store.Store.getRecord) * [`Store.update()`](/PierMesh/piermesh/src/branch/main/docs/Daisy/Store.md#Daisy.Store.Store.update) * [WhaleSong: Diffie hellman ephemeral Fernet based encryption](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md) * [`DHEFern`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern) * [`DHEFern.cLog`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.cLog) * [`DHEFern.loadedParams`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.loadedParams) * [`DHEFern.loadedKeys`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.loadedKeys) * [`DHEFern.nodeNickname`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.nodeNickname) * [`DHEFern.cache`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.cache) * [`DHEFern.publicKey`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.publicKey) * [`DHEFern.privateKey`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.privateKey) * [`DHEFern.checkInMem()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.checkInMem) * [`DHEFern.decrypt()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.decrypt) * [`DHEFern.encrypt()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.encrypt) * [`DHEFern.genKeyPair()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.genKeyPair) * [`DHEFern.genParams()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.genParams) * [`DHEFern.getParamsBytes()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.getParamsBytes) * [`DHEFern.getRecord()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.getRecord) * [`DHEFern.getSalt()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.getSalt) * [`DHEFern.initStore()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.initStore) * [`DHEFern.keyDerive()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.keyDerive) * [`DHEFern.loadParamBytes()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.loadParamBytes) * [`DHEFern.loadRecordToMem()`](/PierMesh/piermesh/src/branch/main/docs/Cryptography/WhaleSong.md#Cryptography.WhaleSong.DHEFern.loadRecordToMem) * [base: Primary filtering functionality](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md) * [`Filter`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.base.Filter) * [`Filter.cache`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.base.Filter.cache) * [`Filter.mCheck()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.base.Filter.mCheck) * [`Filter.protoMap()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.base.Filter.protoMap) * [`Filter.protoRoute()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.base.Filter.protoRoute) * [`Filter.selfCheck()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.base.Filter.selfCheck) * [`Filter.sieve()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.base.Filter.sieve) * [Protocols](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#protocols) * [`bubble.filter()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.Protocols.bubble.filter) * [`catch.filter()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.Protocols.catch.filter) * [`cryptography.filter()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.Protocols.cryptography.filter) * [`map.filter()`](/PierMesh/piermesh/src/branch/main/docs/Sponge/base.md#Sponge.Protocols.map.filter) * [Header packet: Metadata packet](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md) * [`Header`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header) * [`Header.sender`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.sender) * [`Header.senderDisplayName`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.senderDisplayName) * [`Header.recipient`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.recipient) * [`Header.recipientNode`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.recipientNode) * [`Header.subpacket`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.subpacket) * [`Header.wantFullResponse`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.wantFullResponse) * [`Header.pAction`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.pAction) * [`Header.dump()`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.dump) * [`Header.usePreset()`](/PierMesh/piermesh/src/branch/main/docs/Packets/HeaderPacket.md#Packets.HeaderPacket.Header.usePreset) * [Packet: Base packet](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md) * [`Packet`](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md#Packets.Packet.Packet) * [`Packet.data`](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md#Packets.Packet.Packet.data) * [`Packet.packetsID`](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md#Packets.Packet.Packet.packetsID) * [`Packet.packetNumber`](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md#Packets.Packet.Packet.packetNumber) * [`Packet.packetCount`](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md#Packets.Packet.Packet.packetCount) * [`Packet.packetsClass`](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md#Packets.Packet.Packet.packetsClass) * [`Packet.dump()`](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md#Packets.Packet.Packet.dump) * [`Packet.parsePayload()`](/PierMesh/piermesh/src/branch/main/docs/Packets/Packet.md#Packets.Packet.Packet.parsePayload) * [SinglePacket: Singular packet messages for very low data applications](/PierMesh/piermesh/src/branch/main/docs/Packets/SinglePacket.md) * [`SinglePacket`](/PierMesh/piermesh/src/branch/main/docs/Packets/SinglePacket.md#Packets.SinglePacket.SinglePacket) * [SubMessage: Additional data for larger messages](/PierMesh/piermesh/src/branch/main/docs/Packets/SubMessage.md) * [`SubMessage`](/PierMesh/piermesh/src/branch/main/docs/Packets/SubMessage.md#Packets.SubMessage.SubMessage) * [SubPacket: Packets for submessages](/PierMesh/piermesh/src/branch/main/docs/Packets/SubPacket.md) * [`SubPacket`](/PierMesh/piermesh/src/branch/main/docs/Packets/SubPacket.md#Packets.SubPacket.SubPacket) * [Transceiver: Layer 0 data transceiving](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md) * [`Transceiver`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver) * [`Transceiver.cLog`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.cLog) * [`Transceiver.cryptographyInfo`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.cryptographyInfo) * [`Transceiver.filter`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.filter) * [`Transceiver.tcache`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.tcache) * [`Transceiver.tcatch`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.tcatch) * [`Transceiver.notConnected`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.notConnected) * [`Transceiver.acks`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.acks) * [`Transceiver.onodeID`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.onodeID) * [`Transceiver.messages`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.messages) * [`Transceiver.addPackets()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.addPackets) * [`Transceiver.announce()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.announce) * [`Transceiver.awaitFullResponse()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.awaitFullResponse) * [`Transceiver.awaitResponse()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.awaitResponse) * [`Transceiver.initNodeDH()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.initNodeDH) * [`Transceiver.onConnection()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.onConnection) * [`Transceiver.onReceive()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.onReceive) * [`Transceiver.progressCheck()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.progressCheck) * [`Transceiver.responseCheck()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.responseCheck) * [`Transceiver.send()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.send) * [`Transceiver.sendAnnounce()`](/PierMesh/piermesh/src/branch/main/docs/Transceiver/Transceiver.md#Transceiver.Transceiver.Transceiver.sendAnnounce) * [serve: Web UI server](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md) * [`Server`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server) * [`Server.cLog`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server.cLog) * [`Server.transmitter`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server.transmitter) * [`Server.network`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server.network) * [`Server.nodeID`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server.nodeID) * [`Server.peerIDs`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server.peerIDs) * [`Server.app`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server.app) * [`Server.catch`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server.catch) * [`Server.sendToPeer()`](/PierMesh/piermesh/src/branch/main/docs/Splash/serve.md#Splash.serve.Server.sendToPeer) # System Overview PierMesh has two main events loops to learn about: the TUI and the service. ## TUI [🔗 Docs](https://git.utopic.work/PierMesh/piermesh/src/branch/main/docs/ui.md) [🔗 Source](https://git.utopic.work/PierMesh/piermesh/src/branch/main/src/ui.py) The TUI is provided via [Textual's](https://textual.textualize.io/) library. It's a relatively simple application that gives us a quick overview of system statistics in the way of memory and cpu usage as well as scrollable logs. You can toggle full screen logs with f and close the TUI and service with q. ## The Service PierMesh runs a number of loops under the hood. These are primarily initialized in the main loop of run with a special logging loop outside of that. Note that we make heavy use of [Meshtastic's Python API](https://github.com/meshtastic/python). ### run [🔗 run.py docs](https://git.utopic.work/PierMesh/piermesh/src/branch/main/docs/run.md) [🔗 run.py source](https://git.utopic.work/PierMesh/piermesh/src/branch/main/src/run.py) #### run.main In run.main we (in order) 1. Initialize the `Node` class to a global `nodeOb`. 2. Wait for x seconds determined by command line arguments (see the falin and marcille scripts in scripts) 3. Initialize our `Transceiver` class (and the corresponding hardware) 4. Initialize our `Server` class 5. Create an async task running the `Node.spongeListen` method which looks for updates from the filter system 6. Kick the loop on with `await asyncio.sleep(1)` (we do this to kick on all async loops so I will omit this step going forward) 7. Create an async task running the `Transceiver.checkProgress` method which checks for packet reception progress and resends packets if necessary 8. Create an async task running `Node.monitor` which checks and reports system usage 9. Create an async task running the `Transceiver.announce` method which broadcasts a `Packets.Message` containing network mapping information 10. Last we start the `Microdot` server loop ### .. Travelling out of the run.main thread to the primary ____main____ code we see the other two threads: one running the `logPassLoop` loop which is created in the same way as the main thread: `lplThread = threading.Thread(target=asyncio.run, args=(logPassLoop(),))` and one running the TUI loop which has it's own system we just kick on by instantiating the TUI class and calling .run() on. ## Packet lifecycle Prior to this we've been talking relatively high level but if you've read this far you probably want more low level details. Let's talk about packets. ### Packets.Packet This is a base singular packet. At the very least a packet will contain: a packets ID which determines what set of packets (message) a singular packet belongs to if any, a packetNumber which determines which order the data will be put in, a packetCount which is, well a count of all the packets in a set of packets and in most cases data which is an lzma compressed msgpack encoded chunk of data to be fused together when the full set of packets is received. ### Packets.HeaderPacket This is the metadata packet for a set of packets (message) which handles the details necessary for routing and action triggering ### Packets.Message A set of packets instantiated primarily from lzma compressed msgpack encoded bytes ### You keep saying msgpack what is that? [msgpack](https://msgpack.org/) is what I landed on for bundling metadata and arbitrary bytes after initially using bson as msgpack is leaner, simpler and better adopted for cross platform data interchange ### Transmitting Once we have our msgpack encoded lzma compressed data we can send it with `Transceiver.addPackets` this method creates a `Message` and sends each `Packet` (dumped to binary data) over LoRa using Meshtastic's Python interface via the `Transceiver.send` method. ### Receiving On the other end when we receive a `Packet` we pass it directly into `Sponge.base.sieve` which checks: if it's msgpack encoded and if it's a packet sent by the same node. In both cases it skips the packet, otherwise we sieve! ### Sieving Primarily in this stage we are gathering packets and adding them to an object containing all of the packet info and data we've received for that `Message`. Once a `Message` is completed we pass it on to the appropriate protocol from `Sponge.Protocols`. These will pass the `Message` wherever it needs to go from there which can be any number of places. To avoid unnecessary manual documentation labor for future devs I will not list everything that could happen here but here are some examples: - Updating a Catch - Sending a message up to a peer on the node - Sending a Diffie Hellman handshake # Fin Well not really, there's more to learn but these are the basics. There's more in the docs above and you can always submit an issue or reach me at info@piermesh.net or on Tumblr at utopicwork.