1use std::fmt;
4
5use obex_core::client::ObexError;
6use obex_core::TransportError;
7use quick_xml::{events::Event, Reader, XmlVersion};
8use thiserror::Error;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum EventType {
13 NewMessage,
15 DeliverySuccess,
17 SendingSuccess,
19 DeliveryFailure,
21 SendingFailure,
23 MessageDeleted,
25 MessageShift,
27 MemoryFull,
29 MemoryAvailable,
31 ReadStatusChanged,
33}
34
35impl fmt::Display for EventType {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 f.write_str(match self {
39 Self::NewMessage => "NewMessage",
40 Self::DeliverySuccess => "DeliverySuccess",
41 Self::SendingSuccess => "SendingSuccess",
42 Self::DeliveryFailure => "DeliveryFailure",
43 Self::SendingFailure => "SendingFailure",
44 Self::MessageDeleted => "MessageDeleted",
45 Self::MessageShift => "MessageShift",
46 Self::MemoryFull => "MemoryFull",
47 Self::MemoryAvailable => "MemoryAvailable",
48 Self::ReadStatusChanged => "ReadStatusChanged",
49 })
50 }
51}
52
53#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct MnsEvent {
56 event_type: EventType,
57 handle: Option<String>,
58 folder: Option<String>,
59 old_folder: Option<String>,
60 msg_type: Option<String>,
61 datetime: Option<String>,
62}
63
64impl MnsEvent {
65 #[must_use]
67 pub const fn event_type(&self) -> EventType {
68 self.event_type
69 }
70
71 #[must_use]
73 pub fn handle(&self) -> Option<&str> {
74 self.handle.as_deref()
75 }
76
77 #[must_use]
79 pub fn folder(&self) -> Option<&str> {
80 self.folder.as_deref()
81 }
82
83 #[must_use]
85 pub fn old_folder(&self) -> Option<&str> {
86 self.old_folder.as_deref()
87 }
88
89 #[must_use]
91 pub fn msg_type(&self) -> Option<&str> {
92 self.msg_type.as_deref()
93 }
94
95 #[must_use]
97 pub fn datetime(&self) -> Option<&str> {
98 self.datetime.as_deref()
99 }
100}
101
102#[derive(Debug, Error)]
104pub enum MnsError {
105 #[error("XML error: {0}")]
107 Parse(#[from] quick_xml::Error),
108 #[error("attribute error: {0}")]
110 Attr(#[from] quick_xml::events::attributes::AttrError),
111 #[error("unknown event type: {0}")]
113 UnknownEventType(String),
114 #[error("<event> element has no type attribute")]
116 MissingEventType,
117 #[error("MAP-event-report contained no <event> element")]
119 MissingEvent,
120 #[error("OBEX: {0}")]
122 Obex(#[from] ObexError),
123 #[error("transport: {0}")]
125 Transport(#[from] TransportError),
126 #[error("unexpected end of stream")]
128 UnexpectedEof,
129 #[error("unexpected OBEX opcode {0:#04x} from MNS client")]
131 UnexpectedOpcode(u8),
132 #[error("CONNECT Target UUID does not match MNS service UUID")]
134 InvalidTarget,
135}
136
137pub fn parse_event_report(xml: &[u8]) -> Result<MnsEvent, MnsError> {
149 let mut reader = Reader::from_reader(xml);
150 reader.config_mut().trim_text(true);
151 let mut buf = Vec::with_capacity(256);
152 loop {
153 match reader.read_event_into(&mut buf)? {
154 Event::Empty(e) | Event::Start(e) if e.name().as_ref() == b"event" => {
155 let mut raw_type: Option<String> = None;
156 let mut handle = None;
157 let mut folder = None;
158 let mut old_folder = None;
159 let mut msg_type = None;
160 let mut datetime = None;
161 for attr in e.attributes() {
162 let a = attr?;
163 let val = a.normalized_value(XmlVersion::Implicit1_0)?.into_owned();
164 match a.key.as_ref() {
165 b"type" => raw_type = Some(val),
166 b"handle" => handle = Some(val),
167 b"folder" => folder = Some(val),
168 b"old_folder" => old_folder = Some(val),
169 b"msg_type" => msg_type = Some(val),
170 b"datetime" => datetime = Some(val),
171 _ => {}
172 }
173 }
174 let event_type = match raw_type {
175 Some(ref s) => event_type_from_str(s)?,
176 None => return Err(MnsError::MissingEventType),
177 };
178 return Ok(MnsEvent { event_type, handle, folder, old_folder, msg_type, datetime });
179 }
180 Event::Eof => return Err(MnsError::MissingEvent),
181 _ => {}
182 }
183 buf.clear();
184 }
185}
186
187fn event_type_from_str(s: &str) -> Result<EventType, MnsError> {
188 match s {
189 "NewMessage" => Ok(EventType::NewMessage),
190 "DeliverySuccess" => Ok(EventType::DeliverySuccess),
191 "SendingSuccess" => Ok(EventType::SendingSuccess),
192 "DeliveryFailure" => Ok(EventType::DeliveryFailure),
193 "SendingFailure" => Ok(EventType::SendingFailure),
194 "MessageDeleted" => Ok(EventType::MessageDeleted),
195 "MessageShift" => Ok(EventType::MessageShift),
196 "MemoryFull" => Ok(EventType::MemoryFull),
197 "MemoryAvailable" => Ok(EventType::MemoryAvailable),
198 "ReadStatusChanged" => Ok(EventType::ReadStatusChanged),
199 other => Err(MnsError::UnknownEventType(other.to_owned())),
200 }
201}