takproto 0.4.2

Rust library for TAK (Team Awareness Kit) Protocol - send CoT messages to TAK servers with mTLS support
Documentation
# takproto

[![Crates.io](https://img.shields.io/crates/v/takproto.svg)](https://crates.io/crates/takproto)
[![Documentation](https://docs.rs/takproto/badge.svg)](https://docs.rs/takproto)
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/License-MIT%20OR%20Apache--2.0-blue.svg)](https://github.com/yourusername/takproto#license)

A Rust library for sending TAK (Team Awareness Kit) Protocol messages to TAK servers with full mTLS support.

## Features

- **TAK Protocol Version 1** - Protocol Buffer-based messaging
-**mTLS Support** - Client certificate authentication
-**Protocol Negotiation** - Automatic handshake with TAK servers
-**XML Mode** - Legacy Protocol Version 0 support
-**Async/Await** - Built on Tokio for efficient I/O
-**Type-Safe** - Generated protobuf types with prost
-**Builder Pattern** - Ergonomic CotEventBuilder for easy event creation
-**Detail Helpers** - Contact, track, group, status, and more
-**Helper Functions** - Easy marker and URL creation

## Quick Start

Add to your `Cargo.toml`:

```toml
[dependencies]
takproto = "0.4"
tokio = { version = "1", features = ["full"] }
```

### Feature Flags

- **`openssl-p12`**: Enable full PKCS#12 support using OpenSSL (recommended for legacy TAK P12 files)

```toml
[dependencies]
takproto = { version = "0.4", features = ["openssl-p12"] }
```

### Certificate Validation Options

For development, testing, or working with self-signed certificates, use `TlsConfigBuilder` to customize validation:

```rust
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.

## Example: Send a Position Report with Builder

### Using PKCS#12 Certificate (Recommended for TAK)

**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:

```bash
# 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:

```bash
./convert_p12.sh legacy.p12 modern.p12 atakatak
```

```rust
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(())
}
```

### Using Separate PEM Files

```rust
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(())
}
```

## Example: Create Markers with URLs (iTAK Compatible)

```rust
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?;
```

## CoT Event Types

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 |

## Protocol Modes

### Protobuf Mode (Recommended for high-frequency updates)

```rust
// Negotiate protocol
client.negotiate_protocol(1, 60).await?;

// Send as protobuf
client.send_cot_event(event).await?;
```

### XML Mode (Recommended for markers with details)

```rust
// No negotiation needed - stays in XML mode

// Send as XML
client.send_cot_event_xml(event).await?;
```

## Helper Functions

The library includes helpers for common tasks:

### Detail Helpers (Protobuf messages)

```rust
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");
```

### XML Helpers

```rust
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 Support

| Platform | Client Certificate | Protocol Negotiation | XML Mode | Protobuf Mode |
|----------|-------------------|---------------------|----------|---------------|
| iTAK 2.12.3 |||||
| ATAK |||||
| WinTAK |||||

## Documentation

- [API Documentation]https://docs.rs/takproto
- [CoT Types Guide]https://github.com/yourusername/takproto/blob/main/docs/COT_TYPES_AND_LINKS.md
- [iTAK Solution Guide]https://github.com/yourusername/takproto/blob/main/docs/ITAK_FINAL_SOLUTION.md
- [Troubleshooting]https://github.com/yourusername/takproto/blob/main/docs/ITAK_TROUBLESHOOTING.md

## Examples

The repository includes comprehensive examples:

- `send_position_tls.rs` - Basic mTLS connection and position report
- `best_practice_itak.rs` - iTAK-compatible markers with URLs
- `listen_tls.rs` - Receive messages from TAK server
- And many more in the `examples/` directory

Run an example:

```bash
cargo run --example send_position_tls -- \
  takserver.example.com:8089 \
  takserver.example.com \
  ca.pem client.pem client-key.pem
```

## Security

This library supports:
- **mTLS** - Mutual TLS authentication with client certificates
- **TLS 1.2/1.3** - Modern TLS protocols via rustls
- **Certificate validation** - Proper CA certificate chain validation

## Requirements

- Rust 1.70 or later
- TAK server (FreeTAKServer, TAK Server, etc.)
- Client certificates for mTLS (if required by server)

## License

Licensed under either of:

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE)
- MIT License ([LICENSE-MIT]LICENSE-MIT)

at your option.

## Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

## Related Projects

- [TAK Protocol Specification]https://tak.gov
- [ATAK]https://tak.gov/products/atak - Android Team Awareness Kit
- [iTAK]https://tak.gov/products/itak - iOS Team Awareness Kit
- [FreeTAKServer]https://github.com/FreeTAKTeam/FreeTakServer - Open source TAK server

## Acknowledgments

Based on the TAK Protocol specification. Protocol Buffer definitions from the official TAK protocol documentation.