libcoap  4.3.0rc2
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  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use.
7  */
8 
14 #include "coap3/coap_internal.h"
15 
16 #ifndef WITHOUT_ASYNC
17 
18 /* utlist-style macros for searching pairs in linked lists */
19 #define SEARCH_PAIR(head,out,field1,val1,field2,val2,field3,val3) \
20  SEARCH_PAIR3(head,out,field1,val1,field2,val2,field3,val3,next)
21 
22 #define SEARCH_PAIR3(head,out,field1,val1,field2,val2,field3,val3,next) \
23  do { \
24  LL_FOREACH2(head,out,next) { \
25  if ((out)->field1 == (val1) && (out)->field2 == (val2) && \
26  ((val2) == 0 || memcmp((out)->field3, (val3), (val2)) == 0)) break; \
27  } \
28 } while(0)
29 
30 int
32  return 1;
33 }
34 
37  coap_pdu_t *request, coap_tick_t delay) {
38  coap_async_t *s;
39  coap_mid_t mid = request->mid;
40  size_t len;
41  const uint8_t *data;
42 
43  if (!COAP_PDU_IS_REQUEST(request))
44  return NULL;
45 
46  SEARCH_PAIR(context->async_state, s,
47  session, session,
48  pdu->token_length, request->token_length,
49  pdu->token, request->token);
50 
51  if (s != NULL) {
53  "asynchronous state for mid=0x%x already registered\n", mid);
54  return NULL;
55  }
56 
57  /* store information for handling the asynchronous task */
58  s = (coap_async_t *)coap_malloc(sizeof(coap_async_t));
59  if (!s) {
60  coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n");
61  return NULL;
62  }
63 
64  memset(s, 0, sizeof(coap_async_t));
65 
66  s->pdu = coap_pdu_duplicate(request, session, request->token_length,
67  request->token, NULL);
68  if (s->pdu == NULL) {
69  coap_free_async(context, s);
70  coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n");
71  return NULL;
72  }
73  s->pdu->mid = mid; /* coap_pdu_duplicate() created one */
74 
75  if (coap_get_data(request, &len, &data)) {
76  coap_add_data(s->pdu, len, data);
77  }
78 
79  s->session = coap_session_reference( session );
80 
81  coap_async_set_delay(s, delay);
82 
83  LL_PREPEND(context->async_state, s);
84 
85  return s;
86 }
87 
88 void
90  assert(async != NULL);
91 
92  if (delay) {
93  coap_ticks(&async->delay);
94  async->delay += delay;
95  }
96  else
97  async->delay = 0;
98  coap_log(LOG_DEBUG, " %s: Request for delayed for %u.%03u secs\n",
99  coap_session_str(async->session),
100  (unsigned int)(delay / COAP_TICKS_PER_SECOND),
101  (unsigned int)((delay % COAP_TICKS_PER_SECOND) *
102  1000 / COAP_TICKS_PER_SECOND));
103 }
104 
105 
106 coap_async_t *
108  coap_binary_t token) {
109  coap_async_t *tmp;
110  SEARCH_PAIR(context->async_state, tmp,
111  session, session,
112  pdu->token_length, token.length,
113  pdu->token, token.s);
114  return tmp;
115 }
116 
117 void
119  if (s) {
120  LL_DELETE(context->async_state,s);
121  if (s->session) {
123  }
124  if (s->pdu) {
125  coap_delete_pdu(s->pdu);
126  s->pdu = NULL;
127  }
128  coap_free(s);
129  }
130 }
131 
132 void
134  coap_async_t *astate, *tmp;
135 
136  LL_FOREACH_SAFE(context->async_state, astate, tmp) {
137  coap_free_async(context, astate);
138  }
139  context->async_state = NULL;
140 }
141 
142 void
143 coap_async_set_app_data(coap_async_t *async, void *app_data) {
144  async->appdata = app_data;
145 }
146 
147 void *
149  return async->appdata;
150 }
151 
152 #else
153 
154 int
156  return 0;
157 }
158 
159 coap_async_t *
161  coap_session_t *session,
162  coap_pdu_t *request,
163  coap_tick_t delay) {
164  (void)context;
165  (void)session;
166  (void)request;
167  (void)delay;
168  return NULL;
169 }
170 
171 void
173  (void)async;
174  (void)delay;
175 }
176 
177 void
178 coap_free_async(coap_context_t *context, coap_async_t *async) {
179  (void)context;
180  (void)async;
181 }
182 
183 coap_async_t *
185  coap_session_t *session,
186  coap_binary_t token) {
187  (void)context;
188  (void)session;
189  (void)token;
190  return NULL;
191 }
192 
193 void
194 coap_async_set_app_data(coap_async_t *async, void *app_data) {
195  (void)async;
196  (void)app_data;
197 }
198 
199 void *
201  (void)async;
202  return NULL;
203 }
204 
205 #endif /* WITHOUT_ASYNC */
#define SEARCH_PAIR(head, out, field1, val1, field2, val2, field3, val3)
Definition: async.c:19
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:120
#define COAP_TICKS_PER_SECOND
Use ms resolution on POSIX systems.
Definition: coap_time.h:135
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:133
coap_async_t * coap_find_async(coap_context_t *context, coap_session_t *session, coap_binary_t token)
Retrieves the object identified by token from the list of asynchronous transactions that are register...
Definition: async.c:107
void coap_free_async(coap_context_t *context, coap_async_t *s)
Releases the memory that was allocated by coap_async_state_init() for the object async.
Definition: async.c:118
void * coap_async_get_app_data(const coap_async_t *async)
Gets the application data pointer held in async.
Definition: async.c:148
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:89
coap_async_t * coap_register_async(coap_context_t *context, coap_session_t *session, 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:36
void coap_async_set_app_data(coap_async_t *async, void *app_data)
Set the application data pointer held in async.
Definition: async.c:143
int coap_async_is_supported(void)
Returns 1 if libcoap was built with separate messages enabled, 0 otherwise.
Definition: async.c:31
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log(level,...)
Logging function.
Definition: coap_debug.h:150
@ LOG_CRIT
Critical.
Definition: coap_debug.h:52
@ LOG_DEBUG
Debug.
Definition: coap_debug.h:57
#define COAP_PDU_IS_REQUEST(pdu)
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:153
void coap_delete_pdu(coap_pdu_t *pdu)
Dispose of an CoAP PDU and frees associated storage.
Definition: pdu.c:140
int coap_mid_t
coap_mid_t is used to store the CoAP Message ID of a CoAP PDU.
Definition: pdu.h:229
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:652
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:622
coap_session_t * coap_session_reference(coap_session_t *session)
Increment reference counter on a session.
Definition: coap_session.c:68
void coap_session_release(coap_session_t *session)
Decrement reference counter on a session.
Definition: coap_session.c:74
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
Definition: mem.h:96
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
Definition: mem.h:103
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.
Definition: str.h:48
size_t length
length of binary data
Definition: str.h:49
uint8_t * s
binary data
Definition: str.h:50
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...
#define LL_DELETE(head, del)
Definition: utlist.h:385
#define LL_PREPEND(head, add)
Definition: utlist.h:314
#define LL_FOREACH_SAFE(head, el, tmp)
Definition: utlist.h:419