matc/clusters/codec/
content_launcher.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, serde::Serialize)]
14pub struct AdditionalInfo {
15 pub name: Option<String>,
16 pub value: Option<String>,
17}
18
19#[derive(Debug, serde::Serialize)]
20pub struct BrandingInformation {
21 pub provider_name: Option<String>,
22 pub background: Option<StyleInformation>,
23 pub logo: Option<StyleInformation>,
24 pub progress_bar: Option<StyleInformation>,
25 pub splash: Option<StyleInformation>,
26 pub water_mark: Option<StyleInformation>,
27}
28
29#[derive(Debug, serde::Serialize)]
30pub struct ContentSearch {
31 pub parameter_list: Option<Vec<Parameter>>,
32}
33
34#[derive(Debug, serde::Serialize)]
35pub struct Dimension {
36 pub width: Option<u8>,
37 pub height: Option<u8>,
38 pub metric: Option<u8>,
39}
40
41#[derive(Debug, serde::Serialize)]
42pub struct Parameter {
43 pub type_: Option<u8>,
44 pub value: Option<String>,
45 pub external_id_list: Option<Vec<AdditionalInfo>>,
46}
47
48#[derive(Debug, serde::Serialize)]
49pub struct PlaybackPreferences {
50 pub playback_position: Option<u64>,
51 pub text_track: Option<TrackPreference>,
52 pub audio_tracks: Option<Vec<TrackPreference>>,
53}
54
55#[derive(Debug, serde::Serialize)]
56pub struct StyleInformation {
57 pub image_url: Option<String>,
58 pub color: Option<String>,
59 pub size: Option<Dimension>,
60}
61
62#[derive(Debug, serde::Serialize)]
63pub struct TrackPreference {
64 pub language_code: Option<String>,
65 pub characteristics: Option<Vec<u8>>,
66 pub audio_output_index: Option<u8>,
67}
68
69pub fn encode_launch_content(search: u8, auto_play: bool, data: String, playback_preferences: u8, use_current_context: bool) -> anyhow::Result<Vec<u8>> {
73 let tlv = tlv::TlvItemEnc {
74 tag: 0,
75 value: tlv::TlvItemValueEnc::StructInvisible(vec![
76 (0, tlv::TlvItemValueEnc::UInt8(search)).into(),
77 (1, tlv::TlvItemValueEnc::Bool(auto_play)).into(),
78 (2, tlv::TlvItemValueEnc::String(data)).into(),
79 (3, tlv::TlvItemValueEnc::UInt8(playback_preferences)).into(),
80 (4, tlv::TlvItemValueEnc::Bool(use_current_context)).into(),
81 ]),
82 };
83 Ok(tlv.encode()?)
84}
85
86pub fn encode_launch_url(content_url: String, display_string: String, branding_information: u8, playback_preferences: u8) -> anyhow::Result<Vec<u8>> {
88 let tlv = tlv::TlvItemEnc {
89 tag: 0,
90 value: tlv::TlvItemValueEnc::StructInvisible(vec![
91 (0, tlv::TlvItemValueEnc::String(content_url)).into(),
92 (1, tlv::TlvItemValueEnc::String(display_string)).into(),
93 (2, tlv::TlvItemValueEnc::UInt8(branding_information)).into(),
94 (3, tlv::TlvItemValueEnc::UInt8(playback_preferences)).into(),
95 ]),
96 };
97 Ok(tlv.encode()?)
98}
99
100pub fn decode_accept_header(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<String>> {
104 let mut res = Vec::new();
105 if let tlv::TlvItemValue::List(v) = inp {
106 for item in v {
107 if let tlv::TlvItemValue::String(s) = &item.value {
108 res.push(s.clone());
109 }
110 }
111 }
112 Ok(res)
113}
114
115pub fn decode_supported_streaming_protocols(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
117 if let tlv::TlvItemValue::Int(v) = inp {
118 Ok(*v as u8)
119 } else {
120 Err(anyhow::anyhow!("Expected Integer"))
121 }
122}
123
124
125pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
137 if cluster_id != 0x050A {
139 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x050A, got {}\"}}", cluster_id);
140 }
141
142 match attribute_id {
143 0x0000 => {
144 match decode_accept_header(tlv_value) {
145 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
146 Err(e) => format!("{{\"error\": \"{}\"}}", e),
147 }
148 }
149 0x0001 => {
150 match decode_supported_streaming_protocols(tlv_value) {
151 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
152 Err(e) => format!("{{\"error\": \"{}\"}}", e),
153 }
154 }
155 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
156 }
157}
158
159pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
164 vec![
165 (0x0000, "AcceptHeader"),
166 (0x0001, "SupportedStreamingProtocols"),
167 ]
168}
169