Program that uses the QuickStart Library to interface a SmartMesh IP mote: Connects to the default network and starts publishing a random walk value every 5 seconds.

Dependencies:   mbed millis

Fork of QSL_SimplePublish by Jon-Håkon Bøe Røli

QSL SimplePublish

SmartMesh IP QuickStart Library

Committer:
jhbr
Date:
Thu Sep 08 14:26:15 2016 +0000
Revision:
4:0285bcbbc855
Replaced sleep() with simple wait_ms(), as board seems to not always wake up or go to sleep as it should.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jhbr 4:0285bcbbc855 1 /*
jhbr 4:0285bcbbc855 2 Copyright (c) 2016, Dust Networks. All rights reserved.
jhbr 4:0285bcbbc855 3
jhbr 4:0285bcbbc855 4 Finite State Machine for the QuickStart Library.
jhbr 4:0285bcbbc855 5
jhbr 4:0285bcbbc855 6 \license See attached DN_LICENSE.txt.
jhbr 4:0285bcbbc855 7 */
jhbr 4:0285bcbbc855 8
jhbr 4:0285bcbbc855 9 #include "dn_fsm.h"
jhbr 4:0285bcbbc855 10 #include "dn_ipmt.h"
jhbr 4:0285bcbbc855 11 #include "dn_time.h"
jhbr 4:0285bcbbc855 12 #include "dn_watchdog.h"
jhbr 4:0285bcbbc855 13 #include "dn_qsl_api.h"
jhbr 4:0285bcbbc855 14 #include "dn_debug.h"
jhbr 4:0285bcbbc855 15
jhbr 4:0285bcbbc855 16 //=========================== variables =======================================
jhbr 4:0285bcbbc855 17
jhbr 4:0285bcbbc855 18 typedef struct
jhbr 4:0285bcbbc855 19 {
jhbr 4:0285bcbbc855 20 // FSM
jhbr 4:0285bcbbc855 21 uint32_t fsmEventScheduled_ms;
jhbr 4:0285bcbbc855 22 uint16_t fsmDelay_ms;
jhbr 4:0285bcbbc855 23 bool fsmArmed;
jhbr 4:0285bcbbc855 24 uint8_t state;
jhbr 4:0285bcbbc855 25 // C Library API
jhbr 4:0285bcbbc855 26 dn_fsm_reply_cbt replyCb;
jhbr 4:0285bcbbc855 27 dn_fsm_timer_cbt fsmCb;
jhbr 4:0285bcbbc855 28 uint8_t replyBuf[MAX_FRAME_LENGTH];
jhbr 4:0285bcbbc855 29 uint8_t notifBuf[MAX_FRAME_LENGTH];
jhbr 4:0285bcbbc855 30 // Connection
jhbr 4:0285bcbbc855 31 uint8_t socketId;
jhbr 4:0285bcbbc855 32 uint16_t networkId;
jhbr 4:0285bcbbc855 33 uint8_t joinKey[DN_JOIN_KEY_LEN];
jhbr 4:0285bcbbc855 34 uint16_t srcPort;
jhbr 4:0285bcbbc855 35 uint32_t service_ms;
jhbr 4:0285bcbbc855 36 uint8_t payloadBuf[DN_DEFAULT_PAYLOAD_SIZE_LIMIT];
jhbr 4:0285bcbbc855 37 uint8_t payloadSize;
jhbr 4:0285bcbbc855 38 uint8_t destIPv6[DN_IPv6ADDR_LEN];
jhbr 4:0285bcbbc855 39 uint16_t destPort;
jhbr 4:0285bcbbc855 40 dn_inbox_t inbox;
jhbr 4:0285bcbbc855 41 } dn_fsm_vars_t;
jhbr 4:0285bcbbc855 42
jhbr 4:0285bcbbc855 43 static dn_fsm_vars_t dn_fsm_vars;
jhbr 4:0285bcbbc855 44
jhbr 4:0285bcbbc855 45
jhbr 4:0285bcbbc855 46 //=========================== prototypes ======================================
jhbr 4:0285bcbbc855 47 // FSM
jhbr 4:0285bcbbc855 48 static void dn_fsm_run(void);
jhbr 4:0285bcbbc855 49 static void dn_fsm_scheduleEvent(uint16_t delay, dn_fsm_timer_cbt cb);
jhbr 4:0285bcbbc855 50 static void dn_fsm_cancelEvent(void);
jhbr 4:0285bcbbc855 51 static void dn_fsm_setReplyCallback(dn_fsm_reply_cbt cb);
jhbr 4:0285bcbbc855 52 static void dn_fsm_enterState(uint8_t newState, uint16_t spesificDelay);
jhbr 4:0285bcbbc855 53 static bool dn_fsm_cmd_timeout(uint32_t cmdStart_ms, uint32_t cmdTimeout_ms);
jhbr 4:0285bcbbc855 54 // C Library API
jhbr 4:0285bcbbc855 55 static void dn_ipmt_notif_cb(uint8_t cmdId, uint8_t subCmdId);
jhbr 4:0285bcbbc855 56 static void dn_ipmt_reply_cb(uint8_t cmdId);
jhbr 4:0285bcbbc855 57 static void dn_event_responseTimeout(void);
jhbr 4:0285bcbbc855 58 static void dn_event_reset(void);
jhbr 4:0285bcbbc855 59 static void dn_reply_reset(void);
jhbr 4:0285bcbbc855 60 static void dn_event_disconnect(void);
jhbr 4:0285bcbbc855 61 static void dn_reply_disconnect(void);
jhbr 4:0285bcbbc855 62 static void dn_event_getMoteStatus(void);
jhbr 4:0285bcbbc855 63 static void dn_reply_getMoteStatus(void);
jhbr 4:0285bcbbc855 64 static void dn_event_openSocket(void);
jhbr 4:0285bcbbc855 65 static void dn_reply_openSocket(void);
jhbr 4:0285bcbbc855 66 static void dn_event_bindSocket(void);
jhbr 4:0285bcbbc855 67 static void dn_reply_bindSocket(void);
jhbr 4:0285bcbbc855 68 static void dn_event_setJoinKey(void);
jhbr 4:0285bcbbc855 69 static void dn_reply_setJoinKey(void);
jhbr 4:0285bcbbc855 70 static void dn_event_setNetworkId(void);
jhbr 4:0285bcbbc855 71 static void dn_reply_setNetworkId(void);
jhbr 4:0285bcbbc855 72 static void dn_event_search(void);
jhbr 4:0285bcbbc855 73 static void dn_reply_search(void);
jhbr 4:0285bcbbc855 74 static void dn_event_join(void);
jhbr 4:0285bcbbc855 75 static void dn_reply_join(void);
jhbr 4:0285bcbbc855 76 static void dn_event_requestService(void);
jhbr 4:0285bcbbc855 77 static void dn_reply_requestService(void);
jhbr 4:0285bcbbc855 78 static void dn_event_getServiceInfo(void);
jhbr 4:0285bcbbc855 79 static void dn_reply_getServiceInfo(void);
jhbr 4:0285bcbbc855 80 static void dn_event_sendTo(void);
jhbr 4:0285bcbbc855 81 static void dn_reply_sendTo(void);
jhbr 4:0285bcbbc855 82 // helpers
jhbr 4:0285bcbbc855 83 static dn_err_t checkAndSaveNetConfig(uint16_t netID, const uint8_t* joinKey, uint16_t srcPort, uint32_t req_service_ms);
jhbr 4:0285bcbbc855 84 static uint8_t getPayloadLimit(uint16_t destPort);
jhbr 4:0285bcbbc855 85
jhbr 4:0285bcbbc855 86 //=========================== public ==========================================
jhbr 4:0285bcbbc855 87
jhbr 4:0285bcbbc855 88 //========== QSL API
jhbr 4:0285bcbbc855 89
jhbr 4:0285bcbbc855 90 bool dn_qsl_init(void)
jhbr 4:0285bcbbc855 91 {
jhbr 4:0285bcbbc855 92 debug("QSL: Init");
jhbr 4:0285bcbbc855 93 // Reset local variables
jhbr 4:0285bcbbc855 94 memset(&dn_fsm_vars, 0, sizeof (dn_fsm_vars));
jhbr 4:0285bcbbc855 95
jhbr 4:0285bcbbc855 96 // Initialize the ipmt module
jhbr 4:0285bcbbc855 97 dn_ipmt_init // Should be augmented with return value to know if successful...
jhbr 4:0285bcbbc855 98 (
jhbr 4:0285bcbbc855 99 dn_ipmt_notif_cb,
jhbr 4:0285bcbbc855 100 dn_fsm_vars.notifBuf,
jhbr 4:0285bcbbc855 101 sizeof (dn_fsm_vars.notifBuf),
jhbr 4:0285bcbbc855 102 dn_ipmt_reply_cb
jhbr 4:0285bcbbc855 103 );
jhbr 4:0285bcbbc855 104
jhbr 4:0285bcbbc855 105 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 106 return TRUE;
jhbr 4:0285bcbbc855 107 }
jhbr 4:0285bcbbc855 108
jhbr 4:0285bcbbc855 109 bool dn_qsl_isConnected(void)
jhbr 4:0285bcbbc855 110 {
jhbr 4:0285bcbbc855 111 debug("QSL: isConnected");
jhbr 4:0285bcbbc855 112 return dn_fsm_vars.state == DN_FSM_STATE_CONNECTED;
jhbr 4:0285bcbbc855 113 }
jhbr 4:0285bcbbc855 114
jhbr 4:0285bcbbc855 115 bool dn_qsl_connect(uint16_t netID, const uint8_t* joinKey, uint16_t srcPort, uint32_t req_service_ms)
jhbr 4:0285bcbbc855 116 {
jhbr 4:0285bcbbc855 117 uint32_t cmdStart_ms = dn_time_ms();
jhbr 4:0285bcbbc855 118 dn_err_t err;
jhbr 4:0285bcbbc855 119 debug("QSL: Connect");
jhbr 4:0285bcbbc855 120 switch (dn_fsm_vars.state)
jhbr 4:0285bcbbc855 121 {
jhbr 4:0285bcbbc855 122 case DN_FSM_STATE_NOT_INITIALIZED:
jhbr 4:0285bcbbc855 123 log_warn("Can't connect; not initialized");
jhbr 4:0285bcbbc855 124 return FALSE;
jhbr 4:0285bcbbc855 125 case DN_FSM_STATE_DISCONNECTED:
jhbr 4:0285bcbbc855 126 err = checkAndSaveNetConfig(netID, joinKey, srcPort, req_service_ms);
jhbr 4:0285bcbbc855 127 if (err != DN_ERR_NONE)
jhbr 4:0285bcbbc855 128 {
jhbr 4:0285bcbbc855 129 return FALSE;
jhbr 4:0285bcbbc855 130 }
jhbr 4:0285bcbbc855 131 debug("Starting connect process...");
jhbr 4:0285bcbbc855 132 dn_fsm_enterState(DN_FSM_STATE_PRE_JOIN, 0);
jhbr 4:0285bcbbc855 133 break;
jhbr 4:0285bcbbc855 134 case DN_FSM_STATE_CONNECTED:
jhbr 4:0285bcbbc855 135 if ((netID > 0 && netID != dn_fsm_vars.networkId)
jhbr 4:0285bcbbc855 136 || (joinKey != NULL && memcmp(joinKey, dn_fsm_vars.joinKey, DN_JOIN_KEY_LEN) != 0)
jhbr 4:0285bcbbc855 137 || (srcPort > 0 && srcPort != dn_fsm_vars.srcPort))
jhbr 4:0285bcbbc855 138 {
jhbr 4:0285bcbbc855 139 err = checkAndSaveNetConfig(netID, joinKey, srcPort, req_service_ms);
jhbr 4:0285bcbbc855 140 if (err != DN_ERR_NONE)
jhbr 4:0285bcbbc855 141 {
jhbr 4:0285bcbbc855 142 return FALSE;
jhbr 4:0285bcbbc855 143 }
jhbr 4:0285bcbbc855 144 debug("New network ID, join key and/or source port; reconnecting...");
jhbr 4:0285bcbbc855 145 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 146 } else if (req_service_ms > 0 && req_service_ms != dn_fsm_vars.service_ms)
jhbr 4:0285bcbbc855 147 {
jhbr 4:0285bcbbc855 148 debug("New service request");
jhbr 4:0285bcbbc855 149 dn_fsm_vars.service_ms = req_service_ms;
jhbr 4:0285bcbbc855 150 dn_fsm_enterState(DN_FSM_STATE_REQ_SERVICE, 0);
jhbr 4:0285bcbbc855 151 } else
jhbr 4:0285bcbbc855 152 {
jhbr 4:0285bcbbc855 153 debug("Already connected");
jhbr 4:0285bcbbc855 154 // Nothing to do
jhbr 4:0285bcbbc855 155 }
jhbr 4:0285bcbbc855 156 break;
jhbr 4:0285bcbbc855 157 default:
jhbr 4:0285bcbbc855 158 log_err("Unexpected state");
jhbr 4:0285bcbbc855 159 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 160 return FALSE;
jhbr 4:0285bcbbc855 161 }
jhbr 4:0285bcbbc855 162
jhbr 4:0285bcbbc855 163 // Drive FSM until connect success/failure or timeout
jhbr 4:0285bcbbc855 164 while (dn_fsm_vars.state != DN_FSM_STATE_CONNECTED
jhbr 4:0285bcbbc855 165 && dn_fsm_vars.state != DN_FSM_STATE_DISCONNECTED
jhbr 4:0285bcbbc855 166 && !dn_fsm_cmd_timeout(cmdStart_ms, DN_CONNECT_TIMEOUT_S * 1000))
jhbr 4:0285bcbbc855 167 {
jhbr 4:0285bcbbc855 168 dn_watchdog_feed();
jhbr 4:0285bcbbc855 169 dn_fsm_run();
jhbr 4:0285bcbbc855 170 }
jhbr 4:0285bcbbc855 171
jhbr 4:0285bcbbc855 172 return dn_fsm_vars.state == DN_FSM_STATE_CONNECTED;
jhbr 4:0285bcbbc855 173 }
jhbr 4:0285bcbbc855 174
jhbr 4:0285bcbbc855 175 bool dn_qsl_send(const uint8_t* payload, uint8_t payloadSize_B, uint16_t destPort)
jhbr 4:0285bcbbc855 176 {
jhbr 4:0285bcbbc855 177 uint32_t cmdStart_ms = dn_time_ms();
jhbr 4:0285bcbbc855 178 uint8_t maxPayloadSize;
jhbr 4:0285bcbbc855 179 debug("QSL: Send");
jhbr 4:0285bcbbc855 180 switch (dn_fsm_vars.state)
jhbr 4:0285bcbbc855 181 {
jhbr 4:0285bcbbc855 182 case DN_FSM_STATE_CONNECTED:
jhbr 4:0285bcbbc855 183 maxPayloadSize = getPayloadLimit(destPort);
jhbr 4:0285bcbbc855 184
jhbr 4:0285bcbbc855 185 if (payloadSize_B > maxPayloadSize)
jhbr 4:0285bcbbc855 186 {
jhbr 4:0285bcbbc855 187 log_warn("Payload size (%u) exceeds limit (%u)", payloadSize_B, maxPayloadSize);
jhbr 4:0285bcbbc855 188 return FALSE;
jhbr 4:0285bcbbc855 189 }
jhbr 4:0285bcbbc855 190 // Store outbound payload and parameters
jhbr 4:0285bcbbc855 191 memcpy(dn_fsm_vars.payloadBuf, payload, payloadSize_B);
jhbr 4:0285bcbbc855 192 dn_fsm_vars.payloadSize = payloadSize_B;
jhbr 4:0285bcbbc855 193 memcpy(dn_fsm_vars.destIPv6, DN_DEST_IP, DN_IPv6ADDR_LEN);
jhbr 4:0285bcbbc855 194 dn_fsm_vars.destPort = (destPort > 0) ? destPort : DN_DEFAULT_DEST_PORT;
jhbr 4:0285bcbbc855 195 // Start send process
jhbr 4:0285bcbbc855 196 dn_fsm_enterState(DN_FSM_STATE_SENDING, 0);
jhbr 4:0285bcbbc855 197 break;
jhbr 4:0285bcbbc855 198 default:
jhbr 4:0285bcbbc855 199 log_warn("Can't send; not connected");
jhbr 4:0285bcbbc855 200 return FALSE;
jhbr 4:0285bcbbc855 201 }
jhbr 4:0285bcbbc855 202
jhbr 4:0285bcbbc855 203 // Drive FSM until send success/failure or timeout
jhbr 4:0285bcbbc855 204 while (dn_fsm_vars.state == DN_FSM_STATE_SENDING
jhbr 4:0285bcbbc855 205 && !dn_fsm_cmd_timeout(cmdStart_ms, DN_SEND_TIMEOUT_MS))
jhbr 4:0285bcbbc855 206 {
jhbr 4:0285bcbbc855 207 dn_watchdog_feed();
jhbr 4:0285bcbbc855 208 dn_fsm_run();
jhbr 4:0285bcbbc855 209 }
jhbr 4:0285bcbbc855 210
jhbr 4:0285bcbbc855 211 // Catch send failure
jhbr 4:0285bcbbc855 212 if (dn_fsm_vars.state == DN_FSM_STATE_SEND_FAILED)
jhbr 4:0285bcbbc855 213 {
jhbr 4:0285bcbbc855 214 debug("Send failed");
jhbr 4:0285bcbbc855 215 dn_fsm_enterState(DN_FSM_STATE_CONNECTED, 0);
jhbr 4:0285bcbbc855 216 return FALSE;
jhbr 4:0285bcbbc855 217 }
jhbr 4:0285bcbbc855 218
jhbr 4:0285bcbbc855 219 return dn_fsm_vars.state == DN_FSM_STATE_CONNECTED;
jhbr 4:0285bcbbc855 220 }
jhbr 4:0285bcbbc855 221
jhbr 4:0285bcbbc855 222 uint8_t dn_qsl_read(uint8_t* readBuffer)
jhbr 4:0285bcbbc855 223 {
jhbr 4:0285bcbbc855 224 uint8_t bytesRead = 0;
jhbr 4:0285bcbbc855 225 debug("QSL: Read");
jhbr 4:0285bcbbc855 226 if (dn_fsm_vars.inbox.unreadPackets > 0)
jhbr 4:0285bcbbc855 227 {
jhbr 4:0285bcbbc855 228 // Pop payload at head of inbox
jhbr 4:0285bcbbc855 229 memcpy
jhbr 4:0285bcbbc855 230 (
jhbr 4:0285bcbbc855 231 readBuffer,
jhbr 4:0285bcbbc855 232 dn_fsm_vars.inbox.pktBuf[dn_fsm_vars.inbox.head],
jhbr 4:0285bcbbc855 233 dn_fsm_vars.inbox.pktSize[dn_fsm_vars.inbox.head]
jhbr 4:0285bcbbc855 234 );
jhbr 4:0285bcbbc855 235 bytesRead = dn_fsm_vars.inbox.pktSize[dn_fsm_vars.inbox.head];
jhbr 4:0285bcbbc855 236 dn_fsm_vars.inbox.head = (dn_fsm_vars.inbox.head + 1) % DN_INBOX_SIZE;
jhbr 4:0285bcbbc855 237 dn_fsm_vars.inbox.unreadPackets--;
jhbr 4:0285bcbbc855 238 debug("Read %u bytes from inbox", bytesRead);
jhbr 4:0285bcbbc855 239 } else
jhbr 4:0285bcbbc855 240 {
jhbr 4:0285bcbbc855 241 debug("Inbox empty");
jhbr 4:0285bcbbc855 242 }
jhbr 4:0285bcbbc855 243 return bytesRead;
jhbr 4:0285bcbbc855 244 }
jhbr 4:0285bcbbc855 245
jhbr 4:0285bcbbc855 246 //=========================== private =========================================
jhbr 4:0285bcbbc855 247
jhbr 4:0285bcbbc855 248 //========== FSM
jhbr 4:0285bcbbc855 249
jhbr 4:0285bcbbc855 250 //===== run
jhbr 4:0285bcbbc855 251
jhbr 4:0285bcbbc855 252 /**
jhbr 4:0285bcbbc855 253 Check if an event is scheduled and run it if due.
jhbr 4:0285bcbbc855 254 */
jhbr 4:0285bcbbc855 255 static void dn_fsm_run(void)
jhbr 4:0285bcbbc855 256 {
jhbr 4:0285bcbbc855 257 uint32_t timePassed_ms = dn_time_ms() - dn_fsm_vars.fsmEventScheduled_ms; // Handle dn_time_ms wrap around
jhbr 4:0285bcbbc855 258 if (dn_fsm_vars.fsmArmed && (timePassed_ms > dn_fsm_vars.fsmDelay_ms))
jhbr 4:0285bcbbc855 259 {
jhbr 4:0285bcbbc855 260 // Scheduled event is due; execute it
jhbr 4:0285bcbbc855 261 dn_fsm_vars.fsmArmed = FALSE;
jhbr 4:0285bcbbc855 262 if (dn_fsm_vars.fsmCb != NULL)
jhbr 4:0285bcbbc855 263 {
jhbr 4:0285bcbbc855 264 dn_fsm_vars.fsmCb();
jhbr 4:0285bcbbc855 265 }
jhbr 4:0285bcbbc855 266 } else
jhbr 4:0285bcbbc855 267 {
jhbr 4:0285bcbbc855 268 // Sleep to save CPU power
jhbr 4:0285bcbbc855 269 dn_sleep_ms(DN_FSM_RUN_INTERVAL_MS);
jhbr 4:0285bcbbc855 270 }
jhbr 4:0285bcbbc855 271 }
jhbr 4:0285bcbbc855 272
jhbr 4:0285bcbbc855 273 //===== scheduleEvent
jhbr 4:0285bcbbc855 274
jhbr 4:0285bcbbc855 275 /**
jhbr 4:0285bcbbc855 276 Schedule function to be called after a given delay.
jhbr 4:0285bcbbc855 277 */
jhbr 4:0285bcbbc855 278 static void dn_fsm_scheduleEvent(uint16_t delay_ms, dn_fsm_timer_cbt cb)
jhbr 4:0285bcbbc855 279 {
jhbr 4:0285bcbbc855 280 dn_fsm_vars.fsmEventScheduled_ms = dn_time_ms();
jhbr 4:0285bcbbc855 281 dn_fsm_vars.fsmDelay_ms = delay_ms;
jhbr 4:0285bcbbc855 282 dn_fsm_vars.fsmCb = cb;
jhbr 4:0285bcbbc855 283 dn_fsm_vars.fsmArmed = TRUE;
jhbr 4:0285bcbbc855 284 }
jhbr 4:0285bcbbc855 285
jhbr 4:0285bcbbc855 286 //===== cancelEvent
jhbr 4:0285bcbbc855 287
jhbr 4:0285bcbbc855 288 /**
jhbr 4:0285bcbbc855 289 Cancel currently scheduled event.
jhbr 4:0285bcbbc855 290 */
jhbr 4:0285bcbbc855 291 static void dn_fsm_cancelEvent(void)
jhbr 4:0285bcbbc855 292 {
jhbr 4:0285bcbbc855 293 dn_fsm_vars.fsmDelay_ms = 0;
jhbr 4:0285bcbbc855 294 dn_fsm_vars.fsmCb = NULL;
jhbr 4:0285bcbbc855 295 dn_fsm_vars.fsmArmed = FALSE;
jhbr 4:0285bcbbc855 296 }
jhbr 4:0285bcbbc855 297
jhbr 4:0285bcbbc855 298 //===== setReplyCallback
jhbr 4:0285bcbbc855 299
jhbr 4:0285bcbbc855 300 /**
jhbr 4:0285bcbbc855 301 Set the callback function that the C Library will execute when the next reply
jhbr 4:0285bcbbc855 302 is received and the reply buffer is ready to be parsed.
jhbr 4:0285bcbbc855 303 */
jhbr 4:0285bcbbc855 304 static void dn_fsm_setReplyCallback(dn_fsm_reply_cbt cb)
jhbr 4:0285bcbbc855 305 {
jhbr 4:0285bcbbc855 306 dn_fsm_vars.replyCb = cb;
jhbr 4:0285bcbbc855 307 }
jhbr 4:0285bcbbc855 308
jhbr 4:0285bcbbc855 309 //===== enterState
jhbr 4:0285bcbbc855 310
jhbr 4:0285bcbbc855 311 /**
jhbr 4:0285bcbbc855 312 Transition FSM to new state and schedule any default entry events.
jhbr 4:0285bcbbc855 313 */
jhbr 4:0285bcbbc855 314 static void dn_fsm_enterState(uint8_t newState, uint16_t spesificDelay)
jhbr 4:0285bcbbc855 315 {
jhbr 4:0285bcbbc855 316 uint32_t now = dn_time_ms();
jhbr 4:0285bcbbc855 317 uint16_t delay = DN_CMD_PERIOD_MS;
jhbr 4:0285bcbbc855 318 static uint32_t lastTransition = 0;
jhbr 4:0285bcbbc855 319 if (lastTransition == 0)
jhbr 4:0285bcbbc855 320 lastTransition = now;
jhbr 4:0285bcbbc855 321
jhbr 4:0285bcbbc855 322 // Use default delay if none given
jhbr 4:0285bcbbc855 323 if (spesificDelay > 0)
jhbr 4:0285bcbbc855 324 delay = spesificDelay;
jhbr 4:0285bcbbc855 325
jhbr 4:0285bcbbc855 326 // Schedule default events for transition into states
jhbr 4:0285bcbbc855 327 switch (newState)
jhbr 4:0285bcbbc855 328 {
jhbr 4:0285bcbbc855 329 case DN_FSM_STATE_PRE_JOIN:
jhbr 4:0285bcbbc855 330 dn_fsm_scheduleEvent(delay, dn_event_getMoteStatus);
jhbr 4:0285bcbbc855 331 break;
jhbr 4:0285bcbbc855 332 case DN_FSM_STATE_PROMISCUOUS:
jhbr 4:0285bcbbc855 333 dn_fsm_scheduleEvent(delay, dn_event_search);
jhbr 4:0285bcbbc855 334 break;
jhbr 4:0285bcbbc855 335 case DN_FSM_STATE_JOINING:
jhbr 4:0285bcbbc855 336 dn_fsm_scheduleEvent(delay, dn_event_join);
jhbr 4:0285bcbbc855 337 break;
jhbr 4:0285bcbbc855 338 case DN_FSM_STATE_REQ_SERVICE:
jhbr 4:0285bcbbc855 339 dn_fsm_scheduleEvent(delay, dn_event_requestService);
jhbr 4:0285bcbbc855 340 break;
jhbr 4:0285bcbbc855 341 case DN_FSM_STATE_RESETTING:
jhbr 4:0285bcbbc855 342 if (DN_MOTE_DISCONNECT_BEFORE_RESET)
jhbr 4:0285bcbbc855 343 dn_fsm_scheduleEvent(delay, dn_event_disconnect); // More graceful
jhbr 4:0285bcbbc855 344 else
jhbr 4:0285bcbbc855 345 dn_fsm_scheduleEvent(delay, dn_event_reset); // Faster
jhbr 4:0285bcbbc855 346 break;
jhbr 4:0285bcbbc855 347 case DN_FSM_STATE_SENDING:
jhbr 4:0285bcbbc855 348 /*
jhbr 4:0285bcbbc855 349 Send is scheduled immediately because it is the users responsibility
jhbr 4:0285bcbbc855 350 to implement the necessary backoff and not exceed the granted bandwidth.
jhbr 4:0285bcbbc855 351 */
jhbr 4:0285bcbbc855 352 dn_fsm_scheduleEvent(0, dn_event_sendTo);
jhbr 4:0285bcbbc855 353 break;
jhbr 4:0285bcbbc855 354 case DN_FSM_STATE_SEND_FAILED:
jhbr 4:0285bcbbc855 355 case DN_FSM_STATE_DISCONNECTED:
jhbr 4:0285bcbbc855 356 case DN_FSM_STATE_CONNECTED:
jhbr 4:0285bcbbc855 357 // These states have no default entry events
jhbr 4:0285bcbbc855 358 break;
jhbr 4:0285bcbbc855 359 default:
jhbr 4:0285bcbbc855 360 log_warn("Attempt at entering unexpected state %#.2x", newState);
jhbr 4:0285bcbbc855 361 return;
jhbr 4:0285bcbbc855 362 }
jhbr 4:0285bcbbc855 363
jhbr 4:0285bcbbc855 364 debug("FSM state transition: %#.2x --> %#.2x (%u ms)",
jhbr 4:0285bcbbc855 365 dn_fsm_vars.state, newState, (uint32_t)(now - lastTransition));
jhbr 4:0285bcbbc855 366 lastTransition = now;
jhbr 4:0285bcbbc855 367 dn_fsm_vars.state = newState;
jhbr 4:0285bcbbc855 368 }
jhbr 4:0285bcbbc855 369
jhbr 4:0285bcbbc855 370 //===== cmdTimeout
jhbr 4:0285bcbbc855 371
jhbr 4:0285bcbbc855 372 /**
jhbr 4:0285bcbbc855 373 Correctly abort the current API command if time passed since the given start
jhbr 4:0285bcbbc855 374 has exceeded the given timeout.
jhbr 4:0285bcbbc855 375 */
jhbr 4:0285bcbbc855 376 static bool dn_fsm_cmd_timeout(uint32_t cmdStart_ms, uint32_t cmdTimeout_ms)
jhbr 4:0285bcbbc855 377 {
jhbr 4:0285bcbbc855 378 uint32_t timePassed_ms = dn_time_ms() - cmdStart_ms; // Handle dn_time_ms wrap around
jhbr 4:0285bcbbc855 379 bool timeout = timePassed_ms > cmdTimeout_ms;
jhbr 4:0285bcbbc855 380 if (timeout)
jhbr 4:0285bcbbc855 381 {
jhbr 4:0285bcbbc855 382 // Cancel any ongoing transmission or scheduled event and reset reply cb
jhbr 4:0285bcbbc855 383 dn_ipmt_cancelTx();
jhbr 4:0285bcbbc855 384 dn_fsm_vars.replyCb = NULL;
jhbr 4:0285bcbbc855 385 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 386
jhbr 4:0285bcbbc855 387 // Default timeout state is different while connecting vs sending
jhbr 4:0285bcbbc855 388 switch (dn_fsm_vars.state)
jhbr 4:0285bcbbc855 389 {
jhbr 4:0285bcbbc855 390 case DN_FSM_STATE_PRE_JOIN:
jhbr 4:0285bcbbc855 391 case DN_FSM_STATE_JOINING:
jhbr 4:0285bcbbc855 392 case DN_FSM_STATE_REQ_SERVICE:
jhbr 4:0285bcbbc855 393 case DN_FSM_STATE_RESETTING:
jhbr 4:0285bcbbc855 394 debug("Connect timeout");
jhbr 4:0285bcbbc855 395 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 396 break;
jhbr 4:0285bcbbc855 397 case DN_FSM_STATE_SENDING:
jhbr 4:0285bcbbc855 398 debug("Send timeout");
jhbr 4:0285bcbbc855 399 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0);
jhbr 4:0285bcbbc855 400 break;
jhbr 4:0285bcbbc855 401 default:
jhbr 4:0285bcbbc855 402 log_err("Command timeout in unexpected state: %#x", dn_fsm_vars.state);
jhbr 4:0285bcbbc855 403 break;
jhbr 4:0285bcbbc855 404 }
jhbr 4:0285bcbbc855 405 }
jhbr 4:0285bcbbc855 406 return timeout;
jhbr 4:0285bcbbc855 407 }
jhbr 4:0285bcbbc855 408
jhbr 4:0285bcbbc855 409 //========== C Library API
jhbr 4:0285bcbbc855 410
jhbr 4:0285bcbbc855 411 //===== notif_cb
jhbr 4:0285bcbbc855 412
jhbr 4:0285bcbbc855 413 /**
jhbr 4:0285bcbbc855 414 This function is called whenever a notification is received through the
jhbr 4:0285bcbbc855 415 SmartMesh C Library. The notification variables are than available through
jhbr 4:0285bcbbc855 416 the notification buffer that can be cast to the correct type based on the
jhbr 4:0285bcbbc855 417 given command ID (notification type).
jhbr 4:0285bcbbc855 418 */
jhbr 4:0285bcbbc855 419 static void dn_ipmt_notif_cb(uint8_t cmdId, uint8_t subCmdId)
jhbr 4:0285bcbbc855 420 {
jhbr 4:0285bcbbc855 421 //dn_ipmt_timeIndication_nt* notif_timeIndication;
jhbr 4:0285bcbbc855 422 dn_ipmt_events_nt* notif_events;
jhbr 4:0285bcbbc855 423 dn_ipmt_receive_nt* notif_receive;
jhbr 4:0285bcbbc855 424 //dn_ipmt_macRx_nt* notif_macRx;
jhbr 4:0285bcbbc855 425 //dn_ipmt_txDone_nt* notif_txDone;
jhbr 4:0285bcbbc855 426 dn_ipmt_advReceived_nt* notif_advReceived;
jhbr 4:0285bcbbc855 427
jhbr 4:0285bcbbc855 428 debug("Got notification: cmdId; %#.2x (%u), subCmdId; %#.2x (%u)",
jhbr 4:0285bcbbc855 429 cmdId, cmdId, subCmdId, subCmdId);
jhbr 4:0285bcbbc855 430
jhbr 4:0285bcbbc855 431 switch (cmdId)
jhbr 4:0285bcbbc855 432 {
jhbr 4:0285bcbbc855 433 case CMDID_TIMEINDICATION:
jhbr 4:0285bcbbc855 434 // Not implemented
jhbr 4:0285bcbbc855 435 break;
jhbr 4:0285bcbbc855 436 case CMDID_EVENTS:
jhbr 4:0285bcbbc855 437 notif_events = (dn_ipmt_events_nt*)dn_fsm_vars.notifBuf;
jhbr 4:0285bcbbc855 438 debug("State: %#.2x | Events: %#.4x", notif_events->state, notif_events->events);
jhbr 4:0285bcbbc855 439
jhbr 4:0285bcbbc855 440 // Check if in fsm state where we expect a certain mote event
jhbr 4:0285bcbbc855 441 switch (dn_fsm_vars.state)
jhbr 4:0285bcbbc855 442 {
jhbr 4:0285bcbbc855 443 case DN_FSM_STATE_JOINING:
jhbr 4:0285bcbbc855 444 if (notif_events->events & DN_MOTE_EVENT_MASK_OPERATIONAL)
jhbr 4:0285bcbbc855 445 {
jhbr 4:0285bcbbc855 446 // Join complete
jhbr 4:0285bcbbc855 447 if (dn_fsm_vars.service_ms > 0)
jhbr 4:0285bcbbc855 448 {
jhbr 4:0285bcbbc855 449 dn_fsm_enterState(DN_FSM_STATE_REQ_SERVICE, 0);
jhbr 4:0285bcbbc855 450 } else
jhbr 4:0285bcbbc855 451 {
jhbr 4:0285bcbbc855 452 dn_fsm_enterState(DN_FSM_STATE_CONNECTED, 0);
jhbr 4:0285bcbbc855 453 }
jhbr 4:0285bcbbc855 454 return;
jhbr 4:0285bcbbc855 455 }
jhbr 4:0285bcbbc855 456 break;
jhbr 4:0285bcbbc855 457 case DN_FSM_STATE_REQ_SERVICE:
jhbr 4:0285bcbbc855 458 if (notif_events->events & DN_MOTE_EVENT_MASK_SVC_CHANGE)
jhbr 4:0285bcbbc855 459 {
jhbr 4:0285bcbbc855 460 // Service request complete; check what we were granted
jhbr 4:0285bcbbc855 461 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_getServiceInfo);
jhbr 4:0285bcbbc855 462 return;
jhbr 4:0285bcbbc855 463 }
jhbr 4:0285bcbbc855 464 break;
jhbr 4:0285bcbbc855 465 }
jhbr 4:0285bcbbc855 466
jhbr 4:0285bcbbc855 467 // Check if reported mote state should trigger fsm state transition
jhbr 4:0285bcbbc855 468 switch (notif_events->state)
jhbr 4:0285bcbbc855 469 {
jhbr 4:0285bcbbc855 470 case DN_MOTE_STATE_IDLE:
jhbr 4:0285bcbbc855 471 switch (dn_fsm_vars.state)
jhbr 4:0285bcbbc855 472 {
jhbr 4:0285bcbbc855 473 case DN_FSM_STATE_PRE_JOIN:
jhbr 4:0285bcbbc855 474 case DN_FSM_STATE_JOINING:
jhbr 4:0285bcbbc855 475 case DN_FSM_STATE_REQ_SERVICE:
jhbr 4:0285bcbbc855 476 case DN_FSM_STATE_RESETTING:
jhbr 4:0285bcbbc855 477 case DN_FSM_STATE_PROMISCUOUS:
jhbr 4:0285bcbbc855 478 // Restart during connect; retry
jhbr 4:0285bcbbc855 479 dn_fsm_enterState(DN_FSM_STATE_PRE_JOIN, 0);
jhbr 4:0285bcbbc855 480 break;
jhbr 4:0285bcbbc855 481 case DN_FSM_STATE_CONNECTED:
jhbr 4:0285bcbbc855 482 case DN_FSM_STATE_SENDING:
jhbr 4:0285bcbbc855 483 case DN_FSM_STATE_SEND_FAILED:
jhbr 4:0285bcbbc855 484 // Disconnect/reset; set state accordingly
jhbr 4:0285bcbbc855 485 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 486 break;
jhbr 4:0285bcbbc855 487 }
jhbr 4:0285bcbbc855 488 break;
jhbr 4:0285bcbbc855 489 case DN_MOTE_STATE_OPERATIONAL:
jhbr 4:0285bcbbc855 490 switch (dn_fsm_vars.state)
jhbr 4:0285bcbbc855 491 {
jhbr 4:0285bcbbc855 492 case DN_FSM_STATE_PRE_JOIN:
jhbr 4:0285bcbbc855 493 case DN_FSM_STATE_PROMISCUOUS:
jhbr 4:0285bcbbc855 494 /*
jhbr 4:0285bcbbc855 495 Early (and unexpected) operational (connected to network)
jhbr 4:0285bcbbc855 496 during connect; reset and retry
jhbr 4:0285bcbbc855 497 */
jhbr 4:0285bcbbc855 498 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 499 break;
jhbr 4:0285bcbbc855 500 }
jhbr 4:0285bcbbc855 501 break;
jhbr 4:0285bcbbc855 502 }
jhbr 4:0285bcbbc855 503 break;
jhbr 4:0285bcbbc855 504 case CMDID_RECEIVE:
jhbr 4:0285bcbbc855 505 notif_receive = (dn_ipmt_receive_nt*)dn_fsm_vars.notifBuf;
jhbr 4:0285bcbbc855 506 debug("Received downstream data");
jhbr 4:0285bcbbc855 507
jhbr 4:0285bcbbc855 508 // Push payload at tail of inbox
jhbr 4:0285bcbbc855 509 memcpy
jhbr 4:0285bcbbc855 510 (
jhbr 4:0285bcbbc855 511 dn_fsm_vars.inbox.pktBuf[dn_fsm_vars.inbox.tail],
jhbr 4:0285bcbbc855 512 notif_receive->payload,
jhbr 4:0285bcbbc855 513 notif_receive->payloadLen
jhbr 4:0285bcbbc855 514 );
jhbr 4:0285bcbbc855 515 dn_fsm_vars.inbox.pktSize[dn_fsm_vars.inbox.tail] = notif_receive->payloadLen;
jhbr 4:0285bcbbc855 516 dn_fsm_vars.inbox.tail = (dn_fsm_vars.inbox.tail + 1) % DN_INBOX_SIZE;
jhbr 4:0285bcbbc855 517 if(dn_fsm_vars.inbox.unreadPackets == DN_INBOX_SIZE)
jhbr 4:0285bcbbc855 518 {
jhbr 4:0285bcbbc855 519 log_warn("Inbox overflow; oldest packet dropped");
jhbr 4:0285bcbbc855 520 } else
jhbr 4:0285bcbbc855 521 {
jhbr 4:0285bcbbc855 522 dn_fsm_vars.inbox.unreadPackets++;
jhbr 4:0285bcbbc855 523 }
jhbr 4:0285bcbbc855 524 debug("Inbox capacity at %u / %u", dn_fsm_vars.inbox.unreadPackets, DN_INBOX_SIZE);
jhbr 4:0285bcbbc855 525
jhbr 4:0285bcbbc855 526 break;
jhbr 4:0285bcbbc855 527 case CMDID_MACRX:
jhbr 4:0285bcbbc855 528 // Not implemented
jhbr 4:0285bcbbc855 529 break;
jhbr 4:0285bcbbc855 530 case CMDID_TXDONE:
jhbr 4:0285bcbbc855 531 // Not implemented
jhbr 4:0285bcbbc855 532 break;
jhbr 4:0285bcbbc855 533 case CMDID_ADVRECEIVED:
jhbr 4:0285bcbbc855 534 notif_advReceived = (dn_ipmt_advReceived_nt*)dn_fsm_vars.notifBuf;
jhbr 4:0285bcbbc855 535 debug("Received network advertisement");
jhbr 4:0285bcbbc855 536
jhbr 4:0285bcbbc855 537 if (dn_fsm_vars.state == DN_FSM_STATE_PROMISCUOUS
jhbr 4:0285bcbbc855 538 && dn_fsm_vars.networkId == DN_PROMISCUOUS_NET_ID)
jhbr 4:0285bcbbc855 539 {
jhbr 4:0285bcbbc855 540 debug("Saving network ID: %#.4x (%u)",
jhbr 4:0285bcbbc855 541 notif_advReceived->netId, notif_advReceived->netId);
jhbr 4:0285bcbbc855 542 dn_fsm_vars.networkId = notif_advReceived->netId;
jhbr 4:0285bcbbc855 543 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_setNetworkId);
jhbr 4:0285bcbbc855 544 }
jhbr 4:0285bcbbc855 545
jhbr 4:0285bcbbc855 546 break;
jhbr 4:0285bcbbc855 547 default:
jhbr 4:0285bcbbc855 548 log_warn("Unknown notification ID");
jhbr 4:0285bcbbc855 549 break;
jhbr 4:0285bcbbc855 550 }
jhbr 4:0285bcbbc855 551 }
jhbr 4:0285bcbbc855 552
jhbr 4:0285bcbbc855 553 //===== reply_cb
jhbr 4:0285bcbbc855 554
jhbr 4:0285bcbbc855 555 /**
jhbr 4:0285bcbbc855 556 This function is called whenever a reply is received through the SmartMesh.
jhbr 4:0285bcbbc855 557 C Library. It calls the reply function that was armed at the start of the
jhbr 4:0285bcbbc855 558 current event.
jhbr 4:0285bcbbc855 559 */
jhbr 4:0285bcbbc855 560 static void dn_ipmt_reply_cb(uint8_t cmdId)
jhbr 4:0285bcbbc855 561 {
jhbr 4:0285bcbbc855 562 debug("Got reply: cmdId; %#.2x (%u)", cmdId, cmdId);
jhbr 4:0285bcbbc855 563 if (dn_fsm_vars.replyCb == NULL)
jhbr 4:0285bcbbc855 564 {
jhbr 4:0285bcbbc855 565 debug("Reply callback empty");
jhbr 4:0285bcbbc855 566 return;
jhbr 4:0285bcbbc855 567 }
jhbr 4:0285bcbbc855 568 dn_fsm_vars.replyCb();
jhbr 4:0285bcbbc855 569 }
jhbr 4:0285bcbbc855 570
jhbr 4:0285bcbbc855 571 //===== response_timeout
jhbr 4:0285bcbbc855 572
jhbr 4:0285bcbbc855 573 /**
jhbr 4:0285bcbbc855 574 This event is scheduled after each mote API command is sent, effectively
jhbr 4:0285bcbbc855 575 placing a timeout for the mote to reply.
jhbr 4:0285bcbbc855 576 */
jhbr 4:0285bcbbc855 577 static void dn_event_responseTimeout(void)
jhbr 4:0285bcbbc855 578 {
jhbr 4:0285bcbbc855 579 debug("Response timeout");
jhbr 4:0285bcbbc855 580
jhbr 4:0285bcbbc855 581 // Cancel any ongoing transmission and reset reply cb
jhbr 4:0285bcbbc855 582 dn_ipmt_cancelTx();
jhbr 4:0285bcbbc855 583 dn_fsm_vars.replyCb = NULL;
jhbr 4:0285bcbbc855 584
jhbr 4:0285bcbbc855 585 switch (dn_fsm_vars.state)
jhbr 4:0285bcbbc855 586 {
jhbr 4:0285bcbbc855 587 case DN_FSM_STATE_PRE_JOIN:
jhbr 4:0285bcbbc855 588 case DN_FSM_STATE_JOINING:
jhbr 4:0285bcbbc855 589 case DN_FSM_STATE_REQ_SERVICE:
jhbr 4:0285bcbbc855 590 case DN_FSM_STATE_RESETTING:
jhbr 4:0285bcbbc855 591 case DN_FSM_STATE_PROMISCUOUS:
jhbr 4:0285bcbbc855 592 // Response timeout during connect; retry
jhbr 4:0285bcbbc855 593 dn_fsm_enterState(DN_FSM_STATE_PRE_JOIN, 0);
jhbr 4:0285bcbbc855 594 break;
jhbr 4:0285bcbbc855 595 case DN_FSM_STATE_SENDING:
jhbr 4:0285bcbbc855 596 // Response timeout during send; fail
jhbr 4:0285bcbbc855 597 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0);
jhbr 4:0285bcbbc855 598 break;
jhbr 4:0285bcbbc855 599 default:
jhbr 4:0285bcbbc855 600 log_err("Response timeout in unexpected state: %#x", dn_fsm_vars.state);
jhbr 4:0285bcbbc855 601 break;
jhbr 4:0285bcbbc855 602 }
jhbr 4:0285bcbbc855 603 }
jhbr 4:0285bcbbc855 604
jhbr 4:0285bcbbc855 605 //===== reset
jhbr 4:0285bcbbc855 606
jhbr 4:0285bcbbc855 607 /**
jhbr 4:0285bcbbc855 608 Initiates a soft-reset of the mote. Its reply simply checks that
jhbr 4:0285bcbbc855 609 the command was accepted, as the FSM will wait for the ensuing boot event.
jhbr 4:0285bcbbc855 610 */
jhbr 4:0285bcbbc855 611 static void dn_event_reset(void)
jhbr 4:0285bcbbc855 612 {
jhbr 4:0285bcbbc855 613 debug("Reset");
jhbr 4:0285bcbbc855 614 // Arm reply callback
jhbr 4:0285bcbbc855 615 dn_fsm_setReplyCallback(dn_reply_reset);
jhbr 4:0285bcbbc855 616
jhbr 4:0285bcbbc855 617 // Issue mote API command
jhbr 4:0285bcbbc855 618 dn_ipmt_reset
jhbr 4:0285bcbbc855 619 (
jhbr 4:0285bcbbc855 620 (dn_ipmt_reset_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 621 );
jhbr 4:0285bcbbc855 622
jhbr 4:0285bcbbc855 623 // Schedule timeout for reply
jhbr 4:0285bcbbc855 624 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 625 }
jhbr 4:0285bcbbc855 626
jhbr 4:0285bcbbc855 627 static void dn_reply_reset(void)
jhbr 4:0285bcbbc855 628 {
jhbr 4:0285bcbbc855 629 dn_ipmt_reset_rpt* reply;
jhbr 4:0285bcbbc855 630 debug("Reset reply");
jhbr 4:0285bcbbc855 631
jhbr 4:0285bcbbc855 632 // Cancel reply timeout
jhbr 4:0285bcbbc855 633 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 634
jhbr 4:0285bcbbc855 635 // Parse reply
jhbr 4:0285bcbbc855 636 reply = (dn_ipmt_reset_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 637
jhbr 4:0285bcbbc855 638 // Choose next event or state transition
jhbr 4:0285bcbbc855 639 switch (reply->RC)
jhbr 4:0285bcbbc855 640 {
jhbr 4:0285bcbbc855 641 case DN_RC_OK:
jhbr 4:0285bcbbc855 642 debug("Mote soft-reset initiated");
jhbr 4:0285bcbbc855 643 // Will wait for notification of reboot
jhbr 4:0285bcbbc855 644 break;
jhbr 4:0285bcbbc855 645 default:
jhbr 4:0285bcbbc855 646 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 647 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 648 break;
jhbr 4:0285bcbbc855 649 }
jhbr 4:0285bcbbc855 650 }
jhbr 4:0285bcbbc855 651
jhbr 4:0285bcbbc855 652 //===== disconnect
jhbr 4:0285bcbbc855 653
jhbr 4:0285bcbbc855 654 /**
jhbr 4:0285bcbbc855 655 This event does much the same as reset, however it uses the disconnect command
jhbr 4:0285bcbbc855 656 instead, where the mote first spends a couple of seconds notifying its
jhbr 4:0285bcbbc855 657 neighbors of its imminent soft-reset. If the reply is anything but success,
jhbr 4:0285bcbbc855 658 it will schedule a simple reset event instead.
jhbr 4:0285bcbbc855 659 */
jhbr 4:0285bcbbc855 660 static void dn_event_disconnect(void)
jhbr 4:0285bcbbc855 661 {
jhbr 4:0285bcbbc855 662 debug("Disconnect");
jhbr 4:0285bcbbc855 663
jhbr 4:0285bcbbc855 664 // Arm reply callback
jhbr 4:0285bcbbc855 665 dn_fsm_setReplyCallback(dn_reply_disconnect);
jhbr 4:0285bcbbc855 666
jhbr 4:0285bcbbc855 667 // Issue mote API command
jhbr 4:0285bcbbc855 668 dn_ipmt_disconnect
jhbr 4:0285bcbbc855 669 (
jhbr 4:0285bcbbc855 670 (dn_ipmt_disconnect_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 671 );
jhbr 4:0285bcbbc855 672
jhbr 4:0285bcbbc855 673 // Schedule timeout for reply
jhbr 4:0285bcbbc855 674 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 675 }
jhbr 4:0285bcbbc855 676
jhbr 4:0285bcbbc855 677 static void dn_reply_disconnect(void)
jhbr 4:0285bcbbc855 678 {
jhbr 4:0285bcbbc855 679 dn_ipmt_disconnect_rpt* reply;
jhbr 4:0285bcbbc855 680 debug("Disconnect reply");
jhbr 4:0285bcbbc855 681
jhbr 4:0285bcbbc855 682 // Cancel reply timeout
jhbr 4:0285bcbbc855 683 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 684
jhbr 4:0285bcbbc855 685 // Parse reply
jhbr 4:0285bcbbc855 686 reply = (dn_ipmt_disconnect_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 687
jhbr 4:0285bcbbc855 688 // Choose next event or state transition
jhbr 4:0285bcbbc855 689 switch (reply->RC)
jhbr 4:0285bcbbc855 690 {
jhbr 4:0285bcbbc855 691 case DN_RC_OK:
jhbr 4:0285bcbbc855 692 debug("Mote disconnect initiated");
jhbr 4:0285bcbbc855 693 // Will wait for notification of reboot
jhbr 4:0285bcbbc855 694 break;
jhbr 4:0285bcbbc855 695 case DN_RC_INVALID_STATE:
jhbr 4:0285bcbbc855 696 debug("The mote is in an invalid state to disconnect; resetting");
jhbr 4:0285bcbbc855 697 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_reset);
jhbr 4:0285bcbbc855 698 break;
jhbr 4:0285bcbbc855 699 default:
jhbr 4:0285bcbbc855 700 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 701 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_reset);
jhbr 4:0285bcbbc855 702 break;
jhbr 4:0285bcbbc855 703 }
jhbr 4:0285bcbbc855 704 }
jhbr 4:0285bcbbc855 705
jhbr 4:0285bcbbc855 706 //===== getMoteStatus
jhbr 4:0285bcbbc855 707
jhbr 4:0285bcbbc855 708 /**
jhbr 4:0285bcbbc855 709 Asks the mote for its status, and the reply will use the reported
jhbr 4:0285bcbbc855 710 mote state to decide whether or not it is ready to proceed with pre-join
jhbr 4:0285bcbbc855 711 configurations or if a reset is needed first.
jhbr 4:0285bcbbc855 712 */
jhbr 4:0285bcbbc855 713 static void dn_event_getMoteStatus(void)
jhbr 4:0285bcbbc855 714 {
jhbr 4:0285bcbbc855 715 debug("Mote status");
jhbr 4:0285bcbbc855 716
jhbr 4:0285bcbbc855 717 // Arm reply callback
jhbr 4:0285bcbbc855 718 dn_fsm_setReplyCallback(dn_reply_getMoteStatus);
jhbr 4:0285bcbbc855 719
jhbr 4:0285bcbbc855 720 // Issue mote API command
jhbr 4:0285bcbbc855 721 dn_ipmt_getParameter_moteStatus
jhbr 4:0285bcbbc855 722 (
jhbr 4:0285bcbbc855 723 (dn_ipmt_getParameter_moteStatus_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 724 );
jhbr 4:0285bcbbc855 725
jhbr 4:0285bcbbc855 726 // Schedule timeout for reply
jhbr 4:0285bcbbc855 727 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 728 }
jhbr 4:0285bcbbc855 729
jhbr 4:0285bcbbc855 730 static void dn_reply_getMoteStatus(void)
jhbr 4:0285bcbbc855 731 {
jhbr 4:0285bcbbc855 732 dn_ipmt_getParameter_moteStatus_rpt* reply;
jhbr 4:0285bcbbc855 733 debug("Mote status reply");
jhbr 4:0285bcbbc855 734
jhbr 4:0285bcbbc855 735 // Cancel reply timeout
jhbr 4:0285bcbbc855 736 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 737
jhbr 4:0285bcbbc855 738 // Parse reply
jhbr 4:0285bcbbc855 739 reply = (dn_ipmt_getParameter_moteStatus_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 740 debug("Mote state: %#.2x", reply->state);
jhbr 4:0285bcbbc855 741
jhbr 4:0285bcbbc855 742 // Choose next event or state transition
jhbr 4:0285bcbbc855 743 switch (reply->state)
jhbr 4:0285bcbbc855 744 {
jhbr 4:0285bcbbc855 745 case DN_MOTE_STATE_IDLE:
jhbr 4:0285bcbbc855 746 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_openSocket);
jhbr 4:0285bcbbc855 747 break;
jhbr 4:0285bcbbc855 748 case DN_MOTE_STATE_OPERATIONAL:
jhbr 4:0285bcbbc855 749 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 750 break;
jhbr 4:0285bcbbc855 751 default:
jhbr 4:0285bcbbc855 752 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 753 break;
jhbr 4:0285bcbbc855 754 }
jhbr 4:0285bcbbc855 755 }
jhbr 4:0285bcbbc855 756
jhbr 4:0285bcbbc855 757 //===== openSocket
jhbr 4:0285bcbbc855 758
jhbr 4:0285bcbbc855 759 /**
jhbr 4:0285bcbbc855 760 Tells the mote to open a socket, and the reply saves the reported
jhbr 4:0285bcbbc855 761 socket ID before scheduling its binding. If no sockets are available, a mote
jhbr 4:0285bcbbc855 762 reset is scheduled and the connect process starts over.
jhbr 4:0285bcbbc855 763 */
jhbr 4:0285bcbbc855 764 static void dn_event_openSocket(void)
jhbr 4:0285bcbbc855 765 {
jhbr 4:0285bcbbc855 766 debug("Open socket");
jhbr 4:0285bcbbc855 767
jhbr 4:0285bcbbc855 768 // Arm reply callback
jhbr 4:0285bcbbc855 769 dn_fsm_setReplyCallback(dn_reply_openSocket);
jhbr 4:0285bcbbc855 770
jhbr 4:0285bcbbc855 771 // Issue mote API command
jhbr 4:0285bcbbc855 772 dn_ipmt_openSocket
jhbr 4:0285bcbbc855 773 (
jhbr 4:0285bcbbc855 774 DN_PROTOCOL_TYPE_UDP,
jhbr 4:0285bcbbc855 775 (dn_ipmt_openSocket_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 776 );
jhbr 4:0285bcbbc855 777
jhbr 4:0285bcbbc855 778 // Schedule timeout for reply
jhbr 4:0285bcbbc855 779 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 780 }
jhbr 4:0285bcbbc855 781
jhbr 4:0285bcbbc855 782 static void dn_reply_openSocket(void)
jhbr 4:0285bcbbc855 783 {
jhbr 4:0285bcbbc855 784 dn_ipmt_openSocket_rpt* reply;
jhbr 4:0285bcbbc855 785 debug("Open socket reply");
jhbr 4:0285bcbbc855 786
jhbr 4:0285bcbbc855 787 // Cancel reply timeout
jhbr 4:0285bcbbc855 788 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 789
jhbr 4:0285bcbbc855 790 // Parse reply
jhbr 4:0285bcbbc855 791 reply = (dn_ipmt_openSocket_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 792
jhbr 4:0285bcbbc855 793 // Choose next event or state transition
jhbr 4:0285bcbbc855 794 switch (reply->RC)
jhbr 4:0285bcbbc855 795 {
jhbr 4:0285bcbbc855 796 case DN_RC_OK:
jhbr 4:0285bcbbc855 797 debug("Socket %d opened successfully", reply->socketId);
jhbr 4:0285bcbbc855 798 dn_fsm_vars.socketId = reply->socketId;
jhbr 4:0285bcbbc855 799 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_bindSocket);
jhbr 4:0285bcbbc855 800 break;
jhbr 4:0285bcbbc855 801 case DN_RC_NO_RESOURCES:
jhbr 4:0285bcbbc855 802 debug("Couldn't create socket due to resource availability");
jhbr 4:0285bcbbc855 803 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 804 break;
jhbr 4:0285bcbbc855 805 default:
jhbr 4:0285bcbbc855 806 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 807 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 808 break;
jhbr 4:0285bcbbc855 809 }
jhbr 4:0285bcbbc855 810 }
jhbr 4:0285bcbbc855 811
jhbr 4:0285bcbbc855 812 //===== bindSocket
jhbr 4:0285bcbbc855 813
jhbr 4:0285bcbbc855 814 /**
jhbr 4:0285bcbbc855 815 Binds the previously opened socket to a port. If said port is already bound,
jhbr 4:0285bcbbc855 816 a mote reset is scheduled and the connect process starts over.
jhbr 4:0285bcbbc855 817 */
jhbr 4:0285bcbbc855 818 static void dn_event_bindSocket(void)
jhbr 4:0285bcbbc855 819 {
jhbr 4:0285bcbbc855 820 debug("Bind socket");
jhbr 4:0285bcbbc855 821
jhbr 4:0285bcbbc855 822 // Arm reply callback
jhbr 4:0285bcbbc855 823 dn_fsm_setReplyCallback(dn_reply_bindSocket);
jhbr 4:0285bcbbc855 824
jhbr 4:0285bcbbc855 825 // Issue mote API command
jhbr 4:0285bcbbc855 826 dn_ipmt_bindSocket
jhbr 4:0285bcbbc855 827 (
jhbr 4:0285bcbbc855 828 dn_fsm_vars.socketId,
jhbr 4:0285bcbbc855 829 dn_fsm_vars.srcPort,
jhbr 4:0285bcbbc855 830 (dn_ipmt_bindSocket_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 831 );
jhbr 4:0285bcbbc855 832
jhbr 4:0285bcbbc855 833 // Schedule timeout for reply
jhbr 4:0285bcbbc855 834 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 835 }
jhbr 4:0285bcbbc855 836
jhbr 4:0285bcbbc855 837 static void dn_reply_bindSocket(void)
jhbr 4:0285bcbbc855 838 {
jhbr 4:0285bcbbc855 839 dn_ipmt_bindSocket_rpt* reply;
jhbr 4:0285bcbbc855 840 debug("Bind socket reply");
jhbr 4:0285bcbbc855 841
jhbr 4:0285bcbbc855 842 // Cancel reply timeout
jhbr 4:0285bcbbc855 843 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 844
jhbr 4:0285bcbbc855 845 // Parse reply
jhbr 4:0285bcbbc855 846 reply = (dn_ipmt_bindSocket_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 847
jhbr 4:0285bcbbc855 848 // Choose next event or state transition
jhbr 4:0285bcbbc855 849 switch (reply->RC)
jhbr 4:0285bcbbc855 850 {
jhbr 4:0285bcbbc855 851 case DN_RC_OK:
jhbr 4:0285bcbbc855 852 debug("Socket bound successfully");
jhbr 4:0285bcbbc855 853 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_setJoinKey);
jhbr 4:0285bcbbc855 854 break;
jhbr 4:0285bcbbc855 855 case DN_RC_BUSY:
jhbr 4:0285bcbbc855 856 debug("Port already bound");
jhbr 4:0285bcbbc855 857 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 858 break;
jhbr 4:0285bcbbc855 859 case DN_RC_NOT_FOUND:
jhbr 4:0285bcbbc855 860 debug("Invalid socket ID");
jhbr 4:0285bcbbc855 861 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 862 break;
jhbr 4:0285bcbbc855 863 default:
jhbr 4:0285bcbbc855 864 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 865 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 866 break;
jhbr 4:0285bcbbc855 867 }
jhbr 4:0285bcbbc855 868 }
jhbr 4:0285bcbbc855 869
jhbr 4:0285bcbbc855 870 //===== setJoinKey
jhbr 4:0285bcbbc855 871
jhbr 4:0285bcbbc855 872 /**
jhbr 4:0285bcbbc855 873 Configures the join key that the mote should use when attempting to join a
jhbr 4:0285bcbbc855 874 network.
jhbr 4:0285bcbbc855 875 */
jhbr 4:0285bcbbc855 876 static void dn_event_setJoinKey(void)
jhbr 4:0285bcbbc855 877 {
jhbr 4:0285bcbbc855 878 debug("Set join key");
jhbr 4:0285bcbbc855 879
jhbr 4:0285bcbbc855 880 // Arm reply callback
jhbr 4:0285bcbbc855 881 dn_fsm_setReplyCallback(dn_reply_setJoinKey);
jhbr 4:0285bcbbc855 882
jhbr 4:0285bcbbc855 883 // Issue mote API command
jhbr 4:0285bcbbc855 884 dn_ipmt_setParameter_joinKey
jhbr 4:0285bcbbc855 885 (
jhbr 4:0285bcbbc855 886 dn_fsm_vars.joinKey,
jhbr 4:0285bcbbc855 887 (dn_ipmt_setParameter_joinKey_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 888 );
jhbr 4:0285bcbbc855 889
jhbr 4:0285bcbbc855 890 // Schedule timeout for reply
jhbr 4:0285bcbbc855 891 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 892 }
jhbr 4:0285bcbbc855 893
jhbr 4:0285bcbbc855 894 static void dn_reply_setJoinKey(void)
jhbr 4:0285bcbbc855 895 {
jhbr 4:0285bcbbc855 896 dn_ipmt_setParameter_joinKey_rpt* reply;
jhbr 4:0285bcbbc855 897 debug("Set join key reply");
jhbr 4:0285bcbbc855 898
jhbr 4:0285bcbbc855 899 // Cancel reply timeout
jhbr 4:0285bcbbc855 900 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 901
jhbr 4:0285bcbbc855 902 // Parse reply
jhbr 4:0285bcbbc855 903 reply = (dn_ipmt_setParameter_joinKey_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 904
jhbr 4:0285bcbbc855 905 // Choose next event or state transition
jhbr 4:0285bcbbc855 906 switch (reply->RC)
jhbr 4:0285bcbbc855 907 {
jhbr 4:0285bcbbc855 908 case DN_RC_OK:
jhbr 4:0285bcbbc855 909 debug("Join key set");
jhbr 4:0285bcbbc855 910 if (dn_fsm_vars.networkId == DN_PROMISCUOUS_NET_ID)
jhbr 4:0285bcbbc855 911 {
jhbr 4:0285bcbbc855 912 // Promiscuous netID set; search for new first
jhbr 4:0285bcbbc855 913 dn_fsm_enterState(DN_FSM_STATE_PROMISCUOUS, 0);
jhbr 4:0285bcbbc855 914 /*
jhbr 4:0285bcbbc855 915 As of version 1.4.x, a network ID of 0xFFFF can be used to indicate
jhbr 4:0285bcbbc855 916 that the mote should join the first network heard. Thus, searching
jhbr 4:0285bcbbc855 917 before joining will not be necessary.
jhbr 4:0285bcbbc855 918 */
jhbr 4:0285bcbbc855 919 } else
jhbr 4:0285bcbbc855 920 {
jhbr 4:0285bcbbc855 921 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_setNetworkId);
jhbr 4:0285bcbbc855 922 }
jhbr 4:0285bcbbc855 923 break;
jhbr 4:0285bcbbc855 924 case DN_RC_WRITE_FAIL:
jhbr 4:0285bcbbc855 925 debug("Could not write the key to storage");
jhbr 4:0285bcbbc855 926 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 927 break;
jhbr 4:0285bcbbc855 928 default:
jhbr 4:0285bcbbc855 929 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 930 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 931 break;
jhbr 4:0285bcbbc855 932 }
jhbr 4:0285bcbbc855 933 }
jhbr 4:0285bcbbc855 934
jhbr 4:0285bcbbc855 935 //===== setNetworkId
jhbr 4:0285bcbbc855 936
jhbr 4:0285bcbbc855 937 /**
jhbr 4:0285bcbbc855 938 Configures the ID of the network that the mote should should try to join.
jhbr 4:0285bcbbc855 939 */
jhbr 4:0285bcbbc855 940 static void dn_event_setNetworkId(void)
jhbr 4:0285bcbbc855 941 {
jhbr 4:0285bcbbc855 942 debug("Set network ID");
jhbr 4:0285bcbbc855 943
jhbr 4:0285bcbbc855 944 // Arm reply callback
jhbr 4:0285bcbbc855 945 dn_fsm_setReplyCallback(dn_reply_setNetworkId);
jhbr 4:0285bcbbc855 946
jhbr 4:0285bcbbc855 947 // Issue mote API command
jhbr 4:0285bcbbc855 948 dn_ipmt_setParameter_networkId
jhbr 4:0285bcbbc855 949 (
jhbr 4:0285bcbbc855 950 dn_fsm_vars.networkId,
jhbr 4:0285bcbbc855 951 (dn_ipmt_setParameter_networkId_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 952 );
jhbr 4:0285bcbbc855 953
jhbr 4:0285bcbbc855 954 // Schedule timeout for reply
jhbr 4:0285bcbbc855 955 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 956 }
jhbr 4:0285bcbbc855 957
jhbr 4:0285bcbbc855 958 static void dn_reply_setNetworkId(void)
jhbr 4:0285bcbbc855 959 {
jhbr 4:0285bcbbc855 960 dn_ipmt_setParameter_networkId_rpt* reply;
jhbr 4:0285bcbbc855 961 debug("Set network ID reply");
jhbr 4:0285bcbbc855 962
jhbr 4:0285bcbbc855 963 // Cancel reply timeout
jhbr 4:0285bcbbc855 964 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 965
jhbr 4:0285bcbbc855 966 // Parse reply
jhbr 4:0285bcbbc855 967 reply = (dn_ipmt_setParameter_networkId_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 968
jhbr 4:0285bcbbc855 969 // Choose next event or state transition
jhbr 4:0285bcbbc855 970 switch (reply->RC)
jhbr 4:0285bcbbc855 971 {
jhbr 4:0285bcbbc855 972 case DN_RC_OK:
jhbr 4:0285bcbbc855 973 debug("Network ID set");
jhbr 4:0285bcbbc855 974 dn_fsm_enterState(DN_FSM_STATE_JOINING, 0);
jhbr 4:0285bcbbc855 975 break;
jhbr 4:0285bcbbc855 976 case DN_RC_WRITE_FAIL:
jhbr 4:0285bcbbc855 977 debug("Could not write the network ID to storage");
jhbr 4:0285bcbbc855 978 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 979 break;
jhbr 4:0285bcbbc855 980 default:
jhbr 4:0285bcbbc855 981 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 982 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 983 break;
jhbr 4:0285bcbbc855 984 }
jhbr 4:0285bcbbc855 985 }
jhbr 4:0285bcbbc855 986
jhbr 4:0285bcbbc855 987 //===== search
jhbr 4:0285bcbbc855 988
jhbr 4:0285bcbbc855 989 /**
jhbr 4:0285bcbbc855 990 Tells the mote to start listening for network advertisements. The mote will
jhbr 4:0285bcbbc855 991 then report the network ID (among other things) of any advertisements heard.
jhbr 4:0285bcbbc855 992 Upon a successful reply, the FSM will wait for an advReceived notification,
jhbr 4:0285bcbbc855 993 before attempting to join the reported network.
jhbr 4:0285bcbbc855 994 */
jhbr 4:0285bcbbc855 995 static void dn_event_search(void)
jhbr 4:0285bcbbc855 996 {
jhbr 4:0285bcbbc855 997 debug("Search");
jhbr 4:0285bcbbc855 998
jhbr 4:0285bcbbc855 999 // Arm reply callback
jhbr 4:0285bcbbc855 1000 dn_fsm_setReplyCallback(dn_reply_search);
jhbr 4:0285bcbbc855 1001
jhbr 4:0285bcbbc855 1002 // Issue mote API command
jhbr 4:0285bcbbc855 1003 dn_ipmt_search
jhbr 4:0285bcbbc855 1004 (
jhbr 4:0285bcbbc855 1005 (dn_ipmt_search_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 1006 );
jhbr 4:0285bcbbc855 1007
jhbr 4:0285bcbbc855 1008 // Schedule timeout for reply
jhbr 4:0285bcbbc855 1009 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 1010 }
jhbr 4:0285bcbbc855 1011
jhbr 4:0285bcbbc855 1012 static void dn_reply_search(void)
jhbr 4:0285bcbbc855 1013 {
jhbr 4:0285bcbbc855 1014 dn_ipmt_search_rpt* reply;
jhbr 4:0285bcbbc855 1015 debug("Search reply");
jhbr 4:0285bcbbc855 1016
jhbr 4:0285bcbbc855 1017 // Cancel reply timeout
jhbr 4:0285bcbbc855 1018 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 1019
jhbr 4:0285bcbbc855 1020 // Parse reply
jhbr 4:0285bcbbc855 1021 reply = (dn_ipmt_search_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 1022
jhbr 4:0285bcbbc855 1023 // Choose next event or state transition
jhbr 4:0285bcbbc855 1024 switch (reply->RC)
jhbr 4:0285bcbbc855 1025 {
jhbr 4:0285bcbbc855 1026 case DN_RC_OK:
jhbr 4:0285bcbbc855 1027 debug("Searching for network advertisements");
jhbr 4:0285bcbbc855 1028 // Will wait for notification of advertisement received
jhbr 4:0285bcbbc855 1029 break;
jhbr 4:0285bcbbc855 1030 case DN_RC_INVALID_STATE:
jhbr 4:0285bcbbc855 1031 debug("The mote is in an invalid state to start searching");
jhbr 4:0285bcbbc855 1032 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 1033 break;
jhbr 4:0285bcbbc855 1034 default:
jhbr 4:0285bcbbc855 1035 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 1036 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 1037 break;
jhbr 4:0285bcbbc855 1038 }
jhbr 4:0285bcbbc855 1039 }
jhbr 4:0285bcbbc855 1040
jhbr 4:0285bcbbc855 1041 //===== join
jhbr 4:0285bcbbc855 1042
jhbr 4:0285bcbbc855 1043 /**
jhbr 4:0285bcbbc855 1044 Requests that the mote start searching for the previously configured network
jhbr 4:0285bcbbc855 1045 and attempt to join with the configured join key. If the mote is in an invalid
jhbr 4:0285bcbbc855 1046 state to join or lacks configuration to start joining, a reset is scheduled and
jhbr 4:0285bcbbc855 1047 the connect procedure starts over. Otherwise the FSM will wait for the ensuing
jhbr 4:0285bcbbc855 1048 operational event when the mote has finished joining.
jhbr 4:0285bcbbc855 1049 */
jhbr 4:0285bcbbc855 1050 static void dn_event_join(void)
jhbr 4:0285bcbbc855 1051 {
jhbr 4:0285bcbbc855 1052 debug("Join");
jhbr 4:0285bcbbc855 1053
jhbr 4:0285bcbbc855 1054 // Arm reply callback
jhbr 4:0285bcbbc855 1055 dn_fsm_setReplyCallback(dn_reply_join);
jhbr 4:0285bcbbc855 1056
jhbr 4:0285bcbbc855 1057 // Issue mote API command
jhbr 4:0285bcbbc855 1058 dn_ipmt_join
jhbr 4:0285bcbbc855 1059 (
jhbr 4:0285bcbbc855 1060 (dn_ipmt_join_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 1061 );
jhbr 4:0285bcbbc855 1062
jhbr 4:0285bcbbc855 1063 // Schedule timeout for reply
jhbr 4:0285bcbbc855 1064 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 1065 }
jhbr 4:0285bcbbc855 1066
jhbr 4:0285bcbbc855 1067 static void dn_reply_join(void)
jhbr 4:0285bcbbc855 1068 {
jhbr 4:0285bcbbc855 1069 dn_ipmt_join_rpt* reply;
jhbr 4:0285bcbbc855 1070 debug("Join reply");
jhbr 4:0285bcbbc855 1071
jhbr 4:0285bcbbc855 1072 // Cancel reply timeout
jhbr 4:0285bcbbc855 1073 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 1074
jhbr 4:0285bcbbc855 1075 // Parse reply
jhbr 4:0285bcbbc855 1076 reply = (dn_ipmt_join_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 1077
jhbr 4:0285bcbbc855 1078 // Choose next event or state transition
jhbr 4:0285bcbbc855 1079 switch (reply->RC)
jhbr 4:0285bcbbc855 1080 {
jhbr 4:0285bcbbc855 1081 case DN_RC_OK:
jhbr 4:0285bcbbc855 1082 debug("Join operation started");
jhbr 4:0285bcbbc855 1083 // Will wait for join complete notification (operational event)
jhbr 4:0285bcbbc855 1084 break;
jhbr 4:0285bcbbc855 1085 case DN_RC_INVALID_STATE:
jhbr 4:0285bcbbc855 1086 debug("The mote is in an invalid state to start join operation");
jhbr 4:0285bcbbc855 1087 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 1088 break;
jhbr 4:0285bcbbc855 1089 case DN_RC_INCOMPLETE_JOIN_INFO:
jhbr 4:0285bcbbc855 1090 debug("Incomplete configuration to start joining");
jhbr 4:0285bcbbc855 1091 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0);
jhbr 4:0285bcbbc855 1092 break;
jhbr 4:0285bcbbc855 1093 default:
jhbr 4:0285bcbbc855 1094 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 1095 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 1096 break;
jhbr 4:0285bcbbc855 1097 }
jhbr 4:0285bcbbc855 1098 }
jhbr 4:0285bcbbc855 1099
jhbr 4:0285bcbbc855 1100 //===== requestService
jhbr 4:0285bcbbc855 1101
jhbr 4:0285bcbbc855 1102 /**
jhbr 4:0285bcbbc855 1103 The mote is told to request a new service level from the manager. Its reply
jhbr 4:0285bcbbc855 1104 simply checks that the command was accepted, as the FSM will wait for the
jhbr 4:0285bcbbc855 1105 ensuing svcChange event when the service allocation has changed.
jhbr 4:0285bcbbc855 1106 */
jhbr 4:0285bcbbc855 1107 static void dn_event_requestService(void)
jhbr 4:0285bcbbc855 1108 {
jhbr 4:0285bcbbc855 1109 debug("Request service");
jhbr 4:0285bcbbc855 1110
jhbr 4:0285bcbbc855 1111 // Arm reply callback
jhbr 4:0285bcbbc855 1112 dn_fsm_setReplyCallback(dn_reply_requestService);
jhbr 4:0285bcbbc855 1113
jhbr 4:0285bcbbc855 1114 // Issue mote API command
jhbr 4:0285bcbbc855 1115 dn_ipmt_requestService
jhbr 4:0285bcbbc855 1116 (
jhbr 4:0285bcbbc855 1117 DN_SERVICE_ADDRESS,
jhbr 4:0285bcbbc855 1118 DN_SERVICE_TYPE_BW,
jhbr 4:0285bcbbc855 1119 dn_fsm_vars.service_ms,
jhbr 4:0285bcbbc855 1120 (dn_ipmt_requestService_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 1121 );
jhbr 4:0285bcbbc855 1122
jhbr 4:0285bcbbc855 1123 // Schedule timeout for reply
jhbr 4:0285bcbbc855 1124 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 1125 }
jhbr 4:0285bcbbc855 1126
jhbr 4:0285bcbbc855 1127 static void dn_reply_requestService(void)
jhbr 4:0285bcbbc855 1128 {
jhbr 4:0285bcbbc855 1129 dn_ipmt_requestService_rpt* reply;
jhbr 4:0285bcbbc855 1130 debug("Request service reply");
jhbr 4:0285bcbbc855 1131
jhbr 4:0285bcbbc855 1132 // Cancel reply timeout
jhbr 4:0285bcbbc855 1133 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 1134
jhbr 4:0285bcbbc855 1135 // Parse reply
jhbr 4:0285bcbbc855 1136 reply = (dn_ipmt_requestService_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 1137
jhbr 4:0285bcbbc855 1138 // Choose next event or state transition
jhbr 4:0285bcbbc855 1139 switch (reply->RC)
jhbr 4:0285bcbbc855 1140 {
jhbr 4:0285bcbbc855 1141 case DN_RC_OK:
jhbr 4:0285bcbbc855 1142 debug("Service request accepted");
jhbr 4:0285bcbbc855 1143 // Will wait for svcChanged notification
jhbr 4:0285bcbbc855 1144 break;
jhbr 4:0285bcbbc855 1145 default:
jhbr 4:0285bcbbc855 1146 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 1147 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 1148 break;
jhbr 4:0285bcbbc855 1149 }
jhbr 4:0285bcbbc855 1150 }
jhbr 4:0285bcbbc855 1151
jhbr 4:0285bcbbc855 1152 //===== getServiceInfo
jhbr 4:0285bcbbc855 1153
jhbr 4:0285bcbbc855 1154 /**
jhbr 4:0285bcbbc855 1155 Requests details about the service currently allocated to the mote. Its reply
jhbr 4:0285bcbbc855 1156 checks that we have been granted a service equal to or better than what was
jhbr 4:0285bcbbc855 1157 requested (smaller value equals better).
jhbr 4:0285bcbbc855 1158 */
jhbr 4:0285bcbbc855 1159 static void dn_event_getServiceInfo(void)
jhbr 4:0285bcbbc855 1160 {
jhbr 4:0285bcbbc855 1161 debug("Get service info");
jhbr 4:0285bcbbc855 1162
jhbr 4:0285bcbbc855 1163 // Arm reply callback
jhbr 4:0285bcbbc855 1164 dn_fsm_setReplyCallback(dn_reply_getServiceInfo);
jhbr 4:0285bcbbc855 1165
jhbr 4:0285bcbbc855 1166 // Issue mote API command
jhbr 4:0285bcbbc855 1167 dn_ipmt_getServiceInfo
jhbr 4:0285bcbbc855 1168 (
jhbr 4:0285bcbbc855 1169 DN_SERVICE_ADDRESS,
jhbr 4:0285bcbbc855 1170 DN_SERVICE_TYPE_BW,
jhbr 4:0285bcbbc855 1171 (dn_ipmt_getServiceInfo_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 1172 );
jhbr 4:0285bcbbc855 1173
jhbr 4:0285bcbbc855 1174 // Schedule timeout for reply
jhbr 4:0285bcbbc855 1175 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 1176 }
jhbr 4:0285bcbbc855 1177
jhbr 4:0285bcbbc855 1178 static void dn_reply_getServiceInfo(void)
jhbr 4:0285bcbbc855 1179 {
jhbr 4:0285bcbbc855 1180 dn_ipmt_getServiceInfo_rpt* reply;
jhbr 4:0285bcbbc855 1181 debug("Get service info reply");
jhbr 4:0285bcbbc855 1182
jhbr 4:0285bcbbc855 1183 // Cancel reply timeout
jhbr 4:0285bcbbc855 1184 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 1185
jhbr 4:0285bcbbc855 1186 // Parse reply
jhbr 4:0285bcbbc855 1187 reply = (dn_ipmt_getServiceInfo_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 1188
jhbr 4:0285bcbbc855 1189 // Choose next event or state transition
jhbr 4:0285bcbbc855 1190 switch (reply->RC)
jhbr 4:0285bcbbc855 1191 {
jhbr 4:0285bcbbc855 1192 case DN_RC_OK:
jhbr 4:0285bcbbc855 1193 if (reply->state == DN_SERVICE_STATE_COMPLETED)
jhbr 4:0285bcbbc855 1194 {
jhbr 4:0285bcbbc855 1195 if (reply->value <= dn_fsm_vars.service_ms)
jhbr 4:0285bcbbc855 1196 {
jhbr 4:0285bcbbc855 1197 debug("Granted service of %u ms (requested %u ms)", reply->value, dn_fsm_vars.service_ms);
jhbr 4:0285bcbbc855 1198 dn_fsm_enterState(DN_FSM_STATE_CONNECTED, 0);
jhbr 4:0285bcbbc855 1199 } else
jhbr 4:0285bcbbc855 1200 {
jhbr 4:0285bcbbc855 1201 log_warn("Only granted service of %u ms (requested %u ms)", reply->value, dn_fsm_vars.service_ms);
jhbr 4:0285bcbbc855 1202 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 1203 }
jhbr 4:0285bcbbc855 1204
jhbr 4:0285bcbbc855 1205 } else
jhbr 4:0285bcbbc855 1206 {
jhbr 4:0285bcbbc855 1207 debug("Service request still pending");
jhbr 4:0285bcbbc855 1208 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_getServiceInfo);
jhbr 4:0285bcbbc855 1209 }
jhbr 4:0285bcbbc855 1210 break;
jhbr 4:0285bcbbc855 1211 default:
jhbr 4:0285bcbbc855 1212 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 1213 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0);
jhbr 4:0285bcbbc855 1214 break;
jhbr 4:0285bcbbc855 1215 }
jhbr 4:0285bcbbc855 1216 }
jhbr 4:0285bcbbc855 1217
jhbr 4:0285bcbbc855 1218 //===== sendTo
jhbr 4:0285bcbbc855 1219
jhbr 4:0285bcbbc855 1220 /**
jhbr 4:0285bcbbc855 1221 This event sends a packet into the network, and its reply checks that it was
jhbr 4:0285bcbbc855 1222 accepted and queued up for transmission.
jhbr 4:0285bcbbc855 1223 */
jhbr 4:0285bcbbc855 1224 static void dn_event_sendTo(void)
jhbr 4:0285bcbbc855 1225 {
jhbr 4:0285bcbbc855 1226 dn_err_t err;
jhbr 4:0285bcbbc855 1227 debug("Send");
jhbr 4:0285bcbbc855 1228
jhbr 4:0285bcbbc855 1229 // Arm reply callback
jhbr 4:0285bcbbc855 1230 dn_fsm_setReplyCallback(dn_reply_sendTo);
jhbr 4:0285bcbbc855 1231
jhbr 4:0285bcbbc855 1232 // Issue mote API command
jhbr 4:0285bcbbc855 1233 err = dn_ipmt_sendTo
jhbr 4:0285bcbbc855 1234 (
jhbr 4:0285bcbbc855 1235 dn_fsm_vars.socketId,
jhbr 4:0285bcbbc855 1236 dn_fsm_vars.destIPv6,
jhbr 4:0285bcbbc855 1237 dn_fsm_vars.destPort,
jhbr 4:0285bcbbc855 1238 DN_SERVICE_TYPE_BW,
jhbr 4:0285bcbbc855 1239 DN_PACKET_PRIORITY_MEDIUM,
jhbr 4:0285bcbbc855 1240 DN_PACKET_ID_NO_NOTIF,
jhbr 4:0285bcbbc855 1241 dn_fsm_vars.payloadBuf,
jhbr 4:0285bcbbc855 1242 dn_fsm_vars.payloadSize,
jhbr 4:0285bcbbc855 1243 (dn_ipmt_sendTo_rpt*)dn_fsm_vars.replyBuf
jhbr 4:0285bcbbc855 1244 );
jhbr 4:0285bcbbc855 1245 if (err != DN_ERR_NONE)
jhbr 4:0285bcbbc855 1246 {
jhbr 4:0285bcbbc855 1247 debug("Send error: %u", err);
jhbr 4:0285bcbbc855 1248 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0);
jhbr 4:0285bcbbc855 1249 }
jhbr 4:0285bcbbc855 1250
jhbr 4:0285bcbbc855 1251 // Schedule timeout for reply
jhbr 4:0285bcbbc855 1252 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout);
jhbr 4:0285bcbbc855 1253 }
jhbr 4:0285bcbbc855 1254
jhbr 4:0285bcbbc855 1255 static void dn_reply_sendTo(void)
jhbr 4:0285bcbbc855 1256 {
jhbr 4:0285bcbbc855 1257 dn_ipmt_sendTo_rpt* reply;
jhbr 4:0285bcbbc855 1258 debug("Send reply");
jhbr 4:0285bcbbc855 1259
jhbr 4:0285bcbbc855 1260 // Cancel reply timeout
jhbr 4:0285bcbbc855 1261 dn_fsm_cancelEvent();
jhbr 4:0285bcbbc855 1262
jhbr 4:0285bcbbc855 1263 // Parse reply
jhbr 4:0285bcbbc855 1264 reply = (dn_ipmt_sendTo_rpt*)dn_fsm_vars.replyBuf;
jhbr 4:0285bcbbc855 1265
jhbr 4:0285bcbbc855 1266 // Choose next event or state transition
jhbr 4:0285bcbbc855 1267 switch (reply->RC)
jhbr 4:0285bcbbc855 1268 {
jhbr 4:0285bcbbc855 1269 case DN_RC_OK:
jhbr 4:0285bcbbc855 1270 debug("Packet was queued up for transmission");
jhbr 4:0285bcbbc855 1271 dn_fsm_enterState(DN_FSM_STATE_CONNECTED, 0);
jhbr 4:0285bcbbc855 1272 break;
jhbr 4:0285bcbbc855 1273 case DN_RC_NO_RESOURCES:
jhbr 4:0285bcbbc855 1274 debug("No queue space to accept the packet");
jhbr 4:0285bcbbc855 1275 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0);
jhbr 4:0285bcbbc855 1276 break;
jhbr 4:0285bcbbc855 1277 default:
jhbr 4:0285bcbbc855 1278 log_warn("Unexpected response code: %#x", reply->RC);
jhbr 4:0285bcbbc855 1279 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0);
jhbr 4:0285bcbbc855 1280 break;
jhbr 4:0285bcbbc855 1281 }
jhbr 4:0285bcbbc855 1282 }
jhbr 4:0285bcbbc855 1283
jhbr 4:0285bcbbc855 1284 //=========================== helpers =========================================
jhbr 4:0285bcbbc855 1285
jhbr 4:0285bcbbc855 1286 static dn_err_t checkAndSaveNetConfig(uint16_t netID, const uint8_t* joinKey, uint16_t srcPort, uint32_t req_service_ms)
jhbr 4:0285bcbbc855 1287 {
jhbr 4:0285bcbbc855 1288 if (netID == 0)
jhbr 4:0285bcbbc855 1289 {
jhbr 4:0285bcbbc855 1290 debug("No network ID given; using default");
jhbr 4:0285bcbbc855 1291 dn_fsm_vars.networkId = DN_DEFAULT_NET_ID;
jhbr 4:0285bcbbc855 1292 } else if (netID == DN_PROMISCUOUS_NET_ID)
jhbr 4:0285bcbbc855 1293 {
jhbr 4:0285bcbbc855 1294 debug("Promiscuous network ID given; will search for and join first network advertised");
jhbr 4:0285bcbbc855 1295 dn_fsm_vars.networkId = netID;
jhbr 4:0285bcbbc855 1296 } else
jhbr 4:0285bcbbc855 1297 {
jhbr 4:0285bcbbc855 1298 dn_fsm_vars.networkId = netID;
jhbr 4:0285bcbbc855 1299 }
jhbr 4:0285bcbbc855 1300
jhbr 4:0285bcbbc855 1301 if (joinKey == NULL)
jhbr 4:0285bcbbc855 1302 {
jhbr 4:0285bcbbc855 1303 debug("No join key given; using default");
jhbr 4:0285bcbbc855 1304 memcpy(dn_fsm_vars.joinKey, DN_DEFAULT_JOIN_KEY, DN_JOIN_KEY_LEN);
jhbr 4:0285bcbbc855 1305 } else
jhbr 4:0285bcbbc855 1306 {
jhbr 4:0285bcbbc855 1307 memcpy(dn_fsm_vars.joinKey, joinKey, DN_JOIN_KEY_LEN);
jhbr 4:0285bcbbc855 1308 }
jhbr 4:0285bcbbc855 1309
jhbr 4:0285bcbbc855 1310 if (srcPort == 0)
jhbr 4:0285bcbbc855 1311 {
jhbr 4:0285bcbbc855 1312 debug("No source port given; using default");
jhbr 4:0285bcbbc855 1313 dn_fsm_vars.srcPort = DN_DEFAULT_SRC_PORT;
jhbr 4:0285bcbbc855 1314 } else
jhbr 4:0285bcbbc855 1315 {
jhbr 4:0285bcbbc855 1316 dn_fsm_vars.srcPort = srcPort;
jhbr 4:0285bcbbc855 1317 }
jhbr 4:0285bcbbc855 1318
jhbr 4:0285bcbbc855 1319 if (req_service_ms == 0)
jhbr 4:0285bcbbc855 1320 {
jhbr 4:0285bcbbc855 1321 debug("No service requested; will only be granted base bandwidth");
jhbr 4:0285bcbbc855 1322 }
jhbr 4:0285bcbbc855 1323 dn_fsm_vars.service_ms = req_service_ms;
jhbr 4:0285bcbbc855 1324
jhbr 4:0285bcbbc855 1325 return DN_ERR_NONE;
jhbr 4:0285bcbbc855 1326 }
jhbr 4:0285bcbbc855 1327
jhbr 4:0285bcbbc855 1328 static uint8_t getPayloadLimit(uint16_t destPort)
jhbr 4:0285bcbbc855 1329 {
jhbr 4:0285bcbbc855 1330 bool destIsF0Bx = (destPort >= DN_WELL_KNOWN_PORT_1 && destPort <= DN_WELL_KNOWN_PORT_8);
jhbr 4:0285bcbbc855 1331 bool srcIsF0Bx = (dn_fsm_vars.srcPort >= DN_WELL_KNOWN_PORT_1 && dn_fsm_vars.srcPort <= DN_WELL_KNOWN_PORT_8);
jhbr 4:0285bcbbc855 1332 int8_t destIsMng = memcmp(DN_DEST_IP, DN_DEFAULT_DEST_IP, DN_IPv6ADDR_LEN);
jhbr 4:0285bcbbc855 1333
jhbr 4:0285bcbbc855 1334 if (destIsMng == 0)
jhbr 4:0285bcbbc855 1335 {
jhbr 4:0285bcbbc855 1336 if (destIsF0Bx && srcIsF0Bx)
jhbr 4:0285bcbbc855 1337 return DN_PAYLOAD_SIZE_LIMIT_MNG_HIGH;
jhbr 4:0285bcbbc855 1338 else if (destIsF0Bx || srcIsF0Bx)
jhbr 4:0285bcbbc855 1339 return DN_PAYLOAD_SIZE_LIMIT_MNG_MED;
jhbr 4:0285bcbbc855 1340 else
jhbr 4:0285bcbbc855 1341 return DN_PAYLOAD_SIZE_LIMIT_MNG_LOW;
jhbr 4:0285bcbbc855 1342 } else
jhbr 4:0285bcbbc855 1343 {
jhbr 4:0285bcbbc855 1344 if (destIsF0Bx && srcIsF0Bx)
jhbr 4:0285bcbbc855 1345 return DN_PAYLOAD_SIZE_LIMIT_IP_HIGH;
jhbr 4:0285bcbbc855 1346 else if (destIsF0Bx || srcIsF0Bx)
jhbr 4:0285bcbbc855 1347 return DN_PAYLOAD_SIZE_LIMIT_IP_MED;
jhbr 4:0285bcbbc855 1348 else
jhbr 4:0285bcbbc855 1349 return DN_PAYLOAD_SIZE_LIMIT_IP_LOW;
jhbr 4:0285bcbbc855 1350 }
jhbr 4:0285bcbbc855 1351 }
jhbr 4:0285bcbbc855 1352