libcoap 4.3.0
async.c
Go to the documentation of this file.
1/* async.c -- state management for asynchronous messages
2 *
3 * Copyright (C) 2010,2011,2021 Olaf Bergmann <bergmann@tzi.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10
16#include "coap3/coap_internal.h"
17
18#ifndef WITHOUT_ASYNC
19
20/* utlist-style macros for searching pairs in linked lists */
21#define SEARCH_PAIR(head,out,field1,val1,field2,val2,field3,val3) \
22 SEARCH_PAIR3(head,out,field1,val1,field2,val2,field3,val3,next)
23
24#define SEARCH_PAIR3(head,out,field1,val1,field2,val2,field3,val3,next) \
25 do { \
26 LL_FOREACH2(head,out,next) { \
27 if ((out)->field1 == (val1) && (out)->field2 == (val2) && \
28 ((val2) == 0 || memcmp((out)->field3, (val3), (val2)) == 0)) break; \
29 } \
30} while(0)
31
32int
34 return 1;
35}
36
39 const coap_pdu_t *request, coap_tick_t delay) {
40 coap_async_t *s;
41 coap_mid_t mid = request->mid;
42 size_t len;
43 const uint8_t *data;
44
45 if (!COAP_PDU_IS_REQUEST(request))
46 return NULL;
47
48 SEARCH_PAIR(session->context->async_state, s,
49 session, session,
50 pdu->token_length, request->token_length,
51 pdu->token, request->token);
52
53 if (s != NULL) {
55 "asynchronous state for mid=0x%x already registered\n", mid);
56 return NULL;
57 }
58
59 /* store information for handling the asynchronous task */
61 if (!s) {
62 coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n");
63 return NULL;
64 }
65
66 memset(s, 0, sizeof(coap_async_t));
67
68 s->pdu = coap_pdu_duplicate(request, session, request->token_length,
69 request->token, NULL);
70 if (s->pdu == NULL) {
71 coap_free_async(session, s);
72 coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n");
73 return NULL;
74 }
75 s->pdu->mid = mid; /* coap_pdu_duplicate() created one */
76
77 if (coap_get_data(request, &len, &data)) {
78 coap_add_data(s->pdu, len, data);
79 }
80
81 s->session = coap_session_reference( session );
82
83 coap_async_set_delay(s, delay);
84
85 LL_PREPEND(session->context->async_state, s);
86
87 return s;
88}
89
90void
92 assert(async != NULL);
93
94 if (delay) {
95 coap_ticks(&async->delay);
96 async->delay += delay;
97 }
98 else
99 async->delay = 0;
100 coap_log(LOG_DEBUG, " %s: Request for delayed for %u.%03u secs\n",
102 (unsigned int)(delay / COAP_TICKS_PER_SECOND),
103 (unsigned int)((delay % COAP_TICKS_PER_SECOND) *
104 1000 / COAP_TICKS_PER_SECOND));
105}
106
107
110 coap_async_t *tmp;
111 SEARCH_PAIR(session->context->async_state, tmp,
112 session, session,
113 pdu->token_length, token.length,
114 pdu->token, token.s);
115 return tmp;
116}
117
118static void
120 if (s) {
121 LL_DELETE(context->async_state,s);
122 if (s->session) {
124 }
125 if (s->pdu) {
127 s->pdu = NULL;
128 }
129 coap_free(s);
130 }
131}
132
133void
135 coap_free_async_sub(session->context, s);
136}
137
138void
140 coap_async_t *astate, *tmp;
141
142 LL_FOREACH_SAFE(context->async_state, astate, tmp) {
143 coap_free_async_sub(context, astate);
144 }
145 context->async_state = NULL;
146}
147
148void
149coap_async_set_app_data(coap_async_t *async, void *app_data) {
150 async->appdata = app_data;
151}
152
153void *
155 return async->appdata;
156}
157
158#else
159
160int
162 return 0;
163}
164
167 const coap_pdu_t *request,
168 coap_tick_t delay) {
169 (void)session;
170 (void)request;
171 (void)delay;
172 return NULL;
173}
174
175void
177 (void)async;
178 (void)delay;
179}
180
181void
183 (void)session;
184 (void)async;
185}
186
189 coap_bin_const_t token) {
190 (void)session;
191 (void)token;
192 return NULL;
193}
194
195void
196coap_async_set_app_data(coap_async_t *async, void *app_data) {
197 (void)async;
198 (void)app_data;
199}
200
201void *
203 (void)async;
204 return NULL;
205}
206
207#endif /* WITHOUT_ASYNC */
#define SEARCH_PAIR(head, out, field1, val1, field2, val2, field3, val3)
Definition: async.c:21
static void coap_free_async_sub(coap_context_t *context, coap_async_t *s)
Definition: async.c:119
Pulls together all the internal only header files.
void coap_ticks(coap_tick_t *t)
Sets t to the internal time with COAP_TICKS_PER_SECOND resolution.
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition: coap_time.h:122
#define COAP_TICKS_PER_SECOND
Use ms resolution on POSIX systems.
Definition: coap_time.h:137
void coap_delete_all_async(coap_context_t *context)
Removes and frees off all of the async entries for the given context.
Definition: async.c:139
void coap_free_async(coap_session_t *session, coap_async_t *s)
Releases the memory that was allocated by coap_register_async() for the object async.
Definition: async.c:134
coap_async_t * coap_register_async(coap_session_t *session, const coap_pdu_t *request, coap_tick_t delay)
Allocates a new coap_async_t object and fills its fields according to the given request.
Definition: async.c:38
void coap_async_set_delay(coap_async_t *async, coap_tick_t delay)
Update the delay timeout, so changing when the registered async triggers.
Definition: async.c:91
void * coap_async_get_app_data(const coap_async_t *async)
Gets the application data pointer held in async.
Definition: async.c:154
coap_async_t * coap_find_async(coap_session_t *session, coap_bin_const_t token)
Retrieves the object identified by token from the list of asynchronous transactions that are register...
Definition: async.c:109
void coap_async_set_app_data(coap_async_t *async, void *app_data)
Set the application data pointer held in async.
Definition: async.c:149
int coap_async_is_supported(void)
Returns 1 if libcoap was built with separate messages enabled, 0 otherwise.
Definition: async.c:33
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log(level,...)
Logging function.
Definition: coap_debug.h:152
@ LOG_CRIT
Critical.
Definition: coap_debug.h:54
@ LOG_DEBUG
Debug.
Definition: coap_debug.h:59
#define COAP_PDU_IS_REQUEST(pdu)
void coap_delete_pdu(coap_pdu_t *pdu)
Dispose of an CoAP PDU and frees associated storage.
Definition: pdu.c:142
int coap_mid_t
coap_mid_t is used to store the CoAP Message ID of a CoAP PDU.
Definition: pdu.h:231
int coap_get_data(const coap_pdu_t *pdu, size_t *len, const uint8_t **data)
Retrieves the length and data pointer of specified PDU.
Definition: pdu.c:654
coap_pdu_t * coap_pdu_duplicate(const coap_pdu_t *old_pdu, coap_session_t *session, size_t token_length, const uint8_t *token, coap_opt_filter_t *drop_options)
Duplicate an existing PDU.
Definition: pdu.c:155
int coap_add_data(coap_pdu_t *pdu, size_t len, const uint8_t *data)
Adds given data to the pdu that is passed as first parameter.
Definition: pdu.c:624
void coap_session_release(coap_session_t *session)
Decrement reference counter on a session.
Definition: coap_session.c:76
coap_session_t * coap_session_reference(coap_session_t *session)
Increment reference counter on a session.
Definition: coap_session.c:70
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
Definition: mem.h:105
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
Definition: mem.h:98
coap_session_t * session
transaction session
coap_pdu_t * pdu
copy of request pdu
coap_tick_t delay
When to delay to before triggering the response 0 indicates never trigger.
CoAP binary data definition with const data.
Definition: str.h:58
size_t length
length of binary data
Definition: str.h:59
const uint8_t * s
read-only binary data
Definition: str.h:60
The CoAP stack's global state is stored in a coap_context_t object.
coap_async_t * async_state
list of asynchronous message ids
structure for CoAP PDUs token, if any, follows the fixed size header, then options until payload mark...
uint8_t * token
first byte of token, if any, or options
uint8_t token_length
length of Token
coap_mid_t mid
message id, if any, in regular host byte order
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
coap_context_t * context
session's context