• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "coap_config.h"
2 #include <coap.h>
3 
4 coap_context_t *main_coap_context;
5 
6 static coap_time_t clock_offset;
7 /* changeable clock base (see handle_put_time()) */
8 static coap_time_t my_clock_base = 0;
9 static coap_resource_t *time_resource = NULL; /* just for testing */
10 
11 #ifndef min
12 # define min(a,b) ((a) < (b) ? (a) : (b))
13 #endif
14 
15 void
hnd_get_time(coap_context_t * ctx,struct coap_resource_t * resource,coap_session_t * session,coap_pdu_t * request,coap_binary_t * token,coap_string_t * query,coap_pdu_t * response)16 hnd_get_time(coap_context_t  *ctx, struct coap_resource_t *resource,
17              coap_session_t *session,
18              coap_pdu_t *request, coap_binary_t *token,
19              coap_string_t *query,
20              coap_pdu_t *response) {
21   unsigned char buf[40];
22   size_t len;
23   coap_tick_t now;
24   coap_tick_t t;
25 
26   /* FIXME: return time, e.g. in human-readable by default and ticks
27    * when query ?ticks is given. */
28 
29   /* if my_clock_base was deleted, we pretend to have no such resource */
30   response->code =
31     my_clock_base ? COAP_RESPONSE_CODE(205) : COAP_RESPONSE_CODE(404);
32 
33   if (coap_find_observer(resource, session, token)) {
34     coap_add_option(response, COAP_OPTION_OBSERVE,
35                     coap_encode_var_safe(buf, sizeof(buf),
36                                          resource->observe),
37                     buf);
38   }
39 
40   if (my_clock_base)
41     coap_add_option(response, COAP_OPTION_CONTENT_FORMAT,
42                     coap_encode_var_safe(buf, sizeof(buf),
43                     COAP_MEDIATYPE_TEXT_PLAIN),
44                     buf);
45 
46   coap_add_option(response, COAP_OPTION_MAXAGE,
47           coap_encode_var_safe(buf, sizeof(buf), 0x01), buf);
48 
49   if (my_clock_base) {
50 
51     /* calculate current time */
52     coap_ticks(&t);
53     now = my_clock_base + (t / COAP_TICKS_PER_SECOND);
54 
55 
56     if (query != NULL
57         && coap_string_equal(query, coap_make_str_const("ticks"))) {
58       /* output ticks */
59       len = snprintf((char *)buf, sizeof(buf), "%u", (unsigned int)now);
60       coap_add_data(response, len, buf);
61     }
62   }
63 }
64 
65 void
init_coap_resources(coap_context_t * ctx)66 init_coap_resources(coap_context_t *ctx) {
67   coap_resource_t *r;
68 #if 0
69   r = coap_resource_init(NULL, 0, 0);
70   coap_register_handler(r, COAP_REQUEST_GET, hnd_get_index);
71 
72   coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
73   coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"General Info\""), 0);
74   coap_add_resource(ctx, r);
75 #endif
76   /* store clock base to use in /time */
77   my_clock_base = clock_offset;
78 
79   r = coap_resource_init(coap_make_str_const("time"), 0);
80   if (!r)
81     goto error;
82 
83   coap_resource_set_get_observable(r, 1);
84   time_resource = r;
85   coap_register_handler(r, COAP_REQUEST_GET, hnd_get_time);
86 #if 0
87   coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_time);
88   coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_time);
89 #endif
90   coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
91   /* coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"Internal Clock\""), 0); */
92   coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("\"ticks\""), 0);
93   coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"clock\""), 0);
94 
95   coap_add_resource(ctx, r);
96 #if 0
97 #ifndef WITHOUT_ASYNC
98   r = coap_resource_init(coap_make_str_const("async"), 0);
99   coap_register_handler(r, COAP_REQUEST_GET, hnd_get_async);
100 
101   coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
102   coap_add_resource(ctx, r);
103 #endif /* WITHOUT_ASYNC */
104 #endif
105 
106   return;
107  error:
108   coap_log(LOG_CRIT, "cannot create resource\n");
109 }
110 
server_coap_init(void)111 void server_coap_init(void)
112 {
113   coap_address_t listenaddress;
114 
115   coap_address_init(&listenaddress);
116 
117   /* looks like a server address, but is used as end point for clients too */
118   listenaddress.addr = *(IP_ANY_TYPE);
119   listenaddress.port = COAP_DEFAULT_PORT;
120 
121   coap_set_log_level(LOG_DEBUG);
122   main_coap_context = coap_new_context(&listenaddress);
123 
124   LWIP_ASSERT("Failed to initialize context", main_coap_context != NULL);
125   clock_offset = 1; /* Need a non-zero value */
126   init_coap_resources(main_coap_context);
127 }
128 
server_coap_poll(void)129 void server_coap_poll(void)
130 {
131   static coap_time_t last_time = 0;
132   coap_tick_t ticks_now;
133   coap_time_t time_now;
134 
135   coap_ticks(&ticks_now);
136   time_now = coap_ticks_to_rt(ticks_now);
137 
138   if (last_time != time_now) {
139     /* This takes place once a second */
140     last_time = time_now;
141     coap_resource_notify_observers(time_resource, NULL);
142   }
143   coap_check_notify(main_coap_context);
144 }
145