async_coap/send_desc/
unicast_block2.rs1use super::*;
17use crate::message::{OwnedImmutableMessage, VecMessageEncoder};
18use std::marker::PhantomData;
19
20impl<SD: SendDescUnicast, IC> SendDescUnicast for UnicastBlock2<SD, IC> {}
21impl<SD: SendDescUnicast, IC> SendDescUnicast for UnicastBlock2Collect<SD, IC> {}
22
23#[derive(Debug)]
26pub struct UnicastBlock2<SD, IC> {
27 pub(super) inner: SD,
28 pub(super) block2_default: Option<BlockInfo>,
29 pub(super) reconstructor: Option<BlockReconstructor<VecMessageEncoder>>,
30 pub(super) etag: Option<ETag>,
31 pub(super) phantom: PhantomData<IC>,
32}
33
34impl<SD, IC> UnicastBlock2<SD, IC> {
35 pub(super) fn new(inner: SD, block2: Option<BlockInfo>) -> UnicastBlock2<SD, IC> {
36 UnicastBlock2 {
37 inner,
38 block2_default: block2,
39 reconstructor: None,
40 etag: None,
41 phantom: PhantomData,
42 }
43 }
44
45 pub fn emit_successful_collected_response(self) -> UnicastBlock2Collect<SD, IC> {
50 UnicastBlock2Collect { inner: self }
51 }
52}
53
54impl<SD, IC, R> SendDesc<IC, R> for UnicastBlock2<SD, IC>
55where
56 SD: SendDesc<IC, R> + Send + SendDescUnicast,
57 IC: InboundContext,
58 R: Send,
59{
60 send_desc_passthru_timing!(inner);
61 send_desc_passthru_payload!(inner);
62
63 fn supports_option(&self, option: OptionNumber) -> bool {
64 self.inner.supports_option(option) || option == OptionNumber::BLOCK2
65 }
66
67 fn write_options(
68 &self,
69 msg: &mut dyn OptionInsert,
70 socket_addr: &IC::SocketAddr,
71 start: Bound<OptionNumber>,
72 end: Bound<OptionNumber>,
73 ) -> Result<(), Error> {
74 let block2 = self
75 .reconstructor
76 .as_ref()
77 .map(|r| r.next_block())
78 .or(self.block2_default);
79
80 write_options!((msg, socket_addr, start, end, self.inner) {
81 BLOCK2 => block2.into_iter(),
84 })
85 }
86
87 fn handler(&mut self, context: Result<&IC, Error>) -> Result<ResponseStatus<R>, Error> {
88 if let Some(context) = context.ok() {
89 if context.is_dupe() {
90 return Ok(ResponseStatus::Continue);
92 }
93 let msg = context.message();
94 let block2 = msg.block2();
95
96 if let Some(block2) = block2 {
97 let etag = msg.options().find_next_of(option::ETAG).transpose()?;
98
99 if etag != self.etag {
100 if self.etag.is_none() && self.reconstructor.is_none() {
101 self.etag = etag;
102 } else {
103 self.reconstructor = None;
105 self.etag = None;
106 return self.inner.handler(Err(Error::Reset));
107 }
108 }
109
110 if self.reconstructor.is_none() {
111 let mut encoder = VecMessageEncoder::default();
112 msg.write_msg_to(&mut encoder)?;
113
114 if !block2.more_flag() || block2.offset() != 0 {
115 return self.inner.handler(Ok(context));
117 }
118
119 let next_block = block2.next().unwrap();
120 self.reconstructor = Some(BlockReconstructor::new(encoder, next_block));
121 }
122
123 match self
124 .reconstructor
125 .as_mut()
126 .unwrap()
127 .feed(block2, msg.payload())
128 {
129 Ok(false) => {
130 return self
131 .inner
132 .handler(Ok(context))
133 .map(|_| ResponseStatus::SendNext)
134 }
135 Ok(true) => return self.inner.handler(Ok(context)),
136 Err(_) => {
137 self.reconstructor = None;
138 self.etag = None;
139 return self.inner.handler(Err(Error::Reset));
140 }
141 };
142 } else {
143 self.reconstructor = None;
144 self.etag = None;
145 }
146 }
147
148 self.inner.handler(context)
149 }
150}
151
152#[derive(Debug)]
157pub struct UnicastBlock2Collect<SD, SA> {
158 inner: UnicastBlock2<SD, SA>,
159}
160
161impl<SD, IC> SendDesc<IC, OwnedImmutableMessage> for UnicastBlock2Collect<SD, IC>
162where
163 SD: SendDesc<IC, ()> + Send + SendDescUnicast,
164 IC: InboundContext,
165{
166 send_desc_passthru_timing!(inner);
167 send_desc_passthru_payload!(inner);
168 send_desc_passthru_options!(inner);
169 send_desc_passthru_supports_option!(inner);
170
171 fn handler(
172 &mut self,
173 context: Result<&IC, Error>,
174 ) -> Result<ResponseStatus<OwnedImmutableMessage>, Error> {
175 let ret = match self.inner.handler(context) {
176 Ok(rs) => {
177 if let Some(recons) = self.inner.reconstructor.as_ref() {
178 if recons.is_finished() {
179 self.inner.reconstructor.take().unwrap().into_inner().into()
180 } else {
181 return Ok(match rs {
182 ResponseStatus::SendNext => ResponseStatus::SendNext,
183 _ => ResponseStatus::Continue,
184 });
185 }
186 } else if let Some(context) = context.ok() {
187 context.message().to_owned()
188 } else {
189 return Ok(match rs {
190 ResponseStatus::SendNext => ResponseStatus::SendNext,
191 _ => ResponseStatus::Continue,
192 });
193 }
194 }
195 Err(Error::ClientRequestError) if context.is_ok() => {
196 context.unwrap().message().to_owned()
197 }
198 Err(e) => return Err(e),
199 };
200
201 return Ok(ResponseStatus::Done(ret));
202 }
203}