1c87c5fbaSopenharmony_ci/* coap-server.c -- Example CoAP server using Contiki and libcoap 2c87c5fbaSopenharmony_ci * 3c87c5fbaSopenharmony_ci * Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org> 4c87c5fbaSopenharmony_ci * 5c87c5fbaSopenharmony_ci * Redistribution and use in source and binary forms, with or without 6c87c5fbaSopenharmony_ci * modification, are permitted provided that the following conditions 7c87c5fbaSopenharmony_ci * are met: 8c87c5fbaSopenharmony_ci * 1. Redistributions of source code must retain the above copyright 9c87c5fbaSopenharmony_ci * notice, this list of conditions and the following disclaimer. 10c87c5fbaSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 11c87c5fbaSopenharmony_ci * notice, this list of conditions and the following disclaimer in the 12c87c5fbaSopenharmony_ci * documentation and/or other materials provided with the distribution. 13c87c5fbaSopenharmony_ci * 3. Neither the name of the Institute nor the names of its contributors 14c87c5fbaSopenharmony_ci * may be used to endorse or promote products derived from this software 15c87c5fbaSopenharmony_ci * without specific prior written permission. 16c87c5fbaSopenharmony_ci * 17c87c5fbaSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18c87c5fbaSopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19c87c5fbaSopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20c87c5fbaSopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21c87c5fbaSopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22c87c5fbaSopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23c87c5fbaSopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24c87c5fbaSopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25c87c5fbaSopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26c87c5fbaSopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27c87c5fbaSopenharmony_ci * SUCH DAMAGE. 28c87c5fbaSopenharmony_ci * 29c87c5fbaSopenharmony_ci * This file is part of the Contiki operating system. 30c87c5fbaSopenharmony_ci * 31c87c5fbaSopenharmony_ci */ 32c87c5fbaSopenharmony_ci 33c87c5fbaSopenharmony_ci#include "contiki-net.h" 34c87c5fbaSopenharmony_ci#include "coap3/coap.h" 35c87c5fbaSopenharmony_ci 36c87c5fbaSopenharmony_cistatic coap_context_t *coap_context; 37c87c5fbaSopenharmony_ci 38c87c5fbaSopenharmony_cistatic clock_time_t clock_offset; 39c87c5fbaSopenharmony_ci/* changeable clock base (see handle_put_time()) */ 40c87c5fbaSopenharmony_cistatic clock_time_t my_clock_base = 0; 41c87c5fbaSopenharmony_cistatic coap_resource_t *time_resource = NULL; /* just for testing */ 42c87c5fbaSopenharmony_ci 43c87c5fbaSopenharmony_ciPROCESS(coap_server_process, "CoAP server process"); 44c87c5fbaSopenharmony_ciAUTOSTART_PROCESSES(&coap_server_process); 45c87c5fbaSopenharmony_ci/*---------------------------------------------------------------------------*/ 46c87c5fbaSopenharmony_civoid 47c87c5fbaSopenharmony_ciinit_coap_server(coap_context_t **ctx) { 48c87c5fbaSopenharmony_ci uip_ds6_addr_t *my_address; 49c87c5fbaSopenharmony_ci coap_address_t listen_addr; 50c87c5fbaSopenharmony_ci 51c87c5fbaSopenharmony_ci assert(ctx); 52c87c5fbaSopenharmony_ci 53c87c5fbaSopenharmony_ci my_address = uip_ds6_get_global(ADDR_PREFERRED); 54c87c5fbaSopenharmony_ci uip_ipaddr_copy(&listen_addr.addr, &my_address->ipaddr); 55c87c5fbaSopenharmony_ci coap_address_set_port(&listen_addr, COAP_DEFAULT_PORT); 56c87c5fbaSopenharmony_ci 57c87c5fbaSopenharmony_ci *ctx = coap_new_context(&listen_addr); 58c87c5fbaSopenharmony_ci 59c87c5fbaSopenharmony_ci if (!*ctx) { 60c87c5fbaSopenharmony_ci coap_log_crit("cannot create CoAP context\r\n"); 61c87c5fbaSopenharmony_ci } 62c87c5fbaSopenharmony_ci coap_context_set_max_idle_sessions(*ctx, 2); 63c87c5fbaSopenharmony_ci} 64c87c5fbaSopenharmony_ci 65c87c5fbaSopenharmony_ci/*---------------------------------------------------------------------------*/ 66c87c5fbaSopenharmony_ci#ifndef min 67c87c5fbaSopenharmony_ci# define min(a,b) ((a) < (b) ? (a) : (b)) 68c87c5fbaSopenharmony_ci#endif 69c87c5fbaSopenharmony_ci 70c87c5fbaSopenharmony_civoid 71c87c5fbaSopenharmony_cihnd_get_time(coap_resource_t *resource, coap_session_t *session, 72c87c5fbaSopenharmony_ci const coap_pdu_t *request, const coap_string_t *query, 73c87c5fbaSopenharmony_ci coap_pdu_t *response) { 74c87c5fbaSopenharmony_ci unsigned char buf[40]; 75c87c5fbaSopenharmony_ci size_t len; 76c87c5fbaSopenharmony_ci coap_tick_t now; 77c87c5fbaSopenharmony_ci coap_tick_t t; 78c87c5fbaSopenharmony_ci 79c87c5fbaSopenharmony_ci if (my_clock_base) { 80c87c5fbaSopenharmony_ci 81c87c5fbaSopenharmony_ci /* calculate current time */ 82c87c5fbaSopenharmony_ci coap_ticks(&t); 83c87c5fbaSopenharmony_ci now = my_clock_base + (t / COAP_TICKS_PER_SECOND); 84c87c5fbaSopenharmony_ci 85c87c5fbaSopenharmony_ci if (query != NULL 86c87c5fbaSopenharmony_ci && coap_string_equal(query, coap_make_str_const("ticks"))) { 87c87c5fbaSopenharmony_ci /* output ticks */ 88c87c5fbaSopenharmony_ci len = snprintf((char *)buf, sizeof(buf), "%u", (unsigned int)now); 89c87c5fbaSopenharmony_ci 90c87c5fbaSopenharmony_ci } else { /* output human-readable time */ 91c87c5fbaSopenharmony_ci struct tm *tmp; 92c87c5fbaSopenharmony_ci time_t tnow = now; 93c87c5fbaSopenharmony_ci tmp = gmtime(&tnow); 94c87c5fbaSopenharmony_ci if (!tmp) { 95c87c5fbaSopenharmony_ci /* If 'tnow' is not valid */ 96c87c5fbaSopenharmony_ci coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND); 97c87c5fbaSopenharmony_ci return; 98c87c5fbaSopenharmony_ci } else { 99c87c5fbaSopenharmony_ci len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp); 100c87c5fbaSopenharmony_ci } 101c87c5fbaSopenharmony_ci } 102c87c5fbaSopenharmony_ci coap_add_data_blocked_response(request, response, 103c87c5fbaSopenharmony_ci COAP_MEDIATYPE_TEXT_PLAIN, 1, 104c87c5fbaSopenharmony_ci len, 105c87c5fbaSopenharmony_ci buf); 106c87c5fbaSopenharmony_ci } else { 107c87c5fbaSopenharmony_ci /* if my_clock_base was deleted, we pretend to have no such resource */ 108c87c5fbaSopenharmony_ci coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND); 109c87c5fbaSopenharmony_ci } 110c87c5fbaSopenharmony_ci} 111c87c5fbaSopenharmony_ci 112c87c5fbaSopenharmony_civoid 113c87c5fbaSopenharmony_ciinit_coap_resources(coap_context_t *ctx) { 114c87c5fbaSopenharmony_ci coap_resource_t *r; 115c87c5fbaSopenharmony_ci#if 0 116c87c5fbaSopenharmony_ci r = coap_resource_init(NULL, 0, 0); 117c87c5fbaSopenharmony_ci coap_register_handler(r, COAP_REQUEST_GET, hnd_get_index); 118c87c5fbaSopenharmony_ci 119c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0); 120c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"General Info\""), 0); 121c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 122c87c5fbaSopenharmony_ci#endif 123c87c5fbaSopenharmony_ci /* store clock base to use in /time */ 124c87c5fbaSopenharmony_ci my_clock_base = clock_offset; 125c87c5fbaSopenharmony_ci 126c87c5fbaSopenharmony_ci r = coap_resource_init(coap_make_str_const("time"), 0); 127c87c5fbaSopenharmony_ci if (!r) 128c87c5fbaSopenharmony_ci goto error; 129c87c5fbaSopenharmony_ci 130c87c5fbaSopenharmony_ci coap_resource_set_get_observable(r, 1); 131c87c5fbaSopenharmony_ci time_resource = r; 132c87c5fbaSopenharmony_ci coap_register_handler(r, COAP_REQUEST_GET, hnd_get_time); 133c87c5fbaSopenharmony_ci#if 0 134c87c5fbaSopenharmony_ci coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_time); 135c87c5fbaSopenharmony_ci coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_time); 136c87c5fbaSopenharmony_ci#endif 137c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0); 138c87c5fbaSopenharmony_ci /* coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"Internal Clock\""), 0); */ 139c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("\"ticks\""), 0); 140c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"clock\""), 0); 141c87c5fbaSopenharmony_ci 142c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 143c87c5fbaSopenharmony_ci#if 0 144c87c5fbaSopenharmony_ci if (coap_async_is_supported()) { 145c87c5fbaSopenharmony_ci r = coap_resource_init(coap_make_str_const("async"), 0); 146c87c5fbaSopenharmony_ci coap_register_handler(r, COAP_REQUEST_GET, hnd_get_async); 147c87c5fbaSopenharmony_ci 148c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0); 149c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 150c87c5fbaSopenharmony_ci } 151c87c5fbaSopenharmony_ci#endif 152c87c5fbaSopenharmony_ci 153c87c5fbaSopenharmony_ci return; 154c87c5fbaSopenharmony_cierror: 155c87c5fbaSopenharmony_ci coap_log_crit("cannot create resource\n"); 156c87c5fbaSopenharmony_ci} 157c87c5fbaSopenharmony_ci 158c87c5fbaSopenharmony_ci/* struct etimer notify_timer; */ 159c87c5fbaSopenharmony_cistruct etimer dirty_timer; 160c87c5fbaSopenharmony_ci 161c87c5fbaSopenharmony_ci/*---------------------------------------------------------------------------*/ 162c87c5fbaSopenharmony_ciPROCESS_THREAD(coap_server_process, ev, data) { 163c87c5fbaSopenharmony_ci PROCESS_BEGIN(); 164c87c5fbaSopenharmony_ci 165c87c5fbaSopenharmony_ci /* Initialize libcoap library */ 166c87c5fbaSopenharmony_ci coap_startup(); 167c87c5fbaSopenharmony_ci 168c87c5fbaSopenharmony_ci clock_offset = clock_time(); 169c87c5fbaSopenharmony_ci init_coap_server(&coap_context); 170c87c5fbaSopenharmony_ci 171c87c5fbaSopenharmony_ci if (!coap_context) { 172c87c5fbaSopenharmony_ci coap_log_emerg("cannot create context\n"); 173c87c5fbaSopenharmony_ci PROCESS_EXIT(); 174c87c5fbaSopenharmony_ci } 175c87c5fbaSopenharmony_ci 176c87c5fbaSopenharmony_ci init_coap_resources(coap_context); 177c87c5fbaSopenharmony_ci 178c87c5fbaSopenharmony_ci /* etimer_set(¬ify_timer, 5 * CLOCK_SECOND); */ 179c87c5fbaSopenharmony_ci etimer_set(&dirty_timer, 30 * CLOCK_SECOND); 180c87c5fbaSopenharmony_ci 181c87c5fbaSopenharmony_ci while (1) { 182c87c5fbaSopenharmony_ci PROCESS_YIELD(); 183c87c5fbaSopenharmony_ci if (ev == PROCESS_EVENT_TIMER && etimer_expired(&dirty_timer)) { 184c87c5fbaSopenharmony_ci coap_resource_notify_observers(time_resource, NULL); 185c87c5fbaSopenharmony_ci etimer_reset(&dirty_timer); 186c87c5fbaSopenharmony_ci } 187c87c5fbaSopenharmony_ci } 188c87c5fbaSopenharmony_ci coap_cleanup(); 189c87c5fbaSopenharmony_ci 190c87c5fbaSopenharmony_ci PROCESS_END(); 191c87c5fbaSopenharmony_ci} 192c87c5fbaSopenharmony_ci/*---------------------------------------------------------------------------*/ 193