/** Parse any received messages. If it's one of our OIDs then display it. */
void parseMessages()
{
    getMessage();
    if ((zmBuf[SRSP_LENGTH_FIELD] > 0) && (IS_AF_INCOMING_MESSAGE()))
    {
        setLed(0);                                  //LED will blink to indicate a message was received
#ifdef VERBOSE_MESSAGE_DISPLAY
        printAfIncomingMsgHeader(zmBuf);
        printf("\r\n");
#endif
        if ((AF_INCOMING_MESSAGE_CLUSTER()) == INFO_MESSAGE_CLUSTER)
        {
            processInfoMessage();            
        } else if ((AF_INCOMING_MESSAGE_CLUSTER()) == CONFIG_REQUEST_MESSAGE_CLUSTER) {
            processConfigRequestMessage();            
        } else {    //unknown cluster
            printf("Rx: ");
            printHexBytes(zmBuf+SRSP_HEADER_SIZE+17, zmBuf[SRSP_HEADER_SIZE+16]);   //print out message payload
        }
        clearLed(0);    
    } else if (IS_ZDO_END_DEVICE_ANNCE_IND()) {
        displayZdoEndDeviceAnnounce(zmBuf);
    } else { //unknown message, just print out the whole thing
        printf("MSG: ");
        printHexBytes(zmBuf, (zmBuf[SRSP_LENGTH_FIELD] + SRSP_HEADER_SIZE));
    }
    zmBuf[SRSP_LENGTH_FIELD] = 0;
}
void displayMessages()
{
    spiPoll();
    if (znpBuf[SRSP_LENGTH_FIELD] > 0)
    {
        if (IS_AF_INCOMING_MESSAGE())
        {
            setLed(1);  //LED will blink to indicate a message was received
#ifdef VERBOSE_MESSAGE_DISPLAY               
            printAfIncomingMsgHeader(znpBuf);
            printf("\r\n");
#endif
            if (IS_INFO_MESSAGE_CLUSTER())
            {
                struct infoMessage im = deserializeInfoMessage(znpBuf+20);
                
#ifdef VERBOSE_MESSAGE_DISPLAY                
                printInfoMessage(&im);
#else
                printf("From:");
                for (int j = 0; j<8; j++)
                {
                    printf("%02X", im.header->mac[j]);
                }
                printf(",LQI=%02X", znpBuf[SRSP_HEADER_SIZE+9]);
#endif

                if (im.numParameters > 0)
                {
                    printf(";PanID:%04X", im.parameters[0]);
                    if (im.numParameters == 3)   //panId, vcc3v, light sensor (lux/10)
                    {
                        printf(",Vcc3=%umV,Light Sensor(lux)=%u,Cause=", im.parameters[1], im.parameters[2] * 10); 
                        switch (im.cause)
                        {
                        case CAUSE_SCHEDULED: printf("Timer"); break;
                        case CAUSE_MOTION: printf("Motion"); break;
                        case CAUSE_STARTUP: printf("Startup"); break;
                        }
                    }
                    printf("\r\n");
                }
            } else {
                printf("Rx: ");
                printHexBytes(znpBuf+SRSP_HEADER_SIZE+17, znpBuf[SRSP_HEADER_SIZE+16]);   //print out message payload
            }
            clearLeds();    
        } else { //unknown message, just print out the whole thing
            printf("??: ");
            printHexBytes(znpBuf, (znpBuf[SRSP_LENGTH_FIELD] + SRSP_HEADER_SIZE));
        }             
        znpBuf[SRSP_LENGTH_FIELD] = 0;
    } 
}
Пример #3
0
/** Public method to send messages to the Module. This will send one message and then receive the 
Synchronous Response (SRSP) message from the Module to indicate the command was received.
@pre zmBuf contains a properly formatted message
@pre Module has been initialized
@post buffer zmBuf contains the response (if any) from the Module. 
*/
moduleResult_t sendMessage()
{
#ifdef ZM_PHY_SPI_VERBOSE    
  printf("Tx: ");
  printHexBytes(zmBuf, zmBuf[0] + 3);
#endif    
  
  uint8_t expectedSrspCmdMsb = zmBuf[1] + SRSP_OFFSET;    //store these so we can compare with what is returned
  uint8_t expectedSrspCmdLsb = zmBuf[2];
  
  moduleResult_t result = sendSreq();                     //send message, buffer now holds received data
  
  if (result != MODULE_SUCCESS)                           //ERROR - sendSreq() timeout
  {
#ifdef ZM_PHY_SPI_VERBOSE_ERRORS    
    printf("ERROR - sreq() timeout %02X\r\n", result);
#endif 
    return result;
  }
  
  /* The correct SRSP will always be 0x4000 + cmd, or simpler 0x4000 | cmd
  For example, if the SREQ is 0x2605 then the corresponding SRSP is 0x6605 */
  if ((zmBuf[SRSP_CMD_MSB_FIELD] == expectedSrspCmdMsb) && (zmBuf[SRSP_CMD_LSB_FIELD] == expectedSrspCmdLsb))    //verify the correct SRSP was received
  {
    return MODULE_SUCCESS;
  } else {
#ifdef ZM_PHY_SPI_VERBOSE_ERRORS    
    printf("ERROR - Wrong SRSP - received %02X-%02X, expected %02X-%02X\r\n", zmBuf[1], zmBuf[2],expectedSrspCmdMsb,expectedSrspCmdLsb);
#endif          
    return ZM_PHY_INCORRECT_SRSP;   //Wrong SRSP received
  }
}
Пример #4
0
void testLong2bigEndian()
{
	unsigned long val = 945985565902;
	unsigned char buf[8]={0};
	long2bigEndian(buf,val);
	printHexBytes("buf:",buf, 8);
}
Пример #5
0
/** Requests a device's Short Address for a given long address.
@param ieeeAddress the long address to locate
@param requestType must be SINGLE_DEVICE_RESPONSE or INCLUDE_ASSOCIATED_DEVICES. 
If SINGLE_DEVICE_RESPONSE is selected, then only information about the requested device will be returned. 
If INCLUDE_ASSOCIATED_DEVICES is selected, then the short addresses of the selected device's children will be returned too.
@param startIndex If INCLUDE_ASSOCIATED_DEVICES was selected, then there may be 
too many children to fit in one ZDO_NWK_ADDR_RSP message. 
So, use startIndex to get the next set of children's short addresses.
@note DOES NOT WORK FOR SLEEPING END DEVICES
@post An ZDO_NWK_ADDR_RSP message will be received, with one or more entries.
@return a pointer to the beginning of the payload, or a pointer to indeterminate data if error.
@post znpResult contains the error code, or ZNP_SUCCESS if success.
*/
unsigned char* zdoNetworkAddressRequest(unsigned char* ieeeAddress, unsigned char requestType, unsigned char startIndex)
{
    if ((requestType != SINGLE_DEVICE_RESPONSE) && (requestType != INCLUDE_ASSOCIATED_DEVICES)) 
    {
        znpResult = -1;
        return 0;
    }
#ifdef AF_ZDO_VERBOSE     
    printf("Requesting Network Address for long address ");
    printHexBytes(ieeeAddress, 8);
    printf("requestType %s, startIndex %u\r\n", (requestType == 0) ? "Single" : "Extended", startIndex);
#endif
    
    znpBuf[0] = ZDO_NWK_ADDR_REQ_PAYLOAD_LEN;
    znpBuf[1] = MSB(ZDO_NWK_ADDR_REQ);
    znpBuf[2] = LSB(ZDO_NWK_ADDR_REQ);      

    memcpy(znpBuf+3, ieeeAddress, 8);
    znpBuf[11] = requestType;
    znpBuf[12] = startIndex;

    znpResult = sendMessage();

    if (znpResult != 0)     
        return 0;
    znpResult = waitForMessage(ZDO_NWK_ADDR_RSP, 5);
    if (znpResult != 0)
        return 0;
    if (znpBuf[SRSP_PAYLOAD_START] != SRSP_STATUS_SUCCESS) //verify status is succes
    {
        znpResult = -2;
        return 0;
    }
    return (znpBuf + SRSP_PAYLOAD_START);
}
int main( void )
{
    halInit();
    moduleInit();
    printf("\r\nWriting NV Items\r\n");
    result = moduleReset();
    if (result == MODULE_SUCCESS)
    {
        displaySysResetInd();  // Display the contents of the received SYS_RESET_IND message
    } else {
        printf("Module Reset ERROR 0x%02X\r\n", result);
    }
    debugConsoleIsr = &handleDebugConsoleInterrupt;   //call method handleDebugConsoleInterrupt() when a byte is received    
    HAL_ENABLE_INTERRUPTS();              //Enable Interrupts

    while (1)
    {
        uint8_t whichNvItem = getWhichNvItemToWrite();  
        if (whichNvItem != NO_CHARACTER_RECEIVED)
        {
            uint8_t nvItemSize = getNvItemSize(whichNvItem);
            printf("\r\nWriting to NV item %u, L%u:", whichNvItem, nvItemSize);    
            printHexBytes(dataToWrite, nvItemSize);
            result = sysNvWrite(whichNvItem, dataToWrite);
            if (result != MODULE_SUCCESS)
            {
                printf("sysNvWrite ERROR 0x%02X\r\n", result);
            }
        }
    }
}
Пример #7
0
/** Utility method to display stored network configuration parameters. These are the configuration
parameters stored in NV memory and are used to initialize the ZNP.
@post znpResult contains the error code, or ZNP_SUCCESS if success.
*/
void getNetworkConfigurationParameters()
{
    printf("ZNP Configuration Parameters\r\n");
    unsigned char* param;
    
    param = getConfigurationParameter(ZCD_NV_PANID);
    if (znpResult != 0) return;
    printf("    ZCD_NV_PANID                %04X\r\n", (CONVERT_TO_INT(param[0], param[1])));
    
    param = getConfigurationParameter(ZCD_NV_CHANLIST);
    if (znpResult != 0) return;
    printf("    ZCD_NV_CHANLIST             %02X %02X %02X %02X\r\n", param[0], param[1], param[2], param[3]);
    
    param = getConfigurationParameter(ZCD_NV_SECURITY_MODE);
    if (znpResult != 0) return;
    printf("    ZCD_NV_SECURITY_MODE        %02X\r\n", param[0]);
    
    param = getConfigurationParameter(ZCD_NV_PRECFGKEYS_ENABLE);
    if (znpResult != 0) return;
    printf("    ZCD_NV_PRECFGKEYS_ENABLE    %02X\r\n", param[0]);    
    
    param = getConfigurationParameter(ZCD_NV_PRECFGKEY);
    if (znpResult != 0) return;
    printf("    ZCD_NV_PRECFGKEY            ");    
    printHexBytes(param, ZCD_NV_PRECFGKEY_LEN);
    
}
Пример #8
0
int main( void )
{
    halInit();
    moduleInit();    
    printf("\r\nResetting Module, then getting MAC Address\r\n");
    HAL_ENABLE_INTERRUPTS();
    
    result = moduleReset();
    if (result == MODULE_SUCCESS)
    {
        /* Display the contents of the received SYS_RESET_IND message */
        displaySysResetInd();  
    } else {
        printf("ERROR 0x%02X\r\n", result);
    }    
    
    while (1)
    {
        result = zbGetDeviceInfo(DIP_MAC_ADDRESS);
        if (result == MODULE_SUCCESS)
        {
            uint8_t* mac = zmBuf+SRSP_DIP_VALUE_FIELD;
            printf("MAC (as sent, LSB first):");
            printHexBytes(mac, 8);
            
            /* Note: the MAC address comes over the wire in reverse order (LSB first)
            So we swap the order of the bytes so we can display it correctly. */
            uint8_t temp[8];
            int i;
            for (i=0; i<8; i++)
            {
                temp[i] = mac[7-i];
            }
            printf("MAC (correct, MSB first):");
            printHexBytes(temp, 8);
            printf("\r\n");
        } else {
            printf("ERROR 0x%02X\r\n", result);
        }
        toggleLed(1);
        delayMs(1000);
    }
}
Пример #9
0
/** Poll the ZNP for any messages and display them to the console.
@pre SRDY went LOW indicating data is ready
*/
void pollAndDisplay()
{
    spiPoll();
    if (znpBuf[SRSP_LENGTH_FIELD] > 0)
    {
        printf("Rx: ");
        printHexBytes(znpBuf, (znpBuf[SRSP_LENGTH_FIELD] + SRSP_HEADER_SIZE));
        znpBuf[SRSP_LENGTH_FIELD] = 0;
    } 
}
Пример #10
0
/** Loads the specified key into the ZNP. Does not change security mode, need to use setSecurityMode() too.
@note if NOT using pre-configured keys then the coordinator will distribute its key to all devices.
@param key preConfiguredKey a 16B key to use
@pre setSecurityMode() called
@post znpResult contains the error code, or ZNP_SUCCESS if success.
*/
void setSecurityKey(unsigned char* key)
{
#ifdef ZNP_INTERFACE_VERBOSE     
    printf("Setting Security Key: ");
    printHexBytes(key, ZCD_NV_PRECFGKEY_LEN);
#endif
    znpBuf[0] = ZB_WRITE_CONFIGURATION_LEN + ZCD_NV_PRECFGKEY_LEN;
    znpBuf[1] = MSB(ZB_WRITE_CONFIGURATION);
    znpBuf[2] = LSB(ZB_WRITE_CONFIGURATION);    
    
    znpBuf[3] = ZCD_NV_PRECFGKEY;
    znpBuf[4] = ZCD_NV_PRECFGKEY_LEN;
    
    for (int i=5; i<(ZCD_NV_PRECFGKEY_LEN+5); i++)
        znpBuf[i] = key[i];            
    znpResult = sendMessage();
}
Пример #11
0
/** Public method to send messages to the ZNP. This will send one message and then receive the 
Synchronous Response (SRSP) message from the ZNP to indicate the command was received.
@pre znpBuf contains a properly formatted message
@pre ZNP has been initialized
@post buffer znpBuf contains the response (if any) from the ZNP.
@return 0 if the SRSP received was the expected SRSP, -11 if it was NOT the expected SRSP, 
-12 if sendSreq timeout, or -13 if too many bytes received. 
*/
signed int sendMessage()
{
#ifdef ZNP_INTERFACE_SPI_VERBOSE    
    printf("Tx: ");
    printHexBytes(znpBuf, znpBuf[0] + 3);
#endif    
    
    unsigned char expectedSrspCmdMsb = znpBuf[1] + 0x40;
    unsigned char expectedSrspCmdLsb = znpBuf[2];

    signed int result = sendSreq(); //send message, buffer now holds received data
    
    if (result != 0)                            //ERROR - spiSreq() timeout
    {
        #ifdef ZNP_INTERFACE_SPI_VERBOSE    
        printf("ERROR - sreq() timeout %i\r\n", result);
        #endif 
        return -12;
    }
    if (znpBuf[0] > SRSP_BUFFER_SIZE)           //Error - SRSP length exceeds buffer size
    {
        #ifdef ZNP_INTERFACE_SPI_VERBOSE    
        printf("ERROR - SRSP too long %u > %u\r\n", znpBuf[0], SRSP_BUFFER_SIZE);
        #endif         
        return -13;
    }

    //The correct SRSP will always be 0x4000 + cmd, or simpler 0x4000 | cmd
    //For example, if the SREQ is 0x2605 then the corresponding SRSP is 0x6605
    if ((znpBuf[1] == expectedSrspCmdMsb) && (znpBuf[2] == expectedSrspCmdLsb))    //verify the correct SRSP was received
        return 0;
    else
    {
        #ifdef ZNP_INTERFACE_SPI_VERBOSE    
        printf("ERROR - Wrong SRSP - received %02X-%02X, expected %02X-%02X\r\n", znpBuf[1], znpBuf[2],expectedSrspCmdMsb,expectedSrspCmdLsb);
        #endif          
        return -11;   //Wrong SRSP received
        
    }
}
/** 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            
        }
    }
}
Пример #13
0
/** Writes the specified Non-Volatile (NV) memory item to the ZNP. 
The contents of the selected nvItem will be overwritten from memory starting at data.
@pre ZNP was initialized.
@param nvItem which nvItem to write, 1 through 6 inclusive
@param data the data to write
@post znpResult contains the error code, or ZNP_SUCCESS if success.
*/
void writeNvItem(unsigned char nvItem, unsigned char* data)
{
    if ((nvItem < MIN_NV_ITEM) || (nvItem > MAX_NV_ITEM))
    {
        znpResult = -1;
        return;
    }   
    unsigned char nvItemSize = getNvItemSize(nvItem);
#ifdef ZNP_INTERFACE_VERBOSE
    printf("Writing NV Item %u (length %u) with data: ", nvItem, nvItemSize);
    printHexBytes(data, nvItemSize);
#endif      
    znpBuf[0] = SYS_OSAL_NV_WRITE_PAYLOAD_LEN + nvItemSize;
    znpBuf[1] = MSB(SYS_OSAL_NV_WRITE);
    znpBuf[2] = LSB(SYS_OSAL_NV_WRITE);  
    
    znpBuf[3] = nvItem;         //item number, 1-6
    znpBuf[4] = 0x0F;           //MSB of item number, but only items 1-6 are supported
    znpBuf[5] = 0;              //offset from beginning of the NV item, not used
    znpBuf[6] = nvItemSize;     //length
    
    memcpy(znpBuf+7, data, nvItemSize);
    znpResult = sendMessage();    
}
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;
        }
    }
}
/** Parse any received messages. If it's one of our OIDs then display the value on the RGB LED too. */
void parseMessages()
{
    getMessage();
    if ((zmBuf[SRSP_LENGTH_FIELD] > 0) && (IS_AF_INCOMING_MESSAGE()))
    {
        setLed(4);                                  //LED will blink to indicate a message was received
#ifdef VERBOSE_MESSAGE_DISPLAY
        printAfIncomingMsgHeader(zmBuf);
        printf("\r\n");
#endif
        if ((AF_INCOMING_MESSAGE_CLUSTER()) == INFO_MESSAGE_CLUSTER)
        {
            struct infoMessage im;
            deserializeInfoMessage(zmBuf+20, &im);  // Convert the bytes into a Message struct
            int j = 0;
#ifdef VERBOSE_MESSAGE_DISPLAY                
            printInfoMessage(&im);
            displayZmBuf();
#else
            printf("From:");                        // Display the sender's MAC address
            for (j = 7; j>(-1); j--)
            {
                printf("%02X", im.header.mac[j]);
            }
            int k;
            for (k = 0; k < NUM_DEVICES; k++) {
              int match = 1;
              for (j = 7; j>(-1); j--) {
                if (routers[k].MAC_address[j] != im.header.mac[j]) {
                  match = 0;
                }
              }
              if (match == 1) {
                current_router_index = k;
                routers[current_router_index].LQI = zmBuf[AF_INCOMING_MESSAGE_LQI_FIELD];
              }
            }
            
            printf(", LQI=%02X, ", zmBuf[AF_INCOMING_MESSAGE_LQI_FIELD]);   // Display the received signal quality (Link Quality Indicator)
            //LQI = zmBuf[AF_INCOMING_MESSAGE_LQI_FIELD];

#endif
            printf("%u KVPs received:\r\n", im.numParameters);
#define NO_VALUE_RECEIVED   0xFF
            uint8_t redIndex = NO_VALUE_RECEIVED; 
            uint8_t blueIndex = NO_VALUE_RECEIVED;
            uint8_t greenIndex = NO_VALUE_RECEIVED;
            for (j=0; j<im.numParameters; j++)                              // Iterate through all the received KVPs
            {
                printf("    %s (0x%02X) = %d  ", getOidName(im.kvps[j].oid), im.kvps[j].oid, im.kvps[j].value);    // Display the Key & Value
                displayFormattedOidValue(im.kvps[j].oid, im.kvps[j].value);
                printf("\r\n");
                // If the received OID was an IR temperature OID then we can just display it on the LED
                if ((rgbLedDisplayMode == RGB_LED_DISPLAY_MODE_TEMP_IR) && (im.kvps[j].oid == OID_TEMPERATURE_IR)) 
                    displayTemperatureOnRgbLed(im.kvps[j].value);
                // But for the color sensor we need to get all three values before displaying
                else if (im.kvps[j].oid == OID_COLOR_SENSOR_RED)
                    redIndex = j;
                else if (im.kvps[j].oid == OID_COLOR_SENSOR_BLUE)
                    blueIndex = j;
                else if (im.kvps[j].oid == OID_COLOR_SENSOR_GREEN)
                    greenIndex = j;
            }
            // Now done iterating through all KVPs. If we received color then update RGB LED
#define RED_VALUE   (im.kvps[redIndex].value)
#define BLUE_VALUE  (im.kvps[blueIndex].value)
#define GREEN_VALUE (im.kvps[greenIndex].value)
            
            if ((rgbLedDisplayMode == RGB_LED_DISPLAY_MODE_COLOR) && 
                ((redIndex != NO_VALUE_RECEIVED) && (blueIndex != NO_VALUE_RECEIVED) && (greenIndex != NO_VALUE_RECEIVED)))
            {
                displayColorOnRgbLed(RED_VALUE, BLUE_VALUE, GREEN_VALUE);
            }
            printf("\r\n");
            
        } else {
            printf("Rx: ");
            printHexBytes(zmBuf+SRSP_HEADER_SIZE+17, zmBuf[SRSP_HEADER_SIZE+16]);   //print out message payload
        }
        clearLeds(0);    
    } else if (IS_ZDO_END_DEVICE_ANNCE_IND()) {
        displayZdoEndDeviceAnnounce(zmBuf);
    } else { //unknown message, just print out the whole thing
        printf("MSG: ");
        printHexBytes(zmBuf, (zmBuf[SRSP_LENGTH_FIELD] + SRSP_HEADER_SIZE));
    }
    zmBuf[SRSP_LENGTH_FIELD] = 0;
}
Пример #16
0
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;
        }
    }
}
Пример #17
0
/** 
Displays the type of message in zmBuf.
Ignores the message if length = 0.
@pre moduleHasMessageWaiting() is true
@pre getMessage() called to get message into zmBuf
@post zmBuf Length field = 0
 */
void displayMessage()
{
	if (zmBuf[SRSP_LENGTH_FIELD] > 0)
	{
		switch ( (CONVERT_TO_INT(zmBuf[SRSP_CMD_LSB_FIELD], zmBuf[SRSP_CMD_MSB_FIELD])) )
		{
		case AF_DATA_CONFIRM:
		{
			printf("AF_DATA_CONFIRM\r\n");
			break;
		}
		case AF_INCOMING_MSG:
		{
			printf("AF_INCOMING_MSG ");
			printAfIncomingMsgHeader(zmBuf);
			printf("\r\n");
#ifdef VERBOSE_MESSAGE_DISPLAY  
			printf("Payload: ");
			printHexBytes(zmBuf+SRSP_HEADER_SIZE+17, zmBuf[SRSP_HEADER_SIZE+16]);   //print out message payload
#endif
			break;
		}
		case AF_INCOMING_MSG_EXT:
		{
			printf("AF_INCOMING_MSG_EXT\r\n");
			uint16_t len = AF_INCOMING_MESSAGE_EXT_LENGTH();
			printf("Extended Message Received, L%u ", len);
			break;
		}
		case ZDO_IEEE_ADDR_RSP:
		{
			printf("ZDO_IEEE_ADDR_RSP\r\n");
			displayZdoAddressResponse(zmBuf + SRSP_PAYLOAD_START);
			break;
		}
		case ZDO_NWK_ADDR_RSP:
		{
			printf("ZDO_NWK_ADDR_RSP\r\n");
			displayZdoAddressResponse(zmBuf + SRSP_PAYLOAD_START);
			break;
		}
		case ZDO_END_DEVICE_ANNCE_IND:
		{
			printf("ZDO_END_DEVICE_ANNCE_IND\r\n");
			displayZdoEndDeviceAnnounce(zmBuf);
			break;
		}
		case ZB_FIND_DEVICE_CONFIRM:
		{
			printf("ZB_FIND_DEVICE_CONFIRM\r\n");
			break;
		}
		case ZDO_MGMT_NWK_DISCOVERY_RSP:
		{
			printf("ZDO_MGMT_NWK_DISCOVERY_RSP\r\n");
			displayZdoNetworkDiscoveryResponse(zmBuf + SRSP_PAYLOAD_START);
			break;
		}
		case ZDO_MGMT_LEAVE_RSP:
		{
			printf("ZDO_MGMT_LEAVE_RSP\r\n");
			displayZdoManagementLeaveResponse(zmBuf);
			break;
		}
		case ZDO_JOIN_CNF:
		{
			printf("ZDO_JOIN_CNF\r\n");
			displayZdoJoinConfirm(zmBuf);
			break;
		}
		case ZDO_STATE_CHANGE_IND:
		{
			printf("ZDO_STATE_CHANGE_IND\r\n");
			displayZdoStateChangeInd(zmBuf);
			break;
		}
		default:
		{
			printf("Message received, type 0x%04X\r\n", (CONVERT_TO_INT(zmBuf[SRSP_CMD_LSB_FIELD], zmBuf[SRSP_CMD_MSB_FIELD])));
			printHexBytes(zmBuf, (zmBuf[SRSP_LENGTH_FIELD] + SRSP_HEADER_SIZE));
		}
		}
		zmBuf[SRSP_LENGTH_FIELD] = 0;
	} //ignore messages with length == 0
}