paulmandal/atak-forwarder

How tightly coupled is meshtastic?

Buttars opened this issue · 10 comments

Looking over the example screenshots and code it looks like this is very tightly coupled to meshtastic.
Is there an abstraction layer that would allow other protocols if implemented correctly? I'm specifically trying to implement Zigbee 3.0 but I'm realizing there is no messenger agnostic data export for atak. I'd have to likely write my own plugin if that is the case.

I have done something similar (Iridium SBD). What I did is hijack the packetized payload protobuf before if gets forwarded to the Meshtastic app services. I didn't fork or submit to this tool variation as I didn't want to muddy up Paul's code. Maybe it's time to ask for a more formal slot in his repository for non-meshtastic forwarding ports.

[EDIT] Probably also worth mentioning that I don't use standard Meshtastic hardware or software or really touch Android, it's a RaspberryPi Zero 2 W with a virtual ethernet port. There is a least-cost router running on the RPi trying WiFi, Mesh(tastic), then Iridium ($$$/message), I only send filtered COT messages to the protobuf library Paul has to pack messages if the route is mesh or Iridium. Iridium Short-Burst-Data (their version of SMS) conveniently has a device to device message length limit of 270 bytes which is very similar to the payload byte limit of Meshtastic. Since it only uses a part of this tool, I thought it best to keep it completely separate from this tool's repo. [/EDIT]

I think this repository is very high quality and has a lot of potential. I'd love to see the broadcasting layer abstracted away so we can implement different protocols. Unfortunately I believe they rely heavily on the UI to get meshtastic to work with ATAK with things like the QR code for the room (or whatever they're called on meshtastic).

Is it possible to have two plugins communicate? If so there is some serious opportunity to create a generic plugin to export the COT messages as events that can be observed and reacted to.

I'm thinking two plugs, one to export the messages as events and another to handle the UI and protocol of the specific broadcasting protocol.

Unfortunately, meshtastic is extremely limiting with it's hardware and software limitations with it's HWID binding for identification and the fact it is a message bus and not an event bus like MQTT or Kaffka.

I'd like to get the communities response to idea.

Something to think about is the stability of TAK and the Forwarder plugin. The reason I went the way I did, is that TAK likes to see a network and a fat pipe for data. IIRC DoD/NATO is using cellular and IP packet radio for the network - I didn't want to fight the architecture too much, but I wanted compatibility with the Meshtastic packing that Paul was doing (and others are using). Plugins are plugins, and have to be maintaned/updated - Paul does a monumental job keeping it up to date, but I didn't want to have to rely on that, or pile on with nagging for updates when he's out living life.

The way the Forwarder plugin is written makes it very easy to port the user-space Meshtastic way of the world into a TAK UI - but if you're willing to get into the Meshtastic protocol spec, there is actually a lot of extra mesh flexibility not presented through either the plugin or the Meshtastic app itself. For instance you can't act as both a node and a router with the Meshtastic app.

Have you looked at the COT message protocol? If you can provide a network to your device (android, iphone, etc) TAK will send its heart out over that interface - once you have the COT stream you can pretty much do whatever you want with it.

The ESP32 can do either Bluetooth (how Meshtastic uses it) for low-speed serial or WiFi to present a network directly to TAK - by not modifying the Meshtastic node, a plugin is required to pre-pack data into a form the unmodified Meshtastic node can use. But, if you modified the Meshtastic node to provide WiFi and do the COT protobuf packing on the node instead, you wouldn't need the plugin. If the ESP32 is already doing WiFi and COT-protobuf packing, then is doesn't need to send it out over LoRa, you can send it out any method you chose ZigBee, direct TTL modulated laser point-to-point, even HF/VHF/UHF with an appropriate packet modem or directly via ESP32-SDR (like https://github.com/thaaraak/SDR-Transceiver - no affiliation).

I only used the RPi Zero because it had the option for presenting a USB-OTG-ethernet device out of the box which works with Android - and I'd still have multi-Mbps WiFi I could use for mesh on a different band, and a ton more IO (I2C/I2S/SPI/UART and then GPIOs) and extra compute power for other stuff without tiny memory constraints (512MB of RAM versus 4-32MB for ESP32 parts).

Something to think about is the stability of TAK and the Forwarder plugin. The reason I went the way I did, is that TAK likes to see a network and a fat pipe for data. IIRC DoD/NATO is using cellular and IP packet radio for the network - I didn't want to fight the architecture too much, but I wanted compatibility with the Meshtastic packing that Paul was doing (and others are using). Plugins are plugins, and have to be maintaned/updated - Paul does a monumental job keeping it up to date, but I didn't want to have to rely on that, or pile on with nagging for updates when he's out living life.

The way the Forwarder plugin is written makes it very easy to port the user-space Meshtastic way of the world into a TAK UI - but if you're willing to get into the Meshtastic protocol spec, there is actually a lot of extra mesh flexibility not presented through either the plugin or the Meshtastic app itself. For instance you can't act as both a node and a router with the Meshtastic app.

Have you looked at the COT message protocol? If you can provide a network to your device (android, iphone, etc) TAK will send its heart out over that interface - once you have the COT stream you can pretty much do whatever you want with it.

The ESP32 can do either Bluetooth (how Meshtastic uses it) for low-speed serial or WiFi to present a network directly to TAK - by not modifying the Meshtastic node, a plugin is required to pre-pack data into a form the unmodified Meshtastic node can use. But, if you modified the Meshtastic node to provide WiFi and do the COT protobuf packing on the node instead, you wouldn't need the plugin. If the ESP32 is already doing WiFi and COT-protobuf packing, then is doesn't need to send it out over LoRa, you can send it out any method you chose ZigBee, direct TTL modulated laser point-to-point, even HF/VHF/UHF with an appropriate packet modem or directly via ESP32-SDR (like https://github.com/thaaraak/SDR-Transceiver - no affiliation).

I only used the RPi Zero because it had the option for presenting a USB-OTG-ethernet device out of the box which works with Android - and I'd still have multi-Mbps WiFi I could use for mesh on a different band, and a ton more IO (I2C/I2S/SPI/UART and then GPIOs) and extra compute power for other stuff without tiny memory constraints (512MB of RAM versus 4-32MB for ESP32 parts).

It seems like the code is very coupled to the meshtastic implementation. Why vision is to segregate the layers into distinct layers that abstract from each other as much as possible. This can be achieved by writing a abstraction around COT Messages on a Pi Zero as you suggested and creating a pluggable mapping of sorts to different device types.

If I understand what you're saying is that by providing the Pi Zero I get a stream of COT data and can package it at that layer to be sent over whatever medium I want.

I've seen this done to get ATAK over UHF/VHF before the HAMMER plugin and in other projects where they're sending burst data over HAM.

Do you have any resources around how ATAK exposes that data upon a connection? Is it some protocol on a port or something? I appreciate any support.

If I understand what you're saying is that by providing the Pi Zero I get a stream of COT data and can package it at that layer to be sent over whatever medium I want.

You got it. Forwarder ingests this stream in TAK before it's sent out to a network port and then whittles it down to a more compact bitstream that fits in Meshtastic packets, and redirects it to Meshtastic hardware and subsequent air-protocol instead of a network gateway for forwarding to a TAK server.

Typical ports ar 8087/8089 TCP/UDP. The COT traffic is XML - a Google search for Cursor On Target schema provides a PDF result from MITRE which is still pretty current. Various other Git repos have tools for converting your favorite data format into and out of a given schema.

The method I picked was building a thin regular-expression-based stream-processor on an NGINX server runing on PI to act as a pseudo-TAK-server (cuts down the lag in processing-to-air), then creating a vitual "TAK Server Net" to make entry-and-exit points to the virtual net. In TAK parlance, this would be like a singular soldier's ATAK phone connecting to a TAK server on a nearby MRAP with a micro-cell basestation (in the chain this would be my RPi) and then the local MRAP TAK server federating with a network of other TAK servers to syncronize real-time state using whatever network access it has. Like I said I didn't want to fight the architecture too much, it was a pretty good idea/setup to start with (us civilians just aren't allowed to purchase the sensitive military gear to replicate all of it). When I did this TAK server was also not public-release, and FreeTAKServer was not really up an running.

Slight Tangent... Dealing with a network, standard network security cautions apply. With my setup, the "network" is hardwired from USB to the RPi, so I can see if there is a man-in-the-middle-attack taking place on my physical person :P, TAK implemented on general network hardware is best done with pre-diretibuted certificates, encryption (TLS 1.2+), VPN, user authentication, etc... This is the bulk of the support docs for setting up TAK Server official (i.e. all the security stuff). Same applies for any over-the-air protocol you land on, even Mestastic is not "secure" secure (just difficult to read for those not in-the-know). The nice thing about symmetric encryption like AES128/256 is that it doesn't add to the payload size... if it fits in a block. But not much beats a OTP and XOR at any size.

Yes I think I'm going to go with a wired OTG approach too. It makes sense for my use case. I was unaware that ATAK has native federation support. That makes a ton of sense. My ideal setup would be having local short range nodes/hubs that federate with several but fewer long range hubs. Like a fireteam having a local instance of tak server that communicates to the HQ tak server to keep everything synced. Glad to hear this is the intended architecture.

Are you saying I need the forwarder plugin to expose the traffic to those ports or is that something that is already natively available while connected to a network? If I do need the plugin, I may fork it and strip out the UI and meshtastic specific code to allow just exposing of traffic.

So far my understanding is this, I plugin the Zero to the phone as OTG ethernet source. ATAK exposes ports (either through the plugin or natively) that allow me to listen to the traffic. I then format and encode that into whatever shape I need before sending off the packet to Zigbee in my case. When you're referring to the "pseudo-TAK-server" is that running on the Zero? Is that what you're using to allow ATAK to forward the traffic? In your case you mentioned NGINX to mimic the TAK server, do you have a code example of this or know where I can find one? I think this is 90% of the work for what I'm trying to accomplish.

Another non TAK project I plan on doing with these is to attach them to an access point and provide messaging services for nearby devices. This would be useful say in a search and rescue context where you may have dozens of people and can't have one device per person and want everyone to communicate through the off grid group chat. Or god forbid a natural disaster that takes down communications I could spread a few of these throughout my neighborhood to give my neighbors a better chance at organizing.

And again, thank you for all of this information. It's incredibly useful especially with how difficult it is to find documentation and resources around this stuff.

...I was unaware that ATAK has native federation support...

The TAK client app (iTAK/ATAK even WinTAK) does not AFAIK have direct federation capabilites - it must register to a server or a connector (plug-in) which acts as a proxy for an IT network. Forwarder is a plug-in which handles push pull to a non-internet data exchange, my variant emulates a direct-connected TAK Server. I just want to be clear on that.

Are you saying I need the forwarder plugin to expose the traffic to those ports or is that something that is already natively available while connected to a network?

Plugins provide unmodified TAK client, which is IP network dependent, an alternative path for data. Like Hammer does for radios. TAK client generates and consumes COT packets in XML. XML is not really magic, it's a data structure just like a webpage is (and basically the same markup as XML). One traffic is sent to a plugin, it is under that plugin's control what happens to the packet contents. The Forwarder plugin squeezes the packet down to some basic elemets and compresses it so that it fits in a payload meshtastic can handle (this was the ONLY part of Paul's work I was really interested in), then it forwards it to Meshtastic via API to go over to the hardware and eventually to air. Seriously do a google search for "COT schema", then do a GIT search for projects with the same - anything not private is free to read through, there are a LOT of public projects (even TAK official code btw).

Think of TAK like a human-centered data generator and consumer - most processing is normally done in the backend at aggregation, without even a UI (but very likely with AI). Considering the plugins already out there - most are about either generating more standardized data to aggregate, enabling ways of enabling data transit for eventual aggregation, or closer control for things that would be better served by local control in order to generate more data to aggregate. Information is power - you want information overload so you can throw a Hardigg case of servers at the incoming COT stream to analyze it and give you a global view worth of situational awareness of the combat enviroment and enough insight for you to send back down a common operating picture and form some kind of battle plan.

Another non TAK project I plan on doing with these is to attach them to an access point and provide messaging services for nearby devices. This would be useful say in a search and rescue context where you may have dozens of people and can't have one device per person and want everyone to communicate through the off grid group chat. Or god forbid a natural disaster that takes down communications I could spread a few of these throughout my neighborhood to give my neighbors a better chance at organizing.

This is a can or worms. To be frank you might as well use this Meshtastic Forwarder Plugin for long range infrastrucrure-deficient hopping and put up some meshtastic routers, these are between $15-35 in commodity hardware now. You can spend your effort putting these out in advance of your need and spend te effort to make them more resilient over longer deployments (in this thread, I shared some of what my deployed Meshtastic unconnected nodes and routers have). If you need higher bandwidth networking for non-disaster scenarios use OpenWRT running the actual TAK Server java machine (these Java TAK servers on individual WiFi-APs can be federated to form a full network) - this does not require connection to the internet, it can be a private network (though internet connection might be a good way to ensure you have up-time). That's the lowest effort path to get what you want IMHO. I tend to go tens of miles in BLM back-country where cell service is a fairytale and line of sight radio is infrequent. Thus the mesh and Iridium capability I needed (I can always see the sky, and and probably see a ridgline I've been up). Match your needs to the available solutions first before spending the time/effort building a new thing. You never get spent time back.

...federation support. That makes a ton of sense. My ideal setup would be having local short range nodes/hubs that federate with several but fewer long range hubs. Like a fireteam having a local instance of tak server that communicates to the HQ tak server to keep everything synced. Glad to hear this is the intended architecture.

Federation is actually one the the organizational powers of the TAK system. You can imagine military orgs having granular TAK servers and then federating for "need-to-know" within an event. Put two teams together for a fire mission? Federate their TAK domains, need to send intel down from higher? You can send that in a one-way pipe to the lower TAK domain without revealing the whole TAK hirearchy (reduces clutter, intel leakage, etc...). Same in Civil use, you could use one TAK domain for Fire, one for Police (one each for PD, Sheriff, State PD), one for the Ambulance system - get a mass casualty event and you can start federating servers to give local players a global view of the situation and filter pipes between layers of TAK servers to control what information is going where. It's really slick.

I don't claim to be a professional with a sound grasp of the code-base, just FYI, I got through enough to get what I needed done, my Google-fu is strong I and I know how to copy-paste from Stack Overflow well enough ;-P. I think a alot of the reason the documentation is weak, is that every professional with a sound grasp of the functionaility/code-base who is doing it outside DoD/NATO is trying to sell a product back into that ecosystem - and general understanding reduces the market by enabling additional competition (there's also the security argument - but you don't open source something which is that vulnerable to critical breaches IMO). DoD probably has an interest in the documentation being better and more readily available, but then it comes down to costs and ROI.

So far my understanding is this, I plugin the Zero to the phone as OTG ethernet source. ATAK exposes ports (either through the plugin or natively) that allow me to listen to the traffic. I then format and encode that into whatever shape I need before sending off the packet to Zigbee in my case. When you're referring to the "pseudo-TAK-server" is that running on the Zero? Is that what you're using to allow ATAK to forward the traffic? In your case you mentioned NGINX to mimic the TAK server, do you have a code example of this or know where I can find one? I think this is 90% of the work for what I'm trying to accomplish.

Mostly right on - the RPi looks like a hardwired Ethernet network adapater to the phone, TAK client send the data to the phone to send over whatever network it can, phone sees the USB network adapter (RPi), sends data to the adapter (RPi), RPi has a serivce running on the port (8087 IIRC, but you can set/force this in TAK client to anything) which does all the correct handshaking and reception transmission on that port to look like TAK client just talked to a TAK server. From there the raw data is in the RPi and standard Perl compatible regex stream filters in NGINX allow the RPi to see what kind of data is in there. FastCGI scripts make the work happen in the RPis OS.

I make some descisions in a stand alone thread about what kind of connections are available - I have a B.A.T.M.A.N 2.4GHz Wifi Mesh service running on the RPi, a Meshtastic service running on the RPi, a softmodem for mic-headset jacks for a commercial VHF/UHF radio, and an Iridium modem handler running on the RPi - each reports network connectivity and message traffic. WiFi is cheapest, radio soft modem is still fairly high bandwidth cheap, but meshtastic and Iridium are rate controlled and expensive respectively - messages that don't find a route over WiFi/UHF/VHF get sent to the stripped down packer library from Forwarder (to compress from raw COT XML down to compressed payloads) before either being sent to the Meshtastic servce or sent to the Iridium SBD modem.

I don't have code to share - even if I had a habit of doing that just explaining it is as you can see in this above thread it's bunch of writing. If you've viewed my GIT space, you can see as I've stated before, I'm not a professional at this. I'm first to admit I'm terrible at documentation. That, and due to a recent move for my apartment to be refurbished, all of my development gear is in storage, so I don't even have access to the code-base I built (and knowing how fragile everything is, I'd hesitate to share anyway). This is my lunch break at work.

I can take what I've learend and poke at people in the right direction so they learn too...

You got my brain bugging me, since I have a moment between meetings, look up "The Developer's Guide to Cursor on Target" - it's a PDF put out by MITRE about a decade ago which gives a pretty solid foundation for what is in the XML and why.

Then look up "CoTTypes.xml" on Google and also look up FreeTAKServer on GIT.

Those will probably get you started on seeing how much work it is to roll-your-own.

[EDIT] ...and now about to leave for home, take a look at TAKProto - Greg has a ton of TAK/CoT projects you can read through that should give you some significant protocol insight. Like I said, Google-fu... [/EDIT]

@paulmandal any interest in just building a separate repo with a CoT-->Meshpacket and Meshpacket-->CoT functions and linking your (un-)packaging algorithm linked to this project's repo? Separate from Buttars' query, I've heard through the grapevine a bunch of other interfaces that want your packaging for compatibility/interoperability...