| Crates.io | takproto |
| lib.rs | takproto |
| version | 0.4.2 |
| created_at | 2025-11-10 03:43:46.893783+00 |
| updated_at | 2025-11-11 21:54:42.706809+00 |
| description | Rust library for TAK (Team Awareness Kit) Protocol - send CoT messages to TAK servers with mTLS support |
| homepage | |
| repository | https://github.com/rabarar/takproto |
| max_upload_size | |
| id | 1924690 |
| size | 345,650 |
A Rust library for sending TAK (Team Awareness Kit) Protocol messages to TAK servers with full mTLS support.
Add to your Cargo.toml:
[dependencies]
takproto = "0.4"
tokio = { version = "1", features = ["full"] }
openssl-p12: Enable full PKCS#12 support using OpenSSL (recommended for legacy TAK P12 files)[dependencies]
takproto = { version = "0.4", features = ["openssl-p12"] }
For development, testing, or working with self-signed certificates, use TlsConfigBuilder to customize validation:
use takproto::TlsConfigBuilder;
// Accept self-signed server certificates (with client auth)
let tls_config = TlsConfigBuilder::new()
.with_p12("user.p12", "password")?
.danger_accept_invalid_certs(true)
.build()?;
// Disable hostname verification (useful for IP-based connections)
let tls_config = TlsConfigBuilder::new()
.with_p12("user.p12", "password")?
.danger_disable_hostname_verification(true)
.build()?;
// Both options together (very insecure - testing only!)
let tls_config = TlsConfigBuilder::new()
.with_p12("user.p12", "password")?
.danger_accept_invalid_certs(true)
.danger_disable_hostname_verification(true)
.build()?;
// Also works with PEM certificates
let tls_config = TlsConfigBuilder::new()
.with_client_cert("ca.pem", "client.pem", "client-key.pem")?
.danger_accept_invalid_certs(true)
.build()?;
⚠️ WARNING: These options reduce security and should only be used in trusted networks or during development.
Note: Client authentication (mTLS) is fully supported with all validation options.
Important: Legacy TAK Server P12 files use RC2-40-CBC encryption which is disabled in OpenSSL 3.x. You must convert them to a modern format first:
# Convert legacy TAK Server P12 to modern format
openssl pkcs12 -in legacy.p12 -out temp.pem -nodes -password pass:atakatak -legacy
openssl pkcs12 -export -in temp.pem -out modern.p12 -password pass:atakatak \
-certpbe AES-256-CBC -keypbe AES-256-CBC -macalg SHA256
rm temp.pem
Or use the provided conversion script:
./convert_p12.sh legacy.p12 modern.p12 atakatak
use takproto::{TakClient, TlsConfig, CotEventBuilder};
use takproto::helpers::{contact, track, status};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// For legacy P12 files, first extract to PEM using openssl:
// openssl pkcs12 -legacy -in user.p12 -nokeys -out client.pem -passin pass:atakatak
// openssl pkcs12 -legacy -in user.p12 -nocerts -nodes -out client-key.pem -passin pass:atakatak
// openssl pkcs12 -legacy -in user.p12 -cacerts -nokeys -out ca.pem -passin pass:atakatak
// Configure mTLS with P12 file (or use extracted PEM files with new_with_client_cert)
let tls_config = TlsConfig::new_with_p12("user.p12", "atakatak")?;
// Connect to TAK server
let mut client = TakClient::connect_tls(
"takserver.example.com:8089",
"takserver.example.com",
tls_config
).await?;
// Negotiate protocol (optional - for protobuf mode)
client.negotiate_protocol(1, 60).await?;
// Create a position report with builder
let event = CotEventBuilder::new()
.uid("RUST-TAK-1")
.cot_type("a-f-G-U-C") // Friendly ground unit
.lat_lon(37.7749, -122.4194)
.hae(10.0)
.ce_le(9.9, 9.9)
.how("m-g")
.stale_minutes(5)
.with_contact(contact("ALPHA-1", Some("192.168.1.100:4242")))
.with_track(track(15.0, 270.0)) // 15 m/s heading west
.with_status(status(85)) // 85% battery
.build()?;
// Send the event
client.send_cot_event(event).await?;
Ok(())
}
use takproto::{TakClient, TlsConfig, CotEventBuilder};
use takproto::helpers::{contact, track, status};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Configure mTLS with separate PEM files
let tls_config = TlsConfig::new_with_client_cert(
"ca.pem",
"client.pem",
"client-key.pem"
)?;
// Connect to TAK server
let mut client = TakClient::connect_tls(
"takserver.example.com:8089",
"takserver.example.com",
tls_config
).await?;
// Negotiate protocol (optional - for protobuf mode)
client.negotiate_protocol(1, 60).await?;
// Create a position report with builder
let event = CotEventBuilder::new()
.uid("RUST-TAK-1")
.cot_type("a-f-G-U-C") // Friendly ground unit
.lat_lon(37.7749, -122.4194)
.hae(10.0)
.ce_le(9.9, 9.9)
.how("m-g")
.stale_minutes(5)
.with_contact(contact("ALPHA-1", Some("192.168.1.100:4242")))
.with_track(track(15.0, 270.0)) // 15 m/s heading west
.with_status(status(85)) // 85% battery
.build()?;
// Send the event
client.send_cot_event(event).await?;
Ok(())
}
use takproto::helpers::{url_to_uid, remarks, color, colors};
use takproto::proto::{CotEvent, Detail};
// Put URL in marker name for visibility
let event = CotEvent {
r#type: "b-m-p-s-m".to_string(),
uid: url_to_uid("https://status.example.com"), // Shows as "status.example.com"
// ... time and position fields ...
detail: Some(Detail {
xml_detail: format!(
"{}\n{}",
remarks("📊 System Status Dashboard"),
color(colors::GREEN)
),
..Default::default()
}),
..Default::default()
};
// Send as XML for maximum compatibility
client.send_cot_event_xml(event).await?;
Common CoT types for markers:
| Type | Description | Icon |
|---|---|---|
a-f-G-U-C |
Friendly ground unit | Soldier |
a-f-A-M-F |
Friendly aircraft | Aircraft |
a-h-G-U-C |
Hostile ground unit | Enemy |
b-m-p-s-m |
Map marker | Pin |
// Negotiate protocol
client.negotiate_protocol(1, 60).await?;
// Send as protobuf
client.send_cot_event(event).await?;
// No negotiation needed - stays in XML mode
// Send as XML
client.send_cot_event_xml(event).await?;
The library includes helpers for common tasks:
use takproto::helpers::*;
// Contact information
let c = contact("ALPHA-1", Some("192.168.1.100:4242"));
// Movement tracking
let t = track(15.0, 270.0); // 15 m/s heading west (270°)
// Group affiliation
let g = group("Team Alpha", "Team Leader");
// Device status
let s = status(85); // 85% battery
// TAK version info
let tv = takv("iPhone 14", "iOS", "17.0", "iTAK 2.12.3");
// GPS precision
let p = precision_location("GPS", "GPS");
use takproto::helpers::*;
// Convert URL to clean UID
let uid = url_to_uid("https://www.example.com"); // "example.com"
// Create colored marker
let xml = format!("{}\n{}",
remarks("Important location"),
color(colors::RED)
);
// Create remarks with URLs
let xml = remarks_with_urls(
"Resources",
&[("Report", "https://example.com/report")]
);
| Platform | Client Certificate | Protocol Negotiation | XML Mode | Protobuf Mode |
|---|---|---|---|---|
| iTAK 2.12.3 | ✅ | ✅ | ✅ | ✅ |
| ATAK | ✅ | ✅ | ✅ | ✅ |
| WinTAK | ✅ | ✅ | ✅ | ✅ |
The repository includes comprehensive examples:
send_position_tls.rs - Basic mTLS connection and position reportbest_practice_itak.rs - iTAK-compatible markers with URLslisten_tls.rs - Receive messages from TAK serverexamples/ directoryRun an example:
cargo run --example send_position_tls -- \
takserver.example.com:8089 \
takserver.example.com \
ca.pem client.pem client-key.pem
This library supports:
Licensed under either of:
at your option.
Contributions are welcome! Please feel free to submit issues or pull requests.
Based on the TAK Protocol specification. Protocol Buffer definitions from the official TAK protocol documentation.