예제 #1
0
        /// <summary>
        /// Parses response early recieved by AdsFinder
        /// </summary>
        /// <param name="rr"></param>
        /// <returns>True - if route added, False - otherwise</returns>
        public static bool ParseResponse(ResponseResult rr)
        {
            if (rr == null)
                return false;

            if (!rr.Buffer.Take(4).ToArray().SequenceEqual(Segment.HEADER))
                    return false;
            if (!rr.Buffer.Skip(4).Take(Segment.END.Length).ToArray().SequenceEqual(Segment.END))
                return false;
            if (!rr.Buffer.Skip(8).Take(Segment.RESPONSE_DISCOVER.Length).ToArray().SequenceEqual(Segment.RESPONSE_ADDROUTE))
                return false;

            rr.Shift =
                Segment.HEADER.Length +
                Segment.END.Length +
                Segment.RESPONSE_ADDROUTE.Length +
                Segment.AMSNETID.Length +
                Segment.PORT.Length +
                Segment.END.Length +
                Segment.END.Length;

            byte[] ack = rr.NextChunk(Segment.L_ROUTEACK);

            return (ack[0] == 0) && (ack[1] == 0);
        }
예제 #2
0
        public async Task<ResponseResult> ReceiveAsync()
        {
            ResponseResult result = null;

            var worker = client.ReceiveAsync();
            var task = await Task.WhenAny(worker, Task.Delay(Timeout));

            if (task == worker)
            {
                UdpReceiveResult udpResult = await worker;
                result = new ResponseResult(udpResult);
            }
            else
            {
                client.Close();
            }

            return result;
        }
예제 #3
0
        public static DeviceInfo ParseResponse(ResponseResult rr)
        {
            DeviceInfo device = new DeviceInfo();

            device.Address = rr.RemoteHost;

            if (!rr.Buffer.Take(4).ToArray().SequenceEqual(Segment.HEADER))
                return device;
            if (!rr.Buffer.Skip(4).Take(Segment.END.Length).ToArray().SequenceEqual(Segment.END))
                return device;
            if (!rr.Buffer.Skip(8).Take(Segment.RESPONSE_DISCOVER.Length).ToArray().SequenceEqual(Segment.RESPONSE_DISCOVER))
                return device;

            rr.Shift = Segment.HEADER.Length + Segment.END.Length + Segment.RESPONSE_DISCOVER.Length;

            // AmsNetId
            // then skip 2 bytes of PORT + 4 bytes of ROUTE_TYPE
            byte[] amsNetId = rr.NextChunk(Segment.AMSNETID.Length, add: Segment.PORT.Length + Segment.ROUTETYPE_STATIC.Length);
            device.AmsNetId = new AdsNetId(amsNetId);

            // PLC NameLength
            byte[] bNameLen = rr.NextChunk(Segment.L_NAMELENGTH);
            int nameLen =
                bNameLen[0] == 5 && bNameLen[1] == 0 ?
                    bNameLen[2] + bNameLen[3] * 256 :
                    0;

            byte[] bName = rr.NextChunk(nameLen - 1, add: 1);
            device.Name = System.Text.ASCIIEncoding.Default.GetString(bName);

            // TCat type
            byte[] tcatType = rr.NextChunk(Segment.TCATTYPE_RUNTIME.Length);
            if (tcatType[0] == Segment.TCATTYPE_RUNTIME[0])
            {
                if(tcatType[2] == Segment.TCATTYPE_RUNTIME[2])
                    device.IsRuntime = true;
            }

            // OS version
            byte[] osVer = rr.NextChunk(Segment.L_OSVERSION);
            ushort osKey = (ushort)(osVer[0] * 256 + osVer[4]);
            device.OsVersion = OS_IDS.ContainsKey(osKey) ? OS_IDS[osKey] : osKey.ToString("X2");
            //??? device.OS += " build " + (osVer[8] + osVer[9] * 256).ToString();

            bool isUnicode = false;

            // looking for packet with tcat version;
            // usually it is in the end of the packet
            byte[] tail = rr.NextChunk(rr.Buffer.Length - rr.Shift, true);

            string tcatV = "";
            int ci = tail.Length - 4;
            for (int i = ci; i > 0; i -= 4)
            {
                if (tail[i + 0] == 3 &&
                    tail[i + 2] == 4)
                {
                    isUnicode = tail[i + 4] > 2; // Tc3 uses unicode
                    tcatV = string.Format("{0}.{1} build {2}",
                        tail[i + 4].ToString(),
                        tail[i + 5].ToString(),
                        (tail[i + 6] + tail[i + 7] * 256).ToString());
                    break;
                }
            }
            device.TcVersion = tcatV;

            // Comment
            byte[] descMarker = rr.NextChunk(Segment.L_DESCRIPTIONMARKER);
            int len = 0;
            int c = rr.Buffer.Length;
            if (descMarker[0] == 2)
            {
                if (isUnicode)
                {
                    for (int i = 0; i < c; i += 2)
                    {
                        if (rr.Buffer[rr.Shift + i] == 0 &&
                            rr.Buffer[rr.Shift + i + 1] == 0)
                            break;
                        len += 2;
                    }
                }
                else
                {
                    for (int i = 0; i < c; i++)
                    {
                        if (rr.Buffer[rr.Shift + i] == 0)
                            break;
                        len++;
                    }
                }

                if (len > 0)
                {
                    byte[] description = rr.NextChunk(len);

                    if (isUnicode)
                    {
                        byte[] asciiBytes = Encoding.Convert(Encoding.Unicode, Encoding.ASCII, description);
                        char[] asciiChars = new char[Encoding.ASCII.GetCharCount(asciiBytes, 0, asciiBytes.Length)];
                        Encoding.ASCII.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
                        device.Comment = new string(asciiChars);
                    }
                    else
                        device.Comment = ASCIIEncoding.Default.GetString(description);
                }
            }

            return device;
        }