APS Lab
/
STM32F4_SmartMesh_QSL
SmartMesh QSL for STM32F4 version
Fork of COG-AD4050_QSL by
Embed:
(wiki syntax)
Show/hide line numbers
dn_fsm.c
00001 /* 00002 Copyright (c) 2016, Dust Networks. All rights reserved. 00003 00004 Finite State Machine for the QuickStart Library. 00005 00006 \license See attached DN_LICENSE.txt. 00007 */ 00008 00009 #include "dn_fsm.h" 00010 #include "dn_ipmt.h" 00011 #include "dn_time.h" 00012 #include "dn_watchdog.h" 00013 #include "dn_qsl_api.h" 00014 #include "dn_debug.h" 00015 00016 //=========================== variables ======================================= 00017 00018 typedef struct 00019 { 00020 // FSM 00021 uint32_t fsmEventScheduled_ms; 00022 uint16_t fsmDelay_ms; 00023 bool fsmArmed; 00024 uint8_t state; 00025 // C Library API 00026 dn_fsm_reply_cbt replyCb; 00027 dn_fsm_timer_cbt fsmCb; 00028 uint8_t replyBuf[MAX_FRAME_LENGTH]; 00029 uint8_t notifBuf[MAX_FRAME_LENGTH]; 00030 // Connection 00031 uint8_t socketId; 00032 uint16_t networkId; 00033 uint8_t joinKey[DN_JOIN_KEY_LEN]; 00034 uint16_t srcPort; 00035 uint32_t service_ms; 00036 uint8_t payloadBuf[DN_DEFAULT_PAYLOAD_SIZE_LIMIT]; 00037 uint8_t payloadSize; 00038 uint8_t destIPv6[DN_IPv6ADDR_LEN]; 00039 uint16_t destPort; 00040 dn_inbox_t inbox; 00041 } dn_fsm_vars_t; 00042 00043 static dn_fsm_vars_t dn_fsm_vars; 00044 00045 00046 //=========================== prototypes ====================================== 00047 // FSM 00048 static void dn_fsm_run(void); 00049 static void dn_fsm_scheduleEvent(uint16_t delay, dn_fsm_timer_cbt cb); 00050 static void dn_fsm_cancelEvent(void); 00051 static void dn_fsm_setReplyCallback(dn_fsm_reply_cbt cb); 00052 static void dn_fsm_enterState(uint8_t newState, uint16_t spesificDelay); 00053 static bool dn_fsm_cmd_timeout(uint32_t cmdStart_ms, uint32_t cmdTimeout_ms); 00054 // C Library API 00055 static void dn_ipmt_notif_cb(uint8_t cmdId, uint8_t subCmdId); 00056 static void dn_ipmt_reply_cb(uint8_t cmdId); 00057 static void dn_event_responseTimeout(void); 00058 static void dn_event_reset(void); 00059 static void dn_reply_reset(void); 00060 static void dn_event_disconnect(void); 00061 static void dn_reply_disconnect(void); 00062 static void dn_event_getMoteStatus(void); 00063 static void dn_reply_getMoteStatus(void); 00064 static void dn_event_openSocket(void); 00065 static void dn_reply_openSocket(void); 00066 static void dn_event_bindSocket(void); 00067 static void dn_reply_bindSocket(void); 00068 static void dn_event_setJoinKey(void); 00069 static void dn_reply_setJoinKey(void); 00070 static void dn_event_setNetworkId(void); 00071 static void dn_reply_setNetworkId(void); 00072 static void dn_event_search(void); 00073 static void dn_reply_search(void); 00074 static void dn_event_join(void); 00075 static void dn_reply_join(void); 00076 static void dn_event_requestService(void); 00077 static void dn_reply_requestService(void); 00078 static void dn_event_getServiceInfo(void); 00079 static void dn_reply_getServiceInfo(void); 00080 static void dn_event_sendTo(void); 00081 static void dn_reply_sendTo(void); 00082 // helpers 00083 static dn_err_t checkAndSaveNetConfig(uint16_t netID, const uint8_t* joinKey, uint16_t srcPort, uint32_t req_service_ms); 00084 static uint8_t getPayloadLimit(uint16_t destPort); 00085 00086 //=========================== public ========================================== 00087 00088 //========== QSL API 00089 00090 bool dn_qsl_init(void) 00091 { 00092 //debug("QSL: Init"); 00093 // Reset local variables 00094 memset(&dn_fsm_vars, 0, sizeof (dn_fsm_vars)); 00095 00096 // Initialize the ipmt module 00097 dn_ipmt_init // Should be augmented with return value to know if successful... 00098 ( 00099 dn_ipmt_notif_cb, 00100 dn_fsm_vars.notifBuf, 00101 sizeof (dn_fsm_vars.notifBuf), 00102 dn_ipmt_reply_cb 00103 ); 00104 00105 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00106 return TRUE; 00107 } 00108 00109 bool dn_qsl_isConnected(void) 00110 { 00111 //debug("QSL: isConnected"); 00112 return dn_fsm_vars.state == DN_FSM_STATE_CONNECTED; 00113 } 00114 00115 bool dn_qsl_connect(uint16_t netID, const uint8_t* joinKey, uint16_t srcPort, uint32_t req_service_ms) 00116 { 00117 uint32_t cmdStart_ms = dn_time_ms(); 00118 dn_err_t err; 00119 //debug("QSL: Connect"); 00120 switch (dn_fsm_vars.state) 00121 { 00122 case DN_FSM_STATE_NOT_INITIALIZED: 00123 //log_warn("Can't connect; not initialized"); 00124 return FALSE; 00125 case DN_FSM_STATE_DISCONNECTED: 00126 err = checkAndSaveNetConfig(netID, joinKey, srcPort, req_service_ms); 00127 if (err != DN_ERR_NONE) 00128 { 00129 return FALSE; 00130 } 00131 //debug("Starting connect process..."); 00132 dn_fsm_enterState(DN_FSM_STATE_PRE_JOIN, 0); 00133 break; 00134 case DN_FSM_STATE_CONNECTED: 00135 if ((netID > 0 && netID != dn_fsm_vars.networkId) 00136 || (joinKey != NULL && memcmp(joinKey, dn_fsm_vars.joinKey, DN_JOIN_KEY_LEN) != 0) 00137 || (srcPort > 0 && srcPort != dn_fsm_vars.srcPort)) 00138 { 00139 err = checkAndSaveNetConfig(netID, joinKey, srcPort, req_service_ms); 00140 if (err != DN_ERR_NONE) 00141 { 00142 return FALSE; 00143 } 00144 //debug("New network ID, join key and/or source port; reconnecting..."); 00145 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 00146 } else if (req_service_ms > 0 && req_service_ms != dn_fsm_vars.service_ms) 00147 { 00148 //debug("New service request"); 00149 dn_fsm_vars.service_ms = req_service_ms; 00150 dn_fsm_enterState(DN_FSM_STATE_REQ_SERVICE, 0); 00151 } else 00152 { 00153 //debug("Already connected"); 00154 // Nothing to do 00155 } 00156 break; 00157 default: 00158 //log_err("Unexpected state"); 00159 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00160 return FALSE; 00161 } 00162 00163 // Drive FSM until connect success/failure or timeout 00164 while (dn_fsm_vars.state != DN_FSM_STATE_CONNECTED 00165 && dn_fsm_vars.state != DN_FSM_STATE_DISCONNECTED 00166 && !dn_fsm_cmd_timeout(cmdStart_ms, DN_CONNECT_TIMEOUT_S * 1000)) 00167 { 00168 dn_watchdog_feed(); 00169 dn_fsm_run(); 00170 } 00171 00172 return dn_fsm_vars.state == DN_FSM_STATE_CONNECTED; 00173 } 00174 00175 bool dn_qsl_send(const uint8_t* payload, uint8_t payloadSize_B, uint16_t destPort) 00176 { 00177 uint32_t cmdStart_ms = dn_time_ms(); 00178 uint8_t maxPayloadSize; 00179 //debug("QSL: Send"); 00180 switch (dn_fsm_vars.state) 00181 { 00182 case DN_FSM_STATE_CONNECTED: 00183 maxPayloadSize = getPayloadLimit(destPort); 00184 00185 if (payloadSize_B > maxPayloadSize) 00186 { 00187 //log_warn("Payload size (%u) exceeds limit (%u)", payloadSize_B, maxPayloadSize); 00188 return FALSE; 00189 } 00190 // Store outbound payload and parameters 00191 memcpy(dn_fsm_vars.payloadBuf, payload, payloadSize_B); 00192 dn_fsm_vars.payloadSize = payloadSize_B; 00193 memcpy(dn_fsm_vars.destIPv6, DN_DEST_IP, DN_IPv6ADDR_LEN); 00194 dn_fsm_vars.destPort = (destPort > 0) ? destPort : DN_DEFAULT_DEST_PORT; 00195 // Start send process 00196 dn_fsm_enterState(DN_FSM_STATE_SENDING, 0); 00197 break; 00198 default: 00199 //log_warn("Can't send; not connected"); 00200 return FALSE; 00201 } 00202 00203 // Drive FSM until send success/failure or timeout 00204 while (dn_fsm_vars.state == DN_FSM_STATE_SENDING 00205 && !dn_fsm_cmd_timeout(cmdStart_ms, DN_SEND_TIMEOUT_MS)) 00206 { 00207 dn_watchdog_feed(); 00208 dn_fsm_run(); 00209 } 00210 00211 // Catch send failure 00212 if (dn_fsm_vars.state == DN_FSM_STATE_SEND_FAILED) 00213 { 00214 //debug("Send failed"); 00215 dn_fsm_enterState(DN_FSM_STATE_CONNECTED, 0); 00216 return FALSE; 00217 } 00218 00219 return dn_fsm_vars.state == DN_FSM_STATE_CONNECTED; 00220 } 00221 00222 uint8_t dn_qsl_read(uint8_t* readBuffer) 00223 { 00224 uint8_t bytesRead = 0; 00225 //debug("QSL: Read"); 00226 if (dn_fsm_vars.inbox.unreadPackets > 0) 00227 { 00228 // Pop payload at head of inbox 00229 memcpy 00230 ( 00231 readBuffer, 00232 dn_fsm_vars.inbox.pktBuf[dn_fsm_vars.inbox.head], 00233 dn_fsm_vars.inbox.pktSize[dn_fsm_vars.inbox.head] 00234 ); 00235 bytesRead = dn_fsm_vars.inbox.pktSize[dn_fsm_vars.inbox.head]; 00236 dn_fsm_vars.inbox.head = (dn_fsm_vars.inbox.head + 1) % DN_INBOX_SIZE; 00237 dn_fsm_vars.inbox.unreadPackets--; 00238 //debug("Read %u bytes from inbox", bytesRead); 00239 } else 00240 { 00241 //debug("Inbox empty"); 00242 } 00243 return bytesRead; 00244 } 00245 00246 //=========================== private ========================================= 00247 00248 //========== FSM 00249 00250 //===== run 00251 00252 /** 00253 Check if an event is scheduled and run it if due. 00254 */ 00255 static void dn_fsm_run(void) 00256 { 00257 uint32_t timePassed_ms = dn_time_ms() - dn_fsm_vars.fsmEventScheduled_ms; // Handle dn_time_ms wrap around 00258 if (dn_fsm_vars.fsmArmed && (timePassed_ms > dn_fsm_vars.fsmDelay_ms)) 00259 { 00260 // Scheduled event is due; execute it 00261 dn_fsm_vars.fsmArmed = FALSE; 00262 if (dn_fsm_vars.fsmCb != NULL) 00263 { 00264 dn_fsm_vars.fsmCb(); 00265 } 00266 } else 00267 { 00268 // Sleep to save CPU power 00269 dn_sleep_ms(DN_FSM_RUN_INTERVAL_MS); 00270 } 00271 } 00272 00273 //===== scheduleEvent 00274 00275 /** 00276 Schedule function to be called after a given delay. 00277 */ 00278 static void dn_fsm_scheduleEvent(uint16_t delay_ms, dn_fsm_timer_cbt cb) 00279 { 00280 dn_fsm_vars.fsmEventScheduled_ms = dn_time_ms(); 00281 dn_fsm_vars.fsmDelay_ms = delay_ms; 00282 dn_fsm_vars.fsmCb = cb; 00283 dn_fsm_vars.fsmArmed = TRUE; 00284 } 00285 00286 //===== cancelEvent 00287 00288 /** 00289 Cancel currently scheduled event. 00290 */ 00291 static void dn_fsm_cancelEvent(void) 00292 { 00293 dn_fsm_vars.fsmDelay_ms = 0; 00294 dn_fsm_vars.fsmCb = NULL; 00295 dn_fsm_vars.fsmArmed = FALSE; 00296 } 00297 00298 //===== setReplyCallback 00299 00300 /** 00301 Set the callback function that the C Library will execute when the next reply 00302 is received and the reply buffer is ready to be parsed. 00303 */ 00304 static void dn_fsm_setReplyCallback(dn_fsm_reply_cbt cb) 00305 { 00306 dn_fsm_vars.replyCb = cb; 00307 } 00308 00309 //===== enterState 00310 00311 /** 00312 Transition FSM to new state and schedule any default entry events. 00313 */ 00314 static void dn_fsm_enterState(uint8_t newState, uint16_t spesificDelay) 00315 { 00316 uint32_t now = dn_time_ms(); 00317 uint16_t delay = DN_CMD_PERIOD_MS; 00318 static uint32_t lastTransition = 0; 00319 if (lastTransition == 0) 00320 lastTransition = now; 00321 00322 // Use default delay if none given 00323 if (spesificDelay > 0) 00324 delay = spesificDelay; 00325 00326 // Schedule default events for transition into states 00327 switch (newState) 00328 { 00329 case DN_FSM_STATE_PRE_JOIN: 00330 dn_fsm_scheduleEvent(delay, dn_event_getMoteStatus); 00331 break; 00332 case DN_FSM_STATE_PROMISCUOUS: 00333 dn_fsm_scheduleEvent(delay, dn_event_search); 00334 break; 00335 case DN_FSM_STATE_JOINING: 00336 dn_fsm_scheduleEvent(delay, dn_event_join); 00337 break; 00338 case DN_FSM_STATE_REQ_SERVICE: 00339 dn_fsm_scheduleEvent(delay, dn_event_requestService); 00340 break; 00341 case DN_FSM_STATE_RESETTING: 00342 if (DN_MOTE_DISCONNECT_BEFORE_RESET) 00343 dn_fsm_scheduleEvent(delay, dn_event_disconnect); // More graceful 00344 else 00345 dn_fsm_scheduleEvent(delay, dn_event_reset); // Faster 00346 break; 00347 case DN_FSM_STATE_SENDING: 00348 /* 00349 Send is scheduled immediately because it is the users responsibility 00350 to implement the necessary backoff and not exceed the granted bandwidth. 00351 */ 00352 dn_fsm_scheduleEvent(0, dn_event_sendTo); 00353 break; 00354 case DN_FSM_STATE_SEND_FAILED: 00355 case DN_FSM_STATE_DISCONNECTED: 00356 case DN_FSM_STATE_CONNECTED: 00357 // These states have no default entry events 00358 break; 00359 default: 00360 //log_warn("Attempt at entering unexpected state %#.2x", newState); 00361 return; 00362 } 00363 00364 //debug("FSM state transition: %#.2x --> %#.2x (%u ms)", 00365 //dn_fsm_vars.state, newState, (uint32_t)(now - lastTransition)); 00366 lastTransition = now; 00367 dn_fsm_vars.state = newState; 00368 } 00369 00370 //===== cmdTimeout 00371 00372 /** 00373 Correctly abort the current API command if time passed since the given start 00374 has exceeded the given timeout. 00375 */ 00376 static bool dn_fsm_cmd_timeout(uint32_t cmdStart_ms, uint32_t cmdTimeout_ms) 00377 { 00378 uint32_t timePassed_ms = dn_time_ms() - cmdStart_ms; // Handle dn_time_ms wrap around 00379 bool timeout = timePassed_ms > cmdTimeout_ms; 00380 if (timeout) 00381 { 00382 // Cancel any ongoing transmission or scheduled event and reset reply cb 00383 dn_ipmt_cancelTx(); 00384 dn_fsm_vars.replyCb = NULL; 00385 dn_fsm_cancelEvent(); 00386 00387 // Default timeout state is different while connecting vs sending 00388 switch (dn_fsm_vars.state) 00389 { 00390 case DN_FSM_STATE_PRE_JOIN: 00391 case DN_FSM_STATE_JOINING: 00392 case DN_FSM_STATE_REQ_SERVICE: 00393 case DN_FSM_STATE_RESETTING: 00394 //debug("Connect timeout"); 00395 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00396 break; 00397 case DN_FSM_STATE_SENDING: 00398 //debug("Send timeout"); 00399 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0); 00400 break; 00401 default: 00402 //log_err("Command timeout in unexpected state: %#x", dn_fsm_vars.state); 00403 break; 00404 } 00405 } 00406 return timeout; 00407 } 00408 00409 //========== C Library API 00410 00411 //===== notif_cb 00412 00413 /** 00414 This function is called whenever a notification is received through the 00415 SmartMesh C Library. The notification variables are than available through 00416 the notification buffer that can be cast to the correct type based on the 00417 given command ID (notification type). 00418 */ 00419 static void dn_ipmt_notif_cb(uint8_t cmdId, uint8_t subCmdId) 00420 { 00421 //dn_ipmt_timeIndication_nt* notif_timeIndication; 00422 dn_ipmt_events_nt* notif_events; 00423 dn_ipmt_receive_nt* notif_receive; 00424 //dn_ipmt_macRx_nt* notif_macRx; 00425 //dn_ipmt_txDone_nt* notif_txDone; 00426 dn_ipmt_advReceived_nt* notif_advReceived; 00427 00428 //debug("Got notification: cmdId; %#.2x (%u), subCmdId; %#.2x (%u)", 00429 //cmdId, cmdId, subCmdId, subCmdId); 00430 00431 switch (cmdId) 00432 { 00433 case CMDID_TIMEINDICATION: 00434 // Not implemented 00435 break; 00436 case CMDID_EVENTS: 00437 notif_events = (dn_ipmt_events_nt*)dn_fsm_vars.notifBuf; 00438 //debug("State: %#.2x | Events: %#.4x", notif_events->state, notif_events->events); 00439 00440 // Check if in fsm state where we expect a certain mote event 00441 switch (dn_fsm_vars.state) 00442 { 00443 case DN_FSM_STATE_JOINING: 00444 if (notif_events->events & DN_MOTE_EVENT_MASK_OPERATIONAL) 00445 { 00446 // Join complete 00447 if (dn_fsm_vars.service_ms > 0) 00448 { 00449 dn_fsm_enterState(DN_FSM_STATE_REQ_SERVICE, 0); 00450 } else 00451 { 00452 dn_fsm_enterState(DN_FSM_STATE_CONNECTED, 0); 00453 } 00454 return; 00455 } 00456 break; 00457 case DN_FSM_STATE_REQ_SERVICE: 00458 if (notif_events->events & DN_MOTE_EVENT_MASK_SVC_CHANGE) 00459 { 00460 // Service request complete; check what we were granted 00461 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_getServiceInfo); 00462 return; 00463 } 00464 break; 00465 } 00466 00467 // Check if reported mote state should trigger fsm state transition 00468 switch (notif_events->state) 00469 { 00470 case DN_MOTE_STATE_IDLE: 00471 switch (dn_fsm_vars.state) 00472 { 00473 case DN_FSM_STATE_PRE_JOIN: 00474 case DN_FSM_STATE_JOINING: 00475 case DN_FSM_STATE_REQ_SERVICE: 00476 case DN_FSM_STATE_RESETTING: 00477 case DN_FSM_STATE_PROMISCUOUS: 00478 // Restart during connect; retry 00479 dn_fsm_enterState(DN_FSM_STATE_PRE_JOIN, 0); 00480 break; 00481 case DN_FSM_STATE_CONNECTED: 00482 case DN_FSM_STATE_SENDING: 00483 case DN_FSM_STATE_SEND_FAILED: 00484 // Disconnect/reset; set state accordingly 00485 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00486 break; 00487 } 00488 break; 00489 case DN_MOTE_STATE_OPERATIONAL: 00490 switch (dn_fsm_vars.state) 00491 { 00492 case DN_FSM_STATE_PRE_JOIN: 00493 case DN_FSM_STATE_PROMISCUOUS: 00494 /* 00495 Early (and unexpected) operational (connected to network) 00496 during connect; reset and retry 00497 */ 00498 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 00499 break; 00500 } 00501 break; 00502 } 00503 break; 00504 case CMDID_RECEIVE: 00505 notif_receive = (dn_ipmt_receive_nt*)dn_fsm_vars.notifBuf; 00506 //debug("Received downstream data"); 00507 00508 // Push payload at tail of inbox 00509 memcpy 00510 ( 00511 dn_fsm_vars.inbox.pktBuf[dn_fsm_vars.inbox.tail], 00512 notif_receive->payload, 00513 notif_receive->payloadLen 00514 ); 00515 dn_fsm_vars.inbox.pktSize[dn_fsm_vars.inbox.tail] = notif_receive->payloadLen; 00516 dn_fsm_vars.inbox.tail = (dn_fsm_vars.inbox.tail + 1) % DN_INBOX_SIZE; 00517 if(dn_fsm_vars.inbox.unreadPackets == DN_INBOX_SIZE) 00518 { 00519 //log_warn("Inbox overflow; oldest packet dropped"); 00520 } else 00521 { 00522 dn_fsm_vars.inbox.unreadPackets++; 00523 } 00524 //debug("Inbox capacity at %u / %u", dn_fsm_vars.inbox.unreadPackets, DN_INBOX_SIZE); 00525 00526 break; 00527 case CMDID_MACRX: 00528 // Not implemented 00529 break; 00530 case CMDID_TXDONE: 00531 // Not implemented 00532 break; 00533 case CMDID_ADVRECEIVED: 00534 notif_advReceived = (dn_ipmt_advReceived_nt*)dn_fsm_vars.notifBuf; 00535 //debug("Received network advertisement"); 00536 00537 if (dn_fsm_vars.state == DN_FSM_STATE_PROMISCUOUS 00538 && dn_fsm_vars.networkId == DN_PROMISCUOUS_NET_ID) 00539 { 00540 //debug("Saving network ID: %#.4x (%u)", 00541 //notif_advReceived->netId, notif_advReceived->netId); 00542 dn_fsm_vars.networkId = notif_advReceived->netId; 00543 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_setNetworkId); 00544 } 00545 00546 break; 00547 default: 00548 //log_warn("Unknown notification ID"); 00549 break; 00550 } 00551 } 00552 00553 //===== reply_cb 00554 00555 /** 00556 This function is called whenever a reply is received through the SmartMesh. 00557 C Library. It calls the reply function that was armed at the start of the 00558 current event. 00559 */ 00560 static void dn_ipmt_reply_cb(uint8_t cmdId) 00561 { 00562 //debug("Got reply: cmdId; %#.2x (%u)", cmdId, cmdId); 00563 if (dn_fsm_vars.replyCb == NULL) 00564 { 00565 //debug("Reply callback empty"); 00566 return; 00567 } 00568 dn_fsm_vars.replyCb(); 00569 } 00570 00571 //===== response_timeout 00572 00573 /** 00574 This event is scheduled after each mote API command is sent, effectively 00575 placing a timeout for the mote to reply. 00576 */ 00577 static void dn_event_responseTimeout(void) 00578 { 00579 //debug("Response timeout"); 00580 00581 // Cancel any ongoing transmission and reset reply cb 00582 dn_ipmt_cancelTx(); 00583 dn_fsm_vars.replyCb = NULL; 00584 00585 switch (dn_fsm_vars.state) 00586 { 00587 case DN_FSM_STATE_PRE_JOIN: 00588 case DN_FSM_STATE_JOINING: 00589 case DN_FSM_STATE_REQ_SERVICE: 00590 case DN_FSM_STATE_RESETTING: 00591 case DN_FSM_STATE_PROMISCUOUS: 00592 // Response timeout during connect; retry 00593 dn_fsm_enterState(DN_FSM_STATE_PRE_JOIN, 0); 00594 break; 00595 case DN_FSM_STATE_SENDING: 00596 // Response timeout during send; fail 00597 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0); 00598 break; 00599 default: 00600 //log_err("Response timeout in unexpected state: %#x", dn_fsm_vars.state); 00601 break; 00602 } 00603 } 00604 00605 //===== reset 00606 00607 /** 00608 Initiates a soft-reset of the mote. Its reply simply checks that 00609 the command was accepted, as the FSM will wait for the ensuing boot event. 00610 */ 00611 static void dn_event_reset(void) 00612 { 00613 //debug("Reset"); 00614 // Arm reply callback 00615 dn_fsm_setReplyCallback(dn_reply_reset); 00616 00617 // Issue mote API command 00618 dn_ipmt_reset 00619 ( 00620 (dn_ipmt_reset_rpt*)dn_fsm_vars.replyBuf 00621 ); 00622 00623 // Schedule timeout for reply 00624 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 00625 } 00626 00627 static void dn_reply_reset(void) 00628 { 00629 dn_ipmt_reset_rpt* reply; 00630 //debug("Reset reply"); 00631 00632 // Cancel reply timeout 00633 dn_fsm_cancelEvent(); 00634 00635 // Parse reply 00636 reply = (dn_ipmt_reset_rpt*)dn_fsm_vars.replyBuf; 00637 00638 // Choose next event or state transition 00639 switch (reply->RC) 00640 { 00641 case DN_RC_OK: 00642 //debug("Mote soft-reset initiated"); 00643 // Will wait for notification of reboot 00644 break; 00645 default: 00646 //log_warn("Unexpected response code: %#x", reply->RC); 00647 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00648 break; 00649 } 00650 } 00651 00652 //===== disconnect 00653 00654 /** 00655 This event does much the same as reset, however it uses the disconnect command 00656 instead, where the mote first spends a couple of seconds notifying its 00657 neighbors of its imminent soft-reset. If the reply is anything but success, 00658 it will schedule a simple reset event instead. 00659 */ 00660 static void dn_event_disconnect(void) 00661 { 00662 //debug("Disconnect"); 00663 00664 // Arm reply callback 00665 dn_fsm_setReplyCallback(dn_reply_disconnect); 00666 00667 // Issue mote API command 00668 dn_ipmt_disconnect 00669 ( 00670 (dn_ipmt_disconnect_rpt*)dn_fsm_vars.replyBuf 00671 ); 00672 00673 // Schedule timeout for reply 00674 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 00675 } 00676 00677 static void dn_reply_disconnect(void) 00678 { 00679 dn_ipmt_disconnect_rpt* reply; 00680 //debug("Disconnect reply"); 00681 00682 // Cancel reply timeout 00683 dn_fsm_cancelEvent(); 00684 00685 // Parse reply 00686 reply = (dn_ipmt_disconnect_rpt*)dn_fsm_vars.replyBuf; 00687 00688 // Choose next event or state transition 00689 switch (reply->RC) 00690 { 00691 case DN_RC_OK: 00692 //debug("Mote disconnect initiated"); 00693 // Will wait for notification of reboot 00694 break; 00695 case DN_RC_INVALID_STATE: 00696 //debug("The mote is in an invalid state to disconnect; resetting"); 00697 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_reset); 00698 break; 00699 default: 00700 //log_warn("Unexpected response code: %#x", reply->RC); 00701 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_reset); 00702 break; 00703 } 00704 } 00705 00706 //===== getMoteStatus 00707 00708 /** 00709 Asks the mote for its status, and the reply will use the reported 00710 mote state to decide whether or not it is ready to proceed with pre-join 00711 configurations or if a reset is needed first. 00712 */ 00713 static void dn_event_getMoteStatus(void) 00714 { 00715 //debug("Mote status"); 00716 00717 // Arm reply callback 00718 dn_fsm_setReplyCallback(dn_reply_getMoteStatus); 00719 00720 // Issue mote API command 00721 dn_ipmt_getParameter_moteStatus 00722 ( 00723 (dn_ipmt_getParameter_moteStatus_rpt*)dn_fsm_vars.replyBuf 00724 ); 00725 00726 // Schedule timeout for reply 00727 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 00728 } 00729 00730 static void dn_reply_getMoteStatus(void) 00731 { 00732 dn_ipmt_getParameter_moteStatus_rpt* reply; 00733 //debug("Mote status reply"); 00734 00735 // Cancel reply timeout 00736 dn_fsm_cancelEvent(); 00737 00738 // Parse reply 00739 reply = (dn_ipmt_getParameter_moteStatus_rpt*)dn_fsm_vars.replyBuf; 00740 //debug("Mote state: %#.2x", reply->state); 00741 00742 // Choose next event or state transition 00743 switch (reply->state) 00744 { 00745 case DN_MOTE_STATE_IDLE: 00746 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_openSocket); 00747 break; 00748 case DN_MOTE_STATE_OPERATIONAL: 00749 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 00750 break; 00751 default: 00752 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 00753 break; 00754 } 00755 } 00756 00757 //===== openSocket 00758 00759 /** 00760 Tells the mote to open a socket, and the reply saves the reported 00761 socket ID before scheduling its binding. If no sockets are available, a mote 00762 reset is scheduled and the connect process starts over. 00763 */ 00764 static void dn_event_openSocket(void) 00765 { 00766 //debug("Open socket"); 00767 00768 // Arm reply callback 00769 dn_fsm_setReplyCallback(dn_reply_openSocket); 00770 00771 // Issue mote API command 00772 dn_ipmt_openSocket 00773 ( 00774 DN_PROTOCOL_TYPE_UDP, 00775 (dn_ipmt_openSocket_rpt*)dn_fsm_vars.replyBuf 00776 ); 00777 00778 // Schedule timeout for reply 00779 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 00780 } 00781 00782 static void dn_reply_openSocket(void) 00783 { 00784 dn_ipmt_openSocket_rpt* reply; 00785 //debug("Open socket reply"); 00786 00787 // Cancel reply timeout 00788 dn_fsm_cancelEvent(); 00789 00790 // Parse reply 00791 reply = (dn_ipmt_openSocket_rpt*)dn_fsm_vars.replyBuf; 00792 00793 // Choose next event or state transition 00794 switch (reply->RC) 00795 { 00796 case DN_RC_OK: 00797 //debug("Socket %d opened successfully", reply->socketId); 00798 dn_fsm_vars.socketId = reply->socketId; 00799 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_bindSocket); 00800 break; 00801 case DN_RC_NO_RESOURCES: 00802 //debug("Couldn't create socket due to resource availability"); 00803 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 00804 break; 00805 default: 00806 //log_warn("Unexpected response code: %#x", reply->RC); 00807 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00808 break; 00809 } 00810 } 00811 00812 //===== bindSocket 00813 00814 /** 00815 Binds the previously opened socket to a port. If said port is already bound, 00816 a mote reset is scheduled and the connect process starts over. 00817 */ 00818 static void dn_event_bindSocket(void) 00819 { 00820 //debug("Bind socket"); 00821 00822 // Arm reply callback 00823 dn_fsm_setReplyCallback(dn_reply_bindSocket); 00824 00825 // Issue mote API command 00826 dn_ipmt_bindSocket 00827 ( 00828 dn_fsm_vars.socketId, 00829 dn_fsm_vars.srcPort, 00830 (dn_ipmt_bindSocket_rpt*)dn_fsm_vars.replyBuf 00831 ); 00832 00833 // Schedule timeout for reply 00834 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 00835 } 00836 00837 static void dn_reply_bindSocket(void) 00838 { 00839 dn_ipmt_bindSocket_rpt* reply; 00840 //debug("Bind socket reply"); 00841 00842 // Cancel reply timeout 00843 dn_fsm_cancelEvent(); 00844 00845 // Parse reply 00846 reply = (dn_ipmt_bindSocket_rpt*)dn_fsm_vars.replyBuf; 00847 00848 // Choose next event or state transition 00849 switch (reply->RC) 00850 { 00851 case DN_RC_OK: 00852 //debug("Socket bound successfully"); 00853 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_setJoinKey); 00854 break; 00855 case DN_RC_BUSY: 00856 //debug("Port already bound"); 00857 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 00858 break; 00859 case DN_RC_NOT_FOUND: 00860 //debug("Invalid socket ID"); 00861 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00862 break; 00863 default: 00864 //log_warn("Unexpected response code: %#x", reply->RC); 00865 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00866 break; 00867 } 00868 } 00869 00870 //===== setJoinKey 00871 00872 /** 00873 Configures the join key that the mote should use when attempting to join a 00874 network. 00875 */ 00876 static void dn_event_setJoinKey(void) 00877 { 00878 //debug("Set join key"); 00879 00880 // Arm reply callback 00881 dn_fsm_setReplyCallback(dn_reply_setJoinKey); 00882 00883 // Issue mote API command 00884 dn_ipmt_setParameter_joinKey 00885 ( 00886 dn_fsm_vars.joinKey, 00887 (dn_ipmt_setParameter_joinKey_rpt*)dn_fsm_vars.replyBuf 00888 ); 00889 00890 // Schedule timeout for reply 00891 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 00892 } 00893 00894 static void dn_reply_setJoinKey(void) 00895 { 00896 dn_ipmt_setParameter_joinKey_rpt* reply; 00897 //debug("Set join key reply"); 00898 00899 // Cancel reply timeout 00900 dn_fsm_cancelEvent(); 00901 00902 // Parse reply 00903 reply = (dn_ipmt_setParameter_joinKey_rpt*)dn_fsm_vars.replyBuf; 00904 00905 // Choose next event or state transition 00906 switch (reply->RC) 00907 { 00908 case DN_RC_OK: 00909 //debug("Join key set"); 00910 if (dn_fsm_vars.networkId == DN_PROMISCUOUS_NET_ID) 00911 { 00912 // Promiscuous netID set; search for new first 00913 dn_fsm_enterState(DN_FSM_STATE_PROMISCUOUS, 0); 00914 /* 00915 As of version 1.4.x, a network ID of 0xFFFF can be used to indicate 00916 that the mote should join the first network heard. Thus, searching 00917 before joining will not be necessary. 00918 */ 00919 } else 00920 { 00921 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_setNetworkId); 00922 } 00923 break; 00924 case DN_RC_WRITE_FAIL: 00925 //debug("Could not write the key to storage"); 00926 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00927 break; 00928 default: 00929 //log_warn("Unexpected response code: %#x", reply->RC); 00930 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00931 break; 00932 } 00933 } 00934 00935 //===== setNetworkId 00936 00937 /** 00938 Configures the ID of the network that the mote should should try to join. 00939 */ 00940 static void dn_event_setNetworkId(void) 00941 { 00942 //debug("Set network ID"); 00943 00944 // Arm reply callback 00945 dn_fsm_setReplyCallback(dn_reply_setNetworkId); 00946 00947 // Issue mote API command 00948 dn_ipmt_setParameter_networkId 00949 ( 00950 dn_fsm_vars.networkId, 00951 (dn_ipmt_setParameter_networkId_rpt*)dn_fsm_vars.replyBuf 00952 ); 00953 00954 // Schedule timeout for reply 00955 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 00956 } 00957 00958 static void dn_reply_setNetworkId(void) 00959 { 00960 dn_ipmt_setParameter_networkId_rpt* reply; 00961 //debug("Set network ID reply"); 00962 00963 // Cancel reply timeout 00964 dn_fsm_cancelEvent(); 00965 00966 // Parse reply 00967 reply = (dn_ipmt_setParameter_networkId_rpt*)dn_fsm_vars.replyBuf; 00968 00969 // Choose next event or state transition 00970 switch (reply->RC) 00971 { 00972 case DN_RC_OK: 00973 //debug("Network ID set"); 00974 dn_fsm_enterState(DN_FSM_STATE_JOINING, 0); 00975 break; 00976 case DN_RC_WRITE_FAIL: 00977 //debug("Could not write the network ID to storage"); 00978 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00979 break; 00980 default: 00981 //log_warn("Unexpected response code: %#x", reply->RC); 00982 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 00983 break; 00984 } 00985 } 00986 00987 //===== search 00988 00989 /** 00990 Tells the mote to start listening for network advertisements. The mote will 00991 then report the network ID (among other things) of any advertisements heard. 00992 Upon a successful reply, the FSM will wait for an advReceived notification, 00993 before attempting to join the reported network. 00994 */ 00995 static void dn_event_search(void) 00996 { 00997 //debug("Search"); 00998 00999 // Arm reply callback 01000 dn_fsm_setReplyCallback(dn_reply_search); 01001 01002 // Issue mote API command 01003 dn_ipmt_search 01004 ( 01005 (dn_ipmt_search_rpt*)dn_fsm_vars.replyBuf 01006 ); 01007 01008 // Schedule timeout for reply 01009 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 01010 } 01011 01012 static void dn_reply_search(void) 01013 { 01014 dn_ipmt_search_rpt* reply; 01015 //debug("Search reply"); 01016 01017 // Cancel reply timeout 01018 dn_fsm_cancelEvent(); 01019 01020 // Parse reply 01021 reply = (dn_ipmt_search_rpt*)dn_fsm_vars.replyBuf; 01022 01023 // Choose next event or state transition 01024 switch (reply->RC) 01025 { 01026 case DN_RC_OK: 01027 //debug("Searching for network advertisements"); 01028 // Will wait for notification of advertisement received 01029 break; 01030 case DN_RC_INVALID_STATE: 01031 //debug("The mote is in an invalid state to start searching"); 01032 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 01033 break; 01034 default: 01035 //log_warn("Unexpected response code: %#x", reply->RC); 01036 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 01037 break; 01038 } 01039 } 01040 01041 //===== join 01042 01043 /** 01044 Requests that the mote start searching for the previously configured network 01045 and attempt to join with the configured join key. If the mote is in an invalid 01046 state to join or lacks configuration to start joining, a reset is scheduled and 01047 the connect procedure starts over. Otherwise the FSM will wait for the ensuing 01048 operational event when the mote has finished joining. 01049 */ 01050 static void dn_event_join(void) 01051 { 01052 //debug("Join"); 01053 01054 // Arm reply callback 01055 dn_fsm_setReplyCallback(dn_reply_join); 01056 01057 // Issue mote API command 01058 dn_ipmt_join 01059 ( 01060 (dn_ipmt_join_rpt*)dn_fsm_vars.replyBuf 01061 ); 01062 01063 // Schedule timeout for reply 01064 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 01065 } 01066 01067 static void dn_reply_join(void) 01068 { 01069 dn_ipmt_join_rpt* reply; 01070 //debug("Join reply"); 01071 01072 // Cancel reply timeout 01073 dn_fsm_cancelEvent(); 01074 01075 // Parse reply 01076 reply = (dn_ipmt_join_rpt*)dn_fsm_vars.replyBuf; 01077 01078 // Choose next event or state transition 01079 switch (reply->RC) 01080 { 01081 case DN_RC_OK: 01082 //debug("Join operation started"); 01083 // Will wait for join complete notification (operational event) 01084 break; 01085 case DN_RC_INVALID_STATE: 01086 //debug("The mote is in an invalid state to start join operation"); 01087 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 01088 break; 01089 case DN_RC_INCOMPLETE_JOIN_INFO: 01090 //debug("Incomplete configuration to start joining"); 01091 dn_fsm_enterState(DN_FSM_STATE_RESETTING, 0); 01092 break; 01093 default: 01094 //log_warn("Unexpected response code: %#x", reply->RC); 01095 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 01096 break; 01097 } 01098 } 01099 01100 //===== requestService 01101 01102 /** 01103 The mote is told to request a new service level from the manager. Its reply 01104 simply checks that the command was accepted, as the FSM will wait for the 01105 ensuing svcChange event when the service allocation has changed. 01106 */ 01107 static void dn_event_requestService(void) 01108 { 01109 //debug("Request service"); 01110 01111 // Arm reply callback 01112 dn_fsm_setReplyCallback(dn_reply_requestService); 01113 01114 // Issue mote API command 01115 dn_ipmt_requestService 01116 ( 01117 DN_SERVICE_ADDRESS, 01118 DN_SERVICE_TYPE_BW, 01119 dn_fsm_vars.service_ms, 01120 (dn_ipmt_requestService_rpt*)dn_fsm_vars.replyBuf 01121 ); 01122 01123 // Schedule timeout for reply 01124 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 01125 } 01126 01127 static void dn_reply_requestService(void) 01128 { 01129 dn_ipmt_requestService_rpt* reply; 01130 //debug("Request service reply"); 01131 01132 // Cancel reply timeout 01133 dn_fsm_cancelEvent(); 01134 01135 // Parse reply 01136 reply = (dn_ipmt_requestService_rpt*)dn_fsm_vars.replyBuf; 01137 01138 // Choose next event or state transition 01139 switch (reply->RC) 01140 { 01141 case DN_RC_OK: 01142 //debug("Service request accepted"); 01143 // Will wait for svcChanged notification 01144 break; 01145 default: 01146 //log_warn("Unexpected response code: %#x", reply->RC); 01147 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 01148 break; 01149 } 01150 } 01151 01152 //===== getServiceInfo 01153 01154 /** 01155 Requests details about the service currently allocated to the mote. Its reply 01156 checks that we have been granted a service equal to or better than what was 01157 requested (smaller value equals better). 01158 */ 01159 static void dn_event_getServiceInfo(void) 01160 { 01161 //debug("Get service info"); 01162 01163 // Arm reply callback 01164 dn_fsm_setReplyCallback(dn_reply_getServiceInfo); 01165 01166 // Issue mote API command 01167 dn_ipmt_getServiceInfo 01168 ( 01169 DN_SERVICE_ADDRESS, 01170 DN_SERVICE_TYPE_BW, 01171 (dn_ipmt_getServiceInfo_rpt*)dn_fsm_vars.replyBuf 01172 ); 01173 01174 // Schedule timeout for reply 01175 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 01176 } 01177 01178 static void dn_reply_getServiceInfo(void) 01179 { 01180 dn_ipmt_getServiceInfo_rpt* reply; 01181 //debug("Get service info reply"); 01182 01183 // Cancel reply timeout 01184 dn_fsm_cancelEvent(); 01185 01186 // Parse reply 01187 reply = (dn_ipmt_getServiceInfo_rpt*)dn_fsm_vars.replyBuf; 01188 01189 // Choose next event or state transition 01190 switch (reply->RC) 01191 { 01192 case DN_RC_OK: 01193 if (reply->state == DN_SERVICE_STATE_COMPLETED) 01194 { 01195 if (reply->value <= dn_fsm_vars.service_ms) 01196 { 01197 //debug("Granted service of %u ms (requested %u ms)", reply->value, dn_fsm_vars.service_ms); 01198 dn_fsm_enterState(DN_FSM_STATE_CONNECTED, 0); 01199 } else 01200 { 01201 //log_warn("Only granted service of %u ms (requested %u ms)", reply->value, dn_fsm_vars.service_ms); 01202 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 01203 } 01204 01205 } else 01206 { 01207 //debug("Service request still pending"); 01208 dn_fsm_scheduleEvent(DN_CMD_PERIOD_MS, dn_event_getServiceInfo); 01209 } 01210 break; 01211 default: 01212 //log_warn("Unexpected response code: %#x", reply->RC); 01213 dn_fsm_enterState(DN_FSM_STATE_DISCONNECTED, 0); 01214 break; 01215 } 01216 } 01217 01218 //===== sendTo 01219 01220 /** 01221 This event sends a packet into the network, and its reply checks that it was 01222 accepted and queued up for transmission. 01223 */ 01224 static void dn_event_sendTo(void) 01225 { 01226 dn_err_t err; 01227 //debug("Send"); 01228 01229 // Arm reply callback 01230 dn_fsm_setReplyCallback(dn_reply_sendTo); 01231 01232 // Issue mote API command 01233 err = dn_ipmt_sendTo 01234 ( 01235 dn_fsm_vars.socketId, 01236 dn_fsm_vars.destIPv6, 01237 dn_fsm_vars.destPort, 01238 DN_SERVICE_TYPE_BW, 01239 DN_PACKET_PRIORITY_MEDIUM, 01240 DN_PACKET_ID_NO_NOTIF, 01241 dn_fsm_vars.payloadBuf, 01242 dn_fsm_vars.payloadSize, 01243 (dn_ipmt_sendTo_rpt*)dn_fsm_vars.replyBuf 01244 ); 01245 if (err != DN_ERR_NONE) 01246 { 01247 //debug("Send error: %u", err); 01248 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0); 01249 } 01250 01251 // Schedule timeout for reply 01252 dn_fsm_scheduleEvent(DN_SERIAL_RESPONSE_TIMEOUT_MS, dn_event_responseTimeout); 01253 } 01254 01255 static void dn_reply_sendTo(void) 01256 { 01257 dn_ipmt_sendTo_rpt* reply; 01258 //debug("Send reply"); 01259 01260 // Cancel reply timeout 01261 dn_fsm_cancelEvent(); 01262 01263 // Parse reply 01264 reply = (dn_ipmt_sendTo_rpt*)dn_fsm_vars.replyBuf; 01265 01266 // Choose next event or state transition 01267 switch (reply->RC) 01268 { 01269 case DN_RC_OK: 01270 //debug("Packet was queued up for transmission"); 01271 dn_fsm_enterState(DN_FSM_STATE_CONNECTED, 0); 01272 break; 01273 case DN_RC_NO_RESOURCES: 01274 //debug("No queue space to accept the packet"); 01275 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0); 01276 break; 01277 default: 01278 //log_warn("Unexpected response code: %#x", reply->RC); 01279 dn_fsm_enterState(DN_FSM_STATE_SEND_FAILED, 0); 01280 break; 01281 } 01282 } 01283 01284 //=========================== helpers ========================================= 01285 01286 static dn_err_t checkAndSaveNetConfig(uint16_t netID, const uint8_t* joinKey, uint16_t srcPort, uint32_t req_service_ms) 01287 { 01288 if (netID == 0) 01289 { 01290 //debug("No network ID given; using default"); 01291 dn_fsm_vars.networkId = DN_DEFAULT_NET_ID; 01292 } else if (netID == DN_PROMISCUOUS_NET_ID) 01293 { 01294 //debug("Promiscuous network ID given; will search for and join first network advertised"); 01295 dn_fsm_vars.networkId = netID; 01296 } else 01297 { 01298 dn_fsm_vars.networkId = netID; 01299 } 01300 01301 if (joinKey == NULL) 01302 { 01303 //debug("No join key given; using default"); 01304 memcpy(dn_fsm_vars.joinKey, DN_DEFAULT_JOIN_KEY, DN_JOIN_KEY_LEN); 01305 } else 01306 { 01307 memcpy(dn_fsm_vars.joinKey, joinKey, DN_JOIN_KEY_LEN); 01308 } 01309 01310 if (srcPort == 0) 01311 { 01312 //debug("No source port given; using default"); 01313 dn_fsm_vars.srcPort = DN_DEFAULT_SRC_PORT; 01314 } else 01315 { 01316 dn_fsm_vars.srcPort = srcPort; 01317 } 01318 01319 if (req_service_ms == 0) 01320 { 01321 //debug("No service requested; will only be granted base bandwidth"); 01322 } 01323 dn_fsm_vars.service_ms = req_service_ms; 01324 01325 return DN_ERR_NONE; 01326 } 01327 01328 static uint8_t getPayloadLimit(uint16_t destPort) 01329 { 01330 bool destIsF0Bx = (destPort >= DN_WELL_KNOWN_PORT_1 && destPort <= DN_WELL_KNOWN_PORT_8); 01331 bool srcIsF0Bx = (dn_fsm_vars.srcPort >= DN_WELL_KNOWN_PORT_1 && dn_fsm_vars.srcPort <= DN_WELL_KNOWN_PORT_8); 01332 int8_t destIsMng = memcmp(DN_DEST_IP, DN_DEFAULT_DEST_IP, DN_IPv6ADDR_LEN); 01333 01334 if (destIsMng == 0) 01335 { 01336 if (destIsF0Bx && srcIsF0Bx) 01337 return DN_PAYLOAD_SIZE_LIMIT_MNG_HIGH; 01338 else if (destIsF0Bx || srcIsF0Bx) 01339 return DN_PAYLOAD_SIZE_LIMIT_MNG_MED; 01340 else 01341 return DN_PAYLOAD_SIZE_LIMIT_MNG_LOW; 01342 } else 01343 { 01344 if (destIsF0Bx && srcIsF0Bx) 01345 return DN_PAYLOAD_SIZE_LIMIT_IP_HIGH; 01346 else if (destIsF0Bx || srcIsF0Bx) 01347 return DN_PAYLOAD_SIZE_LIMIT_IP_MED; 01348 else 01349 return DN_PAYLOAD_SIZE_LIMIT_IP_LOW; 01350 } 01351 } 01352
Generated on Tue Jul 12 2022 21:33:36 by 1.7.2