public static async Task <DeviceInformation> Parse(IPEndPoint endpoint, byte[] packet)
        {
            var version = packet[0];
            var cmd     = packet[1];
            var length  = packet[2];

            if (length + 4 > packet.Length)
            {
                return(null);
            }
            if (version == 1 && cmd == 0 && length == 0)
            {
                return(null); // drop ubnt-dp request
            }
            if (version == 1 && cmd == 0)
            {
                return(await Task.FromResult(DeviceInformationV1.Parse(packet)));
            }
            else if (version == 2)
            {
                return(await DeviceInformationV2.Parse(endpoint, cmd, packet));
            }
            else
            {
                return(null);
            }
        }
        internal static DeviceInformationV1 Parse(byte[] data)
        {
            var msg = new DeviceInformationV1();

            var i = 4;

            while (i < data.Length)
            {
                var type  = data[i++];
                var piece = data.Skip(i).Take(2).Reverse().ToArray(); // endianness swap
                var l     = BitConverter.ToUInt16(piece, 0);
                i += 2;

                piece = data.Skip(i).Take(l).ToArray();
                switch (type)
                {
                case PKT_V1_FWVERSION:
                    msg.Firmware = piece.ToString();
                    break;

                case PKT_V1_HOSTNAME:
                    msg.Hostname = piece.ToString();
                    break;

                case PKT_V1_IPINFO:
                    if (piece.Length == 10)
                    {
                        msg.MacAddress = BitConverter.ToString(piece.Take(6).ToArray());
                        msg.IPAddress  = string.Join(".", piece.Skip(6).Take(4));    // aa.bb.cc.dd
                    }
                    break;

                case PKT_V1_HWADDR:
                    msg.MacAddress = BitConverter.ToString(piece.Take(6).ToArray());
                    break;

                case PKT_V1_WEBUI:
                    if (piece.Length == 4)
                    {
                        msg.WebPort = BitConverter.ToInt32(piece, 0) & 0xFFFF;
                        msg.IsHttps = ((BitConverter.ToInt32(piece, 0) >> 16) & 0xFFFF) > 0;
                    }
                    break;

                case PKT_V1_WMODE:
                    if (piece.Length == 4)
                    {
                        msg.WMode = BitConverter.ToInt32(piece, 0);

                        // Docs indicate this as being UniFi Video-specific
                        // 0x101 or 0x102 means the device has gone through wizard
                        msg.IsSetup = true;
                        if (msg.WMode == 0x100)
                        {
                            msg.IsSetup = false;
                        }
                    }
                    break;

                case PKT_V1_ESSID:
                    msg.ESSID = ASCIIEncoding.ASCII.GetString(piece);
                    break;

                case PKT_V1_MODEL:
                    msg.Model = ASCIIEncoding.ASCII.GetString(piece);
                    break;

                case PKT_V1_PLATFORM:
                    msg.Platform = ASCIIEncoding.ASCII.GetString(piece);
                    break;
                }

                i += 1;
            }

            return(msg);
        }