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