libcoap  4.3.0rc1
async.c
Go to the documentation of this file.
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 
14 #include "coap2/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) \
20  SEARCH_PAIR2(head,out,field1,val1,field2,val2,next)
21 
22 #define SEARCH_PAIR2(head,out,field1,val1,field2,val2,next) \
23  do { \
24  LL_FOREACH2(head,out,next) { \
25  if ((out)->field1 == (val1) && (out)->field2 == (val2)) break; \
26  } \
27 } while(0)
28 
31  coap_pdu_t *request, unsigned char flags, void *data) {
33  coap_mid_t id = request->mid;
34 
35  SEARCH_PAIR(context->async_state,s,session,session,id,id);
36 
37  if (s != NULL) {
38  /* We must return NULL here as the caller must know that he is
39  * responsible for releasing @p data. */
41  "asynchronous state for mid=0x%x already registered\n", id);
42  return NULL;
43  }
44 
45  /* store information for handling the asynchronous task */
47  if (!s) {
48  coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n");
49  return NULL;
50  }
51 
52  memset(s, 0, sizeof(coap_async_state_t));
53 
54  /* set COAP_ASYNC_CONFIRM according to request's type */
55  s->flags = flags & ~COAP_ASYNC_CONFIRM;
56  if (request->type == COAP_MESSAGE_CON)
58 
59  s->appdata = data;
60  s->session = coap_session_reference( session );
61  s->id = id;
62 
63  if (request->token_length) {
64  /* A token can be up to 8 bytes */
65  s->tokenlen = (request->token_length > 8) ? 8 : request->token_length;
66  memcpy(s->token, request->token, s->tokenlen);
67  }
68 
70 
71  LL_PREPEND(context->async_state, s);
72 
73  return s;
74 }
75 
78  coap_async_state_t *tmp;
79  SEARCH_PAIR(context->async_state,tmp,session,session,id,id);
80  return tmp;
81 }
82 
83 int
86  coap_async_state_t *tmp = coap_find_async(context, session, id);
87 
88  if (tmp)
89  LL_DELETE(context->async_state,tmp);
90 
91  *s = tmp;
92  return tmp != NULL;
93 }
94 
95 void
97  if (s) {
98  if (s->session) {
100  }
101  if ((s->flags & COAP_ASYNC_RELEASE_DATA) != 0) {
102  coap_free(s->appdata);
103  }
104  coap_free(s);
105  }
106 }
107 
108 void
110  coap_async_state_t *astate, *tmp;
111 
112  LL_FOREACH_SAFE(context->async_state, astate, tmp) {
113  coap_free_async(astate);
114  }
115  context->async_state = NULL;
116 }
117 
118 #else
119 void does_not_exist(void); /* make some compilers happy */
120 #endif /* WITHOUT_ASYNC */
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:109
#define SEARCH_PAIR(head, out, field1, val1, field2, val2)
Definition: async.c:19
Pulls together all the internal only header files.
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_async_state_t * coap_find_async(coap_context_t *context, coap_session_t *session, coap_mid_t id)
Retrieves the object identified by id from the list of asynchronous transactions that are registered ...
Definition: async.c:77
coap_async_state_t * coap_register_async(coap_context_t *context, coap_session_t *session, coap_pdu_t *request, unsigned char flags, void *data)
Allocates a new coap_async_state_t object and fills its fields according to the given request.
Definition: async.c:30
void coap_free_async(coap_async_state_t *s)
Releases the memory that was allocated by coap_async_state_init() for the object s.
Definition: async.c:96
COAP_STATIC_INLINE void coap_touch_async(coap_async_state_t *s)
Updates the time stamp of s.
Definition: async.h:140
int coap_remove_async(coap_context_t *context, coap_session_t *session, coap_mid_t id, coap_async_state_t **s)
Removes the state object identified by id from context.
Definition: async.c:84
#define COAP_ASYNC_RELEASE_DATA
release application data on destruction
Definition: async.h:59
#define COAP_ASYNC_CONFIRM
send confirmable response
Definition: async.h:55
#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
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
int coap_mid_t
coap_mid_t is used to store the CoAP Message ID of a CoAP PDU.
Definition: pdu.h:244
#define COAP_MESSAGE_CON
Definition: pdu.h:75
unsigned char flags
holds the flags to control behaviour
Definition: async.h:31
void * appdata
This field can be used to register opaque application data with the asynchronous state object.
Definition: async.h:44
size_t tokenlen
length of the token
Definition: async.h:48
coap_session_t * session
transaction session
Definition: async.h:45
uint8_t token[8]
the token to use in a response
Definition: async.h:49
coap_mid_t id
message id
Definition: async.h:46
The CoAP stack's global state is stored in a coap_context_t object.
Definition: net.h:150
struct coap_async_state_t * async_state
list of asynchronous message ids
Definition: net.h:165
structure for CoAP PDUs token, if any, follows the fixed size header, then options until payload mark...
Definition: pdu.h:287
uint8_t type
message type
Definition: pdu.h:288
uint8_t * token
first byte of token, if any, or options
Definition: pdu.h:298
uint16_t mid
message id, if any, in regular host byte order
Definition: pdu.h:293
uint8_t token_length
length of Token
Definition: pdu.h:292
#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