The (alpha of the) official Exosite library, CoAP version.

NOTE: This mirror repository may be out of date, check the main repo for changes. If there are any remind me to update this mirror.

This is an unstable alpha of the Official Exosite library, there are known issues with the port to this platform. You probably shouldn't use this library yet if you just want to get things done.

This version uses CoAP for the application protocol.

Committer:
Patrick Barrett
Date:
Wed Jan 07 14:20:56 2015 -0600
Revision:
29:004c318e63fa
Parent:
27:786cdb9c3605
added retry on network error

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Patrick Barrett 0:c7393ae16c16 1 /*****************************************************************************
Patrick Barrett 0:c7393ae16c16 2 *
Patrick Barrett 0:c7393ae16c16 3 * exosite.c - Exosite Activator Library
Patrick Barrett 0:c7393ae16c16 4 * Copyright (C) 2015 Exosite LLC
Patrick Barrett 0:c7393ae16c16 5 *
Patrick Barrett 0:c7393ae16c16 6 * Redistribution and use in source and binary forms, with or without
Patrick Barrett 0:c7393ae16c16 7 * modification, are permitted provided that the following conditions
Patrick Barrett 0:c7393ae16c16 8 * are met:
Patrick Barrett 0:c7393ae16c16 9 *
Patrick Barrett 0:c7393ae16c16 10 * Redistributions of source code must retain the above copyright
Patrick Barrett 0:c7393ae16c16 11 * notice, this list of conditions and the following disclaimer.
Patrick Barrett 0:c7393ae16c16 12 *
Patrick Barrett 0:c7393ae16c16 13 * Redistributions in binary form must reproduce the above copyright
Patrick Barrett 0:c7393ae16c16 14 * notice, this list of conditions and the following disclaimer in the
Patrick Barrett 0:c7393ae16c16 15 * documentation and/or other materials provided with the
Patrick Barrett 0:c7393ae16c16 16 * distribution.
Patrick Barrett 0:c7393ae16c16 17 *
Patrick Barrett 0:c7393ae16c16 18 * Neither the name of Texas Instruments Incorporated nor the names of
Patrick Barrett 0:c7393ae16c16 19 * its contributors may be used to endorse or promote products derived
Patrick Barrett 0:c7393ae16c16 20 * from this software without specific prior written permission.
Patrick Barrett 0:c7393ae16c16 21 *
Patrick Barrett 0:c7393ae16c16 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Patrick Barrett 0:c7393ae16c16 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Patrick Barrett 0:c7393ae16c16 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Patrick Barrett 0:c7393ae16c16 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Patrick Barrett 0:c7393ae16c16 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Patrick Barrett 0:c7393ae16c16 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Patrick Barrett 0:c7393ae16c16 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Patrick Barrett 0:c7393ae16c16 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Patrick Barrett 0:c7393ae16c16 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Patrick Barrett 0:c7393ae16c16 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Patrick Barrett 0:c7393ae16c16 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Patrick Barrett 0:c7393ae16c16 33 *
Patrick Barrett 0:c7393ae16c16 34 *****************************************************************************/
Patrick Barrett 0:c7393ae16c16 35 #include "exosite_pal.h"
Patrick Barrett 0:c7393ae16c16 36 #include "exosite.h"
Patrick Barrett 0:c7393ae16c16 37 #include "coap.h"
Patrick Barrett 0:c7393ae16c16 38
Patrick Barrett 0:c7393ae16c16 39 #include <stdlib.h>
Patrick Barrett 0:c7393ae16c16 40 #include <stdbool.h>
Patrick Barrett 0:c7393ae16c16 41 #include <time.h>
Patrick Barrett 0:c7393ae16c16 42 #include <string.h>
Patrick Barrett 0:c7393ae16c16 43 #include <ctype.h>
Patrick Barrett 0:c7393ae16c16 44
Patrick Barrett 0:c7393ae16c16 45 // Internal Functions
Patrick Barrett 12:68513d2aa2df 46
Patrick Barrett 12:68513d2aa2df 47 static void exo_process_waiting_datagrams(exo_op *op, uint8_t count);
Patrick Barrett 12:68513d2aa2df 48 static void exo_process_active_ops(exo_op *op, uint8_t count);
Patrick Barrett 0:c7393ae16c16 49 exo_error exo_build_msg_activate(coap_pdu *pdu, const char *vendor, const char *model, const char *serial_number);
Patrick Barrett 0:c7393ae16c16 50 exo_error exo_build_msg_read(coap_pdu *pdu, const char *alias);
Patrick Barrett 0:c7393ae16c16 51 exo_error exo_build_msg_observe(coap_pdu *pdu, const char *alias);
Patrick Barrett 0:c7393ae16c16 52 exo_error exo_build_msg_write(coap_pdu *pdu, const char *alias, const char *value);
Patrick Barrett 0:c7393ae16c16 53 exo_error exo_build_msg_rst(coap_pdu *pdu, const uint16_t mid, const uint64_t token, const uint8_t tkl);
Patrick Barrett 0:c7393ae16c16 54 exo_error exo_build_msg_ack(coap_pdu *pdu, const uint16_t mid);
Patrick Barrett 0:c7393ae16c16 55 uint8_t exosite_validate_cik(char *cik);
Patrick Barrett 0:c7393ae16c16 56
Patrick Barrett 0:c7393ae16c16 57 // Local Variables
Patrick Barrett 0:c7393ae16c16 58 static char cik[CIK_LENGTH + 1];
Patrick Barrett 0:c7393ae16c16 59 static const char *vendor;
Patrick Barrett 0:c7393ae16c16 60 static const char *model;
Patrick Barrett 0:c7393ae16c16 61 static const char *serial;
Patrick Barrett 0:c7393ae16c16 62 static uint16_t message_id_counter;
Patrick Barrett 0:c7393ae16c16 63 static exo_device_state device_state = EXO_STATE_UNINITIALIZED;
Patrick Barrett 0:c7393ae16c16 64
Patrick Barrett 23:e94087cd483d 65 // Internal Constants
Patrick Barrett 23:e94087cd483d 66 static const int MINIMUM_DATAGRAM_SIZE = 576; // RFC791: all hosts must accept minimum of 576 octets
Patrick Barrett 23:e94087cd483d 67
Patrick Barrett 0:c7393ae16c16 68 /*!
Patrick Barrett 0:c7393ae16c16 69 * \brief Initializes the Exosite library
Patrick Barrett 0:c7393ae16c16 70 *
Patrick Barrett 0:c7393ae16c16 71 * This **MUST** be called before any other exosite library calls are called.
Patrick Barrett 0:c7393ae16c16 72 *
Patrick Barrett 0:c7393ae16c16 73 * \param[in] *vendor Pointer to string containing the vendor name
Patrick Barrett 0:c7393ae16c16 74 * \param[in] *model Pointer to string containing the model name
Patrick Barrett 0:c7393ae16c16 75 * \param[in] *serial Pointer to string containing the serial number
Patrick Barrett 0:c7393ae16c16 76 *
Patrick Barrett 0:c7393ae16c16 77 * \return EXO_ERROR, EXO_OK on success, else error code
Patrick Barrett 0:c7393ae16c16 78 */
Patrick Barrett 0:c7393ae16c16 79 exo_error exo_init(const char *vendor_in, const char *model_in, const char *serial_in)
Patrick Barrett 0:c7393ae16c16 80 {
Patrick Barrett 0:c7393ae16c16 81 device_state = EXO_STATE_UNINITIALIZED;
Patrick Barrett 0:c7393ae16c16 82
Patrick Barrett 0:c7393ae16c16 83 if (exopal_init() != 0) {
Patrick Barrett 0:c7393ae16c16 84 return EXO_FATAL_ERROR_PAL;
Patrick Barrett 0:c7393ae16c16 85 }
Patrick Barrett 0:c7393ae16c16 86
Patrick Barrett 0:c7393ae16c16 87 srand(time(NULL));
Patrick Barrett 0:c7393ae16c16 88 message_id_counter = rand();
Patrick Barrett 0:c7393ae16c16 89
Patrick Barrett 0:c7393ae16c16 90 serial = serial_in;
Patrick Barrett 0:c7393ae16c16 91 vendor = vendor_in;
Patrick Barrett 0:c7393ae16c16 92 model = model_in;
Patrick Barrett 0:c7393ae16c16 93
Patrick Barrett 0:c7393ae16c16 94 if (exopal_retrieve_cik(cik) > 1){
Patrick Barrett 0:c7393ae16c16 95 return EXO_FATAL_ERROR_PAL;
Patrick Barrett 0:c7393ae16c16 96 } else {
Patrick Barrett 0:c7393ae16c16 97 cik[40] = 0;
Patrick Barrett 0:c7393ae16c16 98 }
Patrick Barrett 0:c7393ae16c16 99
Patrick Barrett 0:c7393ae16c16 100 if (exopal_udp_sock() != 0) {
Patrick Barrett 0:c7393ae16c16 101 return EXO_FATAL_ERROR_PAL;
Patrick Barrett 0:c7393ae16c16 102 }
Patrick Barrett 0:c7393ae16c16 103
Patrick Barrett 0:c7393ae16c16 104 device_state = EXO_STATE_INITIALIZED;
Patrick Barrett 0:c7393ae16c16 105
Patrick Barrett 0:c7393ae16c16 106 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 107 }
Patrick Barrett 0:c7393ae16c16 108
Patrick Barrett 0:c7393ae16c16 109 /*!
Patrick Barrett 0:c7393ae16c16 110 * \brief Queues a Write to the Exosite One Platform
Patrick Barrett 0:c7393ae16c16 111 *
Patrick Barrett 0:c7393ae16c16 112 * Queues a request to write to a dataport.
Patrick Barrett 0:c7393ae16c16 113 *
Patrick Barrett 0:c7393ae16c16 114 * \param[in] *alias Alias of dataport to write to, pointer must remain
Patrick Barrett 0:c7393ae16c16 115 * valid until the request has been sent.
Patrick Barrett 0:c7393ae16c16 116 * \param[in] callback Function pointer to call on success
Patrick Barrett 0:c7393ae16c16 117 *
Patrick Barrett 0:c7393ae16c16 118 * \return EXO_ERROR, EXO_OK on success or error code
Patrick Barrett 0:c7393ae16c16 119 *
Patrick Barrett 0:c7393ae16c16 120 */
Patrick Barrett 0:c7393ae16c16 121
Patrick Barrett 0:c7393ae16c16 122 void exo_write(exo_op *op, const char * alias, const char * value)
Patrick Barrett 0:c7393ae16c16 123 {
Patrick Barrett 0:c7393ae16c16 124 op->type = EXO_WRITE;
Patrick Barrett 0:c7393ae16c16 125 op->state = EXO_REQUEST_NEW;
Patrick Barrett 0:c7393ae16c16 126 op->alias = alias;
Patrick Barrett 0:c7393ae16c16 127 op->value = (char *)value; // this is kinda dirty, I know
Patrick Barrett 0:c7393ae16c16 128 op->value_max = 0;
Patrick Barrett 0:c7393ae16c16 129 op->mid = 0;
Patrick Barrett 0:c7393ae16c16 130 }
Patrick Barrett 0:c7393ae16c16 131
Patrick Barrett 0:c7393ae16c16 132 /*!
Patrick Barrett 0:c7393ae16c16 133 * \brief Queues a Read from the Exosite One Platform
Patrick Barrett 0:c7393ae16c16 134 *
Patrick Barrett 0:c7393ae16c16 135 * Queues a request to read a dataport. If the request is successful, the
Patrick Barrett 0:c7393ae16c16 136 * provided callback will be called with a single parameter, a pointer to the
Patrick Barrett 0:c7393ae16c16 137 * result as a C string.
Patrick Barrett 0:c7393ae16c16 138 *
Patrick Barrett 0:c7393ae16c16 139 * \param[in] *alias Alias of dataport to read from, pointer must remain
Patrick Barrett 0:c7393ae16c16 140 * valid until the request has been sent.
Patrick Barrett 0:c7393ae16c16 141 * \param[in] callback Function pointer to call on success
Patrick Barrett 0:c7393ae16c16 142 *
Patrick Barrett 0:c7393ae16c16 143 * \return EXO_ERROR, EXO_OK on success or error code
Patrick Barrett 0:c7393ae16c16 144 *
Patrick Barrett 0:c7393ae16c16 145 */
Patrick Barrett 0:c7393ae16c16 146 void exo_read(exo_op *op, const char * alias, char * value, const size_t value_max)
Patrick Barrett 0:c7393ae16c16 147 {
Patrick Barrett 0:c7393ae16c16 148 op->type = EXO_READ;
Patrick Barrett 0:c7393ae16c16 149 op->state = EXO_REQUEST_NEW;
Patrick Barrett 0:c7393ae16c16 150 op->alias = alias;
Patrick Barrett 0:c7393ae16c16 151 op->value = value;
Patrick Barrett 0:c7393ae16c16 152 op->value_max = value_max;
Patrick Barrett 0:c7393ae16c16 153 op->mid = 0;
Patrick Barrett 0:c7393ae16c16 154 }
Patrick Barrett 0:c7393ae16c16 155
Patrick Barrett 0:c7393ae16c16 156 /*!
Patrick Barrett 0:c7393ae16c16 157 * \brief Subscribes to a Dataport on the Exosite One Platform
Patrick Barrett 0:c7393ae16c16 158 *
Patrick Barrett 0:c7393ae16c16 159 * Begins a subscription to a dataport The callback is called any time the
Patrick Barrett 0:c7393ae16c16 160 * value is updated as well as when the subscription is started.
Patrick Barrett 0:c7393ae16c16 161 *
Patrick Barrett 0:c7393ae16c16 162 * \param[in] alias Alias of dataport to read from
Patrick Barrett 0:c7393ae16c16 163 * \param[in] callback Function pointer to call on change
Patrick Barrett 0:c7393ae16c16 164 *
Patrick Barrett 0:c7393ae16c16 165 * \return EXO_ERROR, EXO_OK on success or error code
Patrick Barrett 0:c7393ae16c16 166 *
Patrick Barrett 0:c7393ae16c16 167 */
Patrick Barrett 0:c7393ae16c16 168 void exo_subscribe(exo_op *op, const char * alias, char * value, const size_t value_max)
Patrick Barrett 0:c7393ae16c16 169 {
Patrick Barrett 0:c7393ae16c16 170 op->type = EXO_SUBSCRIBE;
Patrick Barrett 0:c7393ae16c16 171 op->state = EXO_REQUEST_NEW;
Patrick Barrett 0:c7393ae16c16 172 op->alias = alias;
Patrick Barrett 0:c7393ae16c16 173 op->value = value;
Patrick Barrett 0:c7393ae16c16 174 op->value_max = value_max;
Patrick Barrett 0:c7393ae16c16 175 op->mid = 0;
Patrick Barrett 0:c7393ae16c16 176 }
Patrick Barrett 0:c7393ae16c16 177
Patrick Barrett 11:08bae8fb9824 178 /*!
Patrick Barrett 11:08bae8fb9824 179 * \brief Activates the Device on the Platform
Patrick Barrett 11:08bae8fb9824 180 *
Patrick Barrett 11:08bae8fb9824 181 * Queues an activation request. Usually only used internally.
Patrick Barrett 11:08bae8fb9824 182 *
Patrick Barrett 11:08bae8fb9824 183 */
Patrick Barrett 11:08bae8fb9824 184 void exo_activate(exo_op *op)
Patrick Barrett 11:08bae8fb9824 185 {
Patrick Barrett 11:08bae8fb9824 186 op->type = EXO_ACTIVATE;
Patrick Barrett 11:08bae8fb9824 187 op->state = EXO_REQUEST_NEW;
Patrick Barrett 11:08bae8fb9824 188 op->alias = NULL;
Patrick Barrett 11:08bae8fb9824 189 op->value = NULL;
Patrick Barrett 11:08bae8fb9824 190 op->value_max = 0;
Patrick Barrett 11:08bae8fb9824 191 op->mid = 0;
Patrick Barrett 11:08bae8fb9824 192 }
Patrick Barrett 11:08bae8fb9824 193
Patrick Barrett 0:c7393ae16c16 194 void exo_op_init(exo_op *op)
Patrick Barrett 0:c7393ae16c16 195 {
Patrick Barrett 0:c7393ae16c16 196 op->type = EXO_NULL;
Patrick Barrett 0:c7393ae16c16 197 op->state = EXO_REQUEST_NULL;
Patrick Barrett 0:c7393ae16c16 198 op->alias = NULL;
Patrick Barrett 0:c7393ae16c16 199 op->value = NULL;
Patrick Barrett 0:c7393ae16c16 200 op->value_max = 0;
Patrick Barrett 0:c7393ae16c16 201 op->mid = 0;
Patrick Barrett 10:76deeaebfafb 202 op->obs_seq = 0;
Patrick Barrett 20:e98884244926 203 op->tkl = 0;
Patrick Barrett 20:e98884244926 204 op->token = 0;
Patrick Barrett 13:df08a86dc06d 205 op->timeout = 0;
Patrick Barrett 29:004c318e63fa 206 op->retries = 0;
Patrick Barrett 0:c7393ae16c16 207 }
Patrick Barrett 0:c7393ae16c16 208
Patrick Barrett 0:c7393ae16c16 209 void exo_op_done(exo_op *op)
Patrick Barrett 0:c7393ae16c16 210 {
Patrick Barrett 0:c7393ae16c16 211 if (exo_is_op_subscribe(op)) {
Patrick Barrett 0:c7393ae16c16 212 op->state = EXO_REQUEST_SUBSCRIBED;
Patrick Barrett 0:c7393ae16c16 213 } else {
Patrick Barrett 0:c7393ae16c16 214 exo_op_init(op);
Patrick Barrett 0:c7393ae16c16 215 }
Patrick Barrett 0:c7393ae16c16 216 }
Patrick Barrett 0:c7393ae16c16 217
Patrick Barrett 0:c7393ae16c16 218 uint8_t exo_is_op_valid(exo_op *op)
Patrick Barrett 0:c7393ae16c16 219 {
Patrick Barrett 0:c7393ae16c16 220 return op->type != EXO_NULL;
Patrick Barrett 0:c7393ae16c16 221 }
Patrick Barrett 0:c7393ae16c16 222
Patrick Barrett 0:c7393ae16c16 223 uint8_t exo_is_op_success(exo_op *op)
Patrick Barrett 0:c7393ae16c16 224 {
Patrick Barrett 0:c7393ae16c16 225 return op->state == EXO_REQUEST_SUCCESS;
Patrick Barrett 0:c7393ae16c16 226 }
Patrick Barrett 0:c7393ae16c16 227
Patrick Barrett 0:c7393ae16c16 228 uint8_t exo_is_op_finished(exo_op *op)
Patrick Barrett 0:c7393ae16c16 229 {
Patrick Barrett 0:c7393ae16c16 230 return op->state == EXO_REQUEST_SUCCESS || op->state == EXO_REQUEST_ERROR;
Patrick Barrett 0:c7393ae16c16 231 }
Patrick Barrett 0:c7393ae16c16 232
Patrick Barrett 0:c7393ae16c16 233 uint8_t exo_is_op_read(exo_op *op)
Patrick Barrett 0:c7393ae16c16 234 {
Patrick Barrett 0:c7393ae16c16 235 return op->type == EXO_READ;
Patrick Barrett 0:c7393ae16c16 236 }
Patrick Barrett 0:c7393ae16c16 237
Patrick Barrett 0:c7393ae16c16 238 uint8_t exo_is_op_subscribe(exo_op *op)
Patrick Barrett 0:c7393ae16c16 239 {
Patrick Barrett 0:c7393ae16c16 240 return op->type == EXO_SUBSCRIBE;
Patrick Barrett 0:c7393ae16c16 241 }
Patrick Barrett 0:c7393ae16c16 242
Patrick Barrett 0:c7393ae16c16 243 uint8_t exo_is_op_write(exo_op *op)
Patrick Barrett 0:c7393ae16c16 244 {
Patrick Barrett 0:c7393ae16c16 245 return op->type == EXO_WRITE;
Patrick Barrett 0:c7393ae16c16 246 }
Patrick Barrett 0:c7393ae16c16 247
Patrick Barrett 0:c7393ae16c16 248
Patrick Barrett 0:c7393ae16c16 249 /*!
Patrick Barrett 0:c7393ae16c16 250 * \brief Performs queued operations with the Exosite One Platform
Patrick Barrett 0:c7393ae16c16 251 *
Patrick Barrett 0:c7393ae16c16 252 * Queues a request to read a dataport from the Exosite One Platform. If the
Patrick Barrett 0:c7393ae16c16 253 * request is successful the provided callback will be called with a single
Patrick Barrett 0:c7393ae16c16 254 * parameter, a pointer to the result as a C string.
Patrick Barrett 0:c7393ae16c16 255 *
Patrick Barrett 0:c7393ae16c16 256 * \param[in] alias Alias of dataport to read from
Patrick Barrett 0:c7393ae16c16 257 * \param[in] callback Function pointer to call on success
Patrick Barrett 0:c7393ae16c16 258 *
Patrick Barrett 0:c7393ae16c16 259 * \return EXO_STATE, EXO_OK on success or error code
Patrick Barrett 0:c7393ae16c16 260 *
Patrick Barrett 0:c7393ae16c16 261 */
Patrick Barrett 0:c7393ae16c16 262 exo_state exo_operate(exo_op *op, uint8_t count)
Patrick Barrett 0:c7393ae16c16 263 {
Patrick Barrett 12:68513d2aa2df 264 int i;
Patrick Barrett 12:68513d2aa2df 265
Patrick Barrett 12:68513d2aa2df 266 switch (device_state){
Patrick Barrett 12:68513d2aa2df 267 case EXO_STATE_UNINITIALIZED:
Patrick Barrett 12:68513d2aa2df 268 return EXO_ERROR;
Patrick Barrett 12:68513d2aa2df 269 case EXO_STATE_INITIALIZED:
Patrick Barrett 12:68513d2aa2df 270 case EXO_STATE_BAD_CIK:
Patrick Barrett 18:c463fb80d81d 271 if (op[0].state == EXO_REQUEST_NULL || op[0].timeout < exopal_get_time())
Patrick Barrett 12:68513d2aa2df 272 exo_activate(&op[0]);
Patrick Barrett 12:68513d2aa2df 273 case EXO_STATE_GOOD:
Patrick Barrett 12:68513d2aa2df 274 break;
Patrick Barrett 12:68513d2aa2df 275 }
Patrick Barrett 12:68513d2aa2df 276
Patrick Barrett 12:68513d2aa2df 277 exo_process_waiting_datagrams(op, count);
Patrick Barrett 12:68513d2aa2df 278 exo_process_active_ops(op, count);
Patrick Barrett 12:68513d2aa2df 279
Patrick Barrett 12:68513d2aa2df 280 for (i = 0; i < count; i++) {
Patrick Barrett 12:68513d2aa2df 281 if (op[i].state == EXO_REQUEST_NEW)
Patrick Barrett 12:68513d2aa2df 282 return EXO_BUSY;
Patrick Barrett 12:68513d2aa2df 283 }
Patrick Barrett 12:68513d2aa2df 284
Patrick Barrett 12:68513d2aa2df 285 for (i = 0; i < count; i++) {
Patrick Barrett 12:68513d2aa2df 286 if (op[i].state == EXO_REQUEST_PENDING)
Patrick Barrett 12:68513d2aa2df 287 return EXO_WAITING;
Patrick Barrett 12:68513d2aa2df 288 }
Patrick Barrett 12:68513d2aa2df 289
Patrick Barrett 12:68513d2aa2df 290 return EXO_IDLE;
Patrick Barrett 12:68513d2aa2df 291 }
Patrick Barrett 12:68513d2aa2df 292
Patrick Barrett 12:68513d2aa2df 293 // Internal Functions
Patrick Barrett 12:68513d2aa2df 294
Patrick Barrett 12:68513d2aa2df 295 static void exo_process_waiting_datagrams(exo_op *op, uint8_t count)
Patrick Barrett 12:68513d2aa2df 296 {
Patrick Barrett 23:e94087cd483d 297 uint8_t buf[MINIMUM_DATAGRAM_SIZE];
Patrick Barrett 0:c7393ae16c16 298 coap_pdu pdu;
Patrick Barrett 24:cfbd25fc62c4 299 coap_option opt;
Patrick Barrett 0:c7393ae16c16 300 coap_payload payload;
Patrick Barrett 0:c7393ae16c16 301 int i;
Patrick Barrett 0:c7393ae16c16 302
Patrick Barrett 0:c7393ae16c16 303 pdu.buf = buf;
Patrick Barrett 23:e94087cd483d 304 pdu.max = MINIMUM_DATAGRAM_SIZE;
Patrick Barrett 0:c7393ae16c16 305 pdu.len = 0;
Patrick Barrett 0:c7393ae16c16 306
Patrick Barrett 0:c7393ae16c16 307 // receive a UDP packet if one or more waiting
Patrick Barrett 0:c7393ae16c16 308 while (exopal_udp_recv(pdu.buf, pdu.max, &pdu.len) == 0) {
Patrick Barrett 0:c7393ae16c16 309 if (coap_validate_pkt(&pdu) != CE_NONE)
Patrick Barrett 0:c7393ae16c16 310 continue; //Invalid Packet, Ignore
Patrick Barrett 0:c7393ae16c16 311
Patrick Barrett 0:c7393ae16c16 312 for (i = 0; i < count; i++) {
Patrick Barrett 17:661d4a5b7c1b 313 if (coap_get_type(&pdu) == CT_CON || coap_get_type(&pdu) == CT_NON) {
Patrick Barrett 19:323801b9c74e 314 if (op[i].state == EXO_REQUEST_SUBSCRIBED && coap_get_token(&pdu) == op[i].token) {
Patrick Barrett 19:323801b9c74e 315 if (coap_get_code(&pdu) == CC_CONTENT) {
Patrick Barrett 19:323801b9c74e 316 uint32_t new_seq = 0;
Patrick Barrett 19:323801b9c74e 317 opt = coap_get_option_by_num(&pdu, CON_OBSERVE, 0);
Patrick Barrett 19:323801b9c74e 318 for (int j = 0; j < opt.len; j++) {
Patrick Barrett 19:323801b9c74e 319 new_seq = (new_seq << (8*j)) | opt.val[j];
Patrick Barrett 19:323801b9c74e 320 }
Patrick Barrett 13:df08a86dc06d 321
Patrick Barrett 19:323801b9c74e 322 payload = coap_get_payload(&pdu);
Patrick Barrett 19:323801b9c74e 323 if (payload.len == 0) {
Patrick Barrett 19:323801b9c74e 324 op[i].value[0] = '\0';
Patrick Barrett 19:323801b9c74e 325 } else if (payload.len+1 > op[i].value_max || op[i].value == 0) {
Patrick Barrett 19:323801b9c74e 326 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 19:323801b9c74e 327 } else{
Patrick Barrett 19:323801b9c74e 328 memcpy(op[i].value, payload.val, payload.len);
Patrick Barrett 19:323801b9c74e 329 op[i].value[payload.len] = 0;
Patrick Barrett 19:323801b9c74e 330 op[i].mid = coap_get_mid(&pdu);
Patrick Barrett 19:323801b9c74e 331 // TODO: User proper logic to ensure it's a new value not a different, but old one.
Patrick Barrett 19:323801b9c74e 332 if (op[i].obs_seq != new_seq) {
Patrick Barrett 19:323801b9c74e 333 op[i].state = EXO_REQUEST_SUB_ACK_NEW;
Patrick Barrett 19:323801b9c74e 334 op[i].obs_seq = new_seq;
Patrick Barrett 19:323801b9c74e 335 } else {
Patrick Barrett 19:323801b9c74e 336 op[i].state = EXO_REQUEST_SUB_ACK;
Patrick Barrett 19:323801b9c74e 337 }
Patrick Barrett 24:cfbd25fc62c4 338
Patrick Barrett 24:cfbd25fc62c4 339 opt = coap_get_option_by_num(&pdu, CON_MAX_AGE, 0);
Patrick Barrett 24:cfbd25fc62c4 340 uint8_t max_age = 120; // default, 2 minutes, see RFC4787 Sec 4.3
Patrick Barrett 24:cfbd25fc62c4 341 if (opt.num !=0 && opt.len == 1){ // if has Max-Age option, use it
Patrick Barrett 24:cfbd25fc62c4 342 max_age = opt.val[0];
Patrick Barrett 24:cfbd25fc62c4 343 }
Patrick Barrett 24:cfbd25fc62c4 344
Patrick Barrett 24:cfbd25fc62c4 345 // Set timeout between Max-Age to Max-Age + ACK_RANDOM_FACTOR (CoAP Defined)
Patrick Barrett 24:cfbd25fc62c4 346 op[i].timeout = exopal_get_time() + (max_age * 1000000)
Patrick Barrett 24:cfbd25fc62c4 347 + (((uint64_t)rand() % 1500000));
Patrick Barrett 19:323801b9c74e 348 }
Patrick Barrett 19:323801b9c74e 349 } else if (coap_get_code_class(&pdu) != 2) {
Patrick Barrett 13:df08a86dc06d 350 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 11:08bae8fb9824 351 }
Patrick Barrett 13:df08a86dc06d 352 break;
Patrick Barrett 0:c7393ae16c16 353 }
Patrick Barrett 17:661d4a5b7c1b 354 } else if (coap_get_type(&pdu) == CT_ACK) {
Patrick Barrett 13:df08a86dc06d 355 if (op[i].state == EXO_REQUEST_PENDING && op[i].mid == coap_get_mid(&pdu)) {
Patrick Barrett 13:df08a86dc06d 356 if (coap_get_code_class(&pdu) == 2) {
Patrick Barrett 17:661d4a5b7c1b 357 switch (op[i].type) {
Patrick Barrett 17:661d4a5b7c1b 358 case EXO_WRITE:
Patrick Barrett 17:661d4a5b7c1b 359 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 17:661d4a5b7c1b 360 break;
Patrick Barrett 17:661d4a5b7c1b 361 case EXO_READ:
Patrick Barrett 17:661d4a5b7c1b 362 payload = coap_get_payload(&pdu);
Patrick Barrett 17:661d4a5b7c1b 363 if (payload.len == 0) {
Patrick Barrett 17:661d4a5b7c1b 364 op[i].value[0] = '\0';
Patrick Barrett 17:661d4a5b7c1b 365 } else if (payload.len+1 > op[i].value_max || op[i].value == 0) {
Patrick Barrett 17:661d4a5b7c1b 366 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 17:661d4a5b7c1b 367 } else{
Patrick Barrett 17:661d4a5b7c1b 368 memcpy(op[i].value, payload.val, payload.len);
Patrick Barrett 17:661d4a5b7c1b 369 op[i].value[payload.len] = 0;
Patrick Barrett 17:661d4a5b7c1b 370 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 17:661d4a5b7c1b 371 }
Patrick Barrett 17:661d4a5b7c1b 372 break;
Patrick Barrett 17:661d4a5b7c1b 373 case EXO_SUBSCRIBE:
Patrick Barrett 17:661d4a5b7c1b 374 payload = coap_get_payload(&pdu);
Patrick Barrett 17:661d4a5b7c1b 375 if (payload.len == 0) {
Patrick Barrett 17:661d4a5b7c1b 376 op[i].value[0] = '\0';
Patrick Barrett 17:661d4a5b7c1b 377 } else if (payload.len+1 > op[i].value_max || op[i].value == 0) {
Patrick Barrett 17:661d4a5b7c1b 378 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 17:661d4a5b7c1b 379 } else{
Patrick Barrett 17:661d4a5b7c1b 380 memcpy(op[i].value, payload.val, payload.len);
Patrick Barrett 17:661d4a5b7c1b 381 op[i].value[payload.len] = 0;
Patrick Barrett 17:661d4a5b7c1b 382 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 24:cfbd25fc62c4 383
Patrick Barrett 24:cfbd25fc62c4 384 opt = coap_get_option_by_num(&pdu, CON_MAX_AGE, 0);
Patrick Barrett 24:cfbd25fc62c4 385 uint8_t max_age = 120; // default, 2 minutes, see RFC4787 Sec 4.3
Patrick Barrett 24:cfbd25fc62c4 386 if (opt.num !=0 && opt.len == 1){ // if has Max-Age option, use it
Patrick Barrett 24:cfbd25fc62c4 387 max_age = opt.val[0];
Patrick Barrett 24:cfbd25fc62c4 388 }
Patrick Barrett 24:cfbd25fc62c4 389
Patrick Barrett 27:786cdb9c3605 390 opt = coap_get_option_by_num(&pdu, CON_OBSERVE, 0);
Patrick Barrett 27:786cdb9c3605 391 for (int j = 0; j < opt.len; j++) {
Patrick Barrett 27:786cdb9c3605 392 op[i].obs_seq = (op[i].obs_seq << (8*j)) | opt.val[j];
Patrick Barrett 27:786cdb9c3605 393 }
Patrick Barrett 27:786cdb9c3605 394
Patrick Barrett 24:cfbd25fc62c4 395 // Set timeout between Max-Age to Max-Age + ACK_RANDOM_FACTOR (CoAP Defined)
Patrick Barrett 24:cfbd25fc62c4 396 op[i].timeout = exopal_get_time() + (max_age * 1000000)
Patrick Barrett 24:cfbd25fc62c4 397 + (((uint64_t)rand() % 1500000));
Patrick Barrett 17:661d4a5b7c1b 398 }
Patrick Barrett 17:661d4a5b7c1b 399 break;
Patrick Barrett 17:661d4a5b7c1b 400 case EXO_ACTIVATE:
Patrick Barrett 17:661d4a5b7c1b 401 payload = coap_get_payload(&pdu);
Patrick Barrett 17:661d4a5b7c1b 402 if (payload.len == CIK_LENGTH) {
Patrick Barrett 17:661d4a5b7c1b 403 memcpy(cik, payload.val, CIK_LENGTH);
Patrick Barrett 17:661d4a5b7c1b 404 cik[CIK_LENGTH] = 0;
Patrick Barrett 17:661d4a5b7c1b 405 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 17:661d4a5b7c1b 406 exopal_store_cik(cik);
Patrick Barrett 17:661d4a5b7c1b 407 device_state = EXO_STATE_GOOD;
Patrick Barrett 17:661d4a5b7c1b 408 } else {
Patrick Barrett 17:661d4a5b7c1b 409 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 17:661d4a5b7c1b 410 }
Patrick Barrett 17:661d4a5b7c1b 411
Patrick Barrett 17:661d4a5b7c1b 412 // We're done with this op now.
Patrick Barrett 17:661d4a5b7c1b 413 exo_op_init(&op[i]);
Patrick Barrett 17:661d4a5b7c1b 414 break;
Patrick Barrett 17:661d4a5b7c1b 415 case EXO_NULL: // pending null request? shouldn't be possible
Patrick Barrett 17:661d4a5b7c1b 416 continue;
Patrick Barrett 13:df08a86dc06d 417 }
Patrick Barrett 13:df08a86dc06d 418 } else {
Patrick Barrett 13:df08a86dc06d 419 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 17:661d4a5b7c1b 420
Patrick Barrett 17:661d4a5b7c1b 421 if (coap_get_code(&pdu) == CC_UNAUTHORIZED){
Patrick Barrett 18:c463fb80d81d 422 //device_state = EXO_STATE_BAD_CIK;
Patrick Barrett 18:c463fb80d81d 423
Patrick Barrett 18:c463fb80d81d 424 if (op[0].type == EXO_NULL || op[0].timeout < exopal_get_time())
Patrick Barrett 18:c463fb80d81d 425 exo_activate(&op[0]);
Patrick Barrett 17:661d4a5b7c1b 426 } else if (coap_get_code(&pdu) == CC_NOT_FOUND) {
Patrick Barrett 17:661d4a5b7c1b 427 device_state = EXO_STATE_GOOD;
Patrick Barrett 17:661d4a5b7c1b 428 }
Patrick Barrett 13:df08a86dc06d 429 }
Patrick Barrett 0:c7393ae16c16 430
Patrick Barrett 17:661d4a5b7c1b 431 break;
Patrick Barrett 17:661d4a5b7c1b 432 }
Patrick Barrett 17:661d4a5b7c1b 433
Patrick Barrett 17:661d4a5b7c1b 434 } else if (coap_get_type(&pdu) == CT_RST) {
Patrick Barrett 17:661d4a5b7c1b 435 if ((op[i].state == EXO_REQUEST_PENDING || op[i].state == EXO_REQUEST_SUBSCRIBED) &&
Patrick Barrett 17:661d4a5b7c1b 436 (op[i].mid == coap_get_mid(&pdu) && op[i].token == coap_get_token(&pdu))){
Patrick Barrett 17:661d4a5b7c1b 437 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 13:df08a86dc06d 438 break;
Patrick Barrett 0:c7393ae16c16 439 }
Patrick Barrett 0:c7393ae16c16 440 }
Patrick Barrett 0:c7393ae16c16 441 }
Patrick Barrett 0:c7393ae16c16 442
Patrick Barrett 13:df08a86dc06d 443 // if the above loop ends normally we don't recognize message, reply RST
Patrick Barrett 0:c7393ae16c16 444 if (i == count){
Patrick Barrett 0:c7393ae16c16 445 if (coap_get_type(&pdu) == CT_CON) {
Patrick Barrett 0:c7393ae16c16 446 // this can't fail
Patrick Barrett 0:c7393ae16c16 447 exo_build_msg_rst(&pdu, coap_get_mid(&pdu), coap_get_token(&pdu), coap_get_tkl(&pdu));
Patrick Barrett 0:c7393ae16c16 448
Patrick Barrett 0:c7393ae16c16 449 // best effort, don't bother checking if it failed, nothing we can do it
Patrick Barrett 0:c7393ae16c16 450 // it did anyway
Patrick Barrett 0:c7393ae16c16 451 exopal_udp_send(pdu.buf, pdu.len);
Patrick Barrett 0:c7393ae16c16 452 }
Patrick Barrett 0:c7393ae16c16 453
Patrick Barrett 0:c7393ae16c16 454 break;
Patrick Barrett 0:c7393ae16c16 455 }
Patrick Barrett 0:c7393ae16c16 456 }
Patrick Barrett 12:68513d2aa2df 457 }
Patrick Barrett 0:c7393ae16c16 458
Patrick Barrett 12:68513d2aa2df 459 // process all ops that are in an active state
Patrick Barrett 12:68513d2aa2df 460 static void exo_process_active_ops(exo_op *op, uint8_t count)
Patrick Barrett 12:68513d2aa2df 461 {
Patrick Barrett 23:e94087cd483d 462 uint8_t buf[MINIMUM_DATAGRAM_SIZE];
Patrick Barrett 12:68513d2aa2df 463 coap_pdu pdu;
Patrick Barrett 12:68513d2aa2df 464 int i;
Patrick Barrett 12:68513d2aa2df 465 uint64_t now = exopal_get_time();
Patrick Barrett 12:68513d2aa2df 466
Patrick Barrett 12:68513d2aa2df 467 pdu.buf = buf;
Patrick Barrett 23:e94087cd483d 468 pdu.max = MINIMUM_DATAGRAM_SIZE;
Patrick Barrett 12:68513d2aa2df 469 pdu.len = 0;
Patrick Barrett 12:68513d2aa2df 470
Patrick Barrett 0:c7393ae16c16 471 for (i = 0; i < count; i++) {
Patrick Barrett 0:c7393ae16c16 472 switch (op[i].state) {
Patrick Barrett 0:c7393ae16c16 473 case EXO_REQUEST_NEW:
Patrick Barrett 0:c7393ae16c16 474 // Build and Send Request
Patrick Barrett 0:c7393ae16c16 475 switch (op[i].type) {
Patrick Barrett 0:c7393ae16c16 476 case EXO_READ:
Patrick Barrett 0:c7393ae16c16 477 exo_build_msg_read(&pdu, op[i].alias);
Patrick Barrett 0:c7393ae16c16 478 break;
Patrick Barrett 0:c7393ae16c16 479 case EXO_SUBSCRIBE:
Patrick Barrett 0:c7393ae16c16 480 exo_build_msg_observe(&pdu, op[i].alias);
Patrick Barrett 0:c7393ae16c16 481 break;
Patrick Barrett 0:c7393ae16c16 482 case EXO_WRITE:
Patrick Barrett 0:c7393ae16c16 483 exo_build_msg_write(&pdu, op[i].alias, op[i].value);
Patrick Barrett 0:c7393ae16c16 484 break;
Patrick Barrett 11:08bae8fb9824 485 case EXO_ACTIVATE:
Patrick Barrett 11:08bae8fb9824 486 exo_build_msg_activate(&pdu, vendor, model, serial);
Patrick Barrett 11:08bae8fb9824 487 break;
Patrick Barrett 0:c7393ae16c16 488 default:
Patrick Barrett 0:c7393ae16c16 489 op[i].type = EXO_NULL;
Patrick Barrett 0:c7393ae16c16 490 continue;
Patrick Barrett 0:c7393ae16c16 491 }
Patrick Barrett 0:c7393ae16c16 492
Patrick Barrett 0:c7393ae16c16 493 if (exopal_udp_send(pdu.buf, pdu.len) == 0) {
Patrick Barrett 0:c7393ae16c16 494 op[i].state = EXO_REQUEST_PENDING;
Patrick Barrett 0:c7393ae16c16 495 op[i].timeout = exopal_get_time() + 4000000;
Patrick Barrett 0:c7393ae16c16 496 op[i].mid = coap_get_mid(&pdu);
Patrick Barrett 0:c7393ae16c16 497 op[i].token = coap_get_token(&pdu);
Patrick Barrett 0:c7393ae16c16 498 }
Patrick Barrett 0:c7393ae16c16 499
Patrick Barrett 0:c7393ae16c16 500 break;
Patrick Barrett 10:76deeaebfafb 501 case EXO_REQUEST_SUBSCRIBED:
Patrick Barrett 0:c7393ae16c16 502 case EXO_REQUEST_PENDING:
Patrick Barrett 0:c7393ae16c16 503 // check if pending requests have reached timeout
Patrick Barrett 0:c7393ae16c16 504 if (op[i].timeout <= now){
Patrick Barrett 0:c7393ae16c16 505 switch (op[i].type) {
Patrick Barrett 0:c7393ae16c16 506 case EXO_READ:
Patrick Barrett 0:c7393ae16c16 507 case EXO_WRITE:
Patrick Barrett 29:004c318e63fa 508 case EXO_ACTIVATE:
Patrick Barrett 29:004c318e63fa 509 if (op[i].retries < COAP_MAX_RETRANSMIT){
Patrick Barrett 29:004c318e63fa 510 switch (op[i].type) {
Patrick Barrett 29:004c318e63fa 511 case EXO_READ:
Patrick Barrett 29:004c318e63fa 512 exo_build_msg_read(&pdu, op[i].alias);
Patrick Barrett 29:004c318e63fa 513 break;
Patrick Barrett 29:004c318e63fa 514 case EXO_WRITE:
Patrick Barrett 29:004c318e63fa 515 exo_build_msg_write(&pdu, op[i].alias, op[i].value);
Patrick Barrett 29:004c318e63fa 516 break;
Patrick Barrett 29:004c318e63fa 517 case EXO_ACTIVATE:
Patrick Barrett 29:004c318e63fa 518 exo_build_msg_activate(&pdu, vendor, model, serial);
Patrick Barrett 29:004c318e63fa 519 break;
Patrick Barrett 29:004c318e63fa 520 default:
Patrick Barrett 29:004c318e63fa 521 break;
Patrick Barrett 29:004c318e63fa 522 }
Patrick Barrett 29:004c318e63fa 523
Patrick Barrett 29:004c318e63fa 524 // reuse old mid and token
Patrick Barrett 29:004c318e63fa 525 coap_set_mid(&pdu, op[i].mid);
Patrick Barrett 29:004c318e63fa 526 coap_set_token(&pdu, op[i].token, op[i].tkl);
Patrick Barrett 29:004c318e63fa 527
Patrick Barrett 29:004c318e63fa 528 if (exopal_udp_send(pdu.buf, pdu.len) == 0) {
Patrick Barrett 29:004c318e63fa 529 op[i].retries++;
Patrick Barrett 29:004c318e63fa 530 op[i].timeout = exopal_get_time() + (op[i].retries * COAP_PROBING_RATE * 1000000)
Patrick Barrett 29:004c318e63fa 531 + (((uint64_t)rand() % 1500000));
Patrick Barrett 29:004c318e63fa 532 }
Patrick Barrett 29:004c318e63fa 533 } else {
Patrick Barrett 29:004c318e63fa 534 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 29:004c318e63fa 535 }
Patrick Barrett 0:c7393ae16c16 536 break;
Patrick Barrett 0:c7393ae16c16 537 case EXO_SUBSCRIBE:
Patrick Barrett 0:c7393ae16c16 538 // force a new observe request
Patrick Barrett 0:c7393ae16c16 539 op[i].state = EXO_REQUEST_NEW;
Patrick Barrett 0:c7393ae16c16 540 break;
Patrick Barrett 0:c7393ae16c16 541 default:
Patrick Barrett 0:c7393ae16c16 542 break;
Patrick Barrett 0:c7393ae16c16 543 }
Patrick Barrett 0:c7393ae16c16 544 }
Patrick Barrett 0:c7393ae16c16 545 break;
Patrick Barrett 0:c7393ae16c16 546 case EXO_REQUEST_SUB_ACK_NEW:
Patrick Barrett 0:c7393ae16c16 547 case EXO_REQUEST_SUB_ACK:
Patrick Barrett 0:c7393ae16c16 548 // send ack for observe notification
Patrick Barrett 0:c7393ae16c16 549 exo_build_msg_ack(&pdu, coap_get_mid(&pdu));
Patrick Barrett 0:c7393ae16c16 550
Patrick Barrett 0:c7393ae16c16 551 if (exopal_udp_send(pdu.buf, pdu.len) == 0) {
Patrick Barrett 0:c7393ae16c16 552 if (op[i].state == EXO_REQUEST_SUB_ACK)
Patrick Barrett 0:c7393ae16c16 553 op[i].state = EXO_REQUEST_SUBSCRIBED;
Patrick Barrett 0:c7393ae16c16 554 else if (op[i].state == EXO_REQUEST_SUB_ACK_NEW)
Patrick Barrett 0:c7393ae16c16 555 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 0:c7393ae16c16 556 }
Patrick Barrett 0:c7393ae16c16 557 break;
Patrick Barrett 0:c7393ae16c16 558 default:
Patrick Barrett 0:c7393ae16c16 559 break;
Patrick Barrett 0:c7393ae16c16 560 }
Patrick Barrett 0:c7393ae16c16 561 }
Patrick Barrett 0:c7393ae16c16 562 }
Patrick Barrett 0:c7393ae16c16 563
Patrick Barrett 0:c7393ae16c16 564
Patrick Barrett 0:c7393ae16c16 565 exo_error exo_build_msg_activate(coap_pdu *pdu, const char *vendor, const char *model, const char *serial_number)
Patrick Barrett 0:c7393ae16c16 566 {
Patrick Barrett 0:c7393ae16c16 567 coap_error ret;
Patrick Barrett 0:c7393ae16c16 568 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 569 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 570 ret |= coap_set_type(pdu, CT_CON);
Patrick Barrett 0:c7393ae16c16 571 ret |= coap_set_code(pdu, CC_POST);
Patrick Barrett 0:c7393ae16c16 572 ret |= coap_set_mid(pdu, message_id_counter++);
Patrick Barrett 0:c7393ae16c16 573 ret |= coap_set_token(pdu, rand(), 2);
Patrick Barrett 0:c7393ae16c16 574 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"provision", 9);
Patrick Barrett 0:c7393ae16c16 575 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"activate", 8);
Patrick Barrett 0:c7393ae16c16 576 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)vendor, strlen(vendor));
Patrick Barrett 0:c7393ae16c16 577 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)model, strlen(model));
Patrick Barrett 0:c7393ae16c16 578 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)serial_number, strlen(serial_number));
Patrick Barrett 0:c7393ae16c16 579
Patrick Barrett 0:c7393ae16c16 580 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 581 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 582
Patrick Barrett 0:c7393ae16c16 583 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 584 }
Patrick Barrett 0:c7393ae16c16 585
Patrick Barrett 0:c7393ae16c16 586 exo_error exo_build_msg_read(coap_pdu *pdu, const char *alias)
Patrick Barrett 0:c7393ae16c16 587 {
Patrick Barrett 0:c7393ae16c16 588 coap_error ret;
Patrick Barrett 0:c7393ae16c16 589 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 590 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 591 ret |= coap_set_type(pdu, CT_CON);
Patrick Barrett 0:c7393ae16c16 592 ret |= coap_set_code(pdu, CC_GET);
Patrick Barrett 0:c7393ae16c16 593 ret |= coap_set_mid(pdu, message_id_counter++);
Patrick Barrett 0:c7393ae16c16 594 ret |= coap_set_token(pdu, rand(), 2);
Patrick Barrett 0:c7393ae16c16 595 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"1a", 2);
Patrick Barrett 0:c7393ae16c16 596 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)alias, strlen(alias));
Patrick Barrett 0:c7393ae16c16 597 ret |= coap_add_option(pdu, CON_URI_QUERY, (uint8_t*)cik, 40);
Patrick Barrett 0:c7393ae16c16 598
Patrick Barrett 0:c7393ae16c16 599 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 600 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 601
Patrick Barrett 0:c7393ae16c16 602 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 603 }
Patrick Barrett 0:c7393ae16c16 604
Patrick Barrett 0:c7393ae16c16 605 exo_error exo_build_msg_observe(coap_pdu *pdu, const char *alias)
Patrick Barrett 0:c7393ae16c16 606 {
Patrick Barrett 0:c7393ae16c16 607 uint8_t obs_opt = 0;
Patrick Barrett 0:c7393ae16c16 608 coap_error ret;
Patrick Barrett 0:c7393ae16c16 609 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 610 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 611 ret |= coap_set_type(pdu, CT_CON);
Patrick Barrett 0:c7393ae16c16 612 ret |= coap_set_code(pdu, CC_GET);
Patrick Barrett 0:c7393ae16c16 613 ret |= coap_set_mid(pdu, message_id_counter++);
Patrick Barrett 0:c7393ae16c16 614 ret |= coap_set_token(pdu, rand(), 2);
Patrick Barrett 0:c7393ae16c16 615 ret |= coap_add_option(pdu, CON_OBSERVE, &obs_opt, 1);
Patrick Barrett 0:c7393ae16c16 616 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"1a", 2);
Patrick Barrett 0:c7393ae16c16 617 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)alias, strlen(alias));
Patrick Barrett 0:c7393ae16c16 618 ret |= coap_add_option(pdu, CON_URI_QUERY, (uint8_t*)cik, 40);
Patrick Barrett 0:c7393ae16c16 619
Patrick Barrett 0:c7393ae16c16 620 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 621 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 622
Patrick Barrett 0:c7393ae16c16 623 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 624 }
Patrick Barrett 0:c7393ae16c16 625
Patrick Barrett 0:c7393ae16c16 626 exo_error exo_build_msg_write(coap_pdu *pdu, const char *alias, const char *value)
Patrick Barrett 0:c7393ae16c16 627 {
Patrick Barrett 0:c7393ae16c16 628 coap_error ret;
Patrick Barrett 0:c7393ae16c16 629 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 630 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 631 ret |= coap_set_type(pdu, CT_CON);
Patrick Barrett 0:c7393ae16c16 632 ret |= coap_set_code(pdu, CC_POST);
Patrick Barrett 0:c7393ae16c16 633 ret |= coap_set_mid(pdu, message_id_counter++);
Patrick Barrett 0:c7393ae16c16 634 ret |= coap_set_token(pdu, rand(), 2);
Patrick Barrett 0:c7393ae16c16 635 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"1a", 2);
Patrick Barrett 0:c7393ae16c16 636 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)alias, strlen(alias));
Patrick Barrett 0:c7393ae16c16 637 ret |= coap_add_option(pdu, CON_URI_QUERY, (uint8_t*)cik, 40);
Patrick Barrett 0:c7393ae16c16 638 ret |= coap_set_payload(pdu, (uint8_t *)value, strlen(value));
Patrick Barrett 0:c7393ae16c16 639
Patrick Barrett 0:c7393ae16c16 640 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 641 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 642
Patrick Barrett 0:c7393ae16c16 643 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 644 }
Patrick Barrett 0:c7393ae16c16 645
Patrick Barrett 0:c7393ae16c16 646 exo_error exo_build_msg_rst(coap_pdu *pdu, const uint16_t mid, const uint64_t token, const uint8_t tkl)
Patrick Barrett 0:c7393ae16c16 647 {
Patrick Barrett 0:c7393ae16c16 648 coap_error ret;
Patrick Barrett 0:c7393ae16c16 649 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 650 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 651 ret |= coap_set_type(pdu, CT_RST);
Patrick Barrett 0:c7393ae16c16 652 ret |= coap_set_code(pdu, CC_EMPTY);
Patrick Barrett 0:c7393ae16c16 653 ret |= coap_set_mid(pdu, mid);
Patrick Barrett 0:c7393ae16c16 654 ret |= coap_set_token(pdu, token, tkl);
Patrick Barrett 0:c7393ae16c16 655
Patrick Barrett 0:c7393ae16c16 656 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 657 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 658
Patrick Barrett 0:c7393ae16c16 659 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 660 }
Patrick Barrett 0:c7393ae16c16 661
Patrick Barrett 0:c7393ae16c16 662 exo_error exo_build_msg_ack(coap_pdu *pdu, const uint16_t mid)
Patrick Barrett 0:c7393ae16c16 663 {
Patrick Barrett 0:c7393ae16c16 664 coap_error ret;
Patrick Barrett 0:c7393ae16c16 665 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 666 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 667 ret |= coap_set_type(pdu, CT_ACK);
Patrick Barrett 0:c7393ae16c16 668 ret |= coap_set_code(pdu, CC_EMPTY);
Patrick Barrett 0:c7393ae16c16 669 ret |= coap_set_mid(pdu, mid);
Patrick Barrett 0:c7393ae16c16 670
Patrick Barrett 0:c7393ae16c16 671 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 672 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 673
Patrick Barrett 0:c7393ae16c16 674 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 675 }
Patrick Barrett 0:c7393ae16c16 676
Patrick Barrett 11:08bae8fb9824 677 exo_error exo_do_activate()
Patrick Barrett 0:c7393ae16c16 678 {
Patrick Barrett 11:08bae8fb9824 679 exo_op op;
Patrick Barrett 11:08bae8fb9824 680
Patrick Barrett 11:08bae8fb9824 681 exo_op_init(&op);
Patrick Barrett 11:08bae8fb9824 682
Patrick Barrett 0:c7393ae16c16 683
Patrick Barrett 11:08bae8fb9824 684 return EXO_OK;
Patrick Barrett 11:08bae8fb9824 685 }
Patrick Barrett 11:08bae8fb9824 686
Patrick Barrett 11:08bae8fb9824 687 uint8_t exo_util_is_ascii_hex(const char *str, size_t len)
Patrick Barrett 11:08bae8fb9824 688 {
Patrick Barrett 11:08bae8fb9824 689 size_t i;
Patrick Barrett 11:08bae8fb9824 690
Patrick Barrett 11:08bae8fb9824 691 for (i = 0; i < len; i++) {
Patrick Barrett 11:08bae8fb9824 692 if (!((str[i] >= 'a' && str[i] <= 'f') ||
Patrick Barrett 11:08bae8fb9824 693 (str[i] >= '0' && str[i] <= '9'))) {
Patrick Barrett 0:c7393ae16c16 694 return 1;
Patrick Barrett 0:c7393ae16c16 695 }
Patrick Barrett 0:c7393ae16c16 696 }
Patrick Barrett 0:c7393ae16c16 697
Patrick Barrett 0:c7393ae16c16 698 return 0;
Patrick Barrett 0:c7393ae16c16 699 }
Patrick Barrett 0:c7393ae16c16 700