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