mirror of
https://github.com/valmojr/armatak.git
synced 2026-06-13 15:43:29 +00:00
Improved code structure on Cursor Over Time generation
This commit is contained in:
109
src/cot/cot.rs
Normal file
109
src/cot/cot.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use uuid::Uuid;
|
||||
use chrono::{Duration, SecondsFormat, Utc};
|
||||
|
||||
pub struct CursorOverTime {
|
||||
pub uuid: Option<String>,
|
||||
pub r#type: Option<String>,
|
||||
pub point_lat: f64,
|
||||
pub point_lon: f64,
|
||||
pub point_hae: f32,
|
||||
pub point_ce: Option<f32>,
|
||||
pub point_le: Option<f32>,
|
||||
pub contact_callsign: String,
|
||||
pub group_name: Option<String>,
|
||||
pub group_role: Option<String>,
|
||||
pub track_course: Option<i32>,
|
||||
pub track_speed: Option<f32>,
|
||||
pub link_uid: Option<String>,
|
||||
}
|
||||
|
||||
impl CursorOverTime {
|
||||
pub fn convert_to_xml(&self) -> String {
|
||||
let uuid = match &self.uuid {
|
||||
Some(uuid) => uuid,
|
||||
None => &Uuid::new_v4().to_string(),
|
||||
};
|
||||
|
||||
let marker_type = match &self.r#type {
|
||||
Some(marker_type) => marker_type,
|
||||
None => &"a-f-G-U-C-I".to_string(),
|
||||
};
|
||||
|
||||
let created_time = Utc::now().to_rfc3339_opts(SecondsFormat::Millis, true);
|
||||
|
||||
let stale_time =
|
||||
(Utc::now() + Duration::seconds(360)).to_rfc3339_opts(SecondsFormat::Millis, true);
|
||||
|
||||
let mut xml = String::new();
|
||||
|
||||
xml.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
|
||||
|
||||
xml.push_str(
|
||||
format!("<event type=\"{}\" version=\"2.0\" how=\"m-g\" uid=\"{}\" time=\"{}\" start=\"{}\" stale=\"{}\">",
|
||||
marker_type, uuid, created_time, created_time, stale_time).as_str());
|
||||
|
||||
let point_ce = match &self.point_ce {
|
||||
Some(point_ce) => point_ce,
|
||||
None => &9999999.0,
|
||||
};
|
||||
|
||||
let point_le = match &self.point_le {
|
||||
Some(point_le) => point_le,
|
||||
None => &9999999.0,
|
||||
};
|
||||
|
||||
xml.push_str(
|
||||
format!(
|
||||
"<point ce=\"{}\" le=\"{}\" hae=\"{}\" lat=\"{}\" lon=\"{}\" />",
|
||||
point_ce, point_le, self.point_hae, self.point_lat, self.point_lon
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
|
||||
xml.push_str("<detail>");
|
||||
|
||||
xml.push_str("<takv device=\"Samsung S24\" os=\"Arma 3\" platform=\"ARMATAK\" version=\"0.9.0.0\" />");
|
||||
|
||||
if let Some(linked_uid) = &self.link_uid {
|
||||
xml.push_str("<precisionlocation altsrc=\"DTED0\" />");
|
||||
xml.push_str(
|
||||
format!(
|
||||
"<link uid=\"{}\" type=\"a-f-G-U-C\" relation=\"p-p\" />",
|
||||
linked_uid,
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
xml.push_str("<hideLabel />");
|
||||
}
|
||||
|
||||
xml.push_str(format!("<contact callsign=\"{}\" />", self.contact_callsign).as_str());
|
||||
|
||||
xml.push_str(format!("<uid Droid=\"{}\"/>", self.contact_callsign).as_str());
|
||||
|
||||
if let (Some(track_course), Some(track_speed)) = (&self.track_course, &self.track_speed) {
|
||||
xml.push_str(
|
||||
format!(
|
||||
"<track course=\"{}\" speed=\"{}\" />",
|
||||
track_course, track_speed
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
|
||||
xml.push_str("<status battery=\"89\" />");
|
||||
}
|
||||
|
||||
if let (Some(group_name), Some(group_role)) = (&self.group_name, &self.group_role) {
|
||||
xml.push_str(
|
||||
format!(
|
||||
"<__group name=\"{}\" role=\"{}\" />",
|
||||
group_name, group_role
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
}
|
||||
|
||||
xml.push_str("</detail></event>");
|
||||
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
46
src/cot/digital_pointer.rs
Normal file
46
src/cot/digital_pointer.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use arma_rs::{FromArma, FromArmaError};
|
||||
|
||||
use super::cot::CursorOverTime;
|
||||
|
||||
|
||||
pub struct DigitalPointerPayload {
|
||||
pub link_uid: String,
|
||||
pub contact_callsign: String,
|
||||
pub point_lat: f64,
|
||||
pub point_lon: f64,
|
||||
pub point_hae: f32,
|
||||
}
|
||||
|
||||
impl FromArma for DigitalPointerPayload {
|
||||
fn from_arma(data: String) -> Result<DigitalPointerPayload, FromArmaError> {
|
||||
let (link_uid, contact_callsign, point_lat, point_lon, point_hae) =
|
||||
<(String, String, f64, f64, f32)>::from_arma(data)?;
|
||||
Ok(Self {
|
||||
link_uid,
|
||||
contact_callsign,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DigitalPointerPayload {
|
||||
pub fn to_cot(&self) -> CursorOverTime {
|
||||
CursorOverTime {
|
||||
uuid: Some(format!("{}{}", self.link_uid.clone(), ".SPI1")),
|
||||
r#type: Some("b-m-p-s-p-i".to_string()),
|
||||
point_lat: self.point_lat,
|
||||
point_lon: self.point_lon,
|
||||
point_hae: self.point_hae,
|
||||
point_ce: None,
|
||||
point_le: None,
|
||||
contact_callsign: self.contact_callsign.clone(),
|
||||
group_name: None,
|
||||
group_role: None,
|
||||
track_course: None,
|
||||
track_speed: None,
|
||||
link_uid: Some(self.link_uid.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
62
src/cot/eud.rs
Normal file
62
src/cot/eud.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use arma_rs::{FromArma, FromArmaError};
|
||||
|
||||
use super::cot::CursorOverTime;
|
||||
|
||||
pub struct EudCoTPayload {
|
||||
pub uuid: String,
|
||||
pub point_lat: f64,
|
||||
pub point_lon: f64,
|
||||
pub point_hae: f32,
|
||||
pub contact_callsign: String,
|
||||
pub group_name: String,
|
||||
pub group_role: String,
|
||||
pub track_course: i32,
|
||||
pub track_speed: f32,
|
||||
}
|
||||
|
||||
impl FromArma for EudCoTPayload {
|
||||
fn from_arma(data: String) -> Result<EudCoTPayload, FromArmaError> {
|
||||
let (
|
||||
uuid,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
contact_callsign,
|
||||
group_name,
|
||||
group_role,
|
||||
track_course,
|
||||
track_speed,
|
||||
) = <(String, f64, f64, f32, String, String, String, i32, f32)>::from_arma(data)?;
|
||||
Ok(Self {
|
||||
uuid,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
contact_callsign,
|
||||
group_name,
|
||||
group_role,
|
||||
track_course,
|
||||
track_speed,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl EudCoTPayload {
|
||||
pub fn to_cot(&self) -> CursorOverTime {
|
||||
CursorOverTime {
|
||||
uuid: Some(self.uuid.clone()),
|
||||
r#type: None,
|
||||
point_lat: self.point_lat,
|
||||
point_lon: self.point_lon,
|
||||
point_hae: self.point_hae,
|
||||
point_ce: None,
|
||||
point_le: None,
|
||||
contact_callsign: self.contact_callsign.clone(),
|
||||
group_name: Some(self.group_name.clone()),
|
||||
group_role: Some(self.group_role.clone()),
|
||||
track_course: Some(self.track_course),
|
||||
track_speed: Some(self.track_speed),
|
||||
link_uid: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
4
src/cot/mod.rs
Normal file
4
src/cot/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod cot;
|
||||
pub mod digital_pointer;
|
||||
pub mod eud;
|
||||
pub mod nato;
|
||||
59
src/cot/nato.rs
Normal file
59
src/cot/nato.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use arma_rs::{FromArma, FromArmaError};
|
||||
|
||||
use super::cot::CursorOverTime;
|
||||
|
||||
pub struct MarkerCoTPayload {
|
||||
pub uuid: String,
|
||||
pub r#type: String,
|
||||
pub point_lat: f64,
|
||||
pub point_lon: f64,
|
||||
pub point_hae: f32,
|
||||
pub contact_callsign: String,
|
||||
pub track_course: i32,
|
||||
pub track_speed: f32,
|
||||
}
|
||||
|
||||
impl FromArma for MarkerCoTPayload {
|
||||
fn from_arma(data: String) -> Result<MarkerCoTPayload, FromArmaError> {
|
||||
let (
|
||||
uuid,
|
||||
r#type,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
contact_callsign,
|
||||
track_course,
|
||||
track_speed,
|
||||
) = <(String, String, f64, f64, f32, String, i32, f32)>::from_arma(data)?;
|
||||
Ok(Self {
|
||||
uuid,
|
||||
r#type,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
contact_callsign,
|
||||
track_course,
|
||||
track_speed,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl MarkerCoTPayload {
|
||||
pub fn to_cot(&self) -> CursorOverTime {
|
||||
CursorOverTime {
|
||||
uuid: Some(self.uuid.clone()),
|
||||
r#type: Some(self.r#type.clone()),
|
||||
point_lat: self.point_lat,
|
||||
point_lon: self.point_lon,
|
||||
point_hae: self.point_hae,
|
||||
point_ce: None,
|
||||
point_le: None,
|
||||
contact_callsign: self.contact_callsign.clone(),
|
||||
group_name: None,
|
||||
group_role: None,
|
||||
track_course: Some(self.track_course),
|
||||
track_speed: Some(self.track_speed),
|
||||
link_uid: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
use arma_rs::{FromArma, FromArmaError};
|
||||
use chrono::{Duration, SecondsFormat, Utc};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct CursorOverTime {
|
||||
pub uuid: Option<String>,
|
||||
pub r#type: Option<String>,
|
||||
pub point_lat: f64,
|
||||
pub point_lon: f64,
|
||||
pub point_hae: f32,
|
||||
pub point_ce: Option<f32>,
|
||||
pub point_le: Option<f32>,
|
||||
pub contact_callsign: String,
|
||||
pub group_name: Option<String>,
|
||||
pub group_role: Option<String>,
|
||||
pub track_course: Option<i32>,
|
||||
pub track_speed: Option<f32>,
|
||||
pub link_uid: Option<String>,
|
||||
}
|
||||
|
||||
impl CursorOverTime {
|
||||
pub fn convert_to_xml(&self) -> String {
|
||||
let uuid = match &self.uuid {
|
||||
Some(uuid) => uuid,
|
||||
None => &Uuid::new_v4().to_string(),
|
||||
};
|
||||
|
||||
let marker_type = match &self.r#type {
|
||||
Some(marker_type) => marker_type,
|
||||
None => &"a-f-G-U-C-I".to_string(),
|
||||
};
|
||||
|
||||
let created_time = Utc::now().to_rfc3339_opts(SecondsFormat::Millis, true);
|
||||
|
||||
let stale_time =
|
||||
(Utc::now() + Duration::seconds(360)).to_rfc3339_opts(SecondsFormat::Millis, true);
|
||||
|
||||
let mut xml = String::new();
|
||||
|
||||
xml.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
|
||||
|
||||
xml.push_str(
|
||||
format!("<event type=\"{}\" version=\"2.0\" how=\"m-g\" uid=\"{}\" time=\"{}\" start=\"{}\" stale=\"{}\">",
|
||||
marker_type, uuid, created_time, created_time, stale_time).as_str());
|
||||
|
||||
let point_ce = match &self.point_ce {
|
||||
Some(point_ce) => point_ce,
|
||||
None => &9999999.0,
|
||||
};
|
||||
|
||||
let point_le = match &self.point_le {
|
||||
Some(point_le) => point_le,
|
||||
None => &9999999.0,
|
||||
};
|
||||
|
||||
xml.push_str(
|
||||
format!(
|
||||
"<point ce=\"{}\" le=\"{}\" hae=\"{}\" lat=\"{}\" lon=\"{}\" />",
|
||||
point_ce, point_le, self.point_hae, self.point_lat, self.point_lon
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
|
||||
xml.push_str("<detail>");
|
||||
|
||||
xml.push_str("<takv device=\"Samsung S24\" os=\"Arma 3\" platform=\"ARMATAK\" version=\"0.9.0.0\" />");
|
||||
|
||||
if let Some(linked_uid) = &self.link_uid {
|
||||
xml.push_str("<precisionlocation altsrc=\"DTED0\" />");
|
||||
xml.push_str(
|
||||
format!(
|
||||
"<link uid=\"{}\" type=\"a-f-G-U-C\" relation=\"p-p\" />",
|
||||
linked_uid,
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
xml.push_str("<hideLabel />");
|
||||
}
|
||||
|
||||
xml.push_str(format!("<contact callsign=\"{}\" />", self.contact_callsign).as_str());
|
||||
|
||||
xml.push_str(format!("<uid Droid=\"{}\"/>", self.contact_callsign).as_str());
|
||||
|
||||
if let (Some(track_course), Some(track_speed)) = (&self.track_course, &self.track_speed) {
|
||||
xml.push_str(
|
||||
format!(
|
||||
"<track course=\"{}\" speed=\"{}\" />",
|
||||
track_course, track_speed
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
|
||||
xml.push_str("<status battery=\"89\" />");
|
||||
}
|
||||
|
||||
if let (Some(group_name), Some(group_role)) = (&self.group_name, &self.group_role) {
|
||||
xml.push_str(
|
||||
format!(
|
||||
"<__group name=\"{}\" role=\"{}\" />",
|
||||
group_name, group_role
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
}
|
||||
|
||||
xml.push_str("</detail></event>");
|
||||
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HumanCoTPayload {
|
||||
pub uuid: String,
|
||||
pub point_lat: f64,
|
||||
pub point_lon: f64,
|
||||
pub point_hae: f32,
|
||||
pub contact_callsign: String,
|
||||
pub group_name: String,
|
||||
pub group_role: String,
|
||||
pub track_course: i32,
|
||||
pub track_speed: f32,
|
||||
}
|
||||
|
||||
impl FromArma for HumanCoTPayload {
|
||||
fn from_arma(data: String) -> Result<HumanCoTPayload, FromArmaError> {
|
||||
let (
|
||||
uuid,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
contact_callsign,
|
||||
group_name,
|
||||
group_role,
|
||||
track_course,
|
||||
track_speed,
|
||||
) = <(String, f64, f64, f32, String, String, String, i32, f32)>::from_arma(data)?;
|
||||
Ok(Self {
|
||||
uuid,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
contact_callsign,
|
||||
group_name,
|
||||
group_role,
|
||||
track_course,
|
||||
track_speed,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl HumanCoTPayload {
|
||||
pub fn to_cot(&self) -> CursorOverTime {
|
||||
CursorOverTime {
|
||||
uuid: Some(self.uuid.clone()),
|
||||
r#type: None,
|
||||
point_lat: self.point_lat,
|
||||
point_lon: self.point_lon,
|
||||
point_hae: self.point_hae,
|
||||
point_ce: None,
|
||||
point_le: None,
|
||||
contact_callsign: self.contact_callsign.clone(),
|
||||
group_name: Some(self.group_name.clone()),
|
||||
group_role: Some(self.group_role.clone()),
|
||||
track_course: Some(self.track_course),
|
||||
track_speed: Some(self.track_speed),
|
||||
link_uid: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MarkerCoTPayload {
|
||||
pub uuid: String,
|
||||
pub r#type: String,
|
||||
pub point_lat: f64,
|
||||
pub point_lon: f64,
|
||||
pub point_hae: f32,
|
||||
pub contact_callsign: String,
|
||||
pub track_course: i32,
|
||||
pub track_speed: f32,
|
||||
}
|
||||
|
||||
impl FromArma for MarkerCoTPayload {
|
||||
fn from_arma(data: String) -> Result<MarkerCoTPayload, FromArmaError> {
|
||||
let (
|
||||
uuid,
|
||||
r#type,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
contact_callsign,
|
||||
track_course,
|
||||
track_speed,
|
||||
) = <(String, String, f64, f64, f32, String, i32, f32)>::from_arma(data)?;
|
||||
Ok(Self {
|
||||
uuid,
|
||||
r#type,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
contact_callsign,
|
||||
track_course,
|
||||
track_speed,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl MarkerCoTPayload {
|
||||
pub fn to_cot(&self) -> CursorOverTime {
|
||||
CursorOverTime {
|
||||
uuid: Some(self.uuid.clone()),
|
||||
r#type: Some(self.r#type.clone()),
|
||||
point_lat: self.point_lat,
|
||||
point_lon: self.point_lon,
|
||||
point_hae: self.point_hae,
|
||||
point_ce: None,
|
||||
point_le: None,
|
||||
contact_callsign: self.contact_callsign.clone(),
|
||||
group_name: None,
|
||||
group_role: None,
|
||||
track_course: Some(self.track_course),
|
||||
track_speed: Some(self.track_speed),
|
||||
link_uid: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DigitalPointerPayload {
|
||||
pub link_uid: String,
|
||||
pub contact_callsign: String,
|
||||
pub point_lat: f64,
|
||||
pub point_lon: f64,
|
||||
pub point_hae: f32,
|
||||
}
|
||||
|
||||
impl FromArma for DigitalPointerPayload {
|
||||
fn from_arma(data: String) -> Result<DigitalPointerPayload, FromArmaError> {
|
||||
let (link_uid, contact_callsign, point_lat, point_lon, point_hae) =
|
||||
<(String, String, f64, f64, f32)>::from_arma(data)?;
|
||||
Ok(Self {
|
||||
link_uid,
|
||||
contact_callsign,
|
||||
point_lat,
|
||||
point_lon,
|
||||
point_hae,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DigitalPointerPayload {
|
||||
pub fn to_cot(&self) -> CursorOverTime {
|
||||
CursorOverTime {
|
||||
uuid: Some(format!("{}{}", self.link_uid.clone(), ".SPI1")),
|
||||
r#type: Some("b-m-p-s-p-i".to_string()),
|
||||
point_lat: self.point_lat,
|
||||
point_lon: self.point_lon,
|
||||
point_hae: self.point_hae,
|
||||
point_ce: None,
|
||||
point_le: None,
|
||||
contact_callsign: self.contact_callsign.clone(),
|
||||
group_name: None,
|
||||
group_role: None,
|
||||
track_course: None,
|
||||
track_speed: None,
|
||||
link_uid: Some(self.link_uid.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
|
||||
use crate::cot_generator::{DigitalPointerPayload, HumanCoTPayload, MarkerCoTPayload};
|
||||
use crate::cot;
|
||||
|
||||
pub enum TcpCommand {
|
||||
SendMessage(String, Context),
|
||||
@@ -123,21 +123,21 @@ pub fn send_payload(ctx: Context, payload: String) -> &'static str {
|
||||
"Sending payload to TCP server"
|
||||
}
|
||||
|
||||
pub fn send_human_cot(ctx: Context, cursor_over_time: HumanCoTPayload) -> &'static str {
|
||||
pub fn send_eud_cot(ctx: Context, cursor_over_time: cot::eud::EudCoTPayload) -> &'static str {
|
||||
let payload = cursor_over_time.to_cot().convert_to_xml();
|
||||
send_payload(ctx, payload);
|
||||
|
||||
"Sending Human Cursor Over Time to TCP server"
|
||||
"Sending End User Device Cursor Over Time to TCP server"
|
||||
}
|
||||
|
||||
pub fn send_marker_cot(ctx: Context, cursor_over_time: MarkerCoTPayload) -> &'static str {
|
||||
pub fn send_marker_cot(ctx: Context, cursor_over_time: cot::nato::MarkerCoTPayload) -> &'static str {
|
||||
let payload = cursor_over_time.to_cot().convert_to_xml();
|
||||
send_payload(ctx, payload);
|
||||
|
||||
"Sending Marker Cursor Over Time to TCP server"
|
||||
}
|
||||
|
||||
pub fn send_digital_pointer_cot(ctx: Context, cursor_over_time: DigitalPointerPayload) -> &'static str {
|
||||
pub fn send_digital_pointer_cot(ctx: Context, cursor_over_time: cot::digital_pointer::DigitalPointerPayload) -> &'static str {
|
||||
let payload = cursor_over_time.to_cot().convert_to_xml();
|
||||
send_payload(ctx, payload);
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@ mod structs;
|
||||
mod tests;
|
||||
mod websocket;
|
||||
mod cot_router;
|
||||
mod cot_generator;
|
||||
mod video_stream;
|
||||
|
||||
mod cot;
|
||||
mod utils;
|
||||
|
||||
#[arma]
|
||||
@@ -45,7 +46,7 @@ pub fn init() -> Extension {
|
||||
Group::new()
|
||||
.command("start", cot_router::start)
|
||||
.command("send_payload", cot_router::send_payload)
|
||||
.command("send_human_cot", cot_router::send_human_cot)
|
||||
.command("send_eud_cot", cot_router::send_eud_cot)
|
||||
.command("send_marker_cot", cot_router::send_marker_cot)
|
||||
.command("send_digital_pointer_cot", cot_router::send_digital_pointer_cot)
|
||||
.command("stop", cot_router::stop)
|
||||
|
||||
Reference in New Issue
Block a user