Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
616 changes: 340 additions & 276 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion gaia-ccsds-c2a/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ funty = "2"
modular-bitfield-msb = "0.11"
serde = { version = "1.0", features = ["derive"] }
zerocopy = "0.6"
tlmcmddb = "0.2.0"
tlmcmddb = { git = "https://github.com/arkedge/c2a-tlmcmddb", branch = "main" }
structpack.workspace = true
async-trait = "0.1"
16 changes: 11 additions & 5 deletions gaia-ccsds-c2a/src/access/tlm/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub struct TelemetryIter<'a> {
}

impl<'a> Iterator for TelemetryIter<'a> {
type Item = (Metadata, FieldIter<'a>);
type Item = (Metadata, Option<FieldIter<'a>>);

fn next(&mut self) -> Option<Self::Item> {
let telemetry = self.telemetries.next()?;
Expand All @@ -104,10 +104,16 @@ impl<'a> Iterator for TelemetryIter<'a> {
tlm_id: telemetry.metadata.packet_id,
is_restriced: telemetry.metadata.is_restricted,
};
let fields = Box::new(iter_fields(&telemetry.entries).filter_map(|(obs, field)| {
build_bit_range(&field.extraction_info).map(|bit_range| (obs, field, bit_range))
}));
Some((metadata, FieldIter { fields }))
use tlmcmddb::tlm::Content;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [clippy] reported by reviewdog 🐶
unresolved import tlmcmddb::tlm::Content

match &telemetry.content {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [clippy] reported by reviewdog 🐶
no field content on type &tlmcmddb::tlm::Telemetry

Content::Struct(entries) => {
let fields = Box::new(iter_fields(entries).filter_map(|(obs, field)| {
build_bit_range(&field.extraction_info).map(|bit_range| (obs, field, bit_range))
}));
Some((metadata, Some(FieldIter { fields })))
}
Content::Blob => Some((metadata, None)),
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion tmtc-c2a/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ rust-embed = { version = "8.0.0", features = ["interpolate-folder-path", "debug-
mime_guess = "2.0.4"
sentry = { version = "0.31", default-features = false, features = ["backtrace", "contexts", "panic", "rustls", "reqwest"] }
sentry-tracing = "0.31"
tlmcmddb = "0.2.0"
tlmcmddb = { git = "https://github.com/arkedge/c2a-tlmcmddb", branch = "main" }
structpack.workspace = true
gaia-ccsds-c2a.workspace = true
gaia-tmtc.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion tmtc-c2a/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ mod tlm;
pub use cmd::FatCommandSchema;
pub use cmd::Registry as CommandRegistry;
pub use tlm::Registry as TelemetryRegistry;
pub use tlm::{FatTelemetrySchema, FieldMetadata, TelemetrySchema};
pub use tlm::{FatTelemetrySchema, FieldMetadata, StructTelemetrySchema, TelemetrySchema};
65 changes: 49 additions & 16 deletions tmtc-c2a/src/registry/tlm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,22 @@ impl<'a> Display for TmivName<'a> {
}

#[derive(Debug, Clone)]
pub struct TelemetrySchema {
pub enum TelemetrySchema {
Struct(StructTelemetrySchema),
Blob,
}

impl TelemetrySchema {
pub fn as_struct(&self) -> Option<&StructTelemetrySchema> {
match self {
TelemetrySchema::Struct(schema) => Some(schema),
TelemetrySchema::Blob => None,
}
}
}

#[derive(Debug, Clone)]
pub struct StructTelemetrySchema {
pub integral_fields: Vec<(FieldMetadata, IntegralFieldSchema)>,
pub floating_fields: Vec<(FieldMetadata, FloatingFieldSchema)>,
}
Expand Down Expand Up @@ -87,18 +102,21 @@ impl Registry {
self.schema_map
.iter()
.map(|((apid, tlm_id), fat_tlm_schema)| {
let fields = fat_tlm_schema
.schema
.integral_fields
.iter()
.map(|(m, _)| m)
.chain(fat_tlm_schema.schema.floating_fields.iter().map(|(m, _)| m))
.sorted_by_key(|m| m.order)
.map(|m| proto::TelemetryFieldSchema {
metadata: Some(proto::TelemetryFieldSchemaMetadata {}),
name: m.original_name.to_string(),
})
.collect();
let fields = match &fat_tlm_schema.schema {
TelemetrySchema::Blob => vec![],
TelemetrySchema::Struct(schema) => {
let integral_fields = schema.integral_fields.iter().map(|(m, _)| m);
let floating_fields = schema.floating_fields.iter().map(|(m, _)| m);
let fields = integral_fields.chain(floating_fields);
fields
.sorted_by_key(|m| m.order)
.map(|m| proto::TelemetryFieldSchema {
metadata: Some(proto::TelemetryFieldSchemaMetadata {}),
name: m.original_name.to_string(),
})
.collect()
}
};
let telemetry_schema = proto::TelemetrySchema {
metadata: Some(proto::TelemetrySchemaMetadata { id: *tlm_id as u32 }),
fields,
Expand Down Expand Up @@ -169,11 +187,16 @@ impl Registry {
}

let mut schema_map = HashMap::new();
let mut unused_apid_map = rev_apid_map.clone();
for (metadata, fields) in from_tlmcmddb(db).flatten() {
let apids = rev_apid_map
.get(metadata.component_name.as_str())
.ok_or_else(|| anyhow!("APID not defined for {}", metadata.component_name))?;
let schema = build_telemetry_schema(fields)?;
let schema = match fields {
Some(fields) => TelemetrySchema::Struct(build_telemetry_schema(fields)?),
None => TelemetrySchema::Blob,
};
unused_apid_map.remove(metadata.component_name.as_str());
for apid in apids {
let metadata = metadata.clone();
let schema = schema.clone();
Expand All @@ -187,6 +210,16 @@ impl Registry {
);
}
}

for (component_name, apid) in unused_apid_map.into_iter() {
let schema = FatTelemetrySchema {
component: component_name.to_owned(),
telemetry: "BLOB".to_owned(),
schema: TelemetrySchema::Blob,
};
schema_map.insert((apid[0], 0), schema);
}

Ok(Self {
channel_map,
schema_map,
Expand All @@ -196,8 +229,8 @@ impl Registry {

fn build_telemetry_schema<'a>(
iter: impl Iterator<Item = Result<(&'a str, FieldSchema)>>,
) -> Result<TelemetrySchema> {
let mut schema = TelemetrySchema {
) -> Result<StructTelemetrySchema> {
let mut schema = StructTelemetrySchema {
integral_fields: vec![],
floating_fields: vec![],
};
Expand Down
8 changes: 7 additions & 1 deletion tmtc-c2a/src/satellite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,14 @@ impl TmivBuilder {
let channels = self
.tlm_registry
.find_channels(space_packet.secondary_header.destination_flags());

let mut fields = vec![];
tmiv::FieldsBuilder::new(&telemetry.schema).build(&mut fields, space_packet_bytes)?;
tmiv::FieldsBuilder::new(&telemetry.schema).build(
&mut fields,
space_packet_bytes,
space_packet,
)?;

let tmivs = channels
.map(|channel| {
let name = telemetry.build_tmiv_name(channel);
Expand Down
60 changes: 52 additions & 8 deletions tmtc-c2a/src/tmiv.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use anyhow::Result;
use gaia_ccsds_c2a::ccsds_c2a::aos::space_packet::SpacePacket;
use gaia_tmtc::tco_tmiv::{tmiv_field, TmivField};

use crate::registry::TelemetrySchema;
use crate::registry::{StructTelemetrySchema, TelemetrySchema};

pub struct FieldsBuilder<'a> {
schema: &'a TelemetrySchema,
Expand All @@ -12,8 +13,12 @@ impl<'a> FieldsBuilder<'a> {
Self { schema }
}

fn build_integral_fields(&self, fields: &mut Vec<TmivField>, bytes: &[u8]) -> Result<()> {
for (name_pair, field_schema) in self.schema.integral_fields.iter() {
fn build_integral_fields(
schema: &StructTelemetrySchema,
fields: &mut Vec<TmivField>,
bytes: &[u8],
) -> Result<()> {
for (name_pair, field_schema) in schema.integral_fields.iter() {
let (raw, converted) = field_schema.read_from(bytes)?;
use gaia_ccsds_c2a::access::tlm::FieldValue;
let converted = match converted {
Expand All @@ -34,8 +39,12 @@ impl<'a> FieldsBuilder<'a> {
Ok(())
}

fn build_floating_fields(&self, fields: &mut Vec<TmivField>, bytes: &[u8]) -> Result<()> {
for (name_pair, field_schema) in self.schema.floating_fields.iter() {
fn build_floating_fields(
schema: &StructTelemetrySchema,
fields: &mut Vec<TmivField>,
bytes: &[u8],
) -> Result<()> {
for (name_pair, field_schema) in schema.floating_fields.iter() {
let (raw, converted) = field_schema.read_from(bytes)?;
use gaia_ccsds_c2a::access::tlm::FieldValue;
let converted = match converted {
Expand All @@ -56,9 +65,44 @@ impl<'a> FieldsBuilder<'a> {
Ok(())
}

pub fn build(&self, tmiv_fields: &mut Vec<TmivField>, space_packet_bytes: &[u8]) -> Result<()> {
self.build_integral_fields(tmiv_fields, space_packet_bytes)?;
self.build_floating_fields(tmiv_fields, space_packet_bytes)?;
fn build_blob_fields(
fields: &mut Vec<TmivField>,
space_packet: SpacePacket<&[u8]>,
) -> Result<()> {
fields.push(TmivField {
name: "@blob".to_string(),
value: Some(tmiv_field::Value::Bytes(space_packet.user_data.to_vec())),
});
fields.push(TmivField {
name: "@sequence_count".to_string(),
value: Some(tmiv_field::Value::Integer(
space_packet.primary_header.sequence_count() as i64,
)),
});
fields.push(TmivField {
name: "@sequence_flag".to_string(),
value: Some(tmiv_field::Value::Integer(
space_packet.primary_header.sequence_flag() as i64,
)),
});
Ok(())
}

pub fn build(
&self,
tmiv_fields: &mut Vec<TmivField>,
space_packet_bytes: &[u8],
space_packet: SpacePacket<&[u8]>,
) -> Result<()> {
match self.schema {
TelemetrySchema::Struct(struct_schema) => {
Self::build_integral_fields(struct_schema, tmiv_fields, space_packet_bytes)?;
Self::build_floating_fields(struct_schema, tmiv_fields, space_packet_bytes)?;
}
TelemetrySchema::Blob => {
Self::build_blob_fields(tmiv_fields, space_packet)?;
}
}
Ok(())
}
}