| | |
| | | } |
| | | |
| | | impl AudioIngressMetadata { |
| | | pub(crate) const ORIGIN_STATUSES: [&'static str; 8] = [ |
| | | "controlled_fixture_bound", |
| | | "ordinary_mic_absent", |
| | | "participant_attributes_absent", |
| | | "participant_attributes_invalid", |
| | | "sequence_absent", |
| | | "sequence_replayed_or_regressed", |
| | | "wrong_participant_or_track", |
| | | "origin_unprovable", |
| | | ]; |
| | | |
| | | pub(crate) fn origin_status(attributes: &HashMap<String, String>) -> &'static str { |
| | | let source = attributes.get("inputSourceCategory").map(String::as_str); |
| | | let sequence = attributes.get("clientFixtureSequence").map(String::as_str); |
| | | match (source, sequence) { |
| | | (None, None) => "ordinary_mic_absent", |
| | | (Some("controlled_fixture"), Some(sequence)) if valid_sequence(sequence) => { |
| | | "controlled_fixture_bound" |
| | | } |
| | | (Some("controlled_fixture"), None) => "sequence_absent", |
| | | (Some("controlled_fixture"), Some(_)) => "participant_attributes_invalid", |
| | | (Some(_), _) | (None, Some(_)) => "participant_attributes_invalid", |
| | | } |
| | | } |
| | | |
| | | pub(crate) fn rejection_status(reason: &str) -> &'static str { |
| | | match reason { |
| | | "incomplete_metadata" => "participant_attributes_absent", |
| | | "invalid_source_or_sequence" => "participant_attributes_invalid", |
| | | _ => "origin_unprovable", |
| | | } |
| | | } |
| | | |
| | | pub(crate) fn rejected_origin_status( |
| | | reason: &str, |
| | | attributes: &HashMap<String, String>, |
| | | ) -> &'static str { |
| | | let status = Self::origin_status(attributes); |
| | | if status == "sequence_absent" { |
| | | status |
| | | } else { |
| | | Self::rejection_status(reason) |
| | | } |
| | | } |
| | | |
| | | pub(crate) fn from_participant( |
| | | attributes: &HashMap<String, String>, |
| | | ) -> Result<Option<Self>, &'static str> { |
| | |
| | | line["inputSourceCategory"] = json!(metadata.input_source_category); |
| | | line["clientFixtureSequence"] = json!(metadata.client_fixture_sequence); |
| | | } |
| | | line["audioIngressOriginStatus"] = json!(match ingress_metadata { |
| | | Some(_) => "controlled_fixture_bound", |
| | | None => "ordinary_mic_absent", |
| | | }); |
| | | encode_line(line) |
| | | } |
| | | |
| | |
| | | assert_eq!("pcm_s16le", value["audio"]["format"]); |
| | | assert_eq!(16000, value["audio"]["sampleRate"]); |
| | | assert_eq!(1, value["audio"]["channels"]); |
| | | assert_eq!("ordinary_mic_absent", value["audioIngressOriginStatus"]); |
| | | } |
| | | |
| | | #[test] |
| | |
| | | }), |
| | | metadata |
| | | ); |
| | | assert_eq!( |
| | | "controlled_fixture_bound", |
| | | AudioIngressMetadata::origin_status(&attributes) |
| | | ); |
| | | |
| | | attributes.insert( |
| | | "clientFixtureSequence".to_string(), |
| | |
| | | Ok(None), |
| | | AudioIngressMetadata::from_participant(&HashMap::new()) |
| | | ); |
| | | attributes.remove("clientFixtureSequence"); |
| | | assert_eq!( |
| | | "sequence_absent", |
| | | AudioIngressMetadata::origin_status(&attributes) |
| | | ); |
| | | attributes.insert( |
| | | "clientFixtureSequence".to_string(), |
| | | "bad sequence".to_string(), |
| | | ); |
| | | assert_eq!( |
| | | "participant_attributes_invalid", |
| | | AudioIngressMetadata::origin_status(&attributes) |
| | | ); |
| | | assert_eq!( |
| | | "ordinary_mic_absent", |
| | | AudioIngressMetadata::origin_status(&HashMap::new()) |
| | | ); |
| | | assert_eq!( |
| | | "participant_attributes_absent", |
| | | AudioIngressMetadata::rejection_status("incomplete_metadata") |
| | | ); |
| | | assert_eq!( |
| | | "participant_attributes_invalid", |
| | | AudioIngressMetadata::rejection_status("invalid_source_or_sequence") |
| | | ); |
| | | assert_eq!( |
| | | "origin_unprovable", |
| | | AudioIngressMetadata::rejection_status("sequence_replayed") |
| | | ); |
| | | assert_eq!( |
| | | "origin_unprovable", |
| | | AudioIngressMetadata::rejection_status("wrong_participant") |
| | | ); |
| | | assert_eq!( |
| | | "origin_unprovable", |
| | | AudioIngressMetadata::rejection_status("unknown") |
| | | ); |
| | | let missing_sequence = HashMap::from([( |
| | | "inputSourceCategory".to_string(), |
| | | "controlled_fixture".to_string(), |
| | | )]); |
| | | assert_eq!( |
| | | "sequence_absent", |
| | | AudioIngressMetadata::rejected_origin_status("incomplete_metadata", &missing_sequence) |
| | | ); |
| | | assert_eq!(8, AudioIngressMetadata::ORIGIN_STATUSES.len()); |
| | | } |
| | | |
| | | #[test] |
| | |
| | | ) |
| | | .expect("absent json"); |
| | | assert!(absent.get("inputSourceCategory").is_none()); |
| | | assert_eq!("ordinary_mic_absent", absent["audioIngressOriginStatus"]); |
| | | let with_metadata = serde_json::from_slice::<serde_json::Value>( |
| | | &session_start_line( |
| | | "call-001", |
| | |
| | | .expect("bound json"); |
| | | assert_eq!("controlled_fixture", with_metadata["inputSourceCategory"]); |
| | | assert_eq!("fixture-01", with_metadata["clientFixtureSequence"]); |
| | | assert_eq!( |
| | | "controlled_fixture_bound", |
| | | with_metadata["audioIngressOriginStatus"] |
| | | ); |
| | | let next = AudioIngressMetadata { |
| | | input_source_category: "controlled_fixture".to_string(), |
| | | client_fixture_sequence: "fixture-02".to_string(), |