32#include "contiki-lib.h"
41MEMB(prop_lists_mem,
struct mqtt_prop_list, MQTT_PROP_MAX_OUT_PROP_LISTS);
42MEMB(props_mem,
struct mqtt_prop_out_property, MQTT_PROP_MAX_OUT_PROPS);
55encode_prop_fixed_len_int(
struct mqtt_prop_out_property **prop_out,
60 DBG(
"MQTT - Creating %d-byte int property %i\n", len, val);
62 if(len > MQTT_PROP_MAX_PROP_LENGTH) {
63 DBG(
"MQTT - Error, property too long (max %i bytes)", MQTT_PROP_MAX_PROP_LENGTH);
67 for(i = len - 1; i >= 0; i--) {
68 (*prop_out)->val[i] = val & 0x00FF;
72 (*prop_out)->property_len = len;
76encode_prop_utf8(
struct mqtt_prop_out_property **prop_out,
81 DBG(
"MQTT - Encoding UTF-8 Property %s\n", str);
82 str_len = strlen(str);
85 if((str_len + 2) > MQTT_PROP_MAX_PROP_LENGTH) {
86 DBG(
"MQTT - Error, property too long (max %i bytes)", MQTT_PROP_MAX_PROP_LENGTH);
90 (*prop_out)->val[0] = str_len >> 8;
91 (*prop_out)->val[1] = str_len & 0x00FF;
92 memcpy((*prop_out)->val + 2, str, str_len);
94 (*prop_out)->property_len = str_len + 2;
98encode_prop_binary(
struct mqtt_prop_out_property **prop_out,
99 const char *data,
int data_len)
101 DBG(
"MQTT - Encoding Binary Data (%d bytes)\n", data_len);
103 if((data_len + 2) > MQTT_PROP_MAX_PROP_LENGTH) {
104 DBG(
"MQTT - Error, property too long (max %i bytes)", MQTT_PROP_MAX_PROP_LENGTH);
108 (*prop_out)->val[0] = data_len >> 8;
109 (*prop_out)->val[1] = data_len & 0x00FF;
110 memcpy((*prop_out)->val + 2, data, data_len);
112 (*prop_out)->property_len = data_len + 2;
116encode_prop_var_byte_int(
struct mqtt_prop_out_property **prop_out,
121 DBG(
"MQTT - Encoding Variable Byte Integer %d\n", val);
123 mqtt_encode_var_byte_int(
128 (*prop_out)->property_len = id_len;
132mqtt_prop_encode(
struct mqtt_prop_out_property **prop_out, mqtt_vhdr_prop_t prop_id,
135 DBG(
"MQTT - Creating property with ID %i\n", prop_id);
138 DBG(
"MQTT - Error, property target NULL!\n");
142 (*prop_out)->property_len = 0;
143 (*prop_out)->id = prop_id;
147 case MQTT_VHDR_PROP_PAYLOAD_FMT_IND:
148 case MQTT_VHDR_PROP_REQ_PROBLEM_INFO:
149 case MQTT_VHDR_PROP_REQ_RESP_INFO: {
152 val = va_arg(args,
int);
153 encode_prop_fixed_len_int(prop_out, val, 1);
157 case MQTT_VHDR_PROP_RECEIVE_MAX:
158 case MQTT_VHDR_PROP_TOPIC_ALIAS_MAX:
159 case MQTT_VHDR_PROP_TOPIC_ALIAS: {
162 val = va_arg(args,
int);
163 encode_prop_fixed_len_int(prop_out, val, 2);
167 case MQTT_VHDR_PROP_MSG_EXP_INT:
168 case MQTT_VHDR_PROP_SESS_EXP_INT:
169 case MQTT_VHDR_PROP_WILL_DELAY_INT:
170 case MQTT_VHDR_PROP_MAX_PKT_SZ: {
173 val = va_arg(args,
int);
174 encode_prop_fixed_len_int(prop_out, val, 4);
178 case MQTT_VHDR_PROP_CONTENT_TYPE:
179 case MQTT_VHDR_PROP_RESP_TOPIC:
180 case MQTT_VHDR_PROP_AUTH_METHOD: {
183 str = va_arg(args,
const char *);
184 encode_prop_utf8(prop_out, str);
188 case MQTT_VHDR_PROP_CORRELATION_DATA:
189 case MQTT_VHDR_PROP_AUTH_DATA: {
193 data = va_arg(args,
const char *);
194 data_len = va_arg(args,
int);
196 encode_prop_binary(prop_out, data, data_len);
200 case MQTT_VHDR_PROP_SUB_ID: {
203 val = va_arg(args,
int);
205 encode_prop_var_byte_int(prop_out, val);
209 case MQTT_VHDR_PROP_USER_PROP: {
215 name = va_arg(args,
const char *);
216 value = va_arg(args,
const char *);
218 name_len = strlen(name);
219 val_len = strlen(value);
221 DBG(
"MQTT - Encoding User Property '%s: %s'\n", name, value);
224 if((name_len + val_len + 4) > MQTT_PROP_MAX_PROP_LENGTH) {
225 DBG(
"MQTT - Error, property '%i' too long (max %i bytes)", prop_id, MQTT_PROP_MAX_PROP_LENGTH);
229 (*prop_out)->val[0] = name_len >> 8;
230 (*prop_out)->val[1] = name_len & 0x00FF;
231 memcpy((*prop_out)->val + 2, name, strlen(name));
232 (*prop_out)->val[name_len + 2] = val_len >> 8;
233 (*prop_out)->val[name_len + 3] = val_len & 0x00FF;
234 memcpy((*prop_out)->val + name_len + 4, value, strlen(value));
236 (*prop_out)->property_len = strlen(name) + strlen(value) + 4;
240 DBG(
"MQTT - Error, no such property '%i'\n", prop_id);
245 DBG(
"MQTT - Property encoded length %i\n", (*prop_out)->property_len);
247 return (*prop_out)->property_len;
252mqtt_prop_decode_input_props(
struct mqtt_connection *conn)
254 uint8_t prop_len_bytes;
256 DBG(
"MQTT - Parsing input properties\n");
259 if(((conn->in_packet.fhdr & 0xF0) == MQTT_FHDR_MSG_TYPE_PINGREQ) ||
260 ((conn->in_packet.fhdr & 0xF0) == MQTT_FHDR_MSG_TYPE_PINGRESP)) {
264 DBG(
"MQTT - Getting length\n");
267 mqtt_decode_var_byte_int(conn->in_packet.payload_start,
268 conn->in_packet.remaining_length - (conn->in_packet.payload_start - conn->in_packet.payload),
269 NULL, NULL, &conn->in_packet.properties_len);
271 if(prop_len_bytes == 0) {
272 DBG(
"MQTT - Error decoding input properties (out of bounds)\n");
276 DBG(
"MQTT - Received %i VBI property bytes\n", prop_len_bytes);
277 DBG(
"MQTT - Input properties length %i\n", conn->in_packet.properties_len);
282 conn->in_packet.properties_enc_len = prop_len_bytes;
284 conn->in_packet.props_start = conn->in_packet.payload_start + prop_len_bytes;
285 conn->in_packet.payload_start += prop_len_bytes;
286 conn->in_packet.curr_props_pos = conn->in_packet.props_start;
288 DBG(
"MQTT - First byte of first prop %i\n", *conn->in_packet.curr_props_pos);
290 conn->in_packet.has_props = 1;
295decode_prop_utf8(
struct mqtt_connection *conn,
301 len = (buf_in[0] << 8) + buf_in[1];
303 DBG(
"MQTT - Decoding %d-char UTF8 string property\n", len);
306 if((len + MQTT_STRING_LEN_SIZE + 1) > MQTT_PROP_MAX_PROP_LENGTH) {
307 DBG(
"MQTT - Error, property too long (max %i bytes)", MQTT_PROP_MAX_PROP_LENGTH);
311 memcpy(data, buf_in, len + MQTT_STRING_LEN_SIZE);
312 data[len + MQTT_STRING_LEN_SIZE] =
'\0';
315 return len + MQTT_STRING_LEN_SIZE;
319decode_prop_fixed_len_int(
struct mqtt_connection *conn,
320 uint8_t *buf_in,
int len,
326 DBG(
"MQTT - Decoding %d-byte int property\n", len);
328 if(len > MQTT_PROP_MAX_PROP_LENGTH) {
329 DBG(
"MQTT - Error, property too long (max %i bytes)", MQTT_PROP_MAX_PROP_LENGTH);
336 data_out = (uint32_t *)data;
338 for(i = 0; i < 4; i++) {
339 *data_out = *data_out << 8;
342 *data_out += buf_in[i];
350decode_prop_vbi(
struct mqtt_connection *conn,
354 uint8_t prop_len_bytes;
356 DBG(
"MQTT - Decoding Variable Byte Integer property\n");
362 mqtt_decode_var_byte_int(buf_in, 4, NULL, NULL, (uint16_t *)data);
364 if(prop_len_bytes == 0) {
365 DBG(
"MQTT - Error decoding Variable Byte Integer\n");
369 if(prop_len_bytes > MQTT_PROP_MAX_PROP_LENGTH) {
370 DBG(
"MQTT - Error, property too long (max %i bytes)", MQTT_PROP_MAX_PROP_LENGTH);
374 return prop_len_bytes;
378decode_prop_binary_data(
struct mqtt_connection *conn,
384 DBG(
"MQTT - Decoding Binary Data property\n");
386 data_len = (buf_in[0] << 8) + buf_in[1];
389 DBG(
"MQTT - Error decoding Binary Data property length\n");
393 if((data_len + 2) > MQTT_PROP_MAX_PROP_LENGTH) {
394 DBG(
"MQTT - Error, property too long (max %i bytes)", MQTT_PROP_MAX_PROP_LENGTH);
398 memcpy(data, buf_in, data_len + 2);
404decode_prop_utf8_pair(
struct mqtt_connection *conn,
412 len1 = (buf_in[0] << 8) + buf_in[1];
413 len2 = (buf_in[len1 + MQTT_STRING_LEN_SIZE] << 8) + buf_in[len1 + MQTT_STRING_LEN_SIZE + 1];
414 total_len = len1 + len2;
416 DBG(
"MQTT - Decoding %d-char UTF8 string pair property (%i + %i)\n", total_len, len1, len2);
418 if((total_len + 2 * MQTT_STRING_LEN_SIZE) > MQTT_PROP_MAX_PROP_LENGTH) {
419 DBG(
"MQTT - Error, property too long (max %i bytes)", MQTT_PROP_MAX_PROP_LENGTH);
423 memcpy(data, buf_in, total_len + 2 * MQTT_STRING_LEN_SIZE);
426 return total_len + 2 * MQTT_STRING_LEN_SIZE;
430parse_prop(
struct mqtt_connection *conn,
431 mqtt_vhdr_prop_t prop_id, uint8_t *buf_in, uint8_t *data)
434 case MQTT_VHDR_PROP_PAYLOAD_FMT_IND:
435 case MQTT_VHDR_PROP_REQ_PROBLEM_INFO:
436 case MQTT_VHDR_PROP_REQ_RESP_INFO:
437 case MQTT_VHDR_PROP_MAX_QOS:
438 case MQTT_VHDR_PROP_RETAIN_AVAIL:
439 case MQTT_VHDR_PROP_WILD_SUB_AVAIL:
440 case MQTT_VHDR_PROP_SUB_ID_AVAIL:
441 case MQTT_VHDR_PROP_SHARED_SUB_AVAIL: {
442 return decode_prop_fixed_len_int(conn, buf_in, 1, data);
444 case MQTT_VHDR_PROP_RECEIVE_MAX:
445 case MQTT_VHDR_PROP_TOPIC_ALIAS_MAX:
446 case MQTT_VHDR_PROP_SERVER_KEEP_ALIVE: {
447 return decode_prop_fixed_len_int(conn, buf_in, 2, data);
449 case MQTT_VHDR_PROP_MSG_EXP_INT:
450 case MQTT_VHDR_PROP_SESS_EXP_INT:
451 case MQTT_VHDR_PROP_WILL_DELAY_INT:
452 case MQTT_VHDR_PROP_MAX_PKT_SZ: {
453 return decode_prop_fixed_len_int(conn, buf_in, 4, data);
455 case MQTT_VHDR_PROP_CONTENT_TYPE:
456 case MQTT_VHDR_PROP_RESP_TOPIC:
457 case MQTT_VHDR_PROP_AUTH_METHOD:
458 case MQTT_VHDR_PROP_ASSIGNED_CLIENT_ID:
459 case MQTT_VHDR_PROP_RESP_INFO:
460 case MQTT_VHDR_PROP_SERVER_REFERENCE:
461 case MQTT_VHDR_PROP_REASON_STRING: {
462 return decode_prop_utf8(conn, buf_in, data);
464 case MQTT_VHDR_PROP_CORRELATION_DATA:
465 case MQTT_VHDR_PROP_AUTH_DATA: {
466 return decode_prop_binary_data(conn, buf_in, data);
468 case MQTT_VHDR_PROP_SUB_ID: {
469 return decode_prop_vbi(conn, buf_in, data);
471 case MQTT_VHDR_PROP_USER_PROP: {
472 return decode_prop_utf8_pair(conn, buf_in, data);
475 DBG(
"MQTT - Error, no such property '%i'", prop_id);
484mqtt_get_next_in_prop(
struct mqtt_connection *conn,
485 mqtt_vhdr_prop_t *prop_id, uint8_t *data)
488 uint8_t prop_id_len_bytes;
489 uint16_t prop_id_decode;
491 if(!conn->in_packet.has_props) {
492 DBG(
"MQTT - Message has no input properties");
496 DBG(
"MQTT - Curr prop pos %i; len %i; byte %i\n", (conn->in_packet.curr_props_pos - conn->in_packet.props_start),
497 conn->in_packet.properties_len,
498 *conn->in_packet.curr_props_pos);
500 if((conn->in_packet.curr_props_pos - conn->in_packet.props_start)
501 >= conn->in_packet.properties_len) {
502 DBG(
"MQTT - Message has no more input properties\n");
507 mqtt_decode_var_byte_int(conn->in_packet.curr_props_pos,
508 conn->in_packet.properties_len - (conn->in_packet.curr_props_pos - conn->in_packet.props_start),
509 NULL, NULL, (uint16_t *)&prop_id_decode);
511 *prop_id = prop_id_decode;
513 DBG(
"MQTT - Decoded property ID %i (encoded using %i bytes)\n", *prop_id, prop_id_len_bytes);
515 prop_len = parse_prop(conn, *prop_id, conn->in_packet.curr_props_pos + 1, data);
517 DBG(
"MQTT - Decoded property len %i bytes\n", prop_len);
519 conn->in_packet.curr_props_pos += prop_id_len_bytes + prop_len;
525mqtt_prop_parse_connack_props(
struct mqtt_connection *conn)
528 mqtt_vhdr_prop_t prop_id;
529 uint8_t data[MQTT_PROP_MAX_PROP_LENGTH];
532 DBG(
"MQTT - Parsing CONNACK properties for server capabilities\n");
534 prop_len = mqtt_get_next_in_prop(conn, &prop_id, data);
537 case MQTT_VHDR_PROP_RETAIN_AVAIL: {
538 val_int = (uint32_t)*data;
540 conn->srv_feature_en &= ~MQTT_CAP_RETAIN_AVAIL;
544 case MQTT_VHDR_PROP_WILD_SUB_AVAIL: {
545 val_int = (uint32_t)*data;
547 conn->srv_feature_en &= ~MQTT_CAP_WILD_SUB_AVAIL;
551 case MQTT_VHDR_PROP_SUB_ID_AVAIL: {
552 val_int = (uint32_t)*data;
554 conn->srv_feature_en &= ~MQTT_CAP_SUB_ID_AVAIL;
558 case MQTT_VHDR_PROP_SHARED_SUB_AVAIL: {
559 val_int = (uint32_t)*data;
561 conn->srv_feature_en &= ~MQTT_CAP_SHARED_SUB_AVAIL;
566 DBG(
"MQTT - Error, unexpected CONNACK property '%i'", prop_id);
571 prop_len = mqtt_get_next_in_prop(conn, &prop_id, data);
576mqtt_prop_parse_auth_props(
struct mqtt_connection *conn,
struct mqtt_prop_auth_event *event)
579 mqtt_vhdr_prop_t prop_id;
580 uint8_t data[MQTT_PROP_MAX_PROP_LENGTH];
582 DBG(
"MQTT - Parsing CONNACK properties for server capabilities\n");
584 event->auth_data.len = 0;
585 event->auth_method.length = 0;
587 prop_len = mqtt_get_next_in_prop(conn, &prop_id, data);
590 case MQTT_VHDR_PROP_AUTH_DATA: {
591 event->auth_data.len = prop_len - 2;
592 memcpy(event->auth_data.data, data, prop_len - 2);
595 case MQTT_VHDR_PROP_AUTH_METHOD: {
596 event->auth_method.length = prop_len - 2;
597 memcpy(event->auth_method.string, data, prop_len - 2);
601 DBG(
"MQTT - Unhandled AUTH property '%i'", prop_id);
606 prop_len = mqtt_get_next_in_prop(conn, &prop_id, data);
611mqtt_prop_print_input_props(
struct mqtt_connection *conn)
614 mqtt_vhdr_prop_t prop_id;
615 uint8_t data[MQTT_PROP_MAX_PROP_LENGTH];
618 DBG(
"MQTT - Printing all input properties\n");
620 prop_len = mqtt_get_next_in_prop(conn, &prop_id, data);
622 DBG(
"MQTT - Property ID %i, length %i\n", prop_id, prop_len);
625 case MQTT_VHDR_PROP_PAYLOAD_FMT_IND:
626 case MQTT_VHDR_PROP_REQ_PROBLEM_INFO:
627 case MQTT_VHDR_PROP_REQ_RESP_INFO:
628 case MQTT_VHDR_PROP_MSG_EXP_INT:
629 case MQTT_VHDR_PROP_SESS_EXP_INT:
630 case MQTT_VHDR_PROP_WILL_DELAY_INT:
631 case MQTT_VHDR_PROP_MAX_PKT_SZ:
632 case MQTT_VHDR_PROP_RECEIVE_MAX:
633 case MQTT_VHDR_PROP_TOPIC_ALIAS_MAX:
634 case MQTT_VHDR_PROP_SUB_ID: {
635 DBG(
"MQTT - Decoded property value '%i'\n", (uint32_t)*data);
638 case MQTT_VHDR_PROP_CONTENT_TYPE:
639 case MQTT_VHDR_PROP_RESP_TOPIC:
640 case MQTT_VHDR_PROP_AUTH_METHOD: {
641 DBG(
"MQTT - Decoded property value ");
642 DBG(
"(%i %i) %s", data[0], data[1], data + MQTT_STRING_LEN_SIZE);
646 case MQTT_VHDR_PROP_CORRELATION_DATA:
647 case MQTT_VHDR_PROP_AUTH_DATA: {
648 DBG(
"MQTT - Decoded property value (%i %i) ", data[0], data[1]);
649 for(i = 2; i < prop_len; i++) {
655 case MQTT_VHDR_PROP_USER_PROP: {
660 len1 = (data[0] << 8) + data[1];
661 len2 = (data[len1 + MQTT_STRING_LEN_SIZE] << 8) + data[len1 + MQTT_STRING_LEN_SIZE + 1];
663 DBG(
"MQTT - Decoded property value [(%i %i) %.*s, (%i %i) %.*s]",
664 data[0], data[1], len1, data + MQTT_STRING_LEN_SIZE,
665 data[len1 + MQTT_STRING_LEN_SIZE], data[len1 + MQTT_STRING_LEN_SIZE + 1], len2, data + len1 + 2 * MQTT_STRING_LEN_SIZE);
670 DBG(
"MQTT - Error, no such property '%i'\n", prop_id);
675 prop_len = mqtt_get_next_in_prop(conn, &prop_id, data);
684mqtt_prop_create_list(
struct mqtt_prop_list **prop_list_out)
686 DBG(
"MQTT - Creating Property List\n");
688#if MQTT_PROP_USE_MEMB
692 if(!(*prop_list_out)) {
693 DBG(
"MQTT - Error, allocated too many property lists (max %i)\n", MQTT_PROP_MAX_OUT_PROP_LISTS);
697 DBG(
"MQTT - Allocated Property list\n");
701 DBG(
"MQTT - mem %p prop_list\n", *prop_list_out);
703 (*prop_list_out)->properties_len = 0;
704 (*prop_list_out)->properties_len_enc_bytes = 1;
712mqtt_prop_print_list(
struct mqtt_prop_list *prop_list, mqtt_vhdr_prop_t prop_id)
714 struct mqtt_prop_out_property *prop;
716 if(prop_list == NULL || prop_list->props == NULL) {
717 DBG(
"MQTT - Prop list empty\n");
719 prop = (
struct mqtt_prop_out_property *)
list_head(prop_list->props);
722 if(prop != NULL && (prop->id == prop_id || prop_id == MQTT_VHDR_PROP_ANY)) {
723 DBG(
"Property %p ID %i len %i\n", prop, prop->id, prop->property_len);
726 }
while(prop != NULL);
731mqtt_prop_register_internal(
struct mqtt_prop_list **prop_list,
732#
if !MQTT_PROP_USE_MEMB
733 struct mqtt_prop_out_property *prop,
736 mqtt_vhdr_prop_t prop_id,
737 struct mqtt_prop_out_property **prop_out, ...)
741 DBG(
"MQTT - Error encoding prop %i on msg %i; list NULL\n", prop_id, msg);
745 DBG(
"MQTT - prop list %p\n", *prop_list);
746 DBG(
"MQTT - prop list->list %p\n", (*prop_list)->props);
748#if MQTT_PROP_USE_MEMB
749 struct mqtt_prop_out_property *prop =
memb_alloc(&props_mem);
753 DBG(
"MQTT - Error, allocated too many properties (max %i)\n", MQTT_PROP_MAX_OUT_PROPS);
758 DBG(
"MQTT - Allocated prop %p\n", prop);
761 va_start(args, prop_out);
762 uint32_t prop_len = mqtt_prop_encode(&prop, prop_id, args);
765 DBG(
"MQTT - Adding prop %p to prop_list %p\n", prop, *prop_list);
766 list_add((*prop_list)->props, prop);
767 (*prop_list)->properties_len += 1;
768 (*prop_list)->properties_len += prop_len;
769 mqtt_encode_var_byte_int(
770 (*prop_list)->properties_len_enc,
771 &((*prop_list)->properties_len_enc_bytes),
772 (*prop_list)->properties_len);
773 DBG(
"MQTT - New prop_list length %i\n", (*prop_list)->properties_len);
775 DBG(
"MQTT - Error encoding prop %i on msg %i\n", prop_id, msg);
776#if MQTT_PROP_USE_MEMB
793mqtt_remove_prop(
struct mqtt_prop_list **prop_list,
794 struct mqtt_prop_out_property *prop)
796 if(prop != NULL && prop_list != NULL &&
list_contains((*prop_list)->props, prop)) {
797 DBG(
"MQTT - Removing property %p from list %p\n", prop, *prop_list);
803 (*prop_list)->properties_len -= prop->property_len;
804 (*prop_list)->properties_len -= 1;
806 mqtt_encode_var_byte_int(
807 (*prop_list)->properties_len_enc,
808 &((*prop_list)->properties_len_enc_bytes),
809 (*prop_list)->properties_len);
812#if MQTT_PROP_USE_MEMB
817 DBG(
"MQTT - Cannot remove property\n");
823mqtt_prop_clear_list(
struct mqtt_prop_list **prop_list)
825 struct mqtt_prop_out_property *prop;
827 DBG(
"MQTT - Clearing Property List\n");
829 if(prop_list == NULL ||
list_length((*prop_list)->props) == 0) {
830 DBG(
"MQTT - Prop list empty\n");
833 prop = (
struct mqtt_prop_out_property *)
list_head((*prop_list)->props);
837 (void)mqtt_remove_prop(prop_list, prop);
839 prop = (
struct mqtt_prop_out_property *)
list_head((*prop_list)->props);
840 }
while(prop != NULL);
845 if((*prop_list)->properties_len != 0 || (*prop_list)->properties_len_enc_bytes != 1) {
846 DBG(
"MQTT - Something went wrong when clearing property list!\n");
static void * list_item_next(const void *item)
Get the next item following this item.
int list_length(const_list_t list)
Get the length of a list.
void list_add(list_t list, void *item)
Add an item at the end of a list.
void list_remove(list_t list, const void *item)
Remove a specific element from a list.
bool list_contains(const_list_t list, const void *item)
Check if the list contains an item.
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
static void * list_head(const_list_t list)
Get a pointer to the first element of a list.
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
#define MEMB(name, structure, num)
Declare a memory block.
Memory block allocation routines.
Header file for the Contiki MQTT engine.