iotivity 0.9.0
[platform/upstream/iotivity.git] / resource / csdk / libcoap-4.1.1 / async.c
1 /* async.c -- state management for asynchronous messages
2  *
3  * Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use. 
7  */
8
9 /** 
10  * @file async.c
11  * @brief state management for asynchronous messages
12  */
13
14 #ifndef WITHOUT_ASYNC
15
16 #include "config.h"
17
18 #include "utlist.h"
19
20 #include "mem.h"
21 #include "debug.h"
22 #include "async.h"
23
24 coap_async_state_t *
25 coap_register_async(coap_context_t *context, coap_address_t *peer,
26                     coap_pdu_t *request, unsigned char flags, void *data) {
27   coap_async_state_t *s;
28   coap_tid_t id;
29
30   coap_transaction_id(peer, request, &id);
31   LL_SEARCH_SCALAR(context->async_state,s,id,id);
32
33   if (s != NULL) {
34     /* We must return NULL here as the caller must know that he is
35      * responsible for releasing @p data. */
36     debug("asynchronous state for transaction %d already registered\n", id);
37     return NULL;
38   }
39
40   /* store information for handling the asynchronous task */
41   s = (coap_async_state_t *)coap_malloc(sizeof(coap_async_state_t) + 
42                                         request->hdr->token_length);
43   if (!s) {
44     coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n");
45     return NULL;
46   }
47
48   memset(s, 0, sizeof(coap_async_state_t) + request->hdr->token_length);
49
50   /* set COAP_ASYNC_CONFIRM according to request's type */
51   s->flags = flags & ~COAP_ASYNC_CONFIRM;
52   if (request->hdr->type == COAP_MESSAGE_CON)
53     s->flags |= COAP_ASYNC_CONFIRM;
54
55   s->appdata = data;
56
57   memcpy(&s->peer, peer, sizeof(coap_address_t));
58
59   if (request->hdr->token_length) {
60     s->tokenlen = request->hdr->token_length;
61     memcpy(s->token, request->hdr->token, request->hdr->token_length);
62   }
63     
64   memcpy(&s->id, &id, sizeof(coap_tid_t));
65
66   coap_touch_async(s);
67
68   LL_PREPEND(context->async_state, s);
69
70   return s;
71 }
72
73 coap_async_state_t *
74 coap_find_async(coap_context_t *context, coap_tid_t id) {
75   coap_async_state_t *tmp;
76   LL_SEARCH_SCALAR(context->async_state,tmp,id,id);  
77   return tmp;
78 }
79
80 int
81 coap_remove_async(coap_context_t *context, coap_tid_t id, 
82                   coap_async_state_t **s) {
83   coap_async_state_t *tmp = coap_find_async(context, id);
84
85   if (tmp)
86     LL_DELETE(context->async_state,tmp);
87
88   *s = tmp;
89   return tmp != NULL;
90 }
91
92 void 
93 coap_free_async(coap_async_state_t *s) {
94   if (s && (s->flags & COAP_ASYNC_RELEASE_DATA) != 0)
95     coap_free(s->appdata);
96   coap_free(s); 
97 }
98
99 #else
100 void does_not_exist();  /* make some compilers happy */
101 #endif /* WITHOUT_ASYNC */