Skip to main content

yooper/ssdp/
message.rs

1//! A set of symbolic representations of SSDP packets
2
3mod codec;
4pub(self) mod types;
5
6use crate::ssdp::packet::{FromHeaders, FromPacket, ToHeaders, ToPacket};
7pub use codec::Codec;
8
9pub use types::{SearchTarget, UniqueServiceName};
10
11#[derive(ToHeaders, FromHeaders, Debug, PartialEq, Default)]
12pub struct MSearch {
13    pub host: String,
14
15    pub man: types::ManDiscover,
16
17    #[header("cache-control")]
18    pub cache_control: Option<String>,
19
20    /// Maximum wait time in seconds. shall be greater than or equal to 1 and should
21    /// be less than 5 inclusive.
22    #[header("mx")]
23    pub max_wait: Option<u8>,
24
25    // TODO: enum
26    /// Field value contains Search Target.
27    #[header("st")]
28    pub target: SearchTarget,
29    /// Field value shall begin with the following “product tokens” (defined
30    /// by HTTP/1.1). The first product token identifes the operating system in the form OS name/OS version, the
31    /// second token represents the UPnP version and shall be UPnP/2.0, and the third token identifes the product
32    /// using the form product name/product version. For example, “USER-AGENT: unix/5.1 UPnP/2.0
33    /// MyProduct/1.0”.
34    pub user_agent: Option<String>,
35    /// if set, this TCP port can be used for any follow up requests
36    #[header("tcpport.upnp.org")]
37    pub tcp_port: Option<u16>,
38    /// Specifies the friendly name of the control point. The friendly name is vendor specific.
39    #[header("cpfn.upnp.org")]
40    pub friendly_name: Option<String>,
41    /// uuid of the control point.
42    #[header("cpuuid.upnp.org")]
43    pub uuid: Option<String>,
44}
45
46#[derive(ToHeaders, FromHeaders, Debug, PartialEq)]
47pub struct Available {
48    pub host: String,
49
50    /// after this duration, control points should assume the device (or
51    /// service)  is  no  longer  available;  as  long  as  a  control  point
52    /// has  received  at  least  one  advertisement  that  is  still  valid
53    /// from a root device, any of its embedded devices or any of its
54    ///services, then the control point can assume that  all  are  available.
55    #[header("cache-control")]
56    pub max_age: String,
57    /// Field  value  contains  a  URL  to  the  UPnP  description  of  the
58    /// root  device.  Normally  the  host  portion  contains  a  literal
59    /// IP  address  rather  than  a  domain  name  in  unmanaged  networks.
60    /// Specified  by  UPnP  vendor. Single absolute URL (see RFC 3986)
61    pub location: String,
62
63    #[header("securelocation.upnp.org")]
64    pub secure_location: Option<String>,
65
66    #[header("nt")]
67    pub notification_type: SearchTarget,
68    /// Field  value  shall begin  with  the  following  “product  tokens”
69    /// (defined by HTTP/1.1). The first product token identifes the operating
70    /// system in the form OSname/OSversion, the  second  token  represents
71    /// the  UPnP version  and  shall be UPnP/2.0,  and  the  third  token
72    /// identifes the product using the form productname/productversion.
73    pub server: String,
74
75    /// Identifies a unique instance of a device or service.
76    #[header("usn")]
77    pub unique_service_name: UniqueServiceName,
78    /// presents the boot instance of the device expressed according to a monotonically increasing value.
79    #[header("bootid.upnp.org")]
80    pub boot_id: Option<i32>,
81
82    /// A number identifying this particular configuration.
83    /// if configuration changes, this should change as well
84    #[header("configid.upnp.org")]
85    pub config_id: Option<i32>,
86    /// A port other than 1900 than can be used for queries
87    #[header("searchport.upnp.org")]
88    pub search_port: Option<u16>,
89}
90
91#[derive(ToHeaders, FromHeaders, Debug, PartialEq)]
92pub struct SearchResponse {
93    /// Specifies how long this response is valid
94    #[header("cache-control")]
95    pub max_age: String,
96
97    /// When the responce was generated
98    pub date: Option<String>,
99
100    /// The URL for the UPNP description of the root device
101    pub location: String,
102
103    ext: types::Ext,
104
105    /// A server string like "unix/5.1 UPnP/2.0 MyProduct/1.0"
106    pub server: String,
107
108    /// If set, a base url with https:// that can be used instead of location
109    #[header("securelocation.upnp.org")]
110    pub secure_location: Option<String>,
111
112    #[header("st")]
113    pub target: types::SearchTarget,
114
115    /// A unique service name for this particular service
116    #[header("usn")]
117    pub unique_service_name: UniqueServiceName,
118
119    /// presents the boot instance of the device expressed according to a monotonically increasing value.
120    #[header("bootid.upnp.org")]
121    pub boot_id: Option<i32>,
122
123    /// A number identifying this particular configuration.
124    /// if configuration changes, this should change as well
125    #[header("configid.upnp.org")]
126    pub config_id: Option<i32>,
127    /// A port other than 1900 than can be used for queries
128    #[header("searchport.upnp.org")]
129    pub search_port: Option<u16>,
130}
131
132/// Any SSDP message
133#[derive(Debug, PartialEq, FromPacket, ToPacket)]
134pub enum Message {
135    /// Search the network for other devices
136    #[message(reqline = "MSearch")]
137    MSearch(MSearch),
138    /// Notification that a device has been added to the network
139    #[message(reqline = "Notify", nts = "ssdp:alive")]
140    Available(Available),
141    /// A response to a search query
142    #[message(reqline = "Ok")]
143    SearchResponse(SearchResponse),
144}
145
146#[cfg(test)]
147mod tests;