1 /*
2 * Copyright (c) 2018 Intel Corporation
3 * Copyright (c) 2023 Basalte bv
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/logging/log.h>
9 LOG_MODULE_DECLARE(net_coap_service_sample);
10
11 #include <zephyr/sys/printk.h>
12 #include <zephyr/net/coap_service.h>
13
14 #include "net_private.h"
15
piggyback_get(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)16 static int piggyback_get(struct coap_resource *resource,
17 struct coap_packet *request,
18 struct sockaddr *addr, socklen_t addr_len)
19 {
20 uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE];
21 struct coap_packet response;
22 uint8_t payload[40];
23 uint8_t token[COAP_TOKEN_MAX_LEN];
24 uint16_t id;
25 uint8_t code;
26 uint8_t type;
27 uint8_t tkl;
28 int r;
29
30 code = coap_header_get_code(request);
31 type = coap_header_get_type(request);
32 id = coap_header_get_id(request);
33 tkl = coap_header_get_token(request, token);
34
35 LOG_INF("*******");
36 LOG_INF("type: %u code %u id %u", type, code, id);
37 LOG_INF("*******");
38
39 if (type == COAP_TYPE_CON) {
40 type = COAP_TYPE_ACK;
41 } else {
42 type = COAP_TYPE_NON_CON;
43 }
44
45 r = coap_packet_init(&response, data, sizeof(data),
46 COAP_VERSION_1, type, tkl, token,
47 COAP_RESPONSE_CODE_CONTENT, id);
48 if (r < 0) {
49 return r;
50 }
51
52 r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT,
53 COAP_CONTENT_FORMAT_TEXT_PLAIN);
54 if (r < 0) {
55 return r;
56 }
57
58 r = coap_packet_append_payload_marker(&response);
59 if (r < 0) {
60 return r;
61 }
62
63 /* The response that coap-client expects */
64 r = snprintk((char *) payload, sizeof(payload),
65 "Type: %u\nCode: %u\nMID: %u\n", type, code, id);
66 if (r < 0) {
67 return r;
68 }
69
70 r = coap_packet_append_payload(&response, (uint8_t *)payload,
71 strlen(payload));
72 if (r < 0) {
73 return r;
74 }
75
76 r = coap_resource_send(resource, &response, addr, addr_len, NULL);
77
78 return r;
79 }
80
test_del(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)81 static int test_del(struct coap_resource *resource,
82 struct coap_packet *request,
83 struct sockaddr *addr, socklen_t addr_len)
84 {
85 uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE];
86 struct coap_packet response;
87 uint8_t token[COAP_TOKEN_MAX_LEN];
88 uint8_t tkl;
89 uint8_t code;
90 uint8_t type;
91 uint16_t id;
92 int r;
93
94 code = coap_header_get_code(request);
95 type = coap_header_get_type(request);
96 id = coap_header_get_id(request);
97 tkl = coap_header_get_token(request, token);
98
99 LOG_INF("*******");
100 LOG_INF("type: %u code %u id %u", type, code, id);
101 LOG_INF("*******");
102
103 if (type == COAP_TYPE_CON) {
104 type = COAP_TYPE_ACK;
105 } else {
106 type = COAP_TYPE_NON_CON;
107 }
108
109 r = coap_packet_init(&response, data, sizeof(data),
110 COAP_VERSION_1, type, tkl, token,
111 COAP_RESPONSE_CODE_DELETED, id);
112 if (r < 0) {
113 return r;
114 }
115
116 r = coap_resource_send(resource, &response, addr, addr_len, NULL);
117
118 return r;
119 }
120
test_put(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)121 static int test_put(struct coap_resource *resource,
122 struct coap_packet *request,
123 struct sockaddr *addr, socklen_t addr_len)
124 {
125 uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE];
126 struct coap_packet response;
127 uint8_t token[COAP_TOKEN_MAX_LEN];
128 const uint8_t *payload;
129 uint16_t payload_len;
130 uint8_t code;
131 uint8_t type;
132 uint8_t tkl;
133 uint16_t id;
134 int r;
135
136 code = coap_header_get_code(request);
137 type = coap_header_get_type(request);
138 id = coap_header_get_id(request);
139 tkl = coap_header_get_token(request, token);
140
141 LOG_INF("*******");
142 LOG_INF("type: %u code %u id %u", type, code, id);
143 LOG_INF("*******");
144
145 payload = coap_packet_get_payload(request, &payload_len);
146 if (payload) {
147 net_hexdump("PUT Payload", payload, payload_len);
148 }
149
150 if (type == COAP_TYPE_CON) {
151 type = COAP_TYPE_ACK;
152 } else {
153 type = COAP_TYPE_NON_CON;
154 }
155
156 r = coap_packet_init(&response, data, sizeof(data),
157 COAP_VERSION_1, type, tkl, token,
158 COAP_RESPONSE_CODE_CHANGED, id);
159 if (r < 0) {
160 return r;
161 }
162
163 r = coap_resource_send(resource, &response, addr, addr_len, NULL);
164
165 return r;
166 }
167
test_post(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)168 static int test_post(struct coap_resource *resource,
169 struct coap_packet *request,
170 struct sockaddr *addr, socklen_t addr_len)
171 {
172 static const char * const location_path[] = { "location1",
173 "location2",
174 "location3",
175 NULL };
176 uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE];
177 const char * const *p;
178 struct coap_packet response;
179 uint8_t token[COAP_TOKEN_MAX_LEN];
180 const uint8_t *payload;
181 uint16_t payload_len;
182 uint8_t code;
183 uint8_t type;
184 uint8_t tkl;
185 uint16_t id;
186 int r;
187
188 code = coap_header_get_code(request);
189 type = coap_header_get_type(request);
190 id = coap_header_get_id(request);
191 tkl = coap_header_get_token(request, token);
192
193 LOG_INF("*******");
194 LOG_INF("type: %u code %u id %u", type, code, id);
195 LOG_INF("*******");
196
197 payload = coap_packet_get_payload(request, &payload_len);
198 if (payload) {
199 net_hexdump("POST Payload", payload, payload_len);
200 }
201
202 if (type == COAP_TYPE_CON) {
203 type = COAP_TYPE_ACK;
204 } else {
205 type = COAP_TYPE_NON_CON;
206 }
207
208 r = coap_packet_init(&response, data, sizeof(data),
209 COAP_VERSION_1, type, tkl, token,
210 COAP_RESPONSE_CODE_CREATED, id);
211 if (r < 0) {
212 return r;
213 }
214
215 for (p = location_path; *p; p++) {
216 r = coap_packet_append_option(&response,
217 COAP_OPTION_LOCATION_PATH,
218 *p, strlen(*p));
219 if (r < 0) {
220 return r;
221 }
222 }
223
224 r = coap_resource_send(resource, &response, addr, addr_len, NULL);
225
226 return r;
227 }
228
229 static const char * const test_path[] = { "test", NULL };
230 COAP_RESOURCE_DEFINE(test, coap_server,
231 {
232 .get = piggyback_get,
233 .post = test_post,
234 .del = test_del,
235 .put = test_put,
236 .path = test_path,
237 });
238
239 static const char * const segments_path[] = { "seg1", "seg2", "seg3", NULL };
240 COAP_RESOURCE_DEFINE(segments, coap_server,
241 {
242 .get = piggyback_get,
243 .path = segments_path,
244 });
245
246 #if defined(CONFIG_COAP_URI_WILDCARD)
247
248 static const char * const wildcard1_path[] = { "wild1", "+", "wild3", NULL };
249 COAP_RESOURCE_DEFINE(wildcard1, coap_server,
250 {
251 .get = piggyback_get,
252 .path = wildcard1_path,
253 });
254
255 static const char * const wildcard2_path[] = { "wild2", "#", NULL };
256 COAP_RESOURCE_DEFINE(wildcard2, coap_server,
257 {
258 .get = piggyback_get,
259 .path = wildcard2_path,
260 });
261
262 #endif
263