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