19 #define COAP_MALLOC_TYPE(Type) \
20 ((coap_##Type##_t *)coap_malloc(sizeof(coap_##Type##_t)))
21 #define COAP_FREE_TYPE(Type, Object) coap_free(Object)
27 MEMB(attribute_storage,
coap_attr_t, COAP_MAX_ATTRIBUTES);
31 coap_resources_init() {
32 memb_init(&resource_storage);
33 memb_init(&attribute_storage);
34 memb_init(&subscription_storage);
38 coap_malloc_subscription() {
39 return memb_alloc(&subscription_storage);
44 memb_free(&subscription_storage, subscription);
48 #define min(a,b) ((a) < (b) ? (a) : (b))
51 match(
const str *text,
const str *pattern,
int match_prefix,
int match_substring) {
52 assert(text); assert(pattern);
57 if (match_substring) {
58 unsigned char *next_token = text->
s;
59 size_t remaining_length = text->
length;
60 while (remaining_length) {
62 unsigned char *token = next_token;
63 next_token = memchr(token,
' ', remaining_length);
66 token_length = next_token - token;
67 remaining_length -= (token_length + 1);
70 token_length = remaining_length;
74 if ((match_prefix || pattern->
length == token_length) &&
75 memcmp(token, pattern->
s, pattern->
length) == 0)
81 return (match_prefix || pattern->
length == text->
length) &&
82 memcmp(text->
s, pattern->
s, pattern->
length) == 0;
99 #if defined(__GNUC__) && defined(WITHOUT_QUERY_FILTER)
102 coap_opt_t *query_filter __attribute__ ((unused))) {
109 unsigned char *p = buf;
110 size_t left, written = 0;
112 #ifndef WITHOUT_QUERY_FILTER
113 str resource_param = { 0, NULL }, query_pattern = { 0, NULL };
115 #define MATCH_URI 0x01
116 #define MATCH_PREFIX 0x02
117 #define MATCH_SUBSTRING 0x04
118 static const str _rt_attributes[] = {
119 {2, (
unsigned char *)
"rt"},
120 {2, (
unsigned char *)
"if"},
121 {3, (
unsigned char *)
"rel"},
129 #ifndef WITHOUT_QUERY_FILTER
134 && resource_param.
s[resource_param.
length] !=
'=')
138 const str *rt_attributes;
139 if (resource_param.
length == 4 &&
140 memcmp(resource_param.
s,
"href", 4) == 0)
143 for (rt_attributes = _rt_attributes; rt_attributes->
s; rt_attributes++) {
145 memcmp(resource_param.
s, rt_attributes->
s, rt_attributes->
length) == 0) {
156 query_pattern.length =
161 query_pattern.length--;
164 if (query_pattern.length &&
165 query_pattern.s[query_pattern.length-1] ==
'*') {
166 query_pattern.length--;
178 for (i = 0; i < resource_storage.num; ++i, ++r) {
179 if (!resource_storage.count[i])
183 #ifndef WITHOUT_QUERY_FILTER
184 if (resource_param.
length) {
194 if (attr->
value.
s[0] ==
'"') {
196 unquoted_val.
s = attr->
value.
s + 1;
198 unquoted_val = attr->
value;
200 if (!(
match(&unquoted_val, &query_pattern,
208 left = *buflen - written;
210 if (left < *buflen) {
243 r->
uri.
s = (
unsigned char *)uri;
250 debug(
"coap_resource_init: no memory left\n");
258 const unsigned char *name,
size_t nlen,
259 const unsigned char *val,
size_t vlen,
263 if (!resource || !name)
269 attr = (
coap_attr_t *)memb_alloc(&attribute_storage);
276 attr->
name.
s = (
unsigned char *)name;
277 attr->
value.
s = (
unsigned char *)val;
288 debug(
"coap_add_attr: no memory left\n");
296 const unsigned char *name,
size_t nlen) {
299 if (!resource || !name)
309 memcmp(attr->
name.
s, name, nlen) == 0)
379 memb_free(&attribute_storage, attr);
382 while ( (obs =
list_pop(resource->subscribers)) ) {
384 memb_free(&subscription_storage, obs);
387 memb_free(&resource_storage, resource);
406 for (i = 0; i < resource_storage.num; ++i) {
407 if (resource_storage.count[i] &&
419 unsigned char *buf,
size_t *len) {
420 unsigned char *p = buf;
423 size_t written = resource->
uri.
length + 3;
457 if (resource->
observable && written + 4 <= *len) {
458 memcpy(p,
";obs", 4);
466 #ifndef WITHOUT_OBSERVE
510 if (token && token->
length) {
536 for (i = 0; i < resource_storage.num; ++i, ++r) {
537 if (resource_storage.count[i]) {
579 debug(
"coap_check_notify: pdu init failed\n");
584 debug(
"coap_check_notify: cannot add token\n");
599 h(context, r, &obs->
subscriber, NULL, &token, response);
632 for (i = 0; i < resource_storage.num; ++i, ++r) {
633 if (resource_storage.count[i]) {
657 for (obs =
list_head(resource->subscribers); obs;
673 #ifndef INET6_ADDRSTRLEN
674 #define INET6_ADDRSTRLEN 40
679 debug(
"** removed observer %s\n", addr);
708 for (i = 0; i < resource_storage.num; ++i, ++r) {
709 if (resource_storage.count[i]) {