iotivity 0.9.0
[platform/upstream/iotivity.git] / resource / csdk / connectivity / lib / 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, coap_pdu_t *request,
26         unsigned char flags, void *data)
27 {
28     coap_async_state_t *s;
29     coap_tid_t id;
30
31     coap_transaction_id(peer, request, &id);
32     LL_SEARCH_SCALAR(context->async_state, s, id, id);
33
34     if (s != NULL)
35     {
36         /* We must return NULL here as the caller must know that he is
37          * responsible for releasing @p data. */
38         debug("asynchronous state for transaction %d already registered\n", id);
39         return NULL;
40     }
41
42     /* store information for handling the asynchronous task */
43     s = (coap_async_state_t *) coap_malloc(sizeof(coap_async_state_t) +
44             request->hdr->token_length);
45     if (!s)
46     {
47         coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n");
48         return NULL;
49     }
50
51     memset(s, 0, sizeof(coap_async_state_t) + request->hdr->token_length);
52
53     /* set COAP_ASYNC_CONFIRM according to request's type */
54     s->flags = flags & ~COAP_ASYNC_CONFIRM;
55     if (request->hdr->type == COAP_MESSAGE_CON)
56         s->flags |= COAP_ASYNC_CONFIRM;
57
58     s->appdata = data;
59
60     memcpy(&s->peer, peer, sizeof(coap_address_t));
61
62     if (request->hdr->token_length)
63     {
64         s->tokenlen = request->hdr->token_length;
65         memcpy(s->token, request->hdr->token, request->hdr->token_length);
66     }
67
68     memcpy(&s->id, &id, sizeof(coap_tid_t));
69
70     coap_touch_async(s);
71
72     LL_PREPEND(context->async_state, s);
73
74     return s;
75 }
76
77 coap_async_state_t *
78 coap_find_async(coap_context_t *context, coap_tid_t id)
79 {
80     coap_async_state_t *tmp;
81     LL_SEARCH_SCALAR(context->async_state, tmp, id, id);
82     return tmp;
83 }
84
85 int coap_remove_async(coap_context_t *context, coap_tid_t id, coap_async_state_t **s)
86 {
87     coap_async_state_t *tmp = coap_find_async(context, id);
88
89     if (tmp)
90         LL_DELETE(context->async_state, tmp);
91
92     *s = tmp;
93     return tmp != NULL;
94 }
95
96 void coap_free_async(coap_async_state_t *s)
97 {
98     if (s && (s->flags & COAP_ASYNC_RELEASE_DATA) != 0)
99         coap_free(s->appdata);
100     coap_free(s);
101 }
102
103 #else
104 void does_not_exist(); /* make some compilers happy */
105 #endif /* WITHOUT_ASYNC */