-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from jiayihu/master
Add CoapRequest and CoapResponse.
- Loading branch information
Showing
3 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use super::header::{MessageClass, RequestType as Method}; | ||
use super::packet::{CoapOption, Packet}; | ||
use super::response::CoapResponse; | ||
use alloc::string::{String, ToString}; | ||
use alloc::vec::Vec; | ||
|
||
/// The CoAP request. | ||
#[derive(Clone, Debug)] | ||
pub struct CoapRequest<Endpoint> { | ||
pub message: Packet, | ||
pub response: Option<CoapResponse>, | ||
pub source: Option<Endpoint>, | ||
} | ||
|
||
impl<Endpoint> CoapRequest<Endpoint> { | ||
/// Creates a new request. | ||
pub fn new() -> CoapRequest<Endpoint> { | ||
CoapRequest { | ||
response: None, | ||
message: Packet::new(), | ||
source: None, | ||
} | ||
} | ||
|
||
/// Creates a request from a packet. | ||
pub fn from_packet( | ||
packet: Packet, | ||
source: Endpoint, | ||
) -> CoapRequest<Endpoint> { | ||
CoapRequest { | ||
response: CoapResponse::new(&packet), | ||
message: packet, | ||
source: Some(source), | ||
} | ||
} | ||
|
||
/// Sets the method. | ||
pub fn set_method(&mut self, method: Method) { | ||
self.message.header.code = MessageClass::Request(method); | ||
} | ||
|
||
/// Returns the method. | ||
pub fn get_method(&self) -> &Method { | ||
match self.message.header.code { | ||
MessageClass::Request(Method::Get) => &Method::Get, | ||
MessageClass::Request(Method::Post) => &Method::Post, | ||
MessageClass::Request(Method::Put) => &Method::Put, | ||
MessageClass::Request(Method::Delete) => &Method::Delete, | ||
_ => &Method::UnKnown, | ||
} | ||
} | ||
|
||
/// Sets the path. | ||
pub fn set_path(&mut self, path: &str) { | ||
self.message.clear_option(CoapOption::UriPath); | ||
|
||
let segs = path.split('/'); | ||
for (i, s) in segs.enumerate() { | ||
if i == 0 && s.is_empty() { | ||
continue; | ||
} | ||
|
||
self.message | ||
.add_option(CoapOption::UriPath, s.as_bytes().to_vec()); | ||
} | ||
} | ||
|
||
/// Returns the path. | ||
pub fn get_path(&self) -> String { | ||
match self.message.get_option(CoapOption::UriPath) { | ||
Some(options) => { | ||
let mut vec = Vec::new(); | ||
for option in options.iter() { | ||
if let Ok(seg) = core::str::from_utf8(option) { | ||
vec.push(seg); | ||
} | ||
} | ||
vec.join("/") | ||
} | ||
_ => "".to_string(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
use super::header::{MessageClass, MessageType, ResponseType as Status}; | ||
use super::packet::Packet; | ||
|
||
/// The CoAP response. | ||
#[derive(Clone, Debug)] | ||
pub struct CoapResponse { | ||
pub message: Packet, | ||
} | ||
|
||
impl CoapResponse { | ||
/// Creates a new response. | ||
pub fn new(request: &Packet) -> Option<CoapResponse> { | ||
let mut packet = Packet::new(); | ||
|
||
packet.header.set_version(1); | ||
let response_type = match request.header.get_type() { | ||
MessageType::Confirmable => MessageType::Acknowledgement, | ||
MessageType::NonConfirmable => MessageType::NonConfirmable, | ||
_ => return None, | ||
}; | ||
packet.header.set_type(response_type); | ||
packet.header.code = MessageClass::Response(Status::Content); | ||
packet.header.message_id = request.header.message_id; | ||
packet.set_token(request.get_token().clone()); | ||
|
||
packet.payload = request.payload.clone(); | ||
|
||
Some(CoapResponse { message: packet }) | ||
} | ||
|
||
/// Sets the status. | ||
pub fn set_status(&mut self, status: Status) { | ||
self.message.header.code = MessageClass::Response(status); | ||
} | ||
|
||
/// Returns the status. | ||
pub fn get_status(&self) -> &Status { | ||
match self.message.header.code { | ||
MessageClass::Response(Status::Created) => &Status::Created, | ||
MessageClass::Response(Status::Deleted) => &Status::Deleted, | ||
MessageClass::Response(Status::Valid) => &Status::Valid, | ||
MessageClass::Response(Status::Changed) => &Status::Changed, | ||
MessageClass::Response(Status::Content) => &Status::Content, | ||
|
||
MessageClass::Response(Status::BadRequest) => &Status::BadRequest, | ||
MessageClass::Response(Status::Unauthorized) => { | ||
&Status::Unauthorized | ||
} | ||
MessageClass::Response(Status::BadOption) => &Status::BadOption, | ||
MessageClass::Response(Status::Forbidden) => &Status::Forbidden, | ||
MessageClass::Response(Status::NotFound) => &Status::NotFound, | ||
MessageClass::Response(Status::MethodNotAllowed) => { | ||
&Status::MethodNotAllowed | ||
} | ||
MessageClass::Response(Status::NotAcceptable) => { | ||
&Status::NotAcceptable | ||
} | ||
MessageClass::Response(Status::PreconditionFailed) => { | ||
&Status::PreconditionFailed | ||
} | ||
MessageClass::Response(Status::RequestEntityTooLarge) => { | ||
&Status::RequestEntityTooLarge | ||
} | ||
MessageClass::Response(Status::UnsupportedContentFormat) => { | ||
&Status::UnsupportedContentFormat | ||
} | ||
|
||
MessageClass::Response(Status::InternalServerError) => { | ||
&Status::InternalServerError | ||
} | ||
MessageClass::Response(Status::NotImplemented) => { | ||
&Status::NotImplemented | ||
} | ||
MessageClass::Response(Status::BadGateway) => &Status::BadGateway, | ||
MessageClass::Response(Status::ServiceUnavailable) => { | ||
&Status::ServiceUnavailable | ||
} | ||
MessageClass::Response(Status::GatewayTimeout) => { | ||
&Status::GatewayTimeout | ||
} | ||
MessageClass::Response(Status::ProxyingNotSupported) => { | ||
&Status::ProxyingNotSupported | ||
} | ||
_ => &Status::UnKnown, | ||
} | ||
} | ||
} |