/** Waits for SRDY to go low, indicating a message has arrived. Displays the msg to console, and find the device's MAC address using ZDO_IEEE_ADDR_REQ. Then, if FIND_NWK_ADDRESS was defined, uses the received MAC address to find the device's short address. The two should match. @pre callbacks have been enabled with enableCallbacks() - otherwise you will never receive the ZDO_IEEE_ADDR_RSP message. */ void displayReceivedMessagesAndFindDevice() { znpBuf[0] = 0; unsigned int shortAddress; while (1) { while (SRDY_IS_HIGH()); pollAndDisplay(); if (CONVERT_TO_INT(znpBuf[2], znpBuf[1]) == AF_INCOMING_MSG) { shortAddress = CONVERT_TO_INT(znpBuf[7], znpBuf[8]); zdoRequestIeeeAddress(shortAddress, SINGLE_DEVICE_RESPONSE, 0); if (znpResult == 0) { printf("MAC Address (LSB first) of sender is :"); printHexBytes(znpBuf+4, 8); } else { printf("IEEE Request Failed (%d)\r\n", znpResult); continue; } #ifdef FIND_NWK_ADDRESS /** Very simple example of zdoNetworkAddressRequest() */ unsigned char* response = zdoNetworkAddressRequest(znpBuf+4, SINGLE_DEVICE_RESPONSE, 0); //was SINGLE_DEVICE_RESPONSE if (znpResult == 0) { unsigned int sa = CONVERT_TO_INT(znpBuf[12], znpBuf[13]); printf("Short Address = %04X\r\n", sa); } else { printf("NWK Request Failed (%d)\r\n", znpResult); continue; } printZdoNetworkAddressResponse(response); #endif } } }
static void stateMachine() { while (1) { if (zigbeeNetworkStatus == NWK_ONLINE) { if(moduleHasMessageWaiting()) //wait until SRDY goes low indicating a message has been received. displayMessages(); } switch (state) { case STATE_IDLE: { /* process command line commands only if not doing anything else: */ if (command != NO_CHARACTER_RECEIVED) { /* parse the command entered, and go to the required state */ state = processCommand(command); command = NO_CHARACTER_RECEIVED; } /* note: other flags (for different messages or events) can be added here */ break; } case STATE_INIT: { printf("Starting State Machine\r\n"); state = STATE_GET_DEVICE_TYPE; break; } /* A button press during startup will cause the application to prompt for device type */ case STATE_GET_DEVICE_TYPE: { //printf("Current Configured DeviceType: %s\r\n", getDeviceTypeName()); set_type: /* if saving device type to flash memory: printf("Any other key to exit. Timeout in 5 seconds.\r\n"); / long wait = 0; long timeout = TICKS_IN_ONE_MS * 5000l; while ((command == NO_CHARACTER_RECEIVED) && (wait != timeout)) wait++; */ while (command == NO_CHARACTER_RECEIVED) { printf("Setting Device Type: Press C for Coordinator, R for Router, or E for End Device.\r\n"); delayMs(2000); } switch (command) { case 'C': case 'c': printf("Coordinator it is...\r\n"); zigbeeDeviceType = COORDINATOR; break; case 'R': case 'r': printf("Router it is...\r\n"); zigbeeDeviceType = ROUTER; break; case 'E': case 'e': printf("End Device it is...\r\n"); zigbeeDeviceType = END_DEVICE; break; default: command = NO_CHARACTER_RECEIVED; goto set_type; } command = NO_CHARACTER_RECEIVED; state = STATE_MODULE_STARTUP; break; } case STATE_MODULE_STARTUP: { #define MODULE_START_DELAY_IF_FAIL_MS 5000 moduleResult_t result; /* Start with the default module configuration */ struct moduleConfiguration defaultConfiguration = DEFAULT_MODULE_CONFIGURATION_COORDINATOR; /* Make any changes needed here (channel list, PAN ID, etc.) We Configure the Zigbee Device Type (Router, Coordinator, End Device) based on what user selected */ defaultConfiguration.deviceType = zigbeeDeviceType; while ((result = startModule(&defaultConfiguration, GENERIC_APPLICATION_CONFIGURATION)) != MODULE_SUCCESS) { printf("Module start unsuccessful. Error Code 0x%02X. Retrying...\r\n", result); delayMs(MODULE_START_DELAY_IF_FAIL_MS); } printf("Success\r\n"); state = STATE_DISPLAY_NETWORK_INFORMATION; zigbeeNetworkStatus = NWK_ONLINE; break; } case STATE_DISPLAY_NETWORK_INFORMATION: { printf("Module Information:\r\n"); /* On network, display info about this network */ displayNetworkConfigurationParameters(); displayDeviceInformation(); displayCommandLineInterfaceHelp(); state = STATE_IDLE; //startup is done! break; } case STATE_VALID_SHORT_ADDRESS_ENTERED: //command line processor has a valid shortAddressEntered { printf("Valid Short Address Entered\r\n"); state = pendingState; break; } case STATE_VALID_LONG_ADDRESS_ENTERED: { /* flip byte order */ int8_t temp[8]; int i; for (i=0; i<8; i++) temp[7-i] = longAddressEntered[i]; memcpy(longAddressEntered, temp, 8); //Store LSB first since that is how it will be sent: state = pendingState; break; } case STATE_SEND_MESSAGE_VIA_SHORT_ADDRESS: { printf("Send via short address to %04X\r\n", shortAddressEntered); moduleResult_t result = afSendData(DEFAULT_ENDPOINT,DEFAULT_ENDPOINT,shortAddressEntered, TEST_CLUSTER, testMessage, 5); if (result == MODULE_SUCCESS) { printf("Success\r\n"); } else { printf("Could not send to that device (Error Code 0x%02X)\r\n", result); #ifdef RESTART_AFTER_ZM_FAILURE printf("\r\nRestarting\r\n"); state = STATE_MODULE_STARTUP; continue; #endif } state = STATE_IDLE; break; } case STATE_SEND_MESSAGE_VIA_LONG_ADDRESS: { printf("Send via long address to (LSB first)"); printHexBytes(longAddressEntered, 8); moduleResult_t result = afSendDataExtended(DEFAULT_ENDPOINT, DEFAULT_ENDPOINT, longAddressEntered, DESTINATION_ADDRESS_MODE_LONG, TEST_CLUSTER, testMessage, 5); if (result == MODULE_SUCCESS) { printf("Success\r\n"); } else { printf("Could not send to that device (Error Code 0x%02X)\r\n", result); #ifdef RESTART_AFTER_ZM_FAILURE printf("\r\nRestarting\r\n"); state = STATE_MODULE_STARTUP; continue; #endif } state = STATE_IDLE; break; } case STATE_FIND_VIA_SHORT_ADDRESS: { printf("Looking for that device...\r\n"); moduleResult_t result = zdoRequestIeeeAddress(shortAddressEntered, SINGLE_DEVICE_RESPONSE, 0); if (result == MODULE_SUCCESS) { #ifndef ZDO_NWK_ADDR_RSP_HANDLED_BY_APPLICATION displayZdoAddressResponse(zmBuf + SRSP_PAYLOAD_START); #endif } else { printf("Could not locate that device (Error Code 0x%02X)\r\n", result); } state = STATE_IDLE; break; } case STATE_FIND_VIA_LONG_ADDRESS: { printf("Looking for that device...\r\n"); moduleResult_t result = zdoNetworkAddressRequest(longAddressEntered, SINGLE_DEVICE_RESPONSE, 0); if (result == MODULE_SUCCESS) { #ifndef ZDO_NWK_ADDR_RSP_HANDLED_BY_APPLICATION displayZdoAddressResponse(zmBuf + SRSP_PAYLOAD_START); #endif } else { printf("Could not locate that device (Error Code 0x%02X)\r\n", result); } state = STATE_IDLE; break; } default: //should never happen { printf("UNKNOWN STATE (%u)\r\n", state); state = STATE_IDLE; } break; } } }
static void stateMachine() { while (1) { if (zigbeeNetworkStatus == NWK_ONLINE) { if(moduleHasMessageWaiting()) //wait until SRDY goes low indicating a message has been received. { getMessage(); displayMessage(); } } switch (state) { case STATE_IDLE: { /* process command line commands only if not doing anything else: */ if (command != NO_CHARACTER_RECEIVED) { /* parse the command entered, and go to the required state */ state = processCommand(command); command = NO_CHARACTER_RECEIVED; } /* note: other flags (for different messages or events) can be added here */ break; } case STATE_INIT: { printf("Starting State Machine\r\n"); state = STATE_GET_DEVICE_TYPE; break; } /* A button press during startup will cause the application to prompt for device type */ case STATE_GET_DEVICE_TYPE: { set_type: while (command == NO_CHARACTER_RECEIVED) { printf("Setting Device Type: Press C for Coordinator, R for Router, or E for End Device.\r\n"); #define DEVICE_TYPE_DELAY_MS 2000 #define DEVICE_TYPE_DELAY_PER_CYCLE_MS 100 uint16_t delayCycles = DEVICE_TYPE_DELAY_MS / DEVICE_TYPE_DELAY_PER_CYCLE_MS; while ((command == NO_CHARACTER_RECEIVED) && (delayCycles--) > 0) delayMs(DEVICE_TYPE_DELAY_PER_CYCLE_MS); } switch (command) { case 'C': case 'c': printf("Coordinator it is...\r\n"); zigbeeDeviceType = COORDINATOR; break; case 'R': case 'r': printf("Router it is...\r\n"); zigbeeDeviceType = ROUTER; break; case 'E': case 'e': printf("End Device it is...\r\n"); zigbeeDeviceType = END_DEVICE; break; default: command = NO_CHARACTER_RECEIVED; goto set_type; } command = NO_CHARACTER_RECEIVED; state = STATE_MODULE_STARTUP; break; } case STATE_MODULE_STARTUP: { #define MODULE_START_DELAY_IF_FAIL_MS 5000 moduleResult_t result; /* Start with the default module configuration */ struct moduleConfiguration defaultConfiguration = DEFAULT_MODULE_CONFIGURATION_COORDINATOR; /* Make any changes needed here (channel list, PAN ID, etc.) We Configure the Zigbee Device Type (Router, Coordinator, End Device) based on what user selected */ defaultConfiguration.deviceType = zigbeeDeviceType; /* Change this below to be your operating region - MODULE_REGION_NORTH_AMERICA or MODULE_REGION_EUROPE */ #define OPERATING_REGION (MODULE_REGION_NORTH_AMERICA) // or MODULE_REGION_EUROPE while ((result = expressStartModule(&defaultConfiguration, GENERIC_APPLICATION_CONFIGURATION, OPERATING_REGION)) != MODULE_SUCCESS) { SET_NETWORK_FAILURE_LED_ON(); // Turn on the LED to show failure handleModuleError(result); printf("Retrying...\r\n"); delayMs(MODULE_START_DELAY_IF_FAIL_MS/2); SET_NETWORK_FAILURE_LED_OFF(); delayMs(MODULE_START_DELAY_IF_FAIL_MS/2); } printf("Success\r\n"); state = STATE_DISPLAY_NETWORK_INFORMATION; zigbeeNetworkStatus = NWK_ONLINE; break; } case STATE_DISPLAY_NETWORK_INFORMATION: { printf("Module Information:\r\n"); /* On network, display info about this network */ displayNetworkConfigurationParameters(); displayDeviceInformation(); displayCommandLineInterfaceHelp(); state = STATE_IDLE; //startup is done! break; } case STATE_VALID_SHORT_ADDRESS_ENTERED: //command line processor has a valid shortAddressEntered { state = pendingState; break; } case STATE_VALID_LONG_ADDRESS_ENTERED: { /* Flip byte order because we need to send it LSB first */ int8_t temp[8]; int i; for (i=0; i<8; i++) temp[7-i] = longAddressEntered[i]; memcpy(longAddressEntered, temp, 8); //Store LSB first since that is how it will be sent: state = pendingState; break; } case STATE_SEND_MESSAGE_VIA_SHORT_ADDRESS: { printf("Send to 0x%04X\r\n", shortAddressEntered); moduleResult_t result = afSendData(DEFAULT_ENDPOINT,DEFAULT_ENDPOINT,shortAddressEntered, TEST_CLUSTER, testMessage, 5); if (result == MODULE_SUCCESS) { printf("Success\r\n"); } else { handleModuleError(result); #ifdef RESTART_AFTER_ZM_FAILURE printf("\r\nRestarting\r\n"); state = STATE_MODULE_STARTUP; continue; #endif } state = STATE_IDLE; break; } case STATE_SEND_MESSAGE_VIA_LONG_ADDRESS: { printf("Send to (LSB first)"); printHexBytes(longAddressEntered, 8); moduleResult_t result = afSendDataExtended(DEFAULT_ENDPOINT, DEFAULT_ENDPOINT, longAddressEntered, DESTINATION_ADDRESS_MODE_LONG, TEST_CLUSTER, testMessage, 5); if (result == MODULE_SUCCESS) { printf("Success\r\n"); } else { handleModuleError(result); #ifdef RESTART_AFTER_ZM_FAILURE printf("\r\nRestarting\r\n"); state = STATE_MODULE_STARTUP; continue; #endif } state = STATE_IDLE; break; } #ifdef LEAVE_REQUEST case STATE_MANAGEMENT_LEAVE_REQUEST: { printf("Sending Leave Request for MAC (LSB first)"); printHexBytes(longAddressEntered, 8); moduleResult_t result = zdoManagementLeaveRequest(longAddressEntered, 0); if (result == MODULE_SUCCESS) { printf("Success\r\n"); } else { handleModuleError(result); } state = STATE_IDLE; break; } #endif case STATE_FIND_VIA_SHORT_ADDRESS: { printf("Looking for that device...\r\n"); moduleResult_t result = zdoRequestIeeeAddress(shortAddressEntered, INCLUDE_ASSOCIATED_DEVICES, 0); if (result == MODULE_SUCCESS) { #ifndef ZDO_NWK_ADDR_RSP_HANDLED_BY_APPLICATION displayZdoAddressResponse(zmBuf + SRSP_PAYLOAD_START); #endif } else { handleModuleError(result); } state = STATE_IDLE; break; } case STATE_FIND_VIA_LONG_ADDRESS: { printf("Looking for that device...\r\n"); moduleResult_t result = zdoNetworkAddressRequest(longAddressEntered, INCLUDE_ASSOCIATED_DEVICES, 0); if (result == MODULE_SUCCESS) { #ifndef ZDO_NWK_ADDR_RSP_HANDLED_BY_APPLICATION displayZdoAddressResponse(zmBuf + SRSP_PAYLOAD_START); #endif } else { handleModuleError(result); } state = STATE_IDLE; break; } #ifdef INCLUDE_PERMIT_JOIN case STATE_SET_PERMIT_JOIN_ON: { printf("Turning joining ON...\r\n"); moduleResult_t result = zdoManagementPermitJoinRequest(shortAddressEntered, PERMIT_JOIN_ON_INDEFINITELY, 0); if (result == MODULE_SUCCESS) { printf("Success\r\n"); } else { handleModuleError(result); } state = STATE_IDLE; break; } case STATE_SET_PERMIT_JOIN_OFF: { printf("Turning joining OFF...\r\n"); moduleResult_t result = zdoManagementPermitJoinRequest(shortAddressEntered, PERMIT_JOIN_OFF, 0); if (result == MODULE_SUCCESS) { printf("Success\r\n"); } else { handleModuleError(result); } state = STATE_IDLE; break; } #endif #ifdef DISCOVER_NETWORKS case STATE_NETWORK_DISCOVERY_REQUEST: { printf("Scanning...\r\n"); moduleResult_t result = zdoNetworkDiscoveryRequest(ANY_CHANNEL_MASK, BEACON_ORDER_480_MSEC); if (result == MODULE_SUCCESS) { printf("Success\r\n"); } else { handleModuleError(result); } state = STATE_IDLE; break; } #endif #ifdef INCLUDE_NETWORK_TOPOLOGY case STATE_GET_NETWORK_TOPOLOGY: { printf("Displaying NWK Topology...........\r\n"); initSet(&searchedSet); // Start the recursive search for all children of the short address //removeAllFromSet(); int8_t numChildren = displayChildren(shortAddressEntered); state = STATE_IDLE; break; } #endif default: //should never happen { printf("UNKNOWN STATE (%u)\r\n", state); state = STATE_IDLE; } break; } } }