IOT-1072 Unfork libcoap: add build flag
[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 "include/coap/config.h"
17 #include "include/coap/utlist.h"
18 #include "include/coap/mem.h"
19 #include "include/coap/debug.h"
20 #include "include/coap/async.h"
21
22 coap_async_state_t *
23 coap_register_async(coap_context_t *context, coap_address_t *peer, coap_pdu_t *request,
24         unsigned char flags, void *data)
25 {
26     coap_async_state_t *s;
27     coap_tid_t id;
28
29     coap_transaction_id(peer, request, &id);
30     LL_SEARCH_SCALAR(context->async_state, s, id, id);
31
32     if (s != NULL)
33     {
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->coap_hdr_udp_t.token_length);
43     if (!s)
44     {
45         coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n");
46         return NULL;
47     }
48
49     memset(s, 0, sizeof(coap_async_state_t) + request->hdr->coap_hdr_udp_t.token_length);
50
51     /* set COAP_ASYNC_CONFIRM according to request's type */
52     s->flags = flags & ~COAP_ASYNC_CONFIRM;
53     if (request->hdr->coap_hdr_udp_t.type == COAP_MESSAGE_CON)
54         s->flags |= COAP_ASYNC_CONFIRM;
55
56     s->appdata = data;
57
58     memcpy(&s->peer, peer, sizeof(coap_address_t));
59
60     if (request->hdr->coap_hdr_udp_t.token_length)
61     {
62         s->tokenlen = request->hdr->coap_hdr_udp_t.token_length;
63         memcpy(s->token, request->hdr->coap_hdr_udp_t.token, request->hdr->coap_hdr_udp_t.token_length);
64     }
65
66     memcpy(&s->id, &id, sizeof(coap_tid_t));
67
68     coap_touch_async(s);
69
70     LL_PREPEND(context->async_state, s);
71
72     return s;
73 }
74
75 coap_async_state_t *
76 coap_find_async(coap_context_t *context, coap_tid_t id)
77 {
78     coap_async_state_t *tmp;
79     LL_SEARCH_SCALAR(context->async_state, tmp, id, id);
80     return tmp;
81 }
82
83 int coap_remove_async(coap_context_t *context, coap_tid_t id, coap_async_state_t **s)
84 {
85     coap_async_state_t *tmp = coap_find_async(context, id);
86
87     if (tmp)
88         LL_DELETE(context->async_state, tmp);
89
90     *s = tmp;
91     return tmp != NULL;
92 }
93
94 void coap_free_async(coap_async_state_t *s)
95 {
96     if (s && (s->flags & COAP_ASYNC_RELEASE_DATA) != 0)
97         coap_free(s->appdata);
98     coap_free(s);
99 }
100
101 #else
102 void does_not_exist(); /* make some compilers happy */
103 #endif /* WITHOUT_ASYNC */