/** Private method used to wait until a message is received indicating that we are on the network. Exits if received message is a ZDO_STATE_CHANGE_IND and the state matches what we want. Else loops until timeout. @note Since this is basically a blocking wait, you can also implement this in your application. @param expectedState the deviceState we are expecting - DEV_ZB_COORD etc. @param timeoutMs the amount of milliseconds to wait before returning an error. Should be an integer multiple of WFDS_POLL_INTERVAL_MS. @todo modify this if using UART. */ static moduleResult_t waitForDeviceState(unsigned char expectedState, uint16_t timeoutMs) { RETURN_INVALID_PARAMETER_IF_TRUE( ((!(IS_VALID_DEVICE_STATE(expectedState))) || (timeoutMs < WFDS_POLL_INTERVAL_MS)), METHOD_WAIT_FOR_DEVICE_STATE); uint16_t intervals = timeoutMs / WFDS_POLL_INTERVAL_MS; // how many times to check uint8_t state = 0xFF; while (intervals--) { if (moduleHasMessageWaiting()) // If there's a message waiting for us { getMessage(); if (CONVERT_TO_INT(zmBuf[2], zmBuf[1]) == ZDO_STATE_CHANGE_IND) // if it's a state change message { state = zmBuf[SRSP_PAYLOAD_START]; printf("%s, ", getDeviceStateName(state)); // display the name of the state in the message if (state == expectedState) // if it's the state we're expecting return MODULE_SUCCESS; //Then we're done! } //else we received a different type of message so we just ignore it } delayMs(WFDS_POLL_INTERVAL_MS); } // We've completed the loop without receiving the sate that we want; so therefore we've timed out. RETURN_RESULT(TIMEOUT, METHOD_WAIT_FOR_DEVICE_STATE); }
/** Displays the radio's device Information Properties. Device Information Properties include: - Device State indicates whether the ZNP is on a network or not, and what type of device it is. This is a handy thing to check if things aren't operating correctly. If the device is starting as a coordinator, you'll see states of 01, 08, 08, then 09 once it has fully started. - MAC Address (aka IEEE Address) is a globally unique serial number for this IC. - Device Short Address is a network address assigned by the coordinator, similar to an IP Address in DHCP. The Coordinator always has a Short Address of 0. - Parent MAC Address is the IEEE Address of this device's "parent", i.e. which device was used to join the network. For a router, once joined this parent MAC address is irrelevant. This DIP will NOT be updated if the network reforms. For an end-device then this parent MAC address will always specify which router the end-device is joined to. - Channel is which frequency channel the device is operating on. - PAN ID (Personal Area Network Identifier) of the network is a unique number shared for all devices on the same network. - Extended PAN ID of the network is the coordinator's MAC Address. If device is not connected to a network then the Short Address fields will be 0xFEFF, the Parent MAC Address and channel will be 0, and the Extended PAN ID will be this device's MAC Address. @post znpResult contains the error code, or ZNP_SUCCESS if success. */ void getDeviceInformation() { printf("Device Information Properties (MSB first)\r\n"); getDeviceInformationProperty(DIP_STATE); if (znpResult != 0) return; printf(" Device State: %s (%u)\r\n", getDeviceStateName(znpBuf[SRSP_DIP_VALUE_FIELD]), (znpBuf[SRSP_DIP_VALUE_FIELD])); getDeviceInformationProperty(DIP_MAC_ADDRESS); printf(" MAC Address: "); if (znpResult != 0) return; for (int i = SRSP_DIP_VALUE_FIELD+7; i>=SRSP_DIP_VALUE_FIELD; i--) printf("%02X ", znpBuf[i]); printf("\r\n"); getDeviceInformationProperty(DIP_SHORT_ADDRESS); if (znpResult != 0) return; printf(" Short Address: %04X\r\n", CONVERT_TO_INT(znpBuf[SRSP_DIP_VALUE_FIELD] , znpBuf[SRSP_DIP_VALUE_FIELD+1])); getDeviceInformationProperty(DIP_PARENT_SHORT_ADDRESS); if (znpResult != 0) return; printf(" Parent Short Address: %04X\r\n", CONVERT_TO_INT(znpBuf[SRSP_DIP_VALUE_FIELD] , znpBuf[SRSP_DIP_VALUE_FIELD+1])); getDeviceInformationProperty(DIP_PARENT_MAC_ADDRESS); if (znpResult != 0) return; printf(" Parent MAC Address: "); for (int i = SRSP_DIP_VALUE_FIELD+7; i>=SRSP_DIP_VALUE_FIELD; i--) printf("%02X ", znpBuf[i]); printf("\r\n"); getDeviceInformationProperty(DIP_CHANNEL); if (znpResult != 0) return; printf(" Device Channel: %u\r\n", znpBuf[SRSP_DIP_VALUE_FIELD]); getDeviceInformationProperty(DIP_PANID); if (znpResult != 0) return; printf(" PAN ID: %04X\r\n", CONVERT_TO_INT(znpBuf[SRSP_DIP_VALUE_FIELD], znpBuf[SRSP_DIP_VALUE_FIELD+1])); getDeviceInformationProperty(DIP_EXTENDED_PANID); if (znpResult != 0) return; printf(" Extended PAN ID: "); for (int i = SRSP_DIP_VALUE_FIELD+7; i>=SRSP_DIP_VALUE_FIELD; i--) printf("%02X ", znpBuf[i]); printf("\r\n"); }
/** Wait until a message is received. Exits if received message is a ZDO_STATE_CHANGE_IND and the state matches what we want. Else loops. @param expectedState the deviceState we are expecting - DEV_ZB_COORD etc. @return 0 if success, -1 if timeout */ signed int waitForDeviceState(unsigned char expectedState) { printf("Waiting for network... "); unsigned char state = 0xFF; unsigned long timeout = WAIT_FOR_DEVICE_STATE_TIMEOUT; while (state != expectedState) { while ((SRDY_IS_HIGH()) && (timeout > 0)) timeout--; if (timeout == 0) return -1; //error spiPoll(); if (CONVERT_TO_INT(znpBuf[2], znpBuf[1]) == ZDO_STATE_CHANGE_IND) { state = znpBuf[SRSP_PAYLOAD_START]; printf("%s ", getDeviceStateName(state)); } } printf("\r\n"); return 0; }