From f427faec15eff7a181deb318fe666b3804d3107e Mon Sep 17 00:00:00 2001
From: James Munns <james.munns@gmail.com>
Date: Fri, 17 Jun 2016 21:09:06 +0200
Subject: [PATCH] Update documentation, Initial logging implementation, Restore
 panic!()

---
 Cargo.toml    |  5 +--
 LICENSE       |  4 +--
 README.md     |  7 +++--
 src/lib.rs    |  3 ++
 src/server.rs | 86 ++++++++++++++++++++++++++++++++-------------------
 5 files changed, 67 insertions(+), 38 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 22ff7f1..4b656fb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "coap"
-version = "0.3.1"
+version = "0.4.0"
 description = "A CoAP library"
 readme = "README.md"
 documentation = "http://covertness.github.io/coap-rs/coap/index.html"
@@ -17,6 +17,7 @@ threadpool = "0.1"
 url = "0.2.36"
 num = "0.1"
 rand = "0.3"
+log = "0.3"
 
 [dev-dependencies]
-quickcheck = "*"
\ No newline at end of file
+quickcheck = "*"
diff --git a/LICENSE b/LICENSE
index 23b5b40..970e986 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014 Sean McArthur
+Copyright (c) 2014-2016 Yang Zhang
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
+THE SOFTWARE.
diff --git a/README.md b/README.md
index 025c07f..a0e628d 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ First add this to your `Cargo.toml`:
 
 ```toml
 [dependencies]
-coap = "0.3"
+coap = "0.4"
 ```
 
 Then, add this to your crate root:
@@ -36,8 +36,9 @@ use std::io;
 use coap::packet::*;
 use coap::{CoAPServer, CoAPClient};
 
-fn request_handler(req: Packet, _resp: CoAPClient) {
+fn request_handler(req: Packet) -> Option<Packet> {
 	println!("Receive request: {:?}", req);
+	None
 }
 
 fn main() {
@@ -45,7 +46,7 @@ fn main() {
 
 	let mut server = CoAPServer::new(addr).unwrap();
 	server.handle(request_handler).unwrap();
-		
+
 	println!("Server up on {}", addr);
     println!("Press any key to stop...");
 	io::stdin().read_line(&mut String::new()).unwrap();
diff --git a/src/lib.rs b/src/lib.rs
index 5f4c687..079d5e3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -74,6 +74,9 @@ extern crate num;
 extern crate rand;
 #[cfg(test)] extern crate quickcheck;
 
+#[macro_use]
+extern crate log;
+
 pub use server::CoAPServer;
 pub use client::CoAPClient;
 
diff --git a/src/server.rs b/src/server.rs
index 79924db..280fcae 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -1,8 +1,9 @@
 use std;
+use std::io::{Error, ErrorKind};
 use std::thread;
 use std::net::{ToSocketAddrs, SocketAddr};
 use std::sync::mpsc;
-use mio::*;
+use mio::{EventLoop, PollOpt, EventSet, Handler, Sender, Token};
 use mio::udp::UdpSocket;
 use packet::Packet;
 use threadpool::ThreadPool;
@@ -57,38 +58,56 @@ impl<H: CoAPHandler + 'static> Handler for UdpHandler<H> {
 	type Message = ();
 
 	fn ready(&mut self, _: &mut EventLoop<UdpHandler<H>>, _: Token, events: EventSet) {
-		if events.is_readable() {
-			let coap_handler = self.coap_handler;
-			let mut buf = [0; 1500];
-
-			match self.socket.recv_from(&mut buf) {
-				Ok(Some((nread, src))) => {
-					let response_q = self.tx_sender.clone();
-					self.thread_pool.execute(move || {
-						match Packet::from_bytes(&buf[..nread]) {
-							Ok(packet) => {
-								// Dispatch user handler, if there is a response packet
-								//   send the reply via the TX thread
-								match coap_handler.handle(packet) {
-									Some(response) => {
-										response_q.send(CoAPResponse{
-											address: src,
-											response: response
-										}).unwrap();
-									},
-									None => {}
-								};
-							},
-							Err(_) => return
-						};
-					});
-				},
-				_ => {}, //panic!("unexpected error"),
-			}
+		if !events.is_readable() {
+			warn!("Unreadable Event");
+			return;
 		}
+
+		let coap_handler = self.coap_handler;
+		let mut buf = [0; 1500];
+
+		match self.socket.recv_from(&mut buf) {
+			Ok(Some((nread, src))) => {
+				debug!("Handling request from {}", src);
+				let response_q = self.tx_sender.clone();
+				self.thread_pool.execute(move || {
+
+					match Packet::from_bytes(&buf[..nread]) {
+						Ok(packet) => {
+							// Dispatch user handler, if there is a response packet
+							//   send the reply via the TX thread
+							match coap_handler.handle(packet) {
+								Some(response) => {
+									debug!("Response: {:?}", response);
+									response_q.send(CoAPResponse{
+										address: src,
+										response: response
+									}).unwrap();
+								},
+								None => {
+									debug!("No response");
+								}
+							};
+						},
+						Err(_) => {
+							error!("Failed to parse request");
+							return;
+						}
+					};
+
+
+				});
+			},
+			_ => {
+				error!("Failed to read from socket");
+				panic!("unexpected error");
+			},
+		}
+
 	}
 
 	fn notify(&mut self, event_loop: &mut EventLoop<UdpHandler<H>>, _: ()) {
+		info!("Shutting down request handler");
         event_loop.shutdown();
     }
 }
@@ -115,7 +134,7 @@ impl CoAPServer {
 						worker_num: DEFAULT_WORKER_NUM,
 					}))
 				},
-				None => Err(std::io::Error::new(std::io::ErrorKind::Other, "no address"))
+				None => Err(Error::new(ErrorKind::Other, "no address"))
 			}
 		})
 	}
@@ -126,6 +145,7 @@ impl CoAPServer {
 
 		// Early return error checking
 		if let Some(_) = self.event_sender {
+			error!("Handler already running!");
 			return Err(CoAPServerError::AnotherHandlerIsRunning);
 		}
 		match self.socket.try_clone() {
@@ -133,6 +153,7 @@ impl CoAPServer {
 				socket = good_socket
 			},
 			Err(_) => {
+				error!("Network Error!");
 				return Err(CoAPServerError::NetworkError);
 			},
 		}
@@ -200,12 +221,15 @@ fn transmit_handler(tx_recv: RxQueue, tx_only: UdpSocket) {
 					Ok(bytes) => {
 						let _ = tx_only.send_to(&bytes[..], &q_res.address);
 					},
-					Err(_) => {}
+					Err(_) => {
+						error!("Failed to decode response");
+					}
 				}
 			},
 			// recv error occurs when all transmitters are terminited
 			//   (when all UDP Handlers are closed)
 			Err(_) => {
+				info!("Shutting down Transmit Handler");
 				break;
 			}
 		}
-- 
GitLab