Update revision to use TI's mqtt and Freertos.

Dependencies:   mbed client server

Fork of cc3100_Test_mqtt_CM3 by David Fletcher

Committer:
dflet
Date:
Thu Sep 03 14:02:37 2015 +0000
Revision:
3:a8c249046181
SPI Mode change 1 to 0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dflet 3:a8c249046181 1 /******************************************************************************
dflet 3:a8c249046181 2 *
dflet 3:a8c249046181 3 * Copyright (C) 2014 Texas Instruments Incorporated
dflet 3:a8c249046181 4 *
dflet 3:a8c249046181 5 * All rights reserved. Property of Texas Instruments Incorporated.
dflet 3:a8c249046181 6 * Restricted rights to use, duplicate or disclose this code are
dflet 3:a8c249046181 7 * granted through contract.
dflet 3:a8c249046181 8 *
dflet 3:a8c249046181 9 * The program may not be used without the written permission of
dflet 3:a8c249046181 10 * Texas Instruments Incorporated or against the terms and conditions
dflet 3:a8c249046181 11 * stipulated in the agreement under which this program has been supplied,
dflet 3:a8c249046181 12 * and under no circumstances can it be used with non-TI connectivity device.
dflet 3:a8c249046181 13 *
dflet 3:a8c249046181 14 ******************************************************************************/
dflet 3:a8c249046181 15
dflet 3:a8c249046181 16 /*
dflet 3:a8c249046181 17 mqtt_common.c
dflet 3:a8c249046181 18
dflet 3:a8c249046181 19 This module implements routines that are common to both client and server
dflet 3:a8c249046181 20 components.
dflet 3:a8c249046181 21 */
dflet 3:a8c249046181 22
dflet 3:a8c249046181 23 #include "mqtt_common.h"
dflet 3:a8c249046181 24 #include "cli_uart.h"
dflet 3:a8c249046181 25
dflet 3:a8c249046181 26 namespace mbed_mqtt {
dflet 3:a8c249046181 27
dflet 3:a8c249046181 28 static void free_mqp(struct mqtt_packet *mqp)
dflet 3:a8c249046181 29 {
dflet 3:a8c249046181 30 if((NULL != mqp->free) && (0 == --mqp->n_refs))
dflet 3:a8c249046181 31 mqp->free(mqp);
dflet 3:a8c249046181 32
dflet 3:a8c249046181 33 return;
dflet 3:a8c249046181 34 }
dflet 3:a8c249046181 35
dflet 3:a8c249046181 36 void mqp_free(struct mqtt_packet *mqp)
dflet 3:a8c249046181 37 {
dflet 3:a8c249046181 38 free_mqp(mqp);
dflet 3:a8c249046181 39 }
dflet 3:a8c249046181 40
dflet 3:a8c249046181 41 static void reset_mqp(struct mqtt_packet *mqp)
dflet 3:a8c249046181 42 {
dflet 3:a8c249046181 43
dflet 3:a8c249046181 44 /* Fields not handled here are meant to be left unaltered. */
dflet 3:a8c249046181 45 mqp->msg_type = 0x00;
dflet 3:a8c249046181 46 mqp->fh_byte1 = 0x00;
dflet 3:a8c249046181 47 mqp->msg_id = 0;
dflet 3:a8c249046181 48 mqp->fh_len = 0x00;
dflet 3:a8c249046181 49 mqp->vh_len = 0;
dflet 3:a8c249046181 50 mqp->pl_len = 0;
dflet 3:a8c249046181 51 mqp->private_ = 0;
dflet 3:a8c249046181 52 }
dflet 3:a8c249046181 53
dflet 3:a8c249046181 54 void mqp_reset(struct mqtt_packet *mqp)
dflet 3:a8c249046181 55 {
dflet 3:a8c249046181 56 reset_mqp(mqp);
dflet 3:a8c249046181 57 }
dflet 3:a8c249046181 58
dflet 3:a8c249046181 59 void mqp_init(struct mqtt_packet *mqp, uint8_t offset)
dflet 3:a8c249046181 60 {
dflet 3:a8c249046181 61 reset_mqp(mqp);
dflet 3:a8c249046181 62
dflet 3:a8c249046181 63 mqp->offset = offset;
dflet 3:a8c249046181 64 mqp->n_refs = 0x01;
dflet 3:a8c249046181 65 mqp->next = NULL;
dflet 3:a8c249046181 66 }
dflet 3:a8c249046181 67
dflet 3:a8c249046181 68 static int32_t buf_wr_utf8(uint8_t *buf, const struct utf8_string *utf8)
dflet 3:a8c249046181 69 {
dflet 3:a8c249046181 70 uint8_t *ref = buf;
dflet 3:a8c249046181 71
dflet 3:a8c249046181 72 buf += buf_wr_nbo_2B(buf, utf8->length);
dflet 3:a8c249046181 73 buf += buf_wr_nbytes(buf, (uint8_t*)utf8->buffer, utf8->length);
dflet 3:a8c249046181 74
dflet 3:a8c249046181 75 return buf - ref;
dflet 3:a8c249046181 76 }
dflet 3:a8c249046181 77
dflet 3:a8c249046181 78 int32_t mqp_buf_wr_utf8(uint8_t *buf, const struct utf8_string *utf8)
dflet 3:a8c249046181 79 {
dflet 3:a8c249046181 80 return buf_wr_utf8(buf, utf8);
dflet 3:a8c249046181 81 }
dflet 3:a8c249046181 82
dflet 3:a8c249046181 83 #define MAX_REMLEN_BYTES (MAX_FH_LEN - 1)
dflet 3:a8c249046181 84
dflet 3:a8c249046181 85 static int32_t buf_tail_wr_remlen(uint8_t *buf, uint32_t remlen)
dflet 3:a8c249046181 86 {
dflet 3:a8c249046181 87
dflet 3:a8c249046181 88 uint8_t val[MAX_REMLEN_BYTES], i = 0;
dflet 3:a8c249046181 89
dflet 3:a8c249046181 90 do {
dflet 3:a8c249046181 91 val[i] = remlen & 0x7F; /* MOD 128 */
dflet 3:a8c249046181 92 remlen = remlen >> 7; /* DIV 128 */
dflet 3:a8c249046181 93
dflet 3:a8c249046181 94 if(remlen)
dflet 3:a8c249046181 95 val[i] |= 0x80;
dflet 3:a8c249046181 96
dflet 3:a8c249046181 97 i++;
dflet 3:a8c249046181 98
dflet 3:a8c249046181 99 } while(remlen > 0);
dflet 3:a8c249046181 100
dflet 3:a8c249046181 101 buf_wr_nbytes(buf + MAX_REMLEN_BYTES - i, val, i);
dflet 3:a8c249046181 102
dflet 3:a8c249046181 103 return i; /* # bytes written in buf */
dflet 3:a8c249046181 104 }
dflet 3:a8c249046181 105
dflet 3:a8c249046181 106 int32_t mqp_buf_tail_wr_remlen(uint8_t *buf, uint32_t remlen)
dflet 3:a8c249046181 107 {
dflet 3:a8c249046181 108 return buf_tail_wr_remlen(buf, remlen);
dflet 3:a8c249046181 109 }
dflet 3:a8c249046181 110
dflet 3:a8c249046181 111 static int32_t buf_rd_remlen(uint8_t *buf, uint32_t *remlen)
dflet 3:a8c249046181 112 {
dflet 3:a8c249046181 113 uint32_t val = 0, mul = 0;
dflet 3:a8c249046181 114 int32_t i = 0;
dflet 3:a8c249046181 115
dflet 3:a8c249046181 116 do {
dflet 3:a8c249046181 117 val += (buf[i] & 0x7F) << mul;
dflet 3:a8c249046181 118 mul += 7;
dflet 3:a8c249046181 119
dflet 3:a8c249046181 120 } while((buf[i++] & 0x80) &&
dflet 3:a8c249046181 121 (i < MAX_REMLEN_BYTES));
dflet 3:a8c249046181 122
dflet 3:a8c249046181 123 *remlen = val;
dflet 3:a8c249046181 124
dflet 3:a8c249046181 125 /* Return -1 if value was not found */
dflet 3:a8c249046181 126 return (buf[i - 1] & 0x80)? -1 : i;
dflet 3:a8c249046181 127 }
dflet 3:a8c249046181 128
dflet 3:a8c249046181 129 int32_t mqp_buf_rd_remlen(uint8_t *buf, uint32_t *remlen)
dflet 3:a8c249046181 130 {
dflet 3:a8c249046181 131 return buf_rd_remlen(buf, remlen);
dflet 3:a8c249046181 132 }
dflet 3:a8c249046181 133
dflet 3:a8c249046181 134 int32_t mqp_pub_append_topic(struct mqtt_packet *mqp, const struct utf8_string *topic,
dflet 3:a8c249046181 135 uint16_t msg_id)
dflet 3:a8c249046181 136 {
dflet 3:a8c249046181 137 uint8_t *buf = MQP_VHEADER_BUF(mqp), *ref = buf;
dflet 3:a8c249046181 138
dflet 3:a8c249046181 139 if(0 != mqp->vh_len){
dflet 3:a8c249046181 140 Uart_Write((uint8_t*)"Topic has been already added\r\n");
dflet 3:a8c249046181 141 return -1; /* Topic has been already added */
dflet 3:a8c249046181 142 }
dflet 3:a8c249046181 143 if(MQP_FREEBUF_LEN(mqp) < (topic + msg_id? 2 : 0)){
dflet 3:a8c249046181 144 Uart_Write((uint8_t*)"Can't WR topic\r\n");
dflet 3:a8c249046181 145 return MQP_ERR_PKT_LEN; /* Can't WR topic */
dflet 3:a8c249046181 146 }
dflet 3:a8c249046181 147 buf += buf_wr_utf8(buf, topic);
dflet 3:a8c249046181 148
dflet 3:a8c249046181 149 if(0 != msg_id) { /* MSG ID 0 indicates ==> QoS0 */
dflet 3:a8c249046181 150 mqp->msg_id = msg_id;
dflet 3:a8c249046181 151 buf += buf_wr_nbo_2B(buf, mqp->msg_id);
dflet 3:a8c249046181 152 }
dflet 3:a8c249046181 153
dflet 3:a8c249046181 154 mqp->vh_len += buf - ref;
dflet 3:a8c249046181 155
dflet 3:a8c249046181 156 return buf - ref;
dflet 3:a8c249046181 157 }
dflet 3:a8c249046181 158
dflet 3:a8c249046181 159 int32_t mqp_pub_append_data(struct mqtt_packet *mqp, const uint8_t *data_buf,
dflet 3:a8c249046181 160 uint32_t data_len)
dflet 3:a8c249046181 161 {
dflet 3:a8c249046181 162 uint8_t *buf = MQP_PAYLOAD_BUF(mqp) + mqp->pl_len, *ref = buf;
dflet 3:a8c249046181 163
dflet 3:a8c249046181 164 if(0 == mqp->vh_len)
dflet 3:a8c249046181 165 return -1; /* Must include topic first */
dflet 3:a8c249046181 166
dflet 3:a8c249046181 167 if(MQP_FREEBUF_LEN(mqp) < data_len)
dflet 3:a8c249046181 168 return MQP_ERR_PKT_LEN; /* Can't WR data */
dflet 3:a8c249046181 169
dflet 3:a8c249046181 170 /* Including payload info for PUBLISH */
dflet 3:a8c249046181 171 buf += buf_wr_nbytes(buf, data_buf, data_len);
dflet 3:a8c249046181 172 mqp->pl_len += buf - ref;
dflet 3:a8c249046181 173
dflet 3:a8c249046181 174 return buf - ref;
dflet 3:a8c249046181 175 }
dflet 3:a8c249046181 176
dflet 3:a8c249046181 177 static bool proc_vh_msg_id_rx(struct mqtt_packet *mqp_raw)
dflet 3:a8c249046181 178 {
dflet 3:a8c249046181 179 uint8_t *buf = MQP_VHEADER_BUF(mqp_raw);
dflet 3:a8c249046181 180
dflet 3:a8c249046181 181 if(mqp_raw->pl_len < 2)
dflet 3:a8c249046181 182 return false; /* Bytes for MSG ID not available */
dflet 3:a8c249046181 183
dflet 3:a8c249046181 184 buf += buf_rd_nbo_2B(buf, &mqp_raw->msg_id);
dflet 3:a8c249046181 185 mqp_raw->vh_len += 2;
dflet 3:a8c249046181 186 mqp_raw->pl_len -= 2;
dflet 3:a8c249046181 187
dflet 3:a8c249046181 188 return true;
dflet 3:a8c249046181 189 }
dflet 3:a8c249046181 190
dflet 3:a8c249046181 191 bool mqp_proc_vh_msg_id_rx(struct mqtt_packet *mqp_raw)
dflet 3:a8c249046181 192 {
dflet 3:a8c249046181 193 return proc_vh_msg_id_rx(mqp_raw);
dflet 3:a8c249046181 194 }
dflet 3:a8c249046181 195
dflet 3:a8c249046181 196 bool mqp_proc_msg_id_ack_rx(struct mqtt_packet *mqp_raw, bool has_pl)
dflet 3:a8c249046181 197 {
dflet 3:a8c249046181 198 if((false == proc_vh_msg_id_rx(mqp_raw)) ||
dflet 3:a8c249046181 199 (has_pl ^ (!!mqp_raw->pl_len)))
dflet 3:a8c249046181 200 return false;
dflet 3:a8c249046181 201
dflet 3:a8c249046181 202 return true;
dflet 3:a8c249046181 203 }
dflet 3:a8c249046181 204
dflet 3:a8c249046181 205 bool mqp_proc_pub_rx(struct mqtt_packet *mqp_raw)
dflet 3:a8c249046181 206 {
dflet 3:a8c249046181 207 uint8_t *buf = MQP_VHEADER_BUF(mqp_raw), *ref = buf;
dflet 3:a8c249046181 208 uint16_t tmp = 0;
dflet 3:a8c249046181 209
dflet 3:a8c249046181 210 if(mqp_raw->pl_len < (buf - ref + 2)) /* Length Check */
dflet 3:a8c249046181 211 return false; /* No space to hold Topic size */
dflet 3:a8c249046181 212
dflet 3:a8c249046181 213 buf += buf_rd_nbo_2B(buf, &tmp); /* Topic Length */
dflet 3:a8c249046181 214 buf += tmp; /* Topic Content */
dflet 3:a8c249046181 215
dflet 3:a8c249046181 216 if(MQTT_QOS0 != ENUM_QOS(mqp_raw->fh_byte1)) {
dflet 3:a8c249046181 217 if(mqp_raw->pl_len < (buf - ref + 2))
dflet 3:a8c249046181 218 return false; /* No space to hold MSG ID */
dflet 3:a8c249046181 219
dflet 3:a8c249046181 220 buf += buf_rd_nbo_2B(buf, &mqp_raw->msg_id);
dflet 3:a8c249046181 221 }
dflet 3:a8c249046181 222
dflet 3:a8c249046181 223 mqp_raw->vh_len += buf - ref;
dflet 3:a8c249046181 224 mqp_raw->pl_len -= buf - ref;
dflet 3:a8c249046181 225
dflet 3:a8c249046181 226 return true;
dflet 3:a8c249046181 227 }
dflet 3:a8c249046181 228
dflet 3:a8c249046181 229 bool mqp_ack_wlist_append(struct mqtt_ack_wlist *list,
dflet 3:a8c249046181 230 struct mqtt_packet *elem)
dflet 3:a8c249046181 231 {
dflet 3:a8c249046181 232 elem->next = NULL;
dflet 3:a8c249046181 233
dflet 3:a8c249046181 234 if(list->tail) {
dflet 3:a8c249046181 235 list->tail->next = elem;
dflet 3:a8c249046181 236 list->tail = elem;
dflet 3:a8c249046181 237 } else {
dflet 3:a8c249046181 238 list->tail = elem;
dflet 3:a8c249046181 239 list->head = elem;
dflet 3:a8c249046181 240 }
dflet 3:a8c249046181 241
dflet 3:a8c249046181 242 return true;
dflet 3:a8c249046181 243 }
dflet 3:a8c249046181 244
dflet 3:a8c249046181 245 struct mqtt_packet *mqp_ack_wlist_remove(struct mqtt_ack_wlist *list,
dflet 3:a8c249046181 246 uint16_t msg_id)
dflet 3:a8c249046181 247 {
dflet 3:a8c249046181 248 struct mqtt_packet *elem = list->head, *prev = NULL;
dflet 3:a8c249046181 249
dflet 3:a8c249046181 250 while(elem) {
dflet 3:a8c249046181 251 if(msg_id == elem->msg_id) {
dflet 3:a8c249046181 252 if(prev)
dflet 3:a8c249046181 253 prev->next = elem->next;
dflet 3:a8c249046181 254 else
dflet 3:a8c249046181 255 list->head = elem->next;
dflet 3:a8c249046181 256
dflet 3:a8c249046181 257 if(NULL == list->head)
dflet 3:a8c249046181 258 list->tail = NULL;
dflet 3:a8c249046181 259
dflet 3:a8c249046181 260 if(list->tail == elem)
dflet 3:a8c249046181 261 list->tail = prev;
dflet 3:a8c249046181 262
dflet 3:a8c249046181 263 break;
dflet 3:a8c249046181 264 }
dflet 3:a8c249046181 265
dflet 3:a8c249046181 266 prev = elem;
dflet 3:a8c249046181 267 elem = elem->next;
dflet 3:a8c249046181 268 }
dflet 3:a8c249046181 269
dflet 3:a8c249046181 270 return elem;
dflet 3:a8c249046181 271 }
dflet 3:a8c249046181 272
dflet 3:a8c249046181 273 void mqp_ack_wlist_purge(struct mqtt_ack_wlist *list)
dflet 3:a8c249046181 274 {
dflet 3:a8c249046181 275
dflet 3:a8c249046181 276 struct mqtt_packet *elem = list->head;
dflet 3:a8c249046181 277
dflet 3:a8c249046181 278 while(elem) {
dflet 3:a8c249046181 279 struct mqtt_packet *next = elem->next;
dflet 3:a8c249046181 280 free_mqp(elem);
dflet 3:a8c249046181 281 elem = next;
dflet 3:a8c249046181 282 }
dflet 3:a8c249046181 283
dflet 3:a8c249046181 284 list->head = NULL;
dflet 3:a8c249046181 285 list->tail = NULL;
dflet 3:a8c249046181 286
dflet 3:a8c249046181 287 return;
dflet 3:a8c249046181 288 }
dflet 3:a8c249046181 289
dflet 3:a8c249046181 290 void secure_conn_struct_init(struct secure_conn *nw_security)
dflet 3:a8c249046181 291 {
dflet 3:a8c249046181 292 nw_security->method = nw_security->cipher = NULL;
dflet 3:a8c249046181 293 nw_security->files = NULL;
dflet 3:a8c249046181 294 nw_security->n_file = 0;
dflet 3:a8c249046181 295
dflet 3:a8c249046181 296 return;
dflet 3:a8c249046181 297 }
dflet 3:a8c249046181 298
dflet 3:a8c249046181 299 int32_t mqp_prep_fh(struct mqtt_packet *mqp, uint8_t flags)
dflet 3:a8c249046181 300 {
dflet 3:a8c249046181 301
dflet 3:a8c249046181 302 uint32_t remlen = mqp->vh_len + mqp->pl_len;
dflet 3:a8c249046181 303 uint8_t *buf = mqp->buffer + mqp->offset;
dflet 3:a8c249046181 304 uint8_t *ref = buf;
dflet 3:a8c249046181 305
dflet 3:a8c249046181 306 buf -= buf_tail_wr_remlen(buf - MAX_REMLEN_BYTES, remlen);
dflet 3:a8c249046181 307
dflet 3:a8c249046181 308 buf -= 1; /* Make space for FH Byte1 */
dflet 3:a8c249046181 309 mqp->fh_byte1 = *buf = MAKE_FH_BYTE1(mqp->msg_type, flags);
dflet 3:a8c249046181 310
dflet 3:a8c249046181 311 mqp->fh_len = ref - buf;
dflet 3:a8c249046181 312 mqp->offset -= ref - buf;
dflet 3:a8c249046181 313
dflet 3:a8c249046181 314 return ref - buf;
dflet 3:a8c249046181 315 }
dflet 3:a8c249046181 316
dflet 3:a8c249046181 317 /*
dflet 3:a8c249046181 318 Since, the network connection is a TCP socket stream, it is imperative that
dflet 3:a8c249046181 319 adequate checks are put in place to identify a MQTT packet and isolate it
dflet 3:a8c249046181 320 for further processing. The intent of following routine is to read just one
dflet 3:a8c249046181 321 packet from continuous stream and leave rest for the next iteration.
dflet 3:a8c249046181 322 */
dflet 3:a8c249046181 323
dflet 3:a8c249046181 324 #define RET_IF_ERR_IN_NET_RECV(net, buf, len, wait_secs, timed_out, ctx)\
dflet 3:a8c249046181 325 rv = net_ops->recv(net, buf, len, wait_secs, timed_out, ctx); \
dflet 3:a8c249046181 326 if(rv < 1) \
dflet 3:a8c249046181 327 return MQP_ERR_NETWORK;
dflet 3:a8c249046181 328
dflet 3:a8c249046181 329 int32_t mqp_recv(int32_t net, const struct device_net_services *net_ops,
dflet 3:a8c249046181 330 struct mqtt_packet *mqp, uint32_t wait_secs, bool *timed_out,
dflet 3:a8c249046181 331 void *ctx)
dflet 3:a8c249046181 332 {
dflet 3:a8c249046181 333 uint8_t *buf = MQP_FHEADER_BUF(mqp), *ref = buf, fh_len = mqp->fh_len;
dflet 3:a8c249046181 334 uint32_t pl_len = mqp->pl_len, remlen = 0;
dflet 3:a8c249046181 335 int32_t rv;
dflet 3:a8c249046181 336
dflet 3:a8c249046181 337 while(2 > fh_len) {
dflet 3:a8c249046181 338 RET_IF_ERR_IN_NET_RECV(net, buf + fh_len, 1, wait_secs,
dflet 3:a8c249046181 339 timed_out, ctx);
dflet 3:a8c249046181 340
dflet 3:a8c249046181 341 mqp->fh_len = ++fh_len;
dflet 3:a8c249046181 342 }
dflet 3:a8c249046181 343
dflet 3:a8c249046181 344 while(buf[fh_len - 1] & 0x80) {
dflet 3:a8c249046181 345 if(fh_len > MAX_FH_LEN)
dflet 3:a8c249046181 346 return MQP_ERR_NOT_DEF;/* Shouldn't happen */
dflet 3:a8c249046181 347
dflet 3:a8c249046181 348 RET_IF_ERR_IN_NET_RECV(net, buf + fh_len, 1, wait_secs,
dflet 3:a8c249046181 349 timed_out, ctx);
dflet 3:a8c249046181 350
dflet 3:a8c249046181 351 mqp->fh_len = ++fh_len;
dflet 3:a8c249046181 352 }
dflet 3:a8c249046181 353
dflet 3:a8c249046181 354 mqp_buf_rd_remlen(buf + 1, &remlen);
dflet 3:a8c249046181 355 if(mqp->maxlen < (remlen + fh_len))
dflet 3:a8c249046181 356 return MQP_ERR_PKT_LEN; /* Inadequate free buffer */
dflet 3:a8c249046181 357
dflet 3:a8c249046181 358 buf += fh_len; /* Try to read all data that follows FH */
dflet 3:a8c249046181 359 while(pl_len < remlen) {
dflet 3:a8c249046181 360 RET_IF_ERR_IN_NET_RECV(net, buf + pl_len, remlen - pl_len,
dflet 3:a8c249046181 361 wait_secs, timed_out, ctx);
dflet 3:a8c249046181 362
dflet 3:a8c249046181 363 mqp->pl_len = pl_len += rv;
dflet 3:a8c249046181 364 }
dflet 3:a8c249046181 365
dflet 3:a8c249046181 366 /* Set up MQTT Packet for received data from broker */
dflet 3:a8c249046181 367 buf_wr_nbytes(MQP_FHEADER_BUF(mqp), ref, fh_len);
dflet 3:a8c249046181 368 mqp->fh_byte1 = *ref;
dflet 3:a8c249046181 369 mqp->msg_type = MSG_TYPE(*ref);
dflet 3:a8c249046181 370
dflet 3:a8c249046181 371 return fh_len + remlen;
dflet 3:a8c249046181 372 }
dflet 3:a8c249046181 373
dflet 3:a8c249046181 374 /*----------------------------------------------------------------------------
dflet 3:a8c249046181 375 * QoS2 PUB RX Message handling mechanism and associated house-keeping
dflet 3:a8c249046181 376 *--------------------------------------------------------------------------*/
dflet 3:a8c249046181 377 void qos2_pub_cq_reset(struct pub_qos2_cq *cq)
dflet 3:a8c249046181 378 {
dflet 3:a8c249046181 379
dflet 3:a8c249046181 380 // memset(cq->id_vec, 0, sizeof(cq->id_vec));
dflet 3:a8c249046181 381 buf_set((uint8_t*)cq->id_vec, 0, sizeof(cq->id_vec));
dflet 3:a8c249046181 382 cq->n_free = MAX_PUBREL_INFLT;
dflet 3:a8c249046181 383 cq->rd_idx = 0;
dflet 3:a8c249046181 384 cq->wr_idx = 0;
dflet 3:a8c249046181 385
dflet 3:a8c249046181 386 return;
dflet 3:a8c249046181 387 }
dflet 3:a8c249046181 388
dflet 3:a8c249046181 389 bool qos2_pub_cq_logup(struct pub_qos2_cq *cq, uint16_t msg_id)
dflet 3:a8c249046181 390 {
dflet 3:a8c249046181 391 if(0 != cq->n_free) {
dflet 3:a8c249046181 392 cq->id_vec[cq->wr_idx++] = msg_id;
dflet 3:a8c249046181 393 cq->wr_idx &= MAX_PUBREL_INFLT - 1;
dflet 3:a8c249046181 394 cq->n_free--;
dflet 3:a8c249046181 395 return true;
dflet 3:a8c249046181 396 }
dflet 3:a8c249046181 397
dflet 3:a8c249046181 398 /* Must ensure through an out-of-band arrangement that a remote doesn't
dflet 3:a8c249046181 399 push more than MAX_PUBREL_INFLT in-flight QOS2 PUB packets to local.
dflet 3:a8c249046181 400 If it still happens that the local receives more in-flight messages,
dflet 3:a8c249046181 401 then it has no option but to close the network connection.
dflet 3:a8c249046181 402
dflet 3:a8c249046181 403 Closing of network connection is left to invoker to of this service.
dflet 3:a8c249046181 404 */
dflet 3:a8c249046181 405
dflet 3:a8c249046181 406 return false;
dflet 3:a8c249046181 407 }
dflet 3:a8c249046181 408
dflet 3:a8c249046181 409 bool qos2_pub_cq_unlog(struct pub_qos2_cq *cq, uint16_t msg_id)
dflet 3:a8c249046181 410 {
dflet 3:a8c249046181 411 /* Simple implementation. Should be good for embedded system */
dflet 3:a8c249046181 412 if(cq->n_free < MAX_PUBREL_INFLT) {
dflet 3:a8c249046181 413 /* Follow-up messages for QOS2 PUB must be transacted in the
dflet 3:a8c249046181 414 same order as the initial sequence of QOS2 PUB dispatches.
dflet 3:a8c249046181 415 Therefore, checking the first entry should be OK
dflet 3:a8c249046181 416 */
dflet 3:a8c249046181 417 if(msg_id == cq->id_vec[cq->rd_idx++]) {
dflet 3:a8c249046181 418 cq->rd_idx &= MAX_PUBREL_INFLT - 1;
dflet 3:a8c249046181 419 cq->n_free++;
dflet 3:a8c249046181 420 return true;
dflet 3:a8c249046181 421 }
dflet 3:a8c249046181 422 }
dflet 3:a8c249046181 423
dflet 3:a8c249046181 424 return false;
dflet 3:a8c249046181 425 }
dflet 3:a8c249046181 426
dflet 3:a8c249046181 427 bool qos2_pub_cq_check(struct pub_qos2_cq *cq, uint16_t msg_id)
dflet 3:a8c249046181 428 {
dflet 3:a8c249046181 429 uint8_t rd_idx = cq->rd_idx;
dflet 3:a8c249046181 430 uint8_t n_free = cq->n_free;
dflet 3:a8c249046181 431 uint8_t i = 0;
dflet 3:a8c249046181 432
dflet 3:a8c249046181 433 /* Go through the vector to see if packet ID is still active */
dflet 3:a8c249046181 434 for(i = 0; i < (MAX_PUBREL_INFLT - n_free); i++) {
dflet 3:a8c249046181 435 if(msg_id == cq->id_vec[rd_idx++])
dflet 3:a8c249046181 436 return true;
dflet 3:a8c249046181 437
dflet 3:a8c249046181 438 rd_idx &= MAX_PUBREL_INFLT - 1;
dflet 3:a8c249046181 439 }
dflet 3:a8c249046181 440
dflet 3:a8c249046181 441 return false;
dflet 3:a8c249046181 442 }
dflet 3:a8c249046181 443
dflet 3:a8c249046181 444 /*----------------------------------------------------------------------------
dflet 3:a8c249046181 445 * Client Context related details and associated house-keeping
dflet 3:a8c249046181 446 *--------------------------------------------------------------------------*/
dflet 3:a8c249046181 447 void cl_ctx_reset(struct client_ctx *cl_ctx)
dflet 3:a8c249046181 448 {
dflet 3:a8c249046181 449 cl_ctx->usr = NULL;
dflet 3:a8c249046181 450 cl_ctx->net = -1;
dflet 3:a8c249046181 451 cl_ctx->ip_length = 16;
dflet 3:a8c249046181 452
dflet 3:a8c249046181 453 cl_ctx->timeout = 0;
dflet 3:a8c249046181 454 cl_ctx->ka_secs = 0;
dflet 3:a8c249046181 455
dflet 3:a8c249046181 456 cl_ctx->flags = 0;
dflet 3:a8c249046181 457
dflet 3:a8c249046181 458 return;
dflet 3:a8c249046181 459 }
dflet 3:a8c249046181 460
dflet 3:a8c249046181 461 void cl_ctx_timeout_insert(struct client_ctx **head, struct client_ctx *elem)
dflet 3:a8c249046181 462 {
dflet 3:a8c249046181 463
dflet 3:a8c249046181 464 struct client_ctx *curr, *prev = NULL;
dflet 3:a8c249046181 465
dflet 3:a8c249046181 466 if(NULL == *head) {
dflet 3:a8c249046181 467 *head = elem;
dflet 3:a8c249046181 468 return;
dflet 3:a8c249046181 469 }
dflet 3:a8c249046181 470
dflet 3:a8c249046181 471 curr = *head;
dflet 3:a8c249046181 472 while(curr) {
dflet 3:a8c249046181 473 if(elem->timeout < curr->timeout) {
dflet 3:a8c249046181 474 if(NULL == prev) {
dflet 3:a8c249046181 475 elem->next = *head;
dflet 3:a8c249046181 476 *head = elem;
dflet 3:a8c249046181 477 } else {
dflet 3:a8c249046181 478 prev->next = elem;
dflet 3:a8c249046181 479 elem->next = curr;
dflet 3:a8c249046181 480 }
dflet 3:a8c249046181 481
dflet 3:a8c249046181 482 break;
dflet 3:a8c249046181 483 }
dflet 3:a8c249046181 484
dflet 3:a8c249046181 485 prev = curr;
dflet 3:a8c249046181 486 curr = curr->next;
dflet 3:a8c249046181 487 }
dflet 3:a8c249046181 488
dflet 3:a8c249046181 489 if(NULL == curr)
dflet 3:a8c249046181 490 prev->next = elem;
dflet 3:a8c249046181 491 }
dflet 3:a8c249046181 492
dflet 3:a8c249046181 493 void cl_ctx_remove(struct client_ctx **head, struct client_ctx *elem)
dflet 3:a8c249046181 494 {
dflet 3:a8c249046181 495 struct client_ctx *curr = *head, *prev = NULL;
dflet 3:a8c249046181 496
dflet 3:a8c249046181 497 while(curr) {
dflet 3:a8c249046181 498 if(curr == elem) {
dflet 3:a8c249046181 499 if(NULL == prev) {
dflet 3:a8c249046181 500 *head = elem->next;
dflet 3:a8c249046181 501 prev = *head;
dflet 3:a8c249046181 502 } else {
dflet 3:a8c249046181 503 prev->next = elem->next;
dflet 3:a8c249046181 504 }
dflet 3:a8c249046181 505
dflet 3:a8c249046181 506 elem->next = NULL;
dflet 3:a8c249046181 507 break;
dflet 3:a8c249046181 508 }
dflet 3:a8c249046181 509
dflet 3:a8c249046181 510 prev = curr;
dflet 3:a8c249046181 511 curr = curr->next;
dflet 3:a8c249046181 512 }
dflet 3:a8c249046181 513 }
dflet 3:a8c249046181 514
dflet 3:a8c249046181 515 void cl_ctx_timeout_update(struct client_ctx *cl_ctx, uint32_t now_secs)
dflet 3:a8c249046181 516 {
dflet 3:a8c249046181 517 uint32_t timeout = KA_TIMEOUT_NONE;
dflet 3:a8c249046181 518 uint16_t ka_secs = cl_ctx->ka_secs;
dflet 3:a8c249046181 519
dflet 3:a8c249046181 520 if((0 == ka_secs) && (KA_TIMEOUT_NONE == cl_ctx->timeout))
dflet 3:a8c249046181 521 return;
dflet 3:a8c249046181 522
dflet 3:a8c249046181 523 if(0 != ka_secs)
dflet 3:a8c249046181 524 timeout = now_secs + ka_secs;
dflet 3:a8c249046181 525
dflet 3:a8c249046181 526 cl_ctx->timeout = timeout;
dflet 3:a8c249046181 527
dflet 3:a8c249046181 528 return;
dflet 3:a8c249046181 529 }
dflet 3:a8c249046181 530
dflet 3:a8c249046181 531 }//namespace mbed_mqtt
dflet 3:a8c249046181 532