/** 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;
    } 
}
/** 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;
}
/** 
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
}