Commit cfd3e9aa authored by Björn Butzin's avatar Björn Butzin
Browse files

Added code documentation & reverse engineered UML class diagrams

parent 04d1c4a8
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="lib/log4j-1.2.16.jar"/>
<classpathentry kind="lib" path="lib/junit-4.12.jar"/>
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>
......
......@@ -198,6 +198,9 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
selector.select(waitFor);
} catch (IOException e) {
// TODO Auto-generated catch block
// IOException - If an I/O error occurs
// ClosedSelectorException - If this selector is closed
// IllegalArgumentException - If the value of the timeout argument is negative
e.printStackTrace();
}
}
......@@ -217,6 +220,12 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
}
}
/**
* Handles an incoming message. If the message is an acknowledgment, a resets or a duplicate, this will will be handled directly.
* Otherwise the message will be passed to the corresponding {@link CoapServerChannel}.
* @param buffer The buffer containing the datagram.
* @param addr The datagram's source address
*/
private void handleIncommingMessage(ByteBuffer buffer, InetSocketAddress addr) {
CoapMessage msg;
try {
......@@ -231,9 +240,9 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
int msgId = msg.getMessageID();
MessageKey msgKey = new MessageKey(msgId, addr.getAddress(), addr.getPort());
/* --- INCOMING REQUEST: This is an incoming client request with a message key generated by the remote client*/
if (msg.isRequest()){
/* --- INCOMING REQUEST: This is an incoming client request with a message key generated by the remote client*/
if (packetType == CoapPacketType.ACK || packetType == CoapPacketType.RST){
logger.warn("Invalid Packet Type: Request can not be in a ACK or a RST packet");
return;
......@@ -268,10 +277,10 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
msg.setChannel(channel);
channel.handleMessage(msg);
return;
/* --- INCOMING RESPONSE: This is an incoming server response (message ID generated by host)
* or a separate server response (message ID generated by remote)*/
} else if (msg.isResponse()){
/* --- INCOMING RESPONSE: This is an incoming server response (message ID generated by host)
* or a separate server response (message ID generated by remote)*/
if (packetType == CoapPacketType.RST){
logger.warn("Invalid Packet Type: RST packet must be empty");
......@@ -339,14 +348,14 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
} else if (msg.isEmpty()){
if (packetType == CoapPacketType.CON || packetType == CoapPacketType.NON){
/* TODO: is this always true? */
/* TODO: is this always true? Could also be ACK or RST?*/
logger.warn("Invalid Packet Type: CON or NON packets cannot be empty");
return;
}
/* ACK or RST, Message Id was generated by the host*/
/* drop duplicate responses */
if (isHostDuplicate(msgId)){
/* drop duplicate responses */
return;
}
......@@ -366,14 +375,15 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
}
msg.setChannel(channel);
/* separate response ACK */
if (packetType == CoapPacketType.ACK ){
/* separate response ACK */
channel.handleMessage(msg);
return;
}
/* connection closed by remote */
if (packetType == CoapPacketType.RST ){
/* connection closed by remote */
channel.handleMessage(msg);
return;
}
......@@ -383,6 +393,10 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
}
}
/**
*
* @return Milliseconds until the next timeout expires. POLLING_INTERVALL if there is no timeout to wait for.
*/
private long handleTimeouts(){
long nextTimeout = POLLING_INTERVALL;
......
......@@ -46,6 +46,7 @@ public interface CoapMessage {
public static final int MAX_RETRANSMIT = 4;
/* TODO: what is the right value? */
//TODO: Documentation
/**
*
*/
......@@ -70,73 +71,73 @@ public interface CoapMessage {
public void setMessageID(int msgID);
/**
*
* @return
* Convert the CoAP message into its serialized form for transmission.<br>
* See rfc7252 - 3. "Message Format" for further details.
* @return The serialized CoAP message.
*/
public byte[] serialize();
//TODO: Documentation
/**
*
*/
public void incRetransCounterAndTimeout();
/**
*
* @return
* @return The packet type of the message (CON, NON, ACK, RST).
*/
public CoapPacketType getPacketType();
/**
*
* @return
* Get the payload of the message for further use on application level.
* @return The payload of the message
*/
public byte[] getPayload();
/**
*
* @param payload
* Set the payload of the message to be sent.
* @param payload the payload of the message to be sent.
*/
public void setPayload(byte[] payload);
/**
*
* @param payload
* Set the payload of the message to be sent.
* @param payload the payload of the message to be sent.
*/
public void setPayload(char[] payload);
/**
*
* @param payload
* Set the payload of the message to be sent.
* @param payload the payload of the message to be sent.
*/
public void setPayload(String payload);
/**
*
* @return
* @return The size of the message payload in byte.
*/
public int getPayloadLength();
/**
*
* @param mediaType
* Change the media type of the message.
* @param mediaType The new media type.
*/
public void setContentType(CoapMediaType mediaType);
/**
*
* @return
* @return The media type of the message.
*/
public CoapMediaType getContentType();
/**
*
* @param token
* Set the token of the message.
* The token value is used to correlate requests and responses.
* @param token The token to be set
*/
public void setToken(byte[] token);
/**
*
* @return
* The token value is used to correlate requests and responses.
* @return The token of the message.
*/
public byte[] getToken();
......@@ -145,26 +146,22 @@ public interface CoapMessage {
// TODO:allow this method only for Clients, Define Token Type
/**
*
* @return
* @return The block option for get requests.
*/
CoapBlockOption getBlock1();
/**
*
* @param blockOption
* @param blockOption The block option for get requests.
*/
void setBlock1(CoapBlockOption blockOption);
/**
*
* @return
* @return The block option for POST & PUT requests.
*/
CoapBlockOption getBlock2();
/**
*
* @param blockOption
* @param blockOption The block option for POST & PUT requests.
*/
void setBlock2(CoapBlockOption blockOption);
......@@ -187,10 +184,6 @@ public interface CoapMessage {
*/
public void removeOption(CoapHeaderOptionType optionType);
/**
*
* @return
*/
@Override
public String toString();
......@@ -243,18 +236,9 @@ public interface CoapMessage {
public boolean isEmpty();
/* unique by remote address, remote port, local port and message id */
/**
*
* @return
*/
@Override
public int hashCode();
/**
*
* @param obj
* @return
*/
@Override
public boolean equals(Object obj);
......
......@@ -23,7 +23,10 @@ public class CoapBlockOption{
private boolean more;
private CoapBlockSize blockSize;
/**
* Parse the block option from its serialized form
* @param data The serialized form of the block option.
*/
public CoapBlockOption(byte[] data){
if (data.length <1 || data.length > 3){
throw new IllegalArgumentException("invalid block option");
......@@ -44,6 +47,13 @@ public class CoapBlockOption{
number = (int) (val >> 4);
}
/**
* Create new block option.
* @param number
* @param more
* @param blockSize
*/
public CoapBlockOption(int number, boolean more, CoapBlockSize blockSize){
if (blockSize == null){
throw new IllegalArgumentException();
......
......@@ -49,7 +49,9 @@ public class BasicCoapResource implements CoapResource {
/** DEFAULT NULL: let the client decide */
Boolean reliableNotification = null;
/** DEFAULT -1: expires never */
/**
* The Unix time (in milliseconds), when resource expires
* -1, when resource never expires */
long expires = -1;
public BasicCoapResource(String path, byte[] value, CoapMediaType mediaType) {
......
......@@ -49,7 +49,7 @@ public interface CoapResource extends Resource {
public void removeObserver(CoapChannel channel);
/**
* @return true if the resource is observable
* @return true, if the resource is observable.
*/
public boolean isObservable();
......@@ -60,7 +60,8 @@ public interface CoapResource extends Resource {
public int getObserveSequenceNumber();
/**
* @return the unix time, when resource expires <br> -1, when resource never expires
* @return The Unix time (in milliseconds), when resource expires. <br>
* -1, when the resource never expires.
*/
public long expires();
......
......@@ -29,7 +29,7 @@ import org.ws4d.coap.interfaces.CoapRequest;
public interface ResourceServer {
/**
* creates a resource. resource must not exist.
* Creates a resource. Resource must not exist.
* @param resource The resource to be handled
* @return false, if resource exists
*/
......
......@@ -79,8 +79,12 @@ public class BasicResourceTest {
@After
public void tearDown() {
// reset server
//FIXME: causes ConcurrentModificationException
for (String path : resourceServer.getResources().keySet()) {
resourceServer.deleteResource(path);
if(path!="/.well-known/core"){
System.out.println(path);
resourceServer.deleteResource(path);
}
}
}
......@@ -93,6 +97,21 @@ public class BasicResourceTest {
// validate test fixtures
}
/*
* test percentage encoding
* Path separator: (U+002F SOLIDUS "/")
* First Argument led by: (U+003F QUESTION MARK "?")
* Argument separator: (U+0026 AMPERSAND "&")
* An empty path component is equivalent to an absolute path of "/"
* The scheme and host are case insensitive and normally provided in lowercase
*
* For example, the following three URIs are equivalent and cause the same
* options and option values to appear in the CoAP messages:
* coap://example.com:5683/~sensors/temp.xml
* coap://EXAMPLE.com/%7Esensors/temp.xml
* coap://EXAMPLE.com:/%7esensors/temp.xml
*/
/*
* ########################################################################
* invalid resources
......@@ -100,28 +119,21 @@ public class BasicResourceTest {
*/
@Test(expected = Exception.class)
public void EmptyPathResource() {
CoapResource res = new BasicCoapResource("", "".getBytes(),
CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test(expected = Exception.class)
public void WrongSlashResource() {
public void invalidPathBadSeparatorResource() {
CoapResource res = new BasicCoapResource("\\", "".getBytes(),
CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test(expected = Exception.class)
public void LongNameResource() {
public void invalidNameTooLongResource() {
CoapResource res = new BasicCoapResource("/shouldbetoolong",
"".getBytes(), CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test(expected = Exception.class)
public void LongPathResource() {
public void invalidPathTooLongResource() {
CoapResource res = new BasicCoapResource(
"/1/2/3/4/5/6/7/8/9/0/1/2/3/4/5/6/7/8/9/0", "".getBytes(),
CoapMediaType.text_plain);
......@@ -135,26 +147,35 @@ public class BasicResourceTest {
*/
@Test
public void ShortestValidPathResources() {
CoapResource res = new BasicCoapResource("/", "".getBytes(),
public void validPathShortestResources() {
//An empty path component is equivalent to an absolute path of "/"
CoapResource res = new BasicCoapResource("/test", "".getBytes(),
CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void validPathRootResources() {
//An empty path component is equivalent to an absolute path of "/"
CoapResource res = new BasicCoapResource("/test", "".getBytes(),
CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void longestValidNameResources() {
CoapResource res = new BasicCoapResource("/12345678", "".getBytes(),
public void validNameLongestResources() {
CoapResource res = new BasicCoapResource("/1234567890", "".getBytes(),
CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void longestValidPathResources() {
CoapResource res = new BasicCoapResource("/1/2/3/4/5/6/7/8",
"".getBytes(), CoapMediaType.text_plain);
public void validPathLongestResources() {
CoapResource res = new BasicCoapResource("/1/2/3/4/5", "".getBytes(),
CoapMediaType.text_plain);
resourceServer.createResource(res);
}
/*
* ########################################################################
* CoreResource (/.well-known/core)
......
......@@ -122,8 +122,12 @@ public class InterfaceTest {
clientDummy = null;
// reset server
//FIXME: causes ConcurrentModificationException
for (String path : resourceServer.getResources().keySet()) {
resourceServer.deleteResource(path);
if(path!="/.well-known/core"){
System.out.println(path);
resourceServer.deleteResource(path);
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment