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 
query_get(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)14 static int query_get(struct coap_resource *resource,
15 		     struct coap_packet *request,
16 		     struct sockaddr *addr, socklen_t addr_len)
17 {
18 	uint8_t data[CONFIG_COAP_SERVER_MESSAGE_SIZE];
19 	struct coap_option options[4];
20 	struct coap_packet response;
21 	uint8_t payload[40];
22 	uint8_t token[COAP_TOKEN_MAX_LEN];
23 	uint16_t id;
24 	uint8_t code;
25 	uint8_t type;
26 	uint8_t tkl;
27 	int i, r;
28 
29 	code = coap_header_get_code(request);
30 	type = coap_header_get_type(request);
31 	id = coap_header_get_id(request);
32 	tkl = coap_header_get_token(request, token);
33 
34 	r = coap_find_options(request, COAP_OPTION_URI_QUERY, options, 4);
35 	if (r < 0) {
36 		return -EINVAL;
37 	}
38 
39 	LOG_INF("*******");
40 	LOG_INF("type: %u code %u id %u", type, code, id);
41 	LOG_INF("num queries: %d", r);
42 
43 	for (i = 0; i < r; i++) {
44 		char str[16];
45 
46 		if (options[i].len + 1 > sizeof(str)) {
47 			LOG_INF("Unexpected length of query: "
48 				"%d (expected %zu)",
49 				options[i].len, sizeof(str));
50 			break;
51 		}
52 
53 		memcpy(str, options[i].value, options[i].len);
54 		str[options[i].len] = '\0';
55 
56 		LOG_INF("query[%d]: %s", i + 1, str);
57 	}
58 
59 	LOG_INF("*******");
60 
61 	r = coap_packet_init(&response, data, sizeof(data),
62 			     COAP_VERSION_1, COAP_TYPE_ACK, tkl, token,
63 			     COAP_RESPONSE_CODE_CONTENT, id);
64 	if (r < 0) {
65 		return r;
66 	}
67 
68 	r = coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT,
69 				   COAP_CONTENT_FORMAT_TEXT_PLAIN);
70 	if (r < 0) {
71 		return r;
72 	}
73 
74 	r = coap_packet_append_payload_marker(&response);
75 	if (r < 0) {
76 		return r;
77 	}
78 
79 	/* The response that coap-client expects */
80 	r = snprintk((char *) payload, sizeof(payload),
81 		     "Type: %u\nCode: %u\nMID: %u\n", type, code, id);
82 	if (r < 0) {
83 		return r;
84 	}
85 
86 	r = coap_packet_append_payload(&response, (uint8_t *)payload,
87 				       strlen(payload));
88 	if (r < 0) {
89 		return r;
90 	}
91 
92 	r = coap_resource_send(resource, &response, addr, addr_len, NULL);
93 
94 	return r;
95 }
96 
97 static const char * const query_path[] = { "query", NULL };
98 COAP_RESOURCE_DEFINE(query, coap_server,
99 {
100 	.get = query_get,
101 	.path = query_path,
102 });
103