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

add request API for client

parent a6234610
Branches
Tags
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