12 #if defined(HAVE_ASSERT_H) && !defined(assert)
18 #ifdef HAVE_ARPA_INET_H
19 # include <arpa/inet.h>
36 #define HMASK (ULONG_MAX >> 1)
50 if ( !context || !res || !sub || !(pdu =
coap_new_pdu()) )
54 pdu->
hdr->
id = rand();
72 if (sub->
token.length) {
86 res->data(res->
uri, &ct, 0, pdu->
data, &length, &finished);
94 if ( inet_ntop(sub->
subscriber.addr.sa.sa_family,
96 debug(
"*** notify for %s to [%s]\n", res->
uri->path.
s, addr);
104 debug(
"coap_check_resource_list: error sending notification\n");
125 debug(
"FIXME: notify subscribers\n");
127 key = coap_uri_hash( COAP_RESOURCE(res)->
uri ) ;
130 for (sub = context->subscriptions; sub; sub = sub->
next) {
131 if ( COAP_SUBSCRIPTION(sub)->resource == key ) {
133 notify(context, COAP_RESOURCE(res), COAP_SUBSCRIPTION(sub),
139 COAP_RESOURCE(res)->dirty = 0;
153 printf(
"check %ux\n", coap_uri_hash(COAP_RESOURCE(node)->
uri));
154 if ( key == coap_uri_hash(COAP_RESOURCE(node)->
uri) ) {
156 return COAP_RESOURCE(node);
161 printf(
"not found\n");
169 printf(
"search resource %ux", coap_uri_hash(uri));
171 printf(
" %02x", uri->
path.
s[i]);
192 node = context->subscriptions;
193 while ( node && COAP_SUBSCRIPTION(node)->expires < now ) {
195 if (inet_ntop(COAP_SUBSCRIPTION(node)->subscriber.addr.sa.sa_family,
196 &COAP_SUBSCRIPTION(node)->subscriber.addr,
197 addr,
sizeof(addr))) {
199 debug(
"** removed expired subscription from [%s]\n", addr);
205 COAP_SUBSCRIPTION(node),
208 context->subscriptions = node->
next;
210 node = context->subscriptions;
215 coap_free_resource(
void *res) {
233 if (!context || key == COAP_INVALID_HASHKEY)
236 for (prev = NULL, node = context->
resources; node;
237 prev = node, node = node->
next) {
238 if (coap_uri_hash(COAP_RESOURCE(node)->uri) == key) {
240 debug(
"removed key %lu (%s)\n",key,COAP_RESOURCE(node)->uri->
path.
s);
257 const struct sockaddr *addr, socklen_t addrlen, time_t expiry) {
260 if ( !context || !resource || !addr
264 result->resource = coap_uri_hash(resource);
265 result->expires = expiry;
266 memcpy(&result->
subscriber.addr.sa, addr, addrlen);
268 memset(&result->
token, 0,
sizeof(
str));
275 coap_list_push_first(
coap_list_t **
list,
void *data,
void (*delete_func)(
void *) ) {
278 if ( !node || !list )
292 _order_subscription(
void *a,
void *b) {
294 return a < b ? -1 : 1;
302 return COAP_INVALID_HASHKEY;
304 return _hash2( subscription->resource, (
unsigned char *)&subscription->
subscriber,
312 if ( !context || !subscription )
313 return COAP_INVALID_HASHKEY;
316 return COAP_INVALID_HASHKEY;
318 if ( !
coap_insert(&context->subscriptions, node, _order_subscription ) ) {
320 return COAP_INVALID_HASHKEY;
323 return coap_subscription_hash(subscription);
329 struct sockaddr *addr,
335 if (!context || !addr || hashkey == COAP_INVALID_HASHKEY)
341 for (node = context->subscriptions; node; node = node->
next) {
342 if (COAP_SUBSCRIPTION(node)->resource == hashkey) {
345 if (token->
length != COAP_SUBSCRIPTION(node)->token.
length ||
346 memcmp(token->
s, COAP_SUBSCRIPTION(node)->token.
s,
351 if (subscriber->sin6_port == COAP_SUBSCRIPTION(node)->subscriber.sin6_port
352 && memcmp(&subscriber->sin6_addr,
353 &COAP_SUBSCRIPTION(node)->subscriber.sin6_addr,
354 sizeof(
struct in6_addr)) == 0)
355 return COAP_SUBSCRIPTION(node);
365 struct sockaddr *addr) {
370 if (!context || !addr || key == COAP_INVALID_HASHKEY)
376 for (prev = NULL, node = context->subscriptions; node;
377 prev = node, node = node->
next) {
378 if (COAP_SUBSCRIPTION(node)->resource == key) {
379 if (subscriber->sin6_port == COAP_SUBSCRIPTION(node)->subscriber.sin6_port
380 && memcmp(&subscriber->sin6_addr,
381 &COAP_SUBSCRIPTION(node)->subscriber.sin6_addr,
382 sizeof(
struct in6_addr)) == 0) {
385 context->subscriptions = node->
next;
Representation of parsed URI.
int coap_delete(coap_list_t *node)
unsigned char coap_key_t[4]
int coap_insert(coap_list_t **queue, coap_list_t *node, int(*order)(void *, void *node))
int coap_delete_resource(coap_context_t *context, coap_key_t key)
Deletes a resource identified by key.
coap_tid_t coap_send_confirmed(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu)
Sends a confirmed CoAP message to given destination.
#define HASH_ITER(hh, head, el, tmp)
unsigned short length
PDU length (including header, options, data)
struct coap_linkedlistnode * next
str path
Beginning of the first path segment.
#define coap_malloc(size)
#define COAP_RESPONSE_400
#define COAP_OPTION_SUBSCRIPTION
str uri
Request URI for this resource.
Header structure for CoAP PDUs.
unsigned int dirty
set to 1 if resource has changed
size_t coap_add_option(coap_pdu_t *pdu, unsigned short type, unsigned int len, const unsigned char *data)
de-duplicate code with coap_add_option_later
#define COAP_MAX_PDU_SIZE
coap_list_t * coap_new_listnode(void *data, void(*delete_func)(void *))
Creates a new list node and adds the given data object.
void coap_delete_pdu(coap_pdu_t *pdu)
#define COAP_OPTION_URI_PATH
#define COAP_RESPONSE_200
void coap_delete_string(str *s)
Deletes the given string and releases any memory allocated.
#define COAP_OPTION_URI_QUERY
unsigned char token[8]
token used for subscription
coap_pdu_t * coap_new_pdu()
Creates a new CoAP PDU.
void coap_subscription_init(coap_subscription_t *s)
#define COAP_OPTION_URI_HOST
unsigned char * data
payload
coap_address_t subscriber
address and port of subscriber
The CoAP stack's global state is stored in a coap_context_t object.
#define COAP_PSEUDOFP_ENCODE_8_4_DOWN(v, ls)
coap_resource_t * coap_get_resource_from_key(coap_context_t *context, coap_key_t key)
Returns the resource identified by the unique string key.
struct coap_resource_t * resources
hash table or list of known resources