├── .gitignore ├── README.md ├── src └── main │ ├── java │ └── org │ │ └── wsncoap │ │ └── embedded │ │ ├── resources │ │ ├── Link2.java │ │ ├── Link3.java │ │ ├── Link1.java │ │ ├── PathSub.java │ │ ├── LocationQuery.java │ │ ├── Shutdown.java │ │ ├── Path.java │ │ ├── ObserveReset.java │ │ ├── Query.java │ │ ├── LongPath.java │ │ ├── Separate.java │ │ ├── LargePost.java │ │ ├── MultiFormat.java │ │ ├── ObserveLarge.java │ │ ├── DefaultTest.java │ │ ├── Create.java │ │ ├── ObservePumping.java │ │ ├── Large.java │ │ ├── LargeSeparate.java │ │ ├── LargeCreate.java │ │ ├── Observe.java │ │ ├── ObserveNon.java │ │ ├── Validate.java │ │ └── LargeUpdate.java │ │ └── PlugtestServer.java │ └── resources │ └── logback.xml └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | .project 4 | *.iml 5 | Californium.properties -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 更新说明 2 | 1. 使用Java Californium 框架,当前版本`2.0.0-M14` 3 | 2. 使用IDEA+Maven重写,2019年之前并没有系统学习和使用Java 4 | 5 | ## 运行 6 | 使用pm2工具保持后台运行,新建一个名为`server.json`的文件,文件内容如下 7 | ``` 8 | { 9 | "name": "coap-plugtest-server", 10 | "script": "/usr/bin/java", 11 | "args": [ 12 | "-jar", 13 | "plugtest-server.jar" 14 | ], 15 | "exec_interpreter": "", 16 | "exec_mode": "fork" 17 | } 18 | ``` 19 | 在控制台中通过pm2启动进行,启动前应使用`pm2 stop [id]`停止原应用 20 | ``` 21 | pm2 start server.json 22 | ``` 23 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Link2.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | 20 | /** 21 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 22 | */ 23 | public class Link2 extends CoapResource { 24 | 25 | public Link2() { 26 | super("link2"); 27 | getAttributes().setTitle("Link test resource"); 28 | getAttributes().addInterfaceDescription("If2"); 29 | getAttributes().addResourceType("Type2"); 30 | getAttributes().addResourceType("Type3"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Link3.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | 20 | /** 21 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 22 | */ 23 | public class Link3 extends CoapResource { 24 | 25 | public Link3() { 26 | super("link3"); 27 | getAttributes().setTitle("Link test resource"); 28 | getAttributes().addInterfaceDescription("foo"); 29 | getAttributes().addResourceType("Type1"); 30 | getAttributes().addResourceType("Type3"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Link1.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | 20 | 21 | /** 22 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 23 | */ 24 | public class Link1 extends CoapResource { 25 | 26 | public Link1() { 27 | super("link1"); 28 | getAttributes().setTitle("Link test resource"); 29 | getAttributes().addInterfaceDescription("If1"); 30 | getAttributes().addResourceType("Type1"); 31 | getAttributes().addResourceType("Type2"); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/PathSub.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.server.resources.CoapExchange; 20 | 21 | /** 22 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 23 | */ 24 | public class PathSub extends CoapResource { 25 | 26 | public PathSub(String name) { 27 | super(name); 28 | getAttributes().setTitle("Hierarchical link description sub-resource"); 29 | } 30 | 31 | @Override 32 | public void handleGET(CoapExchange exchange) { 33 | exchange.respond(this.getURI()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss} %level [%logger{0}]: %msg%n 8 | 9 | 10 | 11 | 12 | logs/application.log 13 | 14 | 15 | logs/application-%d{yyyy-MM-dd}.%i.log 16 | 17 | 20MB 18 | 30 19 | 1GB 20 | 21 | 22 | 23 | 24 | [%date{yyyy-MM-dd HH:mm:ss}]\t%msg%n 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/LocationQuery.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.server.resources.CoapExchange; 20 | 21 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CREATED; 22 | 23 | /** 24 | * This resource implements a test of specification for the 25 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 26 | */ 27 | public class LocationQuery extends CoapResource { 28 | 29 | public LocationQuery() { 30 | super("location-query"); 31 | getAttributes().setTitle("Perform POST transaction with responses containing several Location-Query options (CON mode)"); 32 | } 33 | 34 | @Override 35 | public void handlePOST(CoapExchange exchange) { 36 | exchange.setLocationQuery("?first=1&second=2"); 37 | exchange.respond(CREATED); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Shutdown.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.server.resources.CoapExchange; 20 | 21 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CHANGED; 22 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.FORBIDDEN; 23 | 24 | public class Shutdown extends CoapResource { 25 | 26 | public Shutdown() { 27 | super("shutdown"); 28 | } 29 | 30 | @Override 31 | public void handlePOST(CoapExchange exchange) { 32 | if (exchange.getRequestText().equals("sesame")) { 33 | exchange.respond(CHANGED); 34 | 35 | System.out.println("Shutdown resource received POST. Exiting"); 36 | try { 37 | Thread.sleep(500); 38 | } catch (Exception e) { 39 | e.printStackTrace(); 40 | } 41 | System.exit(0); 42 | 43 | } else { 44 | exchange.respond(FORBIDDEN); 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Path.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.LinkFormat; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | 22 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 23 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.APPLICATION_LINK_FORMAT; 24 | 25 | /** 26 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 27 | */ 28 | public class Path extends CoapResource { 29 | 30 | public Path() { 31 | super("path"); 32 | getAttributes().setTitle("Hierarchical link description entry"); 33 | getAttributes().addContentType(APPLICATION_LINK_FORMAT); 34 | add(new PathSub("sub1")); 35 | add(new PathSub("sub2")); 36 | add(new PathSub("sub3")); 37 | } 38 | 39 | @Override 40 | public void handleGET(CoapExchange exchange) { 41 | exchange.respond(CONTENT, LinkFormat.serializeTree(this), APPLICATION_LINK_FORMAT); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/ObserveReset.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.server.resources.CoapExchange; 20 | 21 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CHANGED; 22 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.FORBIDDEN; 23 | 24 | public class ObserveReset extends CoapResource { 25 | 26 | public ObserveReset() { 27 | super("obs-reset"); 28 | } 29 | 30 | @Override 31 | public void handlePOST(CoapExchange exchange) { 32 | if (exchange.getRequestText().equals("sesame")) { 33 | System.out.println("obs-reset received POST. Clearing observers"); 34 | 35 | // clear observers of the obs resources 36 | Observe obs = (Observe) this.getParent().getChild("obs"); 37 | ObserveNon obsNon = (ObserveNon) this.getParent().getChild("obs-non"); 38 | obs.clearObserveRelations(); 39 | obsNon.clearObserveRelations(); 40 | 41 | exchange.respond(CHANGED); 42 | 43 | } else { 44 | exchange.respond(FORBIDDEN); 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Query.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.Request; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | 22 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 23 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 24 | 25 | /** 26 | * This resource implements a test of specification for the 27 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 28 | */ 29 | public class Query extends CoapResource { 30 | 31 | public Query() { 32 | super("query"); 33 | getAttributes().setTitle("Resource accepting query parameters"); 34 | } 35 | 36 | @Override 37 | public void handleGET(CoapExchange exchange) { 38 | 39 | // get request to read out details 40 | Request request = exchange.advanced().getRequest(); 41 | 42 | StringBuilder payload = new StringBuilder(); 43 | payload.append(String.format("Type: %d (%s)\nCode: %d (%s)\nMID: %d\n", 44 | request.getType().value, 45 | request.getType(), 46 | request.getCode().value, 47 | request.getCode(), 48 | request.getMID() 49 | )); 50 | payload.append("?").append(request.getOptions().getUriQueryString()); 51 | if (payload.length()>64) { 52 | payload.delete(63, payload.length()); 53 | payload.append('»'); 54 | } 55 | 56 | // complete the request 57 | exchange.respond(CONTENT, payload.toString(), TEXT_PLAIN); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/LongPath.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.Request; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | import org.eclipse.californium.core.server.resources.Resource; 22 | 23 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 24 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 25 | 26 | /** 27 | * This resource implements a test of specification for the 28 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 29 | */ 30 | public class LongPath extends CoapResource { 31 | 32 | public LongPath() { 33 | this("seg1"); 34 | 35 | Resource seg2 = new LongPath("seg2"); 36 | Resource seg3 = new LongPath("seg3"); 37 | 38 | add(seg2); 39 | seg2.add(seg3); 40 | } 41 | 42 | public LongPath(String name) { 43 | super(name); 44 | getAttributes().setTitle("Long path resource"); 45 | } 46 | 47 | @Override 48 | public void handleGET(CoapExchange exchange) { 49 | Request request = exchange.advanced().getRequest(); 50 | 51 | String payload = String.format("Long path resource\n" + 52 | "Type: %d (%s)\nCode: %d (%s)\nMID: %d", 53 | request.getType().value, 54 | request.getType(), 55 | request.getCode().value, 56 | request.getCode(), 57 | request.getMID() 58 | ); 59 | 60 | // complete the request 61 | exchange.respond(CONTENT, payload, TEXT_PLAIN); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Separate.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.Request; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | 22 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 23 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 24 | 25 | 26 | /** 27 | * This resource implements a test of specification for the 28 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 29 | */ 30 | public class Separate extends CoapResource { 31 | 32 | public Separate() { 33 | super("separate"); 34 | getAttributes().setTitle("Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way"); 35 | } 36 | 37 | @Override 38 | public void handleGET(CoapExchange exchange) { 39 | 40 | // promise the client that this request will be acted upon by sending an Acknowledgement 41 | exchange.accept(); 42 | 43 | // do the time-consuming computation 44 | try { 45 | Thread.sleep(1000); 46 | } catch (InterruptedException e) { 47 | } 48 | 49 | // get request to read out details 50 | Request request = exchange.advanced().getRequest(); 51 | 52 | String payload = String.format("Type: %d (%s)\nCode: %d (%s)\nMID: %d\n", 53 | request.getType().value, 54 | request.getType(), 55 | request.getCode().value, 56 | request.getCode(), 57 | request.getMID() 58 | ); 59 | 60 | // complete the request 61 | exchange.respond(CONTENT, payload, TEXT_PLAIN); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/LargePost.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.LinkFormat; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | 22 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.*; 23 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.APPLICATION_LINK_FORMAT; 24 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 25 | 26 | /** 27 | * This resource implements a test of specification for the 28 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 29 | */ 30 | public class LargePost extends CoapResource { 31 | 32 | // Constructors //////////////////////////////////////////////////////////// 33 | 34 | /* 35 | * Default constructor. 36 | */ 37 | public LargePost() { 38 | this("large-post"); 39 | } 40 | 41 | /* 42 | * Constructs a new storage resource with the given resourceIdentifier. 43 | */ 44 | public LargePost(String resourceIdentifier) { 45 | super(resourceIdentifier); 46 | getAttributes().setTitle("Handle POST with two-way blockwise transfer"); 47 | getAttributes().addResourceType("block"); 48 | } 49 | 50 | // REST Operations ///////////////////////////////////////////////////////// 51 | 52 | /* 53 | * GET Link Format list of created sub-resources. 54 | */ 55 | @Override 56 | public void handleGET(CoapExchange exchange) { 57 | exchange.respond(CONTENT, LinkFormat.serializeTree(this), APPLICATION_LINK_FORMAT); 58 | } 59 | 60 | /* 61 | * POST content for action result (text changed to upper case). 62 | */ 63 | @Override 64 | public void handlePOST(CoapExchange exchange) { 65 | if (exchange.getRequestOptions().hasContentFormat()) { 66 | exchange.respond(CHANGED, exchange.getRequestText().toUpperCase(), TEXT_PLAIN); 67 | } else { 68 | exchange.respond(BAD_REQUEST, "Content-Format not set"); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/MultiFormat.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.MediaTypeRegistry; 20 | import org.eclipse.californium.core.coap.Request; 21 | import org.eclipse.californium.core.coap.Response; 22 | import org.eclipse.californium.core.server.resources.CoapExchange; 23 | 24 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 25 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.NOT_ACCEPTABLE; 26 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.*; 27 | 28 | /** 29 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 30 | */ 31 | public class MultiFormat extends CoapResource { 32 | 33 | public MultiFormat() { 34 | super("multi-format"); 35 | getAttributes().setTitle("Resource that exists in different content formats (text/plain utf8 and application/xml)"); 36 | getAttributes().addContentType(0); 37 | getAttributes().addContentType(41); 38 | } 39 | 40 | @Override 41 | public void handleGET(CoapExchange exchange) { 42 | 43 | // get request to read out details 44 | Request request = exchange.advanced().getRequest(); 45 | 46 | // successively create response 47 | Response response = new Response(CONTENT); 48 | 49 | String format = ""; 50 | switch (exchange.getRequestOptions().getAccept()) { 51 | case UNDEFINED: 52 | case TEXT_PLAIN: 53 | response.getOptions().setContentFormat(TEXT_PLAIN); 54 | format = "Status type: \"%s\"\nCode: \"%s\"\nMID: \"%s\"\nAccept: \"%s\""; 55 | break; 56 | 57 | case APPLICATION_XML: 58 | response.getOptions().setContentFormat(APPLICATION_XML); 59 | format = ""; // should fit 64 bytes 60 | break; 61 | 62 | default: 63 | response = new Response(NOT_ACCEPTABLE); 64 | format = "text/plain or application/xml only"; 65 | break; 66 | } 67 | 68 | response.setPayload( 69 | String.format(format, 70 | request.getType(), 71 | request.getCode(), 72 | request.getMID(), 73 | MediaTypeRegistry.toString(request.getOptions().getAccept())) 74 | ); 75 | 76 | exchange.respond(response); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/ObserveLarge.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.CoAP.Type; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | 22 | import java.text.DateFormat; 23 | import java.text.SimpleDateFormat; 24 | import java.util.Date; 25 | import java.util.Timer; 26 | import java.util.TimerTask; 27 | 28 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 29 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 30 | 31 | /** 32 | * This resource implements a test of specification for the 33 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 34 | */ 35 | public class ObserveLarge extends CoapResource { 36 | 37 | // Members //////////////////////////////////////////////////////////////// 38 | 39 | private final static String PADDING = "----------------------------------------------------------------"; 40 | 41 | // The current time represented as string 42 | private String time; 43 | 44 | /* 45 | * Constructor for a new TimeResource 46 | */ 47 | public ObserveLarge() { 48 | super("obs-large"); 49 | setObservable(true); 50 | getAttributes().setTitle("Observable resource which changes every 5 seconds"); 51 | getAttributes().addResourceType("observe"); 52 | getAttributes().setObservable(); 53 | setObserveType(Type.CON); 54 | 55 | // Set timer task scheduling 56 | Timer timer = new Timer(); 57 | timer.schedule(new TimeTask(), 0, 5000); 58 | } 59 | 60 | /* 61 | * Defines a new timer task to return the current time 62 | */ 63 | private class TimeTask extends TimerTask { 64 | 65 | @Override 66 | public void run() { 67 | time = String.format("%s\n%-32s\n%s", PADDING, getTime(), PADDING); 68 | 69 | // Call changed to notify subscribers 70 | changed(); 71 | } 72 | } 73 | 74 | /* 75 | * Returns the current time 76 | * 77 | * @return The current time 78 | */ 79 | private String getTime() { 80 | DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); 81 | Date time = new Date(); 82 | return dateFormat.format(time); 83 | } 84 | 85 | @Override 86 | public void handleGET(CoapExchange exchange) { 87 | 88 | exchange.setMaxAge(5); 89 | exchange.respond(CONTENT, time, TEXT_PLAIN); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/DefaultTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | * Achim Kraus (Bosch Software Innovations GmbH) - replace byte array token by Token 16 | ******************************************************************************/ 17 | package org.wsncoap.embedded.resources; 18 | 19 | import org.eclipse.californium.core.CoapResource; 20 | import org.eclipse.californium.core.coap.Request; 21 | import org.eclipse.californium.core.server.resources.CoapExchange; 22 | 23 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.*; 24 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 25 | 26 | /** 27 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 28 | */ 29 | public class DefaultTest extends CoapResource { 30 | 31 | public DefaultTest() { 32 | super("test"); 33 | getAttributes().setTitle("Default test resource"); 34 | } 35 | 36 | @Override 37 | public void handleGET(CoapExchange exchange) { 38 | 39 | // Check: Type, Code 40 | 41 | StringBuilder payload = new StringBuilder(); 42 | 43 | Request request = exchange.advanced().getRequest(); 44 | payload.append(String.format("Type: %d (%s)\nCode: %d (%s)\nMID: %d", 45 | request.getType().value, 46 | request.getType(), 47 | request.getCode().value, 48 | request.getCode(), 49 | request.getMID())); 50 | 51 | if (request.getToken() != null) { 52 | payload.append("\nToken: "); 53 | payload.append(request.getTokenString()); 54 | } 55 | 56 | if (payload.length() > 64) { 57 | payload.delete(62, payload.length()); 58 | payload.append('»'); 59 | } 60 | 61 | // complete the request 62 | exchange.setMaxAge(30); 63 | exchange.respond(CONTENT, payload.toString(), TEXT_PLAIN); 64 | } 65 | 66 | @Override 67 | public void handlePOST(CoapExchange exchange) { 68 | 69 | // Check: Type, Code, has Content-Type 70 | 71 | exchange.setLocationPath("/location1/location2/location3"); 72 | exchange.respond(CREATED); 73 | } 74 | 75 | @Override 76 | public void handlePUT(CoapExchange exchange) { 77 | 78 | // Check: Type, Code, has Content-Type 79 | 80 | if (exchange.getRequestOptions().hasIfNoneMatch()) { 81 | exchange.respond(PRECONDITION_FAILED); 82 | } else { 83 | exchange.respond(CHANGED); 84 | } 85 | } 86 | 87 | @Override 88 | public void handleDELETE(CoapExchange exchange) { 89 | // complete the request 90 | exchange.respond(DELETED); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Create.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.server.resources.CoapExchange; 20 | import org.eclipse.californium.elements.util.Bytes; 21 | 22 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.*; 23 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.UNDEFINED; 24 | 25 | 26 | /** 27 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 28 | */ 29 | public class Create extends CoapResource { 30 | 31 | // Members //////////////////////////////////////////////////////////////// 32 | 33 | private byte[] data = null; 34 | private int dataCf = UNDEFINED; 35 | 36 | public Create() { 37 | super("create1"); 38 | getAttributes().setTitle("Resource which does not exist yet (to perform atomic PUT)"); 39 | setVisible(false); 40 | } 41 | 42 | @Override 43 | public void handlePUT(CoapExchange exchange) { 44 | if (data!=null && exchange.getRequestOptions().hasIfNoneMatch()) { 45 | exchange.respond(PRECONDITION_FAILED); 46 | 47 | // automatically reset 48 | data = null; 49 | } else { 50 | if (exchange.getRequestOptions().hasContentFormat()) { 51 | storeData(exchange.getRequestPayload(), exchange.getRequestOptions().getContentFormat()); 52 | exchange.respond(CREATED); 53 | } else { 54 | exchange.respond(BAD_REQUEST, "Content-Format not set"); 55 | } 56 | } 57 | } 58 | 59 | @Override 60 | public void handleGET(CoapExchange exchange) { 61 | if (data!=null) { 62 | exchange.respond(CONTENT, data, dataCf); 63 | } else { 64 | exchange.respond(NOT_FOUND); 65 | } 66 | } 67 | 68 | @Override 69 | public void handleDELETE(CoapExchange exchange) { 70 | data = null; 71 | setVisible(false); 72 | exchange.respond(DELETED); 73 | } 74 | 75 | // Internal //////////////////////////////////////////////////////////////// 76 | 77 | /* 78 | * Convenience function to store data contained in a 79 | * PUT/POST-Request. Notifies observing endpoints about 80 | * the change of its contents. 81 | */ 82 | private synchronized void storeData(byte[] payload, int cf) { 83 | 84 | // set payload and content type 85 | data = payload != null ? payload : Bytes.EMPTY; 86 | dataCf = cf; 87 | getAttributes().clearContentType(); 88 | getAttributes().addContentType(dataCf); 89 | getAttributes().setMaximumSizeEstimate(data.length); 90 | 91 | setVisible(true); 92 | 93 | // signal that resource state changed 94 | changed(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.wsncoap 8 | plugtest-server 9 | 1.0-SNAPSHOT 10 | 11 | 12 | UTF-8 13 | 14 | org.wsncoap.embedded.PlugtestServer 15 | 16 | 17 | 18 | 19 | junit 20 | junit 21 | 4.12 22 | test 23 | 24 | 25 | org.eclipse.californium 26 | californium-core 27 | 2.0.0-M14 28 | 29 | 30 | org.slf4j 31 | slf4j-api 32 | 1.7.25 33 | 34 | 35 | ch.qos.logback 36 | logback-classic 37 | 1.2.3 38 | 39 | 40 | ch.qos.logback 41 | logback-core 42 | 1.2.3 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-compiler-plugin 51 | 2.0.2 52 | 53 | 1.8 54 | 1.8 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-assembly-plugin 60 | 61 | false 62 | 63 | 64 | true 65 | ${assembly.mainClass} 66 | true 67 | 68 | 69 | 70 | jar-with-dependencies 71 | 72 | 73 | 74 | 75 | make-assembly 76 | package 77 | 78 | single 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/ObservePumping.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.CoAP.Type; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | 22 | import java.text.DateFormat; 23 | import java.text.SimpleDateFormat; 24 | import java.util.Date; 25 | import java.util.Timer; 26 | import java.util.TimerTask; 27 | 28 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 29 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 30 | 31 | /** 32 | * This resource implements a test of specification for the 33 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 34 | */ 35 | public class ObservePumping extends CoapResource { 36 | 37 | // Members //////////////////////////////////////////////////////////////// 38 | 39 | private final static String PADDING = "----------------------------------------------------------------"; 40 | 41 | // The current time represented as string 42 | private String time; 43 | 44 | public ObservePumping() { 45 | this(Type.CON); 46 | } 47 | 48 | public ObservePumping(Type type) { 49 | super("obs-pumping" + (type== Type.NON ? "-non" : "")); 50 | setObservable(true); 51 | getAttributes().setTitle("Observable resource which changes every 5 seconds"); 52 | getAttributes().addResourceType("observe"); 53 | getAttributes().setObservable(); 54 | setObserveType(type); 55 | 56 | // Set timer task scheduling 57 | Timer timer = new Timer(); 58 | timer.schedule(new TimeTask(), 0, 5000); 59 | } 60 | 61 | /* 62 | * Defines a new timer task to return the current time 63 | */ 64 | private class TimeTask extends TimerTask { 65 | 66 | @Override 67 | public void run() { 68 | if (Math.random()>0.5) { 69 | time = String.format("%.31s\n%19s\n%.31s\n", PADDING, getTime(), PADDING); 70 | } else if (Math.random()>0.5) { 71 | time = String.format("%.63s\n%35s\n%.63s\n", PADDING, getTime(), PADDING); 72 | } else { 73 | time = String.format("%s", getTime()); 74 | } 75 | 76 | // Call changed to notify subscribers 77 | changed(); 78 | } 79 | } 80 | 81 | /* 82 | * Returns the current time 83 | * 84 | * @return The current time 85 | */ 86 | private String getTime() { 87 | DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); 88 | Date time = new Date(); 89 | return dateFormat.format(time); 90 | } 91 | 92 | @Override 93 | public void handleGET(CoapExchange exchange) { 94 | 95 | exchange.setMaxAge(5); 96 | exchange.respond(CONTENT, time, TEXT_PLAIN); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Large.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.server.resources.CoapExchange; 20 | 21 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 22 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 23 | 24 | /** 25 | * This resource implements a test of specification for the 26 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 27 | */ 28 | public class Large extends CoapResource { 29 | 30 | public Large() { 31 | super("large"); 32 | getAttributes().setTitle("Large resource"); 33 | getAttributes().addResourceType("block"); 34 | getAttributes().setMaximumSizeEstimate(1280); 35 | } 36 | 37 | @Override 38 | public void handleGET(CoapExchange exchange) { 39 | 40 | StringBuilder builder = new StringBuilder(); 41 | builder.append("/-------------------------------------------------------------\\\n"); 42 | builder.append("| RESOURCE BLOCK NO. 1 OF 5 |\n"); 43 | builder.append("| [each line contains 64 bytes] |\n"); 44 | builder.append("\\-------------------------------------------------------------/\n"); 45 | builder.append("/-------------------------------------------------------------\\\n"); 46 | builder.append("| RESOURCE BLOCK NO. 2 OF 5 |\n"); 47 | builder.append("| [each line contains 64 bytes] |\n"); 48 | builder.append("\\-------------------------------------------------------------/\n"); 49 | builder.append("/-------------------------------------------------------------\\\n"); 50 | builder.append("| RESOURCE BLOCK NO. 3 OF 5 |\n"); 51 | builder.append("| [each line contains 64 bytes] |\n"); 52 | builder.append("\\-------------------------------------------------------------/\n"); 53 | builder.append("/-------------------------------------------------------------\\\n"); 54 | builder.append("| RESOURCE BLOCK NO. 4 OF 5 |\n"); 55 | builder.append("| [each line contains 64 bytes] |\n"); 56 | builder.append("\\-------------------------------------------------------------/\n"); 57 | builder.append("/-------------------------------------------------------------\\\n"); 58 | builder.append("| RESOURCE BLOCK NO. 5 OF 5 |\n"); 59 | builder.append("| [each line contains 64 bytes] |\n"); 60 | builder.append("\\-------------------------------------------------------------/\n"); 61 | 62 | exchange.respond(CONTENT, builder.toString(), TEXT_PLAIN); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/LargeSeparate.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.server.resources.CoapExchange; 20 | 21 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; 22 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 23 | 24 | /** 25 | * This resource implements a test of specification for the 26 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 27 | */ 28 | public class LargeSeparate extends CoapResource { 29 | 30 | public LargeSeparate() { 31 | super("large-separate"); 32 | getAttributes().setTitle("Large resource"); 33 | getAttributes().addResourceType("block"); 34 | getAttributes().setMaximumSizeEstimate(1280); 35 | } 36 | 37 | @Override 38 | public void handleGET(CoapExchange exchange) { 39 | 40 | exchange.accept(); 41 | 42 | StringBuilder builder = new StringBuilder(); 43 | builder.append("/-------------------------------------------------------------\\\n"); 44 | builder.append("| RESOURCE BLOCK NO. 1 OF 5 |\n"); 45 | builder.append("| [each line contains 64 bytes] |\n"); 46 | builder.append("\\-------------------------------------------------------------/\n"); 47 | builder.append("/-------------------------------------------------------------\\\n"); 48 | builder.append("| RESOURCE BLOCK NO. 2 OF 5 |\n"); 49 | builder.append("| [each line contains 64 bytes] |\n"); 50 | builder.append("\\-------------------------------------------------------------/\n"); 51 | builder.append("/-------------------------------------------------------------\\\n"); 52 | builder.append("| RESOURCE BLOCK NO. 3 OF 5 |\n"); 53 | builder.append("| [each line contains 64 bytes] |\n"); 54 | builder.append("\\-------------------------------------------------------------/\n"); 55 | builder.append("/-------------------------------------------------------------\\\n"); 56 | builder.append("| RESOURCE BLOCK NO. 4 OF 5 |\n"); 57 | builder.append("| [each line contains 64 bytes] |\n"); 58 | builder.append("\\-------------------------------------------------------------/\n"); 59 | builder.append("/-------------------------------------------------------------\\\n"); 60 | builder.append("| RESOURCE BLOCK NO. 5 OF 5 |\n"); 61 | builder.append("| [each line contains 64 bytes] |\n"); 62 | builder.append("\\-------------------------------------------------------------/\n"); 63 | 64 | exchange.respond(CONTENT, builder.toString(), TEXT_PLAIN); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/PlugtestServer.java: -------------------------------------------------------------------------------- 1 | 2 | package org.wsncoap.embedded; 3 | 4 | import java.net.Inet4Address; 5 | import java.net.InetAddress; 6 | import java.net.InetSocketAddress; 7 | 8 | 9 | import org.eclipse.californium.core.CoapServer; 10 | import org.eclipse.californium.core.coap.CoAP.Type; 11 | import org.eclipse.californium.core.network.CoapEndpoint; 12 | import org.eclipse.californium.core.network.Endpoint; 13 | import org.eclipse.californium.core.network.EndpointManager; 14 | import org.eclipse.californium.core.network.config.NetworkConfig; 15 | import org.eclipse.californium.core.network.interceptors.MessageTracer; 16 | import org.eclipse.californium.core.network.interceptors.OriginTracer; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.wsncoap.embedded.resources.*; 21 | 22 | 23 | /** 24 | * @author xukai 25 | */ 26 | public class PlugtestServer extends CoapServer { 27 | 28 | // exit codes for runtime errors 29 | public static final int ERR_INIT_FAILED = 1; 30 | 31 | private static final int COAP_PORT = NetworkConfig.getStandard().getInt(NetworkConfig.Keys.COAP_PORT); 32 | private static final Logger log = LoggerFactory.getLogger(CoapServer.class); 33 | 34 | public static void main(String[] args) { 35 | 36 | try { 37 | PlugtestServer server = new PlugtestServer(); 38 | server.addEndpoints(); 39 | server.start(); 40 | // add special interceptor for message traces 41 | for (Endpoint ep:server.getEndpoints()) { 42 | ep.addInterceptor(new MessageTracer()); 43 | ep.addInterceptor(new OriginTracer()); 44 | } 45 | log.info("{} listening on port {}", PlugtestServer.class.getSimpleName(), COAP_PORT); 46 | } catch (Exception e) { 47 | System.err.printf("Failed to create "+PlugtestServer.class.getSimpleName()+": %s\n", e.getMessage()); 48 | System.err.println("Exiting"); 49 | System.exit(ERR_INIT_FAILED); 50 | } 51 | } 52 | 53 | /** 54 | * Add individual endpoints listening on default CoAP port on all IPv4 addresses of all network interfaces. 55 | */ 56 | private void addEndpoints() { 57 | NetworkConfig config = NetworkConfig.getStandard(); 58 | for (InetAddress addr : EndpointManager.getEndpointManager().getNetworkInterfaces()) { 59 | // only binds to IPv4 addresses and localhost 60 | if (addr instanceof Inet4Address || addr.isLoopbackAddress()) { 61 | InetSocketAddress bindToAddress = new InetSocketAddress(addr, COAP_PORT); 62 | // addEndpoint(new CoapEndpoint(bindToAddress)); 63 | CoapEndpoint.Builder builder = new CoapEndpoint.Builder(); 64 | builder.setInetSocketAddress(bindToAddress); 65 | builder.setNetworkConfig(config); 66 | this.addEndpoint(builder.build()); 67 | } 68 | } 69 | } 70 | 71 | public PlugtestServer() { 72 | 73 | NetworkConfig.getStandard() 74 | .setInt(NetworkConfig.Keys.MAX_MESSAGE_SIZE, 64) 75 | .setInt(NetworkConfig.Keys.PREFERRED_BLOCK_SIZE, 64) 76 | .setInt(NetworkConfig.Keys.NOTIFICATION_CHECK_INTERVAL_COUNT, 4) 77 | .setInt(NetworkConfig.Keys.NOTIFICATION_CHECK_INTERVAL_TIME, 30000); 78 | 79 | // add resources to the server 80 | add(new DefaultTest()); 81 | add(new LongPath()); 82 | add(new Query()); 83 | add(new Separate()); 84 | add(new Large()); 85 | add(new LargeUpdate()); 86 | add(new LargeCreate()); 87 | add(new LargePost()); 88 | add(new LargeSeparate()); 89 | add(new Observe()); 90 | add(new ObserveNon()); 91 | add(new ObserveReset()); 92 | add(new ObserveLarge()); 93 | add(new ObservePumping()); 94 | add(new ObservePumping(Type.NON)); 95 | add(new LocationQuery()); 96 | add(new MultiFormat()); 97 | add(new Link1()); 98 | add(new Link2()); 99 | add(new Link3()); 100 | add(new Path()); 101 | add(new Validate()); 102 | add(new Create()); 103 | add(new Shutdown()); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/LargeCreate.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.LinkFormat; 20 | import org.eclipse.californium.core.coap.MediaTypeRegistry; 21 | import org.eclipse.californium.core.server.resources.CoapExchange; 22 | import org.eclipse.californium.elements.util.Bytes; 23 | 24 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.*; 25 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.APPLICATION_LINK_FORMAT; 26 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.UNDEFINED; 27 | 28 | /** 29 | * This resource implements a test of specification for the 30 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 31 | */ 32 | public class LargeCreate extends CoapResource { 33 | 34 | // Members ///////////////////////////////////////////////////////////////// 35 | 36 | private int counter = 0; 37 | 38 | // Constructors //////////////////////////////////////////////////////////// 39 | 40 | /* 41 | * Default constructor. 42 | */ 43 | public LargeCreate() { 44 | this("large-create"); 45 | } 46 | 47 | /* 48 | * Constructs a new storage resource with the given resourceIdentifier. 49 | */ 50 | public LargeCreate(String resourceIdentifier) { 51 | super(resourceIdentifier); 52 | getAttributes().setTitle("Large resource that can be created using POST method"); 53 | getAttributes().addResourceType("block"); 54 | } 55 | 56 | // REST Operations ///////////////////////////////////////////////////////// 57 | 58 | /* 59 | * GET Link Format list of created sub-resources. 60 | */ 61 | @Override 62 | public void handleGET(CoapExchange exchange) { 63 | String subtree = LinkFormat.serializeTree(this); 64 | exchange.respond(CONTENT, subtree, APPLICATION_LINK_FORMAT); 65 | } 66 | 67 | /* 68 | * POST content to create a sub-resource. 69 | */ 70 | @Override 71 | public void handlePOST(CoapExchange exchange) { 72 | 73 | if (exchange.getRequestOptions().hasContentFormat()) { 74 | exchange.setLocationPath( storeData(exchange.getRequestPayload(), exchange.getRequestOptions().getContentFormat()) ); 75 | exchange.respond(CREATED); 76 | } else { 77 | exchange.respond(BAD_REQUEST, "Content-Format not set"); 78 | } 79 | } 80 | 81 | // Internal //////////////////////////////////////////////////////////////// 82 | 83 | private class StorageResource extends CoapResource { 84 | 85 | byte[] data = null; 86 | int dataCt = UNDEFINED; 87 | 88 | public StorageResource(String name, byte[] post, int ct) { 89 | super(name); 90 | 91 | this.data = post != null ? post : Bytes.EMPTY; 92 | this.dataCt = ct; 93 | 94 | getAttributes().addContentType(dataCt); 95 | getAttributes().setMaximumSizeEstimate(data.length); 96 | } 97 | 98 | @Override 99 | public void handleGET(CoapExchange exchange) { 100 | 101 | if (exchange.getRequestOptions().hasAccept() && exchange.getRequestOptions().getAccept() != dataCt) { 102 | exchange.respond(NOT_ACCEPTABLE, MediaTypeRegistry.toString(dataCt) + " only"); 103 | } else { 104 | exchange.respond(CONTENT, data, dataCt); 105 | } 106 | } 107 | 108 | @Override 109 | public void handleDELETE(CoapExchange exchange) { 110 | this.delete(); 111 | } 112 | } 113 | 114 | /* 115 | * Convenience function to store data contained in a 116 | * PUT/POST-Request. Notifies observing endpoints about 117 | * the change of its contents. 118 | */ 119 | private synchronized String storeData(byte[] payload, int cf) { 120 | 121 | String name = new Integer(++counter).toString(); 122 | 123 | // set payload and content type 124 | StorageResource sub = new StorageResource(name, payload, cf); 125 | 126 | add(sub); 127 | 128 | return sub.getURI(); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Observe.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.CoAP.Type; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | import org.eclipse.californium.elements.util.Bytes; 22 | 23 | import java.text.DateFormat; 24 | import java.text.SimpleDateFormat; 25 | import java.util.Date; 26 | import java.util.Timer; 27 | import java.util.TimerTask; 28 | 29 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.*; 30 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 31 | 32 | /** 33 | * This resource implements a test of specification for the 34 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 35 | */ 36 | public class Observe extends CoapResource { 37 | 38 | // Members //////////////////////////////////////////////////////////////// 39 | 40 | private byte[] data = null; 41 | private int dataCf = TEXT_PLAIN; 42 | private boolean wasUpdated = false; 43 | 44 | // The current time represented as string 45 | private String time; 46 | 47 | /* 48 | * Constructor for a new TimeResource 49 | */ 50 | public Observe() { 51 | super("obs"); 52 | setObservable(true); 53 | getAttributes().setTitle("Observable resource which changes every 5 seconds"); 54 | getAttributes().addResourceType("observe"); 55 | getAttributes().setObservable(); 56 | setObserveType(Type.CON); 57 | 58 | // Set timer task scheduling 59 | Timer timer = new Timer(); 60 | timer.schedule(new TimeTask(), 0, 5000); 61 | } 62 | 63 | /* 64 | * Defines a new timer task to return the current time 65 | */ 66 | private class TimeTask extends TimerTask { 67 | 68 | @Override 69 | public void run() { 70 | time = getTime(); 71 | dataCf = TEXT_PLAIN; 72 | 73 | // Call changed to notify subscribers 74 | changed(); 75 | } 76 | } 77 | 78 | /* 79 | * Returns the current time 80 | * 81 | * @return The current time 82 | */ 83 | private String getTime() { 84 | DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); 85 | Date time = new Date(); 86 | return dateFormat.format(time); 87 | } 88 | 89 | @Override 90 | public void handleGET(CoapExchange exchange) { 91 | 92 | exchange.setMaxAge(5); 93 | 94 | if (wasUpdated) { 95 | exchange.respond(CONTENT, data, dataCf); 96 | wasUpdated = false; 97 | } else { 98 | exchange.respond(CONTENT, time, dataCf); 99 | } 100 | } 101 | 102 | @Override 103 | public void handlePUT(CoapExchange exchange) { 104 | 105 | if (!exchange.getRequestOptions().hasContentFormat()) { 106 | exchange.respond(BAD_REQUEST, "Content-Format not set"); 107 | return; 108 | } 109 | 110 | // store payload 111 | storeData(exchange.getRequestPayload(), exchange.getRequestOptions().getContentFormat()); 112 | 113 | // complete the request 114 | exchange.respond(CHANGED); 115 | } 116 | 117 | @Override 118 | public void handleDELETE(CoapExchange exchange) { 119 | wasUpdated = false; 120 | 121 | clearAndNotifyObserveRelations(NOT_FOUND); 122 | 123 | exchange.respond(DELETED); 124 | } 125 | 126 | 127 | // Internal //////////////////////////////////////////////////////////////// 128 | 129 | /* 130 | * Convenience function to store data contained in a 131 | * PUT/POST-Request. Notifies observing endpoints about 132 | * the change of its contents. 133 | */ 134 | private synchronized void storeData(byte[] payload, int format) { 135 | 136 | wasUpdated = true; 137 | 138 | if (format != dataCf) { 139 | clearAndNotifyObserveRelations(NOT_ACCEPTABLE); 140 | } 141 | 142 | // set payload and content type 143 | data = payload != null ? payload : Bytes.EMPTY; 144 | dataCf = format; 145 | 146 | getAttributes().clearContentType(); 147 | getAttributes().addContentType(dataCf); 148 | 149 | // signal that resource state changed 150 | changed(); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/ObserveNon.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.CoAP.Type; 20 | import org.eclipse.californium.core.coap.MediaTypeRegistry; 21 | import org.eclipse.californium.core.server.resources.CoapExchange; 22 | import org.eclipse.californium.elements.util.Bytes; 23 | 24 | import java.text.DateFormat; 25 | import java.text.SimpleDateFormat; 26 | import java.util.Date; 27 | import java.util.Timer; 28 | import java.util.TimerTask; 29 | 30 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.*; 31 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 32 | 33 | /** 34 | * This resource implements a test of specification for the 35 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 36 | */ 37 | public class ObserveNon extends CoapResource { 38 | 39 | // Members //////////////////////////////////////////////////////////////// 40 | 41 | private byte[] data = null; 42 | private int dataCf = MediaTypeRegistry.TEXT_PLAIN; 43 | private boolean wasUpdated = false; 44 | 45 | // The current time represented as string 46 | private String time; 47 | 48 | /* 49 | * Constructor for a new TimeResource 50 | */ 51 | public ObserveNon() { 52 | super("obs-non"); 53 | setObservable(true); 54 | getAttributes().setTitle("Observable resource which changes every 5 seconds"); 55 | getAttributes().addResourceType("observe"); 56 | getAttributes().setObservable(); 57 | setObserveType(Type.NON); 58 | 59 | // Set timer task scheduling 60 | Timer timer = new Timer(); 61 | timer.schedule(new TimeTask(), 0, 5000); 62 | } 63 | 64 | /* 65 | * Defines a new timer task to return the current time 66 | */ 67 | private class TimeTask extends TimerTask { 68 | 69 | @Override 70 | public void run() { 71 | time = getTime(); 72 | dataCf = TEXT_PLAIN; 73 | 74 | // Call changed to notify subscribers 75 | changed(); 76 | } 77 | } 78 | 79 | /* 80 | * Returns the current time 81 | * 82 | * @return The current time 83 | */ 84 | private String getTime() { 85 | DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); 86 | Date time = new Date(); 87 | return dateFormat.format(time); 88 | } 89 | 90 | @Override 91 | public void handleGET(CoapExchange exchange) { 92 | 93 | exchange.setMaxAge(5); 94 | 95 | if (wasUpdated) { 96 | exchange.respond(CONTENT, data, dataCf); 97 | wasUpdated = false; 98 | } else { 99 | exchange.respond(CONTENT, time, dataCf); 100 | } 101 | } 102 | 103 | @Override 104 | public void handlePUT(CoapExchange exchange) { 105 | 106 | if (!exchange.getRequestOptions().hasContentFormat()) { 107 | exchange.respond(BAD_REQUEST, "Content-Format not set"); 108 | return; 109 | } 110 | 111 | // store payload 112 | storeData(exchange.getRequestPayload(), exchange.getRequestOptions().getContentFormat()); 113 | 114 | // complete the request 115 | exchange.respond(CHANGED); 116 | } 117 | 118 | @Override 119 | public void handleDELETE(CoapExchange exchange) { 120 | wasUpdated = false; 121 | 122 | clearAndNotifyObserveRelations(NOT_FOUND); 123 | 124 | exchange.respond(DELETED); 125 | } 126 | 127 | 128 | // Internal //////////////////////////////////////////////////////////////// 129 | 130 | /* 131 | * Convenience function to store data contained in a 132 | * PUT/POST-Request. Notifies observing endpoints about 133 | * the change of its contents. 134 | */ 135 | private synchronized void storeData(byte[] payload, int format) { 136 | 137 | wasUpdated = true; 138 | 139 | if (format != dataCf) { 140 | clearAndNotifyObserveRelations(NOT_ACCEPTABLE); 141 | } 142 | 143 | // set payload and content type 144 | data = payload != null ? payload : Bytes.EMPTY; 145 | dataCf = format; 146 | 147 | getAttributes().clearContentType(); 148 | getAttributes().addContentType(dataCf); 149 | 150 | // signal that resource state changed 151 | changed(); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/Validate.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.Request; 20 | import org.eclipse.californium.core.coap.Response; 21 | import org.eclipse.californium.core.server.resources.CoapExchange; 22 | 23 | import java.nio.ByteBuffer; 24 | 25 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.*; 26 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 27 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.UNDEFINED; 28 | 29 | /** 30 | * This resource implements a test of specification for the ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 31 | */ 32 | public class Validate extends CoapResource { 33 | 34 | private byte[] data = null; 35 | private int dataCf = TEXT_PLAIN; 36 | private byte[] etag = {0,0,0,0}; 37 | 38 | public Validate() { 39 | super("validate"); 40 | getAttributes().setTitle("Resource which varies"); 41 | } 42 | 43 | @Override 44 | public void handleGET(CoapExchange exchange) { 45 | 46 | // get request to read out details 47 | Request request = exchange.advanced().getRequest(); 48 | 49 | // successively create response 50 | Response response; 51 | 52 | if (exchange.getRequestOptions().containsETag(etag)) { 53 | 54 | response = new Response(VALID); 55 | response.getOptions().addETag(etag.clone()); 56 | 57 | // automatically change now 58 | storeData(null, UNDEFINED); 59 | } else { 60 | response = new Response(CONTENT); 61 | 62 | if (data==null) { 63 | etag = ByteBuffer.allocate(2).putShort( (short) (Math.random()*0x10000) ).array(); 64 | 65 | StringBuilder payload = new StringBuilder(); 66 | payload.append( 67 | String.format( 68 | "Type: %d (%s)\nCode: %d (%s)\nMID: %d", 69 | request.getType().value, 70 | request.getType(), 71 | request.getCode().value, 72 | request.getCode(), 73 | request.getMID())); 74 | 75 | if (!request.hasEmptyToken()) { 76 | payload.append("\nToken: "); 77 | payload.append(request.getTokenString()); 78 | } 79 | 80 | if (payload.length() > 64) { 81 | payload.delete(63, payload.length()); 82 | payload.append('»'); 83 | } 84 | response.setPayload(payload.toString()); 85 | response.getOptions().setContentFormat(TEXT_PLAIN); 86 | } else { 87 | response.setPayload(data); 88 | response.getOptions().setContentFormat(dataCf); 89 | } 90 | response.getOptions().addETag(etag.clone()); 91 | } 92 | exchange.respond(response); 93 | } 94 | 95 | @Override 96 | public void handlePUT(CoapExchange exchange) { 97 | 98 | if (exchange.getRequestOptions().isIfMatch(etag)) { 99 | if (exchange.getRequestOptions().hasContentFormat()) { 100 | storeData(exchange.getRequestPayload(), exchange.getRequestOptions().getContentFormat()); 101 | exchange.setETag(etag.clone()); 102 | exchange.respond(CHANGED); 103 | } else { 104 | exchange.respond(BAD_REQUEST, "Content-Format not set"); 105 | } 106 | } else if (exchange.getRequestOptions().hasIfNoneMatch() && data==null) { 107 | storeData(exchange.getRequestPayload(), exchange.getRequestOptions().getContentFormat()); 108 | exchange.respond(CREATED); 109 | } else { 110 | exchange.respond(PRECONDITION_FAILED); 111 | // automatically change now 112 | storeData(null, UNDEFINED); 113 | } 114 | } 115 | 116 | @Override 117 | public void handleDELETE(CoapExchange exchange) { 118 | storeData(null, UNDEFINED); 119 | exchange.respond(DELETED); 120 | } 121 | 122 | // Internal //////////////////////////////////////////////////////////////// 123 | 124 | /* 125 | * Convenience function to store data contained in a 126 | * PUT/POST-Request. Notifies observing endpoints about 127 | * the change of its contents. 128 | */ 129 | private synchronized void storeData(byte[] payload, int cf) { 130 | 131 | if (payload!=null) { 132 | data = payload; 133 | dataCf = cf; 134 | 135 | etag = ByteBuffer.allocate(4).putInt( data.hashCode() ).array(); 136 | 137 | // set payload and content type 138 | getAttributes().clearContentType(); 139 | getAttributes().addContentType(dataCf); 140 | getAttributes().setMaximumSizeEstimate(data.length); 141 | } else { 142 | data = null; 143 | etag = ByteBuffer.allocate(2).putShort( (short) (Math.random()*0x10000) ).array(); 144 | } 145 | 146 | // signal that resource state changed 147 | changed(); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/org/wsncoap/embedded/resources/LargeUpdate.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Institute for Pervasive Computing, ETH Zurich and others. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.html. 12 | * 13 | * Contributors: 14 | * Matthias Kovatsch - creator and main architect 15 | ******************************************************************************/ 16 | package org.wsncoap.embedded.resources; 17 | 18 | import org.eclipse.californium.core.CoapResource; 19 | import org.eclipse.californium.core.coap.MediaTypeRegistry; 20 | import org.eclipse.californium.core.server.resources.CoapExchange; 21 | import org.eclipse.californium.elements.util.Bytes; 22 | 23 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.*; 24 | import static org.eclipse.californium.core.coap.MediaTypeRegistry.TEXT_PLAIN; 25 | 26 | /** 27 | * This resource implements a test of specification for the 28 | * ETSI IoT CoAP Plugtests, London, UK, 7--9 Mar 2014. 29 | */ 30 | public class LargeUpdate extends CoapResource { 31 | 32 | // Members //////////////////////////////////////////////////////////////// 33 | 34 | private byte[] data = null; 35 | private int dataCf = TEXT_PLAIN; 36 | 37 | // Constructors //////////////////////////////////////////////////////////// 38 | 39 | /* 40 | * Default constructor. 41 | */ 42 | public LargeUpdate() { 43 | this("large-update"); 44 | 45 | StringBuilder builder = new StringBuilder(); 46 | builder.append("/-------------------------------------------------------------\\\n"); 47 | builder.append("| RESOURCE BLOCK NO. 1 OF 5 |\n"); 48 | builder.append("| [each line contains 64 bytes] |\n"); 49 | builder.append("\\-------------------------------------------------------------/\n"); 50 | builder.append("/-------------------------------------------------------------\\\n"); 51 | builder.append("| RESOURCE BLOCK NO. 2 OF 5 |\n"); 52 | builder.append("| [each line contains 64 bytes] |\n"); 53 | builder.append("\\-------------------------------------------------------------/\n"); 54 | builder.append("/-------------------------------------------------------------\\\n"); 55 | builder.append("| RESOURCE BLOCK NO. 3 OF 5 |\n"); 56 | builder.append("| [each line contains 64 bytes] |\n"); 57 | builder.append("\\-------------------------------------------------------------/\n"); 58 | builder.append("/-------------------------------------------------------------\\\n"); 59 | builder.append("| RESOURCE BLOCK NO. 4 OF 5 |\n"); 60 | builder.append("| [each line contains 64 bytes] |\n"); 61 | builder.append("\\-------------------------------------------------------------/\n"); 62 | builder.append("/-------------------------------------------------------------\\\n"); 63 | builder.append("| RESOURCE BLOCK NO. 5 OF 5 |\n"); 64 | builder.append("| [each line contains 64 bytes] |\n"); 65 | builder.append("\\-------------------------------------------------------------/\n"); 66 | 67 | data = builder.toString().getBytes(); 68 | } 69 | 70 | /* 71 | * Constructs a new storage resource with the given resourceIdentifier. 72 | */ 73 | public LargeUpdate(String resourceIdentifier) { 74 | super(resourceIdentifier); 75 | getAttributes().setTitle("Large resource that can be updated using PUT method"); 76 | getAttributes().addResourceType("block"); 77 | getAttributes().setMaximumSizeEstimate(1280); 78 | } 79 | 80 | // REST Operations ///////////////////////////////////////////////////////// 81 | 82 | @Override 83 | public void handleGET(CoapExchange exchange) { 84 | 85 | if (exchange.getRequestOptions().hasAccept() && exchange.getRequestOptions().getAccept() != dataCf) { 86 | exchange.respond(NOT_ACCEPTABLE, MediaTypeRegistry.toString(dataCf) + " only"); 87 | } else { 88 | exchange.respond(CONTENT, data, dataCf); 89 | } 90 | } 91 | 92 | @Override 93 | public void handlePUT(CoapExchange exchange) { 94 | 95 | if (exchange.getRequestOptions().hasContentFormat()) { 96 | storeData(exchange.getRequestPayload(), exchange.getRequestOptions().getContentFormat()); 97 | exchange.respond(CHANGED); 98 | } else { 99 | exchange.respond(BAD_REQUEST, "Content-Format not set"); 100 | } 101 | } 102 | 103 | // Internal //////////////////////////////////////////////////////////////// 104 | 105 | /* 106 | * Convenience function to store data contained in a 107 | * PUT/POST-Request. Notifies observing endpoints about 108 | * the change of its contents. 109 | */ 110 | private synchronized void storeData(byte[] payload, int cf) { 111 | 112 | // set payload and content type 113 | data = payload != null ? payload : Bytes.EMPTY; 114 | dataCf = cf; 115 | 116 | getAttributes().clearContentType(); 117 | getAttributes().addContentType(dataCf); 118 | getAttributes().setMaximumSizeEstimate(data.length); 119 | 120 | // signal that resource state changed 121 | changed(); 122 | } 123 | } 124 | --------------------------------------------------------------------------------