@@ -137,6 +137,7 @@ use riot_sys::{
137
137
coap_get_blockopt,
138
138
coap_hdr_t,
139
139
coap_opt_add_uint,
140
+ coap_opt_add_opaque,
140
141
coap_opt_finish,
141
142
gcoap_finish,
142
143
gcoap_register_listener,
@@ -242,13 +243,97 @@ impl<'a> ::core::fmt::Write for BlockWriter<'a> {
242
243
/// A representation of the incoming or outgoing data on the server side of a request. This
243
244
/// includes the coap_pkt_t pre-parsed header and option pointers as well as the memory area
244
245
/// dedicated to returning the packet.
246
+ #[ derive( Debug ) ]
245
247
pub struct PacketBuffer {
246
248
pkt : * mut coap_pkt_t ,
247
249
buf : * mut u8 ,
248
250
len : usize ,
249
251
}
250
252
251
253
impl PacketBuffer {
254
+ pub fn get_code_raw ( & self ) -> u8 {
255
+ // FIXME inlining static coap_get_code_detail
256
+ unsafe { ( * ( * self . pkt ) . hdr ) . code }
257
+ }
258
+
259
+ fn get_total_hdr_len ( & self ) -> usize {
260
+ unsafe { coap_get_total_hdr_len ( & * self . pkt ) }
261
+ }
262
+
263
+ /// Take a message that came in as a request and configure it such that options and payload can
264
+ /// be added. The response code is set to 5.00 Internal Server Error as a precaution.
265
+ ///
266
+ /// This is similar to gcoap_resp_init, but does not try to reserve any space for options.
267
+ ///
268
+ /// The options list is set to empty, and the available payload is configured to span the
269
+ /// complete available buffer right after the header. Subsequent opt_add_* invocations can then
270
+ /// push back the buffer.
271
+ pub fn prepare_response ( & mut self ) {
272
+ unsafe {
273
+ let hdr: & mut coap_hdr_t = & mut * ( * self . pkt ) . hdr ;
274
+ if ( hdr. ver_t_tkl & 0x30 ) >> 4 == COAP_TYPE_CON as u8 {
275
+ hdr. ver_t_tkl = hdr. ver_t_tkl & 0xcf | ( ( COAP_TYPE_ACK as u8 ) << 4 ) ;
276
+ }
277
+ hdr. code = 5 << 5 ;
278
+ }
279
+
280
+ let hdrlen = self . get_total_hdr_len ( ) ;
281
+ unsafe {
282
+ ( * self . pkt ) . payload = self . buf . offset ( hdrlen as isize ) ;
283
+ ( * self . pkt ) . payload_len = self . len . saturating_sub ( hdrlen) as u16 ;
284
+ ( * self . pkt ) . options_len = 0 ;
285
+ }
286
+ }
287
+
288
+ pub fn set_code_raw ( & mut self , code : u8 ) {
289
+ unsafe { ( * ( * self . pkt ) . hdr ) . code = code } ;
290
+ }
291
+
292
+ /// Return the total number of bytes in the message, given that `payload_used` bytes were
293
+ /// written at the payload pointer. Note that those bytes have to include the payload marker.
294
+ ///
295
+ /// This measures the distance between the payload pointer in the pkt and the start of the
296
+ /// buffer. It is the header length after `prepare_response`, and grows as options are added.
297
+ pub fn get_length ( & self , payload_used : usize ) -> usize {
298
+ let own_length = unsafe { ( * self . pkt ) . payload . offset_from ( self . buf ) } ;
299
+ assert ! ( own_length >= 0 ) ;
300
+ let total_length = own_length as usize + payload_used;
301
+ assert ! ( total_length <= self . len) ;
302
+ total_length
303
+ }
304
+
305
+ /// A view of the current message payload
306
+ pub fn payload ( & self ) -> & [ u8 ] {
307
+ unsafe {
308
+ core:: slice:: from_raw_parts ( ( * self . pkt ) . payload , ( * self . pkt ) . payload_len as usize )
309
+ }
310
+ }
311
+
312
+ /// A view of the current message payload
313
+ pub fn payload_mut ( & mut self ) -> & mut [ u8 ] {
314
+ unsafe {
315
+ core:: slice:: from_raw_parts_mut ( ( * self . pkt ) . payload , ( * self . pkt ) . payload_len as usize )
316
+ }
317
+ }
318
+
319
+ /// Add an integer value as an option
320
+ pub fn opt_add_uint ( & mut self , optnum : u16 , value : u32 ) -> Result < ( ) , ( ) > {
321
+ if unsafe { coap_opt_add_uint ( self . pkt , optnum, value) } < 0 {
322
+ Err ( ( ) )
323
+ } else {
324
+ Ok ( ( ) )
325
+ }
326
+ }
327
+
328
+ /// Add a binary value as an option
329
+ pub fn opt_add_opaque ( & mut self , optnum : u16 , data : & [ u8 ] ) -> Result < ( ) , ( ) > {
330
+ if unsafe { coap_opt_add_opaque ( self . pkt , optnum, data. as_ptr ( ) , data. len ( ) ) } < 0 {
331
+ Err ( ( ) )
332
+ } else {
333
+ Ok ( ( ) )
334
+ }
335
+ }
336
+
252
337
pub fn response (
253
338
& mut self ,
254
339
code : u32 ,
@@ -304,7 +389,7 @@ impl PacketBuffer {
304
389
}
305
390
hdr. code = code as u8 ;
306
391
307
- let headroom = coap_get_total_hdr_len ( & * self . pkt ) + 25 /* used to be 8 */ ;
392
+ let headroom = self . get_total_hdr_len ( ) + 25 /* used to be 8 */ ;
308
393
( * self . pkt ) . payload = self . buf . offset ( headroom as isize ) ;
309
394
( * self . pkt ) . payload_len = self . len as u16 - headroom as u16 ;
310
395
}
0 commit comments