public bool TryGetLinkIdentity(InsteonDeviceLinkRecord link, out InsteonIdentity? identity)
 {
     //GetProductData(link, out identity) ||
     return GetLinkIdentity(link.Address, out identity);
 }
        private bool GetProductData(InsteonDeviceLinkRecord link, out InsteonIdentity? identity)
        {
            Dictionary<PropertyKey, int> properties;

            logger.DebugFormat("Controller {0} GetLinkProductData", Address.ToString());
            byte[] message = { (byte)InsteonModemSerialCommand.StandardOrExtendedMessage, link.Address[2], link.Address[1], link.Address[0], 
                                 (byte) MessageFlagsStandard.ThreeHopsThreeRemaining, (byte)InsteonDirectCommands.ProductDataRequest, Byte.MinValue };

            var status = network.Messenger.TrySendReceive(message, false, (byte)InsteonModemSerialCommand.ExtendedMessage, InsteonMessageType.ProductDataResponse, out properties);

            if (status == EchoStatus.NAK)
            {
                logger.ErrorFormat("received NAK trying to get ProductData information");
                identity = null;
                return false;
            }
            if (status == EchoStatus.ACK)
            {
                if (properties == null)
                {
                    logger.ErrorFormat("Device Id {0} has null properties object", Address.ToString());
                    identity = null;
                    return false;
                }
                var pk = new InsteonProductKey((byte)properties[PropertyKey.ProductKeyHigh], (byte)properties[PropertyKey.ProductKeyMid], (byte)properties[PropertyKey.ProductKeyLow]);
                identity = new InsteonIdentity((byte)properties[PropertyKey.DevCat], (byte)properties[PropertyKey.SubCat], (byte)properties[PropertyKey.FirmwareVersion], pk);
                return true;
            }

            logger.ErrorFormat("received unknown status trying to get productdata information");
            identity = null;
            return false; // echo was not ACK or NAK
        }
        /// <summary>
        /// Returns an array of device links in the INSTEON controller.
        /// </summary>
        /// <param name="links">An array of objects representing each device link.</param>
        /// <remarks>
        /// This method does not throw an exception.
        /// </remarks>
        public bool TryGetLinks(out InsteonDeviceLinkRecord[] links)
        {
            links = null;
            deviceLinkRecords = new List<InsteonDeviceLinkRecord>();
            Dictionary<PropertyKey, int> properties;

            logger.DebugFormat("Controller {0} GetLinks", Address.ToString());
            byte[] message1 = { (byte)InsteonModemSerialCommand.GetFirstAllLinkRecord };
            var status = network.Messenger.TrySendReceive(message1, false, (byte)InsteonModemSerialCommand.DeviceLinkRecord, null, out properties);

            if (status == EchoStatus.NAK)
            {
                links = new InsteonDeviceLinkRecord[0]; // empty link table
                logger.DebugFormat("Controller {0} GetLinks returned no links, empty link table", Address.ToString());
                return true;
            }
            if (status == EchoStatus.ACK)
            {
                if (properties == null)
                {
                    logger.ErrorFormat("Controller {0} null properties object", Address.ToString());
                    return false;
                }
                deviceLinkRecords.Add(new InsteonDeviceLinkRecord(properties));
            }
            else
            {
                return false; // echo was not ACK or NAK
            }

            logger.DebugFormat("Controller {0} GetLinks", Address.ToString());
            byte[] message2 = { (byte)InsteonModemSerialCommand.GetNextDeviceLinkRecord };
            status = network.Messenger.TrySendReceive(message2, false, (byte)InsteonModemSerialCommand.DeviceLinkRecord, null, out properties);
            while (status == EchoStatus.ACK)
            {
                if (properties == null)
                {
                    logger.ErrorFormat("Controller {0} null properties object", Address.ToString());
                    return false;
                }
                deviceLinkRecords.Add(new InsteonDeviceLinkRecord(properties));
                status = network.Messenger.TrySendReceive(message2, false, (byte)InsteonModemSerialCommand.DeviceLinkRecord, null, out properties);
            }

            if (status != EchoStatus.NAK)
            {
                return false; // echo was not ACK or NAK
            }

            links = deviceLinkRecords.ToArray();
            logger.DebugFormat("Controller {0} GetLinks returned {1} links", Address.ToString(), links.Length);
            return true;
        }