Skip to content
Snippets Groups Projects
Commit b2e385e2 authored by Covertness's avatar Covertness
Browse files

add request API for client

parent a6234610
No related branches found
No related tags found
No related merge requests found
[package]
name = "coap"
version = "0.1.1"
version = "0.2.0"
description = "A CoAP library"
readme = "README.md"
documentation = "http://covertness.github.io/coap-rs/coap/index.html"
......@@ -14,3 +14,6 @@ bincode = "0.3.0"
rustc-serialize = "0.3"
mio = "0.3.7"
threadpool = "0.1"
url = "0.2.36"
num = "0.1"
rand = "0.3"
\ No newline at end of file
......@@ -17,7 +17,7 @@ First add this to your `Cargo.toml`:
```toml
[dependencies]
coap = "0.1.1"
coap = "0.2.0"
```
Then, add this to your crate root:
......@@ -62,21 +62,10 @@ use coap::packet::*;
use coap::CoAPClient;
fn main() {
let addr = "127.0.0.1:5683";
let request = "test";
let client = CoAPClient::new(addr).unwrap();
let mut packet = Packet::new();
packet.header.set_version(1);
packet.header.set_type(PacketType::Confirmable);
packet.header.set_code("0.01");
packet.header.set_message_id(1);
packet.set_token(vec!(0x51, 0x55, 0x77, 0xE8));
packet.add_option(OptionType::UriPath, request.to_string().into_bytes());
client.send(&packet).unwrap();
println!("Client request: coap://{}/{}", addr, request);
let response = client.receive().unwrap();
let url = "coap://127.0.0.1:5683/Rust";
println!("Client request: {}", url);
let response: Packet = CoAPClient::request(url).unwrap();
println!("Server reply: {}", String::from_utf8(response.payload).unwrap());
}
```
......
......@@ -18,6 +18,12 @@ fn main() {
client.send(&packet).unwrap();
println!("Client request: coap://{}/{}", addr, request);
let response = client.receive().unwrap();
match client.receive() {
Ok(response) => {
println!("Server reply: {}", String::from_utf8(response.payload).unwrap());
},
Err(e) => {
println!("Request error: {:?}", e);
}
}
}
\ No newline at end of file
......@@ -19,23 +19,12 @@ fn request_handler(req: Packet, resp: CoAPClient) {
}
fn main() {
let addr = "127.0.0.1:5683";
let request = "test";
let mut server = CoAPServer::new(addr).unwrap();
let mut server = CoAPServer::new("127.0.0.1:5683").unwrap();
server.handle(request_handler).unwrap();
let client = CoAPClient::new(addr).unwrap();
let mut packet = Packet::new();
packet.header.set_version(1);
packet.header.set_type(PacketType::Confirmable);
packet.header.set_code("0.01");
packet.header.set_message_id(1);
packet.set_token(vec!(0x51, 0x55, 0x77, 0xE8));
packet.add_option(OptionType::UriPath, request.to_string().into_bytes());
client.send(&packet).unwrap();
println!("Client request: coap://{}/{}", addr, request);
let url = "coap://127.0.0.1:5683/Rust";
println!("Client request: {}", url);
let response = client.receive().unwrap();
let response: Packet = CoAPClient::request(url).unwrap();
println!("Server reply: {}", String::from_utf8(response.payload).unwrap());
}
\ No newline at end of file
use std::io::{Result, Error, ErrorKind};
use std::net::{ToSocketAddrs, SocketAddr, UdpSocket};
use packet::Packet;
use url::{UrlParser, SchemeType};
use num;
use rand::{thread_rng, random, Rng};
use packet::{Packet, PacketType, OptionType};
pub struct CoAPClient {
socket: UdpSocket,
......@@ -33,6 +36,58 @@ impl CoAPClient {
})
}
/// Execute a request with the coap url.
pub fn request(url: &str) -> Result<Packet> {
let mut url_parser = UrlParser::new();
url_parser.scheme_type_mapper(Self::coap_scheme_type_mapper);
match url_parser.parse(url) {
Ok(url_params) => {
let mut packet = Packet::new();
packet.header.set_version(1);
packet.header.set_type(PacketType::Confirmable);
packet.header.set_code("0.01");
let message_id = thread_rng().gen_range(0, num::pow(2u32, 16)) as u16;
packet.header.set_message_id(message_id);
let mut token: Vec<u8> = vec!(1, 1, 1, 1);
for x in token.iter_mut() {
*x = random()
}
packet.set_token(token.clone());
let domain = match url_params.domain() {
Some(d) => d,
None => return Err(Error::new(ErrorKind::InvalidInput, "domain error"))
};
let port = url_params.port_or_default().unwrap();
if let Some(path) = url_params.path() {
for p in path.iter() {
packet.add_option(OptionType::UriPath, p.clone().into_bytes().to_vec());
}
};
let client = try!(Self::new((domain, port)));
try!(client.send(&packet));
match client.receive() {
Ok(receive_packet) => {
if receive_packet.header.get_message_id() == message_id
&& *receive_packet.get_token() == token {
return Ok(receive_packet)
} else {
return Err(Error::new(ErrorKind::Other, "receive invalid data"))
}
},
Err(e) => Err(e)
}
},
Err(_) => Err(Error::new(ErrorKind::InvalidInput, "url error"))
}
}
/// Execute a request.
pub fn send(&self, packet: &Packet) -> Result<()> {
match packet.to_bytes() {
......@@ -58,4 +113,11 @@ impl CoAPClient {
Err(_) => Err(Error::new(ErrorKind::InvalidInput, "packet error"))
}
}
fn coap_scheme_type_mapper(scheme: &str) -> SchemeType {
match scheme {
"coap" => SchemeType::Relative(5683),
_ => SchemeType::NonRelative,
}
}
}
\ No newline at end of file
......@@ -79,6 +79,9 @@ extern crate bincode;
extern crate rustc_serialize;
extern crate mio;
extern crate threadpool;
extern crate url;
extern crate num;
extern crate rand;
pub use server::CoAPServer;
pub use client::CoAPClient;
......
......@@ -123,6 +123,7 @@ impl CoAPServer {
}
}
/// Set the number of threads for handling requests
pub fn set_worker_num(&mut self, worker_num: usize) {
self.worker_num = worker_num;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment