formatting of eclipse import tutorial authored by Björn Butzin's avatar Björn Butzin
# Tutorial for jCoAP Hands-on
In this tutorial we will describe how to develop a simple message exchange between devices using jCoAP.
In this tutorial we will explain how to develop a simple message exchange between devices using jCoAP.
Furthermore, we will introduce the observe mechanism.
The following points will be covered by this tutorial:
1. Installation of Copper Plugin for Mozilla Firefox
2. Introduction of jCoAP (based on Task 1)
1. Installation of Copper plugin for Mozilla Firefox
2. Introduction of jCoAP
3. Import of prepared project into Eclipse
4. Task 1: Implementation of client/server and enable simple message exchange
5. Task 2: Implementation of an air conditioner control by using the CoAP-observe mechanism
## 1. Requirements for this tutorial
* JAVA SE JDK 1.6+
* Eclipse IDE for JAVA development
* Prepared JAVA project files for Hands-on
* Java SE JDK 1.6+
* Eclipse IDE for Java development
* Prepared [Java project files for Hands-on](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/tree/master/ws4d-jcoap-handsOn)
## 2. Installation of Copper Plugin for Mozilla Firefox
## 2. Installation of the Copper Plugin for Mozilla Firefox
- https://addons.mozilla.org/de/firefox/addon/copper-270430/
- Click on add to Firefox“ & Confirm Installation
- [https://addons.mozilla.org/de/firefox/addon/copper-270430/](https://addons.mozilla.org/de/firefox/addon/copper-270430/)
- Click on `add to Firefox` and Confirm Installation
- Restart Firefox
After the installation you can enter coap://host:port/resourcePath/?query=filter.
Copper will allow you to make any CoAP interaction interactively.
After the installation you can enter anything like `coap://host:port/resourcePath/?query=filter` in the address bar.
Copper will allow you to make any CoAP interaction.
![Copper Screenshot](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/CopperScreenshot.jpg)
## 3. Introduction of jCoAP
- WS4D-jCoAP: Java implementation of CoAP
- http://ws4d.org/
- https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap
### Task 1 – Sequence Diagram
![Task 1 – Sequence Diagram](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/Task1Sequence.png)
- [http://ws4d.org/](http://ws4d.org/)
- [https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap)
#### Client Side
![Client Side UML Diagram](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/Client%20UML.jpg)
**CoapClient (interface):** describes interfaces that must be supported by a client
**Client:** individual implementation of a client application, implements CoapClient (interface)
**ChannelManager:** manages channels
**Channel:** one channel represents a connection to one client
**CoapClient:** Interface that must be implemented by a client
**Client:** Customized implementation of a client application, implements `CoapClient`
**Channel:** A channel represents a connection between a Client and a Server
**ChannelManager:** Manages `Channels` (Timeouts, Matching Requests and Responses)
#### Server Side
![Server Side UML Diagram](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/ServerUML.jpg)
**CoapResource (interface):** describes interfaces that must be supported by each resource.
**BasicCoapResource:** already implemented resource with basic functionality, implements CoapResource (interface)
**TemperatureResource:** individual resource, inherits from BasicCoapResource
**CoapServer (interface):** describes interfaces that must be supported by a resource server
**CoapResourceServer:** manages a list of resources, enables access of these resources from outside, implements CoapServer (interface)
**Server:** individual implementation of a server application, creates CoapResourceServer and resources
* ToDo on server side:
1. Create a new resource class TemperatureResource
2. Instantiate a new ResourceServer
3. Instantiate a new TemperatureResource
4. Add the TemperatureResource to the ResourceServer
5. Run the ResourceServer
* ToDo on client side:
1. Establish a connection to the Server using the ChannelManager
2. Create a CoapRequest & add some Options
3. Send the CoapRequest
4. Wait for CoapResponse
5. Print the CoapResponse on the console
**CoapResource:** Interface that must be supported by each resource.
**BasicCoapResource:** Already implemented resource with basic functionality, implements `CoapResource`
**TemperatureResource:** Example of a customized resource, inherits from `BasicCoapResource`
**CoapServer:** Interface that must be supported by a resource server
**CoapResourceServer:** Manages a list of resources, enables access of these resources from outside, implements `CoapServer`
**Server:** Example of a customized implementation of a server application, creates `CoapResourceServer` and `CoapResources`
## 4. Import of prepared project into Eclipse
You can find the required files in our repository at https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/tree/master/ws4d-jcoap-handsOn
You can find the required files in our repository at [https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/tree/master/ws4d-jcoap-handsOn](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/tree/master/ws4d-jcoap-handsOn)
1. File > Import
![Eclipse File Import](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/EclipseImport1.png)
2. General > Existing Projects ...
3. Click ‚Next‘
![Eclipse File Import](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/EclipseImport2.png)
4. Browse <Select Project Folder>
5. Click ‚Finish’
![Eclipse File Import](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/EclipseImport3.png)
* the resulting GUI should look like this:
![Eclipse GUI](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/GUI.png)
1. *[File &raquo; Import]*
2. *[General &raquo; Existing Projects into Workspace]*
3. Browse <Project Folder>
4. Finish
* We have prepared some FIXME and TODO annotations:
* Just open the „Task“ view
* FIXMEs are for the first task (message exchange)
* TODOs are for the second task (observe and AC control)
* If you do not have a „Task“ view:
* Window > Show View > Other
* Type task
* Select General > Task view
* *[Window &raquo; Show View &raquo; Other]*
* Type `task`
* Select *[General &raquo; Task]* view
## 5. Task 1: Implementation of client/server and enable simple message exchange
### Sequence Diagram
![Task 1 – Sequence Diagram](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/Task1Sequence.png)
### Server
1. Create a new resource class TemperatureResource (already done in our example Server)
2. Instantiate a new ResourceServer
......@@ -101,10 +80,9 @@ You can find the required files in our repository at https://gitlab.amd.e-techni
4. Add the TemperatureResource to the ResourceServer
5. Run the ResourceServer
#### 1. Create a new resource class TemperatureResource (TemperatureResource.java):
* We could have used the predefined BasicCoapResource
* BasicCoapResource is a resource that just keeps a static `byte[ ]` that is:
* BasicCoapResource is a resource that just keeps a static `byte[]` which is:
* returned on GET requests
* replaced by the payload on PUT requests
* appended with the payload on POST requests
......@@ -112,35 +90,47 @@ You can find the required files in our repository at https://gitlab.amd.e-techni
* We do not want a static `byte[]`
* Instead we want a random number to be returned on a GET
* PUT, POST and DELETE are not used
* ->So we implemented TemperatureResource wich extends BasicCoapResource with:
* ->So we implemented TemperatureResource which extends BasicCoapResource with:
* A constructor to initialize the resource and disallow POST, PUT and DELETE requests
* Two get() Methods:
* Get a list of accepted media types [& query parameters] which returns a `byte[]` together with its media type
```java
CoapData get(List<CoapMediaType> mediaTypesAccepted)
CoapData get(List<String> query, List<CoapMediaType> mediaTypesAccepted)
```
* And the `getResourceType()` method
* Wich returns a description string of the resource
* Which returns a description string of the resource
#### 2. Instantiate a new ResourceServer (Server.java, FIXME 1):
* Need a CoapResourceServer to maintain resources
`CoapResourceServer resourceServer = new CoapResourceServer();`
```java
CoapResourceServer resourceServer = new CoapResourceServer();
```
#### 3. Instantiate a new TemperatureResource (Server.java, FIXME 2):
* Resources are created like normal objects and added to the server
`CoapResource resource = new CoapResource();`
```java
CoapResource resource = new CoapResource();
```
#### 4. Add the TemperatureResource to the ResourceServer (Server.java, FIXME 3):
* Resources are created like normal objects and added to the server
`resourceServer.createResource(resource);`
#### 5. Run the ResourceServer (Server.java):
`resourceServer.start();`
```java
resourceServer.createResource(resource);
```
#### 5. Run the ResourceServer (Server.java FIXME 4):
```java
resourceServer.start(port);
resourceServer.start(); // equals port = CoapConstants.COAP_DEFAULT_PORT
```
* Run Server: Click on Run -> Run in the Menu bar
* Run Server: Click on *[Run &raquo; Run]* in the Menu bar
* To stop the server, press the red terminate button in the console/task area
* Test it with Copper: coap://127.0.0.1
* Test it with Copper: `coap://127.0.0.1`
* Stretch goal:
* Create another resource type e.g.: humidity or current Time
* Tip: make a copy of TemperatureResource.java
* Create another resource type e.g.: humidity or current Time, use real sensor values if possible
* Tip: make a copy of `TemperatureResource.java`
### Client
1. Establish a connection to the Server using the ChannelManager
......@@ -149,68 +139,95 @@ You can find the required files in our repository at https://gitlab.amd.e-techni
4. Wait for CoapResponse
5. Print the CoapResponse on the console (already done in our example)
#### 1. Establish a connection to the Server using the ChannelManager (Client.java, FIXME 4-5):
#### 1. Establish a connection to the Server using the ChannelManager (Client.java, FIXME 5-6):
* A client must implement CoapClient interface
`public class Client implements CoapClient {...}`
```java
public class Client implements CoapClient {...}
```
* A CoapChannelManager is used to manage different connections and to establish a connection to a server
`channelManager = BasicCoapChannelManager.getInstance();`
`clientChannel = channelManager.connect(CoapClient client,InetAddress serverIP, int serverPort);`
```java`
channelManager = BasicCoapChannelManager.getInstance();
clientChannel = channelManager.connect(CoapClient client,InetAddress serverIP, int serverPort);
```
#### 2. Create a CoapRequest & add some Options (Client.java, FIXME 6-8):
#### 2. Create a CoapRequest & add some Options (Client.java, FIXME 7-9):
* A channel represents a single connection and is used to create and send requests
`Boolean reliable = false;`
`CoapRequestCode reqCode = CoapRequestCode.GET;`
`CoapRequest request = clientChannel.createRequest(reliable,reqCode);`
`request.setUriPath("/temperature");`
#### 3. Send the CoapRequest (Client.java, FIXME 6-8):
`clientChannel.sendMessage(request);`
```java
Boolean reliable = false;
CoapRequestCode reqCode = CoapRequestCode.GET;
CoapRequest request = clientChannel.createRequest(reliable,reqCode);
request.setUriPath("/temperature");
```
#### 3. Send the CoapRequest (Client.java, FIXME 7-9):
```java
clientChannel.sendMessage(request);
```
#### 4. Wait for CoapResponse & Print the CoapResponse on the console
* A client has some callbacks that are invoked, when the corresponding event occurs
`public void onConnectionFailed(...)`
`public void onResponse(...) // = Unicast`
`public void onMCResponse(...) // MC = Multicast`
```java
public void onConnectionFailed(...)
public void onResponse(...) // = Unicast
public void onMCResponse(...) // MC = Multicast
```
* Run Server: select Server.java and click on Run -> Run in the Menu bar
* Run Client: select Client.java and click on Run -> Run in the Menu bar
* Run Server: select Server.java and click on *[Run &raquo; Run]* in the Menu bar
* Run Client: select Client.java and click on *[Run &raquo; Run]* in the Menu bar
* Stretch goal:
* GET the “/.well-known/core” resource (it is generated automatically by the server)
* If you have written your own resources before: GET them
* GET the `/.well-known/core` resource (it is generated automatically by the server)
* GET the `/.well-known/core` resource using multicast (aka. Multicast Discovery)
* Multicast Adresses: `CoapConstants.COAP_ALL_NODES_IPV4_MC_ADDR`, `CoapConstants.COAP_ALL_NODES_IPV6_LL_MC_ADDR` and `CoapConstants.COAP_ALL_NODES_IPV6_SL_MC_ADDR`
```java
// add a (mandatory) token to match outgoing multicast message and incoming unicast messages
request.setToken("MCToken".getBytes());
```
## 6. Task 2: Implementation of a AC control by using the CoAP-observe mechanism
![Task 2 - Sequence diagram](https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/raw/master/ws4d-jcoap-handsOn/img/Task2Sequence.png)
1. Use the eventing mechanism CoAP-Observe
2. Let the server notify clients every 5 seconds about a changed TemperatureResource
3. Implement an Air Conditioner Resource with the path “/ACControl”, that can be set to “high”,
“medium”, “low” or “off”
3. Implement an Air Conditioner Resource with the path `/ACControl`, that can be set to `high`, `medium`, `low` or `off`
1. Use the eventing mechanism CoAP-Observe (Server.java, TODO 10):
* Mark the TemperatureResource as observable
`resource.setObservable(true);`
```java
resource.setObservable(true);
```
2. Let server notify clients every 5 s about changed TemperatureResource (Server.java, TODO 11):
* indicate a change for resource every 5 seconds
`while (true) {`
` try {Thread.sleep(5000);}`
` catch (InterruptedException e) {/*do nothing*/}`
` resource.changed();`
`}`
3. Implement an Air Conditioner Resource with the path “/ACControl”, that can be set to “high”, “medium”, “low” or “off” (Client.java & Server.java, TODO 12-15):
```java
while (true) {
try {Thread.sleep(5000);}
catch (InterruptedException e) {/*do nothing*/}
resource.changed();
}
```
3. Implement an Air Conditioner Resource with the path `/ACControl`, that can be set to `high`, `medium`, `low` or `off` (Client.java & Server.java, TODO 12-15):
* Change exitAfterResponse to false (Client.java, TODO 12)
* Add the observe-option to your CoAP-GET request (Client.java, TODO 13)
`request.setObserveOption(0);`
* add a BasicCoapResource to the ResourceServer (Server.java, TODO 14) `resourceServer.createResource(newBasicCoapResource(“/ACControl”,”off”,CoapMediaType.text_plain));`
```java
request.setObserveOption(0);
```
* add a BasicCoapResource to the ResourceServer (Server.java, TODO 14)
```java
resourceServer.createResource(newBasicCoapResource(/ACControl,off,CoapMediaType.text_plain));
```
* send PUT request (Client.java, TODO 15)
`CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.PUT);`
`request.setUriPath(“/ACControl”);`
`request.setContentType(CoapMediaType.text_plain);`
```java
CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.PUT);
request.setUriPath(/ACControl);
request.setContentType(CoapMediaType.text_plain);
```
Depending on the received temperature, set the payload to high, medium, low or off
high -> 28 <= Temperature
medium -> 25 <= Temperature < 28
low -> 21 <= Temperature < 25
off -> Temperature < 21
`request.setPayload(“medium”.getBytes());`
`clientChannel.sendMessage(request);`
| high | 28 <= Temperature |
| medium | 25 <= Temperature < 28 |
| low | 21 <= Temperature < 25 |
| off | Temperature < 21 |
```java
request.setPayload(medium.getBytes());
clientChannel.sendMessage(request);
```
\ No newline at end of file