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:
Fri Jan 02 13:51:25 2015 -0600
Revision:
14:fafaa95f7ad8
Parent:
13:df08a86dc06d
Child:
15:5ab3e0c7413f
fix unauthorized write error handling

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 0:c7393ae16c16 65 /*!
Patrick Barrett 0:c7393ae16c16 66 * \brief Initializes the Exosite library
Patrick Barrett 0:c7393ae16c16 67 *
Patrick Barrett 0:c7393ae16c16 68 * This **MUST** be called before any other exosite library calls are called.
Patrick Barrett 0:c7393ae16c16 69 *
Patrick Barrett 0:c7393ae16c16 70 * \param[in] *vendor Pointer to string containing the vendor name
Patrick Barrett 0:c7393ae16c16 71 * \param[in] *model Pointer to string containing the model name
Patrick Barrett 0:c7393ae16c16 72 * \param[in] *serial Pointer to string containing the serial number
Patrick Barrett 0:c7393ae16c16 73 *
Patrick Barrett 0:c7393ae16c16 74 * \return EXO_ERROR, EXO_OK on success, else error code
Patrick Barrett 0:c7393ae16c16 75 */
Patrick Barrett 0:c7393ae16c16 76 exo_error exo_init(const char *vendor_in, const char *model_in, const char *serial_in)
Patrick Barrett 0:c7393ae16c16 77 {
Patrick Barrett 0:c7393ae16c16 78 device_state = EXO_STATE_UNINITIALIZED;
Patrick Barrett 0:c7393ae16c16 79
Patrick Barrett 0:c7393ae16c16 80 if (exopal_init() != 0) {
Patrick Barrett 0:c7393ae16c16 81 return EXO_FATAL_ERROR_PAL;
Patrick Barrett 0:c7393ae16c16 82 }
Patrick Barrett 0:c7393ae16c16 83
Patrick Barrett 0:c7393ae16c16 84 srand(time(NULL));
Patrick Barrett 0:c7393ae16c16 85 message_id_counter = rand();
Patrick Barrett 0:c7393ae16c16 86
Patrick Barrett 0:c7393ae16c16 87 serial = serial_in;
Patrick Barrett 0:c7393ae16c16 88 vendor = vendor_in;
Patrick Barrett 0:c7393ae16c16 89 model = model_in;
Patrick Barrett 0:c7393ae16c16 90
Patrick Barrett 0:c7393ae16c16 91 if (exopal_retrieve_cik(cik) > 1){
Patrick Barrett 0:c7393ae16c16 92 return EXO_FATAL_ERROR_PAL;
Patrick Barrett 0:c7393ae16c16 93 } else {
Patrick Barrett 0:c7393ae16c16 94 cik[40] = 0;
Patrick Barrett 0:c7393ae16c16 95 }
Patrick Barrett 0:c7393ae16c16 96
Patrick Barrett 0:c7393ae16c16 97 if (exopal_udp_sock() != 0) {
Patrick Barrett 0:c7393ae16c16 98 return EXO_FATAL_ERROR_PAL;
Patrick Barrett 0:c7393ae16c16 99 }
Patrick Barrett 0:c7393ae16c16 100
Patrick Barrett 0:c7393ae16c16 101 device_state = EXO_STATE_INITIALIZED;
Patrick Barrett 0:c7393ae16c16 102
Patrick Barrett 0:c7393ae16c16 103 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 104 }
Patrick Barrett 0:c7393ae16c16 105
Patrick Barrett 0:c7393ae16c16 106 /*!
Patrick Barrett 0:c7393ae16c16 107 * \brief Queues a Write to the Exosite One Platform
Patrick Barrett 0:c7393ae16c16 108 *
Patrick Barrett 0:c7393ae16c16 109 * Queues a request to write to a dataport.
Patrick Barrett 0:c7393ae16c16 110 *
Patrick Barrett 0:c7393ae16c16 111 * \param[in] *alias Alias of dataport to write to, pointer must remain
Patrick Barrett 0:c7393ae16c16 112 * valid until the request has been sent.
Patrick Barrett 0:c7393ae16c16 113 * \param[in] callback Function pointer to call on success
Patrick Barrett 0:c7393ae16c16 114 *
Patrick Barrett 0:c7393ae16c16 115 * \return EXO_ERROR, EXO_OK on success or error code
Patrick Barrett 0:c7393ae16c16 116 *
Patrick Barrett 0:c7393ae16c16 117 */
Patrick Barrett 0:c7393ae16c16 118
Patrick Barrett 0:c7393ae16c16 119 void exo_write(exo_op *op, const char * alias, const char * value)
Patrick Barrett 0:c7393ae16c16 120 {
Patrick Barrett 0:c7393ae16c16 121 op->type = EXO_WRITE;
Patrick Barrett 0:c7393ae16c16 122 op->state = EXO_REQUEST_NEW;
Patrick Barrett 0:c7393ae16c16 123 op->alias = alias;
Patrick Barrett 0:c7393ae16c16 124 op->value = (char *)value; // this is kinda dirty, I know
Patrick Barrett 0:c7393ae16c16 125 op->value_max = 0;
Patrick Barrett 0:c7393ae16c16 126 op->mid = 0;
Patrick Barrett 0:c7393ae16c16 127 }
Patrick Barrett 0:c7393ae16c16 128
Patrick Barrett 0:c7393ae16c16 129 /*!
Patrick Barrett 0:c7393ae16c16 130 * \brief Queues a Read from the Exosite One Platform
Patrick Barrett 0:c7393ae16c16 131 *
Patrick Barrett 0:c7393ae16c16 132 * Queues a request to read a dataport. If the request is successful, the
Patrick Barrett 0:c7393ae16c16 133 * provided callback will be called with a single parameter, a pointer to the
Patrick Barrett 0:c7393ae16c16 134 * result as a C string.
Patrick Barrett 0:c7393ae16c16 135 *
Patrick Barrett 0:c7393ae16c16 136 * \param[in] *alias Alias of dataport to read from, pointer must remain
Patrick Barrett 0:c7393ae16c16 137 * valid until the request has been sent.
Patrick Barrett 0:c7393ae16c16 138 * \param[in] callback Function pointer to call on success
Patrick Barrett 0:c7393ae16c16 139 *
Patrick Barrett 0:c7393ae16c16 140 * \return EXO_ERROR, EXO_OK on success or error code
Patrick Barrett 0:c7393ae16c16 141 *
Patrick Barrett 0:c7393ae16c16 142 */
Patrick Barrett 0:c7393ae16c16 143 void exo_read(exo_op *op, const char * alias, char * value, const size_t value_max)
Patrick Barrett 0:c7393ae16c16 144 {
Patrick Barrett 0:c7393ae16c16 145 op->type = EXO_READ;
Patrick Barrett 0:c7393ae16c16 146 op->state = EXO_REQUEST_NEW;
Patrick Barrett 0:c7393ae16c16 147 op->alias = alias;
Patrick Barrett 0:c7393ae16c16 148 op->value = value;
Patrick Barrett 0:c7393ae16c16 149 op->value_max = value_max;
Patrick Barrett 0:c7393ae16c16 150 op->mid = 0;
Patrick Barrett 0:c7393ae16c16 151 }
Patrick Barrett 0:c7393ae16c16 152
Patrick Barrett 0:c7393ae16c16 153 /*!
Patrick Barrett 0:c7393ae16c16 154 * \brief Subscribes to a Dataport on the Exosite One Platform
Patrick Barrett 0:c7393ae16c16 155 *
Patrick Barrett 0:c7393ae16c16 156 * Begins a subscription to a dataport The callback is called any time the
Patrick Barrett 0:c7393ae16c16 157 * value is updated as well as when the subscription is started.
Patrick Barrett 0:c7393ae16c16 158 *
Patrick Barrett 0:c7393ae16c16 159 * \param[in] alias Alias of dataport to read from
Patrick Barrett 0:c7393ae16c16 160 * \param[in] callback Function pointer to call on change
Patrick Barrett 0:c7393ae16c16 161 *
Patrick Barrett 0:c7393ae16c16 162 * \return EXO_ERROR, EXO_OK on success or error code
Patrick Barrett 0:c7393ae16c16 163 *
Patrick Barrett 0:c7393ae16c16 164 */
Patrick Barrett 0:c7393ae16c16 165 void exo_subscribe(exo_op *op, const char * alias, char * value, const size_t value_max)
Patrick Barrett 0:c7393ae16c16 166 {
Patrick Barrett 0:c7393ae16c16 167 op->type = EXO_SUBSCRIBE;
Patrick Barrett 0:c7393ae16c16 168 op->state = EXO_REQUEST_NEW;
Patrick Barrett 0:c7393ae16c16 169 op->alias = alias;
Patrick Barrett 0:c7393ae16c16 170 op->value = value;
Patrick Barrett 0:c7393ae16c16 171 op->value_max = value_max;
Patrick Barrett 0:c7393ae16c16 172 op->mid = 0;
Patrick Barrett 0:c7393ae16c16 173 }
Patrick Barrett 0:c7393ae16c16 174
Patrick Barrett 11:08bae8fb9824 175 /*!
Patrick Barrett 11:08bae8fb9824 176 * \brief Activates the Device on the Platform
Patrick Barrett 11:08bae8fb9824 177 *
Patrick Barrett 11:08bae8fb9824 178 * Queues an activation request. Usually only used internally.
Patrick Barrett 11:08bae8fb9824 179 *
Patrick Barrett 11:08bae8fb9824 180 */
Patrick Barrett 11:08bae8fb9824 181 void exo_activate(exo_op *op)
Patrick Barrett 11:08bae8fb9824 182 {
Patrick Barrett 11:08bae8fb9824 183 op->type = EXO_ACTIVATE;
Patrick Barrett 11:08bae8fb9824 184 op->state = EXO_REQUEST_NEW;
Patrick Barrett 11:08bae8fb9824 185 op->alias = NULL;
Patrick Barrett 11:08bae8fb9824 186 op->value = NULL;
Patrick Barrett 11:08bae8fb9824 187 op->value_max = 0;
Patrick Barrett 11:08bae8fb9824 188 op->mid = 0;
Patrick Barrett 11:08bae8fb9824 189 }
Patrick Barrett 11:08bae8fb9824 190
Patrick Barrett 0:c7393ae16c16 191 void exo_op_init(exo_op *op)
Patrick Barrett 0:c7393ae16c16 192 {
Patrick Barrett 0:c7393ae16c16 193 op->type = EXO_NULL;
Patrick Barrett 0:c7393ae16c16 194 op->state = EXO_REQUEST_NULL;
Patrick Barrett 0:c7393ae16c16 195 op->alias = NULL;
Patrick Barrett 0:c7393ae16c16 196 op->value = NULL;
Patrick Barrett 0:c7393ae16c16 197 op->value_max = 0;
Patrick Barrett 0:c7393ae16c16 198 op->mid = 0;
Patrick Barrett 10:76deeaebfafb 199 op->obs_seq = 0;
Patrick Barrett 13:df08a86dc06d 200 op->timeout = 0;
Patrick Barrett 0:c7393ae16c16 201 }
Patrick Barrett 0:c7393ae16c16 202
Patrick Barrett 0:c7393ae16c16 203 void exo_op_done(exo_op *op)
Patrick Barrett 0:c7393ae16c16 204 {
Patrick Barrett 0:c7393ae16c16 205 if (exo_is_op_subscribe(op)) {
Patrick Barrett 0:c7393ae16c16 206 op->state = EXO_REQUEST_SUBSCRIBED;
Patrick Barrett 0:c7393ae16c16 207 } else {
Patrick Barrett 0:c7393ae16c16 208 exo_op_init(op);
Patrick Barrett 0:c7393ae16c16 209 }
Patrick Barrett 0:c7393ae16c16 210 }
Patrick Barrett 0:c7393ae16c16 211
Patrick Barrett 0:c7393ae16c16 212 uint8_t exo_is_op_valid(exo_op *op)
Patrick Barrett 0:c7393ae16c16 213 {
Patrick Barrett 0:c7393ae16c16 214 return op->type != EXO_NULL;
Patrick Barrett 0:c7393ae16c16 215 }
Patrick Barrett 0:c7393ae16c16 216
Patrick Barrett 0:c7393ae16c16 217 uint8_t exo_is_op_success(exo_op *op)
Patrick Barrett 0:c7393ae16c16 218 {
Patrick Barrett 0:c7393ae16c16 219 return op->state == EXO_REQUEST_SUCCESS;
Patrick Barrett 0:c7393ae16c16 220 }
Patrick Barrett 0:c7393ae16c16 221
Patrick Barrett 0:c7393ae16c16 222 uint8_t exo_is_op_finished(exo_op *op)
Patrick Barrett 0:c7393ae16c16 223 {
Patrick Barrett 0:c7393ae16c16 224 return op->state == EXO_REQUEST_SUCCESS || op->state == EXO_REQUEST_ERROR;
Patrick Barrett 0:c7393ae16c16 225 }
Patrick Barrett 0:c7393ae16c16 226
Patrick Barrett 0:c7393ae16c16 227 uint8_t exo_is_op_read(exo_op *op)
Patrick Barrett 0:c7393ae16c16 228 {
Patrick Barrett 0:c7393ae16c16 229 return op->type == EXO_READ;
Patrick Barrett 0:c7393ae16c16 230 }
Patrick Barrett 0:c7393ae16c16 231
Patrick Barrett 0:c7393ae16c16 232 uint8_t exo_is_op_subscribe(exo_op *op)
Patrick Barrett 0:c7393ae16c16 233 {
Patrick Barrett 0:c7393ae16c16 234 return op->type == EXO_SUBSCRIBE;
Patrick Barrett 0:c7393ae16c16 235 }
Patrick Barrett 0:c7393ae16c16 236
Patrick Barrett 0:c7393ae16c16 237 uint8_t exo_is_op_write(exo_op *op)
Patrick Barrett 0:c7393ae16c16 238 {
Patrick Barrett 0:c7393ae16c16 239 return op->type == EXO_WRITE;
Patrick Barrett 0:c7393ae16c16 240 }
Patrick Barrett 0:c7393ae16c16 241
Patrick Barrett 0:c7393ae16c16 242
Patrick Barrett 0:c7393ae16c16 243 /*!
Patrick Barrett 0:c7393ae16c16 244 * \brief Performs queued operations with the Exosite One Platform
Patrick Barrett 0:c7393ae16c16 245 *
Patrick Barrett 0:c7393ae16c16 246 * Queues a request to read a dataport from the Exosite One Platform. If the
Patrick Barrett 0:c7393ae16c16 247 * request is successful the provided callback will be called with a single
Patrick Barrett 0:c7393ae16c16 248 * parameter, a pointer to the result as a C string.
Patrick Barrett 0:c7393ae16c16 249 *
Patrick Barrett 0:c7393ae16c16 250 * \param[in] alias Alias of dataport to read from
Patrick Barrett 0:c7393ae16c16 251 * \param[in] callback Function pointer to call on success
Patrick Barrett 0:c7393ae16c16 252 *
Patrick Barrett 0:c7393ae16c16 253 * \return EXO_STATE, EXO_OK on success or error code
Patrick Barrett 0:c7393ae16c16 254 *
Patrick Barrett 0:c7393ae16c16 255 */
Patrick Barrett 0:c7393ae16c16 256 exo_state exo_operate(exo_op *op, uint8_t count)
Patrick Barrett 0:c7393ae16c16 257 {
Patrick Barrett 12:68513d2aa2df 258 int i;
Patrick Barrett 12:68513d2aa2df 259
Patrick Barrett 12:68513d2aa2df 260 switch (device_state){
Patrick Barrett 12:68513d2aa2df 261 case EXO_STATE_UNINITIALIZED:
Patrick Barrett 12:68513d2aa2df 262 return EXO_ERROR;
Patrick Barrett 12:68513d2aa2df 263 case EXO_STATE_INITIALIZED:
Patrick Barrett 12:68513d2aa2df 264 case EXO_STATE_BAD_CIK:
Patrick Barrett 12:68513d2aa2df 265 if (op[0].state == EXO_REQUEST_NULL && op[0].timeout == 0)
Patrick Barrett 12:68513d2aa2df 266 exo_activate(&op[0]);
Patrick Barrett 12:68513d2aa2df 267 case EXO_STATE_GOOD:
Patrick Barrett 12:68513d2aa2df 268 break;
Patrick Barrett 12:68513d2aa2df 269 }
Patrick Barrett 12:68513d2aa2df 270
Patrick Barrett 12:68513d2aa2df 271 exo_process_waiting_datagrams(op, count);
Patrick Barrett 12:68513d2aa2df 272 exo_process_active_ops(op, count);
Patrick Barrett 12:68513d2aa2df 273
Patrick Barrett 12:68513d2aa2df 274 for (i = 0; i < count; i++) {
Patrick Barrett 12:68513d2aa2df 275 if (op[i].state == EXO_REQUEST_NEW)
Patrick Barrett 12:68513d2aa2df 276 return EXO_BUSY;
Patrick Barrett 12:68513d2aa2df 277 }
Patrick Barrett 12:68513d2aa2df 278
Patrick Barrett 12:68513d2aa2df 279 for (i = 0; i < count; i++) {
Patrick Barrett 12:68513d2aa2df 280 if (op[i].state == EXO_REQUEST_PENDING)
Patrick Barrett 12:68513d2aa2df 281 return EXO_WAITING;
Patrick Barrett 12:68513d2aa2df 282 }
Patrick Barrett 12:68513d2aa2df 283
Patrick Barrett 12:68513d2aa2df 284 return EXO_IDLE;
Patrick Barrett 12:68513d2aa2df 285 }
Patrick Barrett 12:68513d2aa2df 286
Patrick Barrett 12:68513d2aa2df 287 // Internal Functions
Patrick Barrett 12:68513d2aa2df 288
Patrick Barrett 12:68513d2aa2df 289 static void exo_process_waiting_datagrams(exo_op *op, uint8_t count)
Patrick Barrett 12:68513d2aa2df 290 {
Patrick Barrett 0:c7393ae16c16 291 uint8_t buf[576];
Patrick Barrett 0:c7393ae16c16 292 coap_pdu pdu;
Patrick Barrett 0:c7393ae16c16 293 coap_payload payload;
Patrick Barrett 0:c7393ae16c16 294 int i;
Patrick Barrett 0:c7393ae16c16 295 uint64_t now = exopal_get_time();
Patrick Barrett 0:c7393ae16c16 296
Patrick Barrett 0:c7393ae16c16 297 pdu.buf = buf;
Patrick Barrett 0:c7393ae16c16 298 pdu.max = 576;
Patrick Barrett 0:c7393ae16c16 299 pdu.len = 0;
Patrick Barrett 0:c7393ae16c16 300
Patrick Barrett 0:c7393ae16c16 301 // receive a UDP packet if one or more waiting
Patrick Barrett 0:c7393ae16c16 302 while (exopal_udp_recv(pdu.buf, pdu.max, &pdu.len) == 0) {
Patrick Barrett 0:c7393ae16c16 303 if (coap_validate_pkt(&pdu) != CE_NONE)
Patrick Barrett 0:c7393ae16c16 304 continue; //Invalid Packet, Ignore
Patrick Barrett 0:c7393ae16c16 305
Patrick Barrett 0:c7393ae16c16 306 for (i = 0; i < count; i++) {
Patrick Barrett 13:df08a86dc06d 307 if(op[i].type == EXO_WRITE) {
Patrick Barrett 13:df08a86dc06d 308 if (op[i].state == EXO_REQUEST_PENDING && op[i].mid == coap_get_mid(&pdu)) {
Patrick Barrett 14:fafaa95f7ad8 309 if (coap_get_code_class(&pdu) == 2) {
Patrick Barrett 13:df08a86dc06d 310 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 14:fafaa95f7ad8 311 } else {
Patrick Barrett 13:df08a86dc06d 312 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 14:fafaa95f7ad8 313
Patrick Barrett 14:fafaa95f7ad8 314 if (coap_get_code(&pdu) == CC_UNAUTHORIZED)
Patrick Barrett 14:fafaa95f7ad8 315 device_state = EXO_STATE_BAD_CIK;
Patrick Barrett 14:fafaa95f7ad8 316 }
Patrick Barrett 13:df08a86dc06d 317 break;
Patrick Barrett 13:df08a86dc06d 318 }
Patrick Barrett 13:df08a86dc06d 319 } else if(op[i].type == EXO_READ) {
Patrick Barrett 13:df08a86dc06d 320 if (op[i].state == EXO_REQUEST_PENDING && op[i].mid == coap_get_mid(&pdu)) {
Patrick Barrett 13:df08a86dc06d 321 if (coap_get_code_class(&pdu) == 2) {
Patrick Barrett 13:df08a86dc06d 322 payload = coap_get_payload(&pdu);
Patrick Barrett 13:df08a86dc06d 323 if (payload.len == 0) {
Patrick Barrett 13:df08a86dc06d 324 op[i].value = 0;
Patrick Barrett 13:df08a86dc06d 325 } else if (payload.len+1 > op[i].value_max || op[i].value == 0) {
Patrick Barrett 13:df08a86dc06d 326 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 13:df08a86dc06d 327 } else{
Patrick Barrett 13:df08a86dc06d 328 memcpy(op[i].value, payload.val, payload.len);
Patrick Barrett 13:df08a86dc06d 329 op[i].value[payload.len] = 0;
Patrick Barrett 13:df08a86dc06d 330 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 13:df08a86dc06d 331 }
Patrick Barrett 13:df08a86dc06d 332 } else {
Patrick Barrett 13:df08a86dc06d 333 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 13:df08a86dc06d 334
Patrick Barrett 13:df08a86dc06d 335 if (coap_get_code(&pdu) == CC_UNAUTHORIZED)
Patrick Barrett 13:df08a86dc06d 336 device_state = EXO_STATE_BAD_CIK;
Patrick Barrett 13:df08a86dc06d 337 }
Patrick Barrett 13:df08a86dc06d 338 break;
Patrick Barrett 13:df08a86dc06d 339 }
Patrick Barrett 13:df08a86dc06d 340 } else if(op[i].type == EXO_SUBSCRIBE) {
Patrick Barrett 13:df08a86dc06d 341 if (op[i].state == EXO_REQUEST_PENDING && op[i].mid == coap_get_mid(&pdu)) {
Patrick Barrett 13:df08a86dc06d 342 if (coap_get_code_class(&pdu) == 2) {
Patrick Barrett 13:df08a86dc06d 343 payload = coap_get_payload(&pdu);
Patrick Barrett 13:df08a86dc06d 344 if (payload.len == 0) {
Patrick Barrett 13:df08a86dc06d 345 op[i].value = 0;
Patrick Barrett 13:df08a86dc06d 346 } else if (payload.len+1 > op[i].value_max || op[i].value == 0) {
Patrick Barrett 13:df08a86dc06d 347 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 13:df08a86dc06d 348 } else{
Patrick Barrett 13:df08a86dc06d 349 memcpy(op[i].value, payload.val, payload.len);
Patrick Barrett 13:df08a86dc06d 350 op[i].value[payload.len] = 0;
Patrick Barrett 0:c7393ae16c16 351 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 13:df08a86dc06d 352 op[i].timeout = exopal_get_time() + 120000000 + (rand() % 15 * 100000);
Patrick Barrett 13:df08a86dc06d 353 }
Patrick Barrett 13:df08a86dc06d 354 } else {
Patrick Barrett 13:df08a86dc06d 355 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 13:df08a86dc06d 356
Patrick Barrett 13:df08a86dc06d 357 if (coap_get_code(&pdu) == CC_UNAUTHORIZED)
Patrick Barrett 13:df08a86dc06d 358 device_state = EXO_STATE_BAD_CIK;
Patrick Barrett 13:df08a86dc06d 359 }
Patrick Barrett 13:df08a86dc06d 360 break;
Patrick Barrett 13:df08a86dc06d 361 }else if(op[i].state == EXO_REQUEST_SUBSCRIBED && coap_get_token(&pdu) == op[i].token) {
Patrick Barrett 13:df08a86dc06d 362 coap_option opt;
Patrick Barrett 13:df08a86dc06d 363 uint32_t new_seq = 0;
Patrick Barrett 13:df08a86dc06d 364 opt = coap_get_option_by_num(&pdu, CON_OBSERVE, 0);
Patrick Barrett 13:df08a86dc06d 365 for (int j = 0; j < opt.len; j++) {
Patrick Barrett 13:df08a86dc06d 366 new_seq = (new_seq << (8*j)) | opt.val[j];
Patrick Barrett 0:c7393ae16c16 367 }
Patrick Barrett 13:df08a86dc06d 368
Patrick Barrett 13:df08a86dc06d 369 payload = coap_get_payload(&pdu);
Patrick Barrett 13:df08a86dc06d 370 if (payload.len == 0) {
Patrick Barrett 13:df08a86dc06d 371 op[i].value = 0;
Patrick Barrett 13:df08a86dc06d 372 } else if (payload.len+1 > op[i].value_max || op[i].value == 0) {
Patrick Barrett 13:df08a86dc06d 373 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 13:df08a86dc06d 374 } else{
Patrick Barrett 13:df08a86dc06d 375 memcpy(op[i].value, payload.val, payload.len);
Patrick Barrett 13:df08a86dc06d 376 op[i].value[payload.len] = 0;
Patrick Barrett 13:df08a86dc06d 377 op[i].mid = coap_get_mid(&pdu);
Patrick Barrett 13:df08a86dc06d 378 // TODO: User proper logic to ensure it's a new value not a different, but old one.
Patrick Barrett 13:df08a86dc06d 379 if (op[i].obs_seq != new_seq) {
Patrick Barrett 13:df08a86dc06d 380 op[i].state = EXO_REQUEST_SUB_ACK_NEW;
Patrick Barrett 13:df08a86dc06d 381 op[i].obs_seq = new_seq;
Patrick Barrett 13:df08a86dc06d 382 } else {
Patrick Barrett 13:df08a86dc06d 383 op[i].state = EXO_REQUEST_SUB_ACK;
Patrick Barrett 13:df08a86dc06d 384 }
Patrick Barrett 11:08bae8fb9824 385 }
Patrick Barrett 13:df08a86dc06d 386 break;
Patrick Barrett 0:c7393ae16c16 387 }
Patrick Barrett 13:df08a86dc06d 388 } else if(op[i].type == EXO_ACTIVATE) {
Patrick Barrett 13:df08a86dc06d 389 if (op[i].state == EXO_REQUEST_PENDING && op[i].mid == coap_get_mid(&pdu)) {
Patrick Barrett 13:df08a86dc06d 390 if (coap_get_code_class(&pdu) == 2) {
Patrick Barrett 13:df08a86dc06d 391 payload = coap_get_payload(&pdu);
Patrick Barrett 13:df08a86dc06d 392 if (payload.len == CIK_LENGTH) {
Patrick Barrett 13:df08a86dc06d 393 memcpy(cik, payload.val, CIK_LENGTH);
Patrick Barrett 13:df08a86dc06d 394 cik[CIK_LENGTH] = 0;
Patrick Barrett 13:df08a86dc06d 395 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 13:df08a86dc06d 396 exopal_store_cik(cik);
Patrick Barrett 13:df08a86dc06d 397 device_state = EXO_STATE_GOOD;
Patrick Barrett 13:df08a86dc06d 398 } else {
Patrick Barrett 13:df08a86dc06d 399 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 13:df08a86dc06d 400 }
Patrick Barrett 13:df08a86dc06d 401 } else {
Patrick Barrett 13:df08a86dc06d 402 // May or may not be an error, might just already be activated.
Patrick Barrett 13:df08a86dc06d 403 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 13:df08a86dc06d 404 device_state = EXO_STATE_GOOD;
Patrick Barrett 13:df08a86dc06d 405 }
Patrick Barrett 0:c7393ae16c16 406
Patrick Barrett 13:df08a86dc06d 407 // We're done with this op now.
Patrick Barrett 13:df08a86dc06d 408 exo_op_init(&op[i]);
Patrick Barrett 13:df08a86dc06d 409 break;
Patrick Barrett 0:c7393ae16c16 410 }
Patrick Barrett 0:c7393ae16c16 411 }
Patrick Barrett 0:c7393ae16c16 412 }
Patrick Barrett 0:c7393ae16c16 413
Patrick Barrett 13:df08a86dc06d 414 // if the above loop ends normally we don't recognize message, reply RST
Patrick Barrett 0:c7393ae16c16 415 if (i == count){
Patrick Barrett 0:c7393ae16c16 416 if (coap_get_type(&pdu) == CT_CON) {
Patrick Barrett 0:c7393ae16c16 417 // this can't fail
Patrick Barrett 0:c7393ae16c16 418 exo_build_msg_rst(&pdu, coap_get_mid(&pdu), coap_get_token(&pdu), coap_get_tkl(&pdu));
Patrick Barrett 0:c7393ae16c16 419
Patrick Barrett 0:c7393ae16c16 420 // best effort, don't bother checking if it failed, nothing we can do it
Patrick Barrett 0:c7393ae16c16 421 // it did anyway
Patrick Barrett 0:c7393ae16c16 422 exopal_udp_send(pdu.buf, pdu.len);
Patrick Barrett 0:c7393ae16c16 423 }
Patrick Barrett 0:c7393ae16c16 424
Patrick Barrett 0:c7393ae16c16 425 break;
Patrick Barrett 0:c7393ae16c16 426 }
Patrick Barrett 0:c7393ae16c16 427 }
Patrick Barrett 12:68513d2aa2df 428 }
Patrick Barrett 0:c7393ae16c16 429
Patrick Barrett 12:68513d2aa2df 430 // process all ops that are in an active state
Patrick Barrett 12:68513d2aa2df 431 static void exo_process_active_ops(exo_op *op, uint8_t count)
Patrick Barrett 12:68513d2aa2df 432 {
Patrick Barrett 12:68513d2aa2df 433 uint8_t buf[576];
Patrick Barrett 12:68513d2aa2df 434 coap_pdu pdu;
Patrick Barrett 12:68513d2aa2df 435 int i;
Patrick Barrett 12:68513d2aa2df 436 uint64_t now = exopal_get_time();
Patrick Barrett 12:68513d2aa2df 437
Patrick Barrett 12:68513d2aa2df 438 pdu.buf = buf;
Patrick Barrett 12:68513d2aa2df 439 pdu.max = 576;
Patrick Barrett 12:68513d2aa2df 440 pdu.len = 0;
Patrick Barrett 12:68513d2aa2df 441
Patrick Barrett 0:c7393ae16c16 442 for (i = 0; i < count; i++) {
Patrick Barrett 0:c7393ae16c16 443 switch (op[i].state) {
Patrick Barrett 0:c7393ae16c16 444 case EXO_REQUEST_NEW:
Patrick Barrett 0:c7393ae16c16 445 // Build and Send Request
Patrick Barrett 0:c7393ae16c16 446 switch (op[i].type) {
Patrick Barrett 0:c7393ae16c16 447 case EXO_READ:
Patrick Barrett 0:c7393ae16c16 448 exo_build_msg_read(&pdu, op[i].alias);
Patrick Barrett 0:c7393ae16c16 449 break;
Patrick Barrett 0:c7393ae16c16 450 case EXO_SUBSCRIBE:
Patrick Barrett 0:c7393ae16c16 451 exo_build_msg_observe(&pdu, op[i].alias);
Patrick Barrett 0:c7393ae16c16 452 break;
Patrick Barrett 0:c7393ae16c16 453 case EXO_WRITE:
Patrick Barrett 0:c7393ae16c16 454 exo_build_msg_write(&pdu, op[i].alias, op[i].value);
Patrick Barrett 0:c7393ae16c16 455 break;
Patrick Barrett 11:08bae8fb9824 456 case EXO_ACTIVATE:
Patrick Barrett 11:08bae8fb9824 457 exo_build_msg_activate(&pdu, vendor, model, serial);
Patrick Barrett 11:08bae8fb9824 458 break;
Patrick Barrett 0:c7393ae16c16 459 default:
Patrick Barrett 0:c7393ae16c16 460 op[i].type = EXO_NULL;
Patrick Barrett 0:c7393ae16c16 461 continue;
Patrick Barrett 0:c7393ae16c16 462 }
Patrick Barrett 0:c7393ae16c16 463
Patrick Barrett 0:c7393ae16c16 464 if (exopal_udp_send(pdu.buf, pdu.len) == 0) {
Patrick Barrett 0:c7393ae16c16 465 op[i].state = EXO_REQUEST_PENDING;
Patrick Barrett 0:c7393ae16c16 466 op[i].timeout = exopal_get_time() + 4000000;
Patrick Barrett 0:c7393ae16c16 467 op[i].mid = coap_get_mid(&pdu);
Patrick Barrett 0:c7393ae16c16 468 op[i].token = coap_get_token(&pdu);
Patrick Barrett 0:c7393ae16c16 469 }
Patrick Barrett 0:c7393ae16c16 470
Patrick Barrett 0:c7393ae16c16 471 break;
Patrick Barrett 10:76deeaebfafb 472 case EXO_REQUEST_SUBSCRIBED:
Patrick Barrett 0:c7393ae16c16 473 case EXO_REQUEST_PENDING:
Patrick Barrett 0:c7393ae16c16 474 // check if pending requests have reached timeout
Patrick Barrett 0:c7393ae16c16 475 if (op[i].timeout <= now){
Patrick Barrett 0:c7393ae16c16 476 switch (op[i].type) {
Patrick Barrett 0:c7393ae16c16 477 case EXO_READ:
Patrick Barrett 0:c7393ae16c16 478 case EXO_WRITE:
Patrick Barrett 0:c7393ae16c16 479 // TODO: may want to do some sort of retry system
Patrick Barrett 0:c7393ae16c16 480 op[i].state = EXO_REQUEST_ERROR;
Patrick Barrett 0:c7393ae16c16 481 break;
Patrick Barrett 0:c7393ae16c16 482 case EXO_SUBSCRIBE:
Patrick Barrett 0:c7393ae16c16 483 // force a new observe request
Patrick Barrett 0:c7393ae16c16 484 op[i].state = EXO_REQUEST_NEW;
Patrick Barrett 0:c7393ae16c16 485 break;
Patrick Barrett 0:c7393ae16c16 486 default:
Patrick Barrett 0:c7393ae16c16 487 break;
Patrick Barrett 0:c7393ae16c16 488 }
Patrick Barrett 0:c7393ae16c16 489 }
Patrick Barrett 0:c7393ae16c16 490 break;
Patrick Barrett 0:c7393ae16c16 491 case EXO_REQUEST_SUB_ACK_NEW:
Patrick Barrett 0:c7393ae16c16 492 case EXO_REQUEST_SUB_ACK:
Patrick Barrett 0:c7393ae16c16 493 // send ack for observe notification
Patrick Barrett 0:c7393ae16c16 494 exo_build_msg_ack(&pdu, coap_get_mid(&pdu));
Patrick Barrett 0:c7393ae16c16 495
Patrick Barrett 0:c7393ae16c16 496 if (exopal_udp_send(pdu.buf, pdu.len) == 0) {
Patrick Barrett 0:c7393ae16c16 497 if (op[i].state == EXO_REQUEST_SUB_ACK)
Patrick Barrett 0:c7393ae16c16 498 op[i].state = EXO_REQUEST_SUBSCRIBED;
Patrick Barrett 0:c7393ae16c16 499 else if (op[i].state == EXO_REQUEST_SUB_ACK_NEW)
Patrick Barrett 0:c7393ae16c16 500 op[i].state = EXO_REQUEST_SUCCESS;
Patrick Barrett 0:c7393ae16c16 501
Patrick Barrett 0:c7393ae16c16 502 // TODO: this should get set to Max-Age value, hard coding 120 s
Patrick Barrett 10:76deeaebfafb 503 op[i].timeout = exopal_get_time() + 120000000 + (rand() % 15 * 100000);
Patrick Barrett 0:c7393ae16c16 504 }
Patrick Barrett 0:c7393ae16c16 505 break;
Patrick Barrett 0:c7393ae16c16 506 default:
Patrick Barrett 0:c7393ae16c16 507 break;
Patrick Barrett 0:c7393ae16c16 508 }
Patrick Barrett 0:c7393ae16c16 509 }
Patrick Barrett 0:c7393ae16c16 510 }
Patrick Barrett 0:c7393ae16c16 511
Patrick Barrett 0:c7393ae16c16 512
Patrick Barrett 0:c7393ae16c16 513 exo_error exo_build_msg_activate(coap_pdu *pdu, const char *vendor, const char *model, const char *serial_number)
Patrick Barrett 0:c7393ae16c16 514 {
Patrick Barrett 0:c7393ae16c16 515 coap_error ret;
Patrick Barrett 0:c7393ae16c16 516 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 517 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 518 ret |= coap_set_type(pdu, CT_CON);
Patrick Barrett 0:c7393ae16c16 519 ret |= coap_set_code(pdu, CC_POST);
Patrick Barrett 0:c7393ae16c16 520 ret |= coap_set_mid(pdu, message_id_counter++);
Patrick Barrett 0:c7393ae16c16 521 ret |= coap_set_token(pdu, rand(), 2);
Patrick Barrett 0:c7393ae16c16 522 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"provision", 9);
Patrick Barrett 0:c7393ae16c16 523 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"activate", 8);
Patrick Barrett 0:c7393ae16c16 524 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)vendor, strlen(vendor));
Patrick Barrett 0:c7393ae16c16 525 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)model, strlen(model));
Patrick Barrett 0:c7393ae16c16 526 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)serial_number, strlen(serial_number));
Patrick Barrett 0:c7393ae16c16 527
Patrick Barrett 0:c7393ae16c16 528 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 529 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 530
Patrick Barrett 0:c7393ae16c16 531 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 532 }
Patrick Barrett 0:c7393ae16c16 533
Patrick Barrett 0:c7393ae16c16 534 exo_error exo_build_msg_read(coap_pdu *pdu, const char *alias)
Patrick Barrett 0:c7393ae16c16 535 {
Patrick Barrett 0:c7393ae16c16 536 coap_error ret;
Patrick Barrett 0:c7393ae16c16 537 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 538 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 539 ret |= coap_set_type(pdu, CT_CON);
Patrick Barrett 0:c7393ae16c16 540 ret |= coap_set_code(pdu, CC_GET);
Patrick Barrett 0:c7393ae16c16 541 ret |= coap_set_mid(pdu, message_id_counter++);
Patrick Barrett 0:c7393ae16c16 542 ret |= coap_set_token(pdu, rand(), 2);
Patrick Barrett 0:c7393ae16c16 543 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"1a", 2);
Patrick Barrett 0:c7393ae16c16 544 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)alias, strlen(alias));
Patrick Barrett 0:c7393ae16c16 545 ret |= coap_add_option(pdu, CON_URI_QUERY, (uint8_t*)cik, 40);
Patrick Barrett 0:c7393ae16c16 546
Patrick Barrett 0:c7393ae16c16 547 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 548 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 549
Patrick Barrett 0:c7393ae16c16 550 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 551 }
Patrick Barrett 0:c7393ae16c16 552
Patrick Barrett 0:c7393ae16c16 553 exo_error exo_build_msg_observe(coap_pdu *pdu, const char *alias)
Patrick Barrett 0:c7393ae16c16 554 {
Patrick Barrett 0:c7393ae16c16 555 uint8_t obs_opt = 0;
Patrick Barrett 0:c7393ae16c16 556 coap_error ret;
Patrick Barrett 0:c7393ae16c16 557 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 558 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 559 ret |= coap_set_type(pdu, CT_CON);
Patrick Barrett 0:c7393ae16c16 560 ret |= coap_set_code(pdu, CC_GET);
Patrick Barrett 0:c7393ae16c16 561 ret |= coap_set_mid(pdu, message_id_counter++);
Patrick Barrett 0:c7393ae16c16 562 ret |= coap_set_token(pdu, rand(), 2);
Patrick Barrett 0:c7393ae16c16 563 ret |= coap_add_option(pdu, CON_OBSERVE, &obs_opt, 1);
Patrick Barrett 0:c7393ae16c16 564 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"1a", 2);
Patrick Barrett 0:c7393ae16c16 565 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)alias, strlen(alias));
Patrick Barrett 0:c7393ae16c16 566 ret |= coap_add_option(pdu, CON_URI_QUERY, (uint8_t*)cik, 40);
Patrick Barrett 0:c7393ae16c16 567
Patrick Barrett 0:c7393ae16c16 568 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 569 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 570
Patrick Barrett 0:c7393ae16c16 571 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 572 }
Patrick Barrett 0:c7393ae16c16 573
Patrick Barrett 0:c7393ae16c16 574 exo_error exo_build_msg_write(coap_pdu *pdu, const char *alias, const char *value)
Patrick Barrett 0:c7393ae16c16 575 {
Patrick Barrett 0:c7393ae16c16 576 coap_error ret;
Patrick Barrett 0:c7393ae16c16 577 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 578 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 579 ret |= coap_set_type(pdu, CT_CON);
Patrick Barrett 0:c7393ae16c16 580 ret |= coap_set_code(pdu, CC_POST);
Patrick Barrett 0:c7393ae16c16 581 ret |= coap_set_mid(pdu, message_id_counter++);
Patrick Barrett 0:c7393ae16c16 582 ret |= coap_set_token(pdu, rand(), 2);
Patrick Barrett 0:c7393ae16c16 583 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)"1a", 2);
Patrick Barrett 0:c7393ae16c16 584 ret |= coap_add_option(pdu, CON_URI_PATH, (uint8_t*)alias, strlen(alias));
Patrick Barrett 0:c7393ae16c16 585 ret |= coap_add_option(pdu, CON_URI_QUERY, (uint8_t*)cik, 40);
Patrick Barrett 0:c7393ae16c16 586 ret |= coap_set_payload(pdu, (uint8_t *)value, strlen(value));
Patrick Barrett 0:c7393ae16c16 587
Patrick Barrett 0:c7393ae16c16 588 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 589 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 590
Patrick Barrett 0:c7393ae16c16 591 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 592 }
Patrick Barrett 0:c7393ae16c16 593
Patrick Barrett 0:c7393ae16c16 594 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 595 {
Patrick Barrett 0:c7393ae16c16 596 coap_error ret;
Patrick Barrett 0:c7393ae16c16 597 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 598 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 599 ret |= coap_set_type(pdu, CT_RST);
Patrick Barrett 0:c7393ae16c16 600 ret |= coap_set_code(pdu, CC_EMPTY);
Patrick Barrett 0:c7393ae16c16 601 ret |= coap_set_mid(pdu, mid);
Patrick Barrett 0:c7393ae16c16 602 ret |= coap_set_token(pdu, token, tkl);
Patrick Barrett 0:c7393ae16c16 603
Patrick Barrett 0:c7393ae16c16 604 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 605 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 606
Patrick Barrett 0:c7393ae16c16 607 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 608 }
Patrick Barrett 0:c7393ae16c16 609
Patrick Barrett 0:c7393ae16c16 610 exo_error exo_build_msg_ack(coap_pdu *pdu, const uint16_t mid)
Patrick Barrett 0:c7393ae16c16 611 {
Patrick Barrett 0:c7393ae16c16 612 coap_error ret;
Patrick Barrett 0:c7393ae16c16 613 coap_init_pdu(pdu);
Patrick Barrett 0:c7393ae16c16 614 ret = coap_set_version(pdu, COAP_V1);
Patrick Barrett 0:c7393ae16c16 615 ret |= coap_set_type(pdu, CT_ACK);
Patrick Barrett 0:c7393ae16c16 616 ret |= coap_set_code(pdu, CC_EMPTY);
Patrick Barrett 0:c7393ae16c16 617 ret |= coap_set_mid(pdu, mid);
Patrick Barrett 0:c7393ae16c16 618
Patrick Barrett 0:c7393ae16c16 619 if (ret != CE_NONE)
Patrick Barrett 0:c7393ae16c16 620 return EXO_GENERAL_ERROR;
Patrick Barrett 0:c7393ae16c16 621
Patrick Barrett 0:c7393ae16c16 622 return EXO_OK;
Patrick Barrett 0:c7393ae16c16 623 }
Patrick Barrett 0:c7393ae16c16 624
Patrick Barrett 11:08bae8fb9824 625 exo_error exo_do_activate()
Patrick Barrett 0:c7393ae16c16 626 {
Patrick Barrett 11:08bae8fb9824 627 exo_op op;
Patrick Barrett 11:08bae8fb9824 628
Patrick Barrett 11:08bae8fb9824 629 exo_op_init(&op);
Patrick Barrett 11:08bae8fb9824 630
Patrick Barrett 0:c7393ae16c16 631
Patrick Barrett 11:08bae8fb9824 632 return EXO_OK;
Patrick Barrett 11:08bae8fb9824 633 }
Patrick Barrett 11:08bae8fb9824 634
Patrick Barrett 11:08bae8fb9824 635 uint8_t exo_util_is_ascii_hex(const char *str, size_t len)
Patrick Barrett 11:08bae8fb9824 636 {
Patrick Barrett 11:08bae8fb9824 637 size_t i;
Patrick Barrett 11:08bae8fb9824 638
Patrick Barrett 11:08bae8fb9824 639 for (i = 0; i < len; i++) {
Patrick Barrett 11:08bae8fb9824 640 if (!((str[i] >= 'a' && str[i] <= 'f') ||
Patrick Barrett 11:08bae8fb9824 641 (str[i] >= '0' && str[i] <= '9'))) {
Patrick Barrett 0:c7393ae16c16 642 return 1;
Patrick Barrett 0:c7393ae16c16 643 }
Patrick Barrett 0:c7393ae16c16 644 }
Patrick Barrett 0:c7393ae16c16 645
Patrick Barrett 0:c7393ae16c16 646 return 0;
Patrick Barrett 0:c7393ae16c16 647 }
Patrick Barrett 0:c7393ae16c16 648