Пример #1
0
        public static async Task<RemotePlcInfo> GetRemotePlcInfoAsync(IPAddress localhost, IPAddress remoteHost, int timeout = 10000, int adsUdpPort = Request.DEFAULT_UDP_PORT)
        {
            Request request = CreateSearchRequest(localhost, timeout);

            IPEndPoint broadcast = new IPEndPoint(remoteHost, adsUdpPort);

            Response response = await request.SendAsync(broadcast);
            ResponseResult rr = await response.ReceiveAsync();
            RemotePlcInfo device = ParseBroadcastSearchResponse(rr);

            return device;
        }
Пример #2
0
        public static async Task<List<RemotePlcInfo>> BroadcastSearchAsync(IPAddress localhost, int timeout = 10000, int adsUdpPort = Request.DEFAULT_UDP_PORT)
        {
            Request request = CreateSearchRequest(localhost, timeout);

            IPEndPoint broadcast =
                new IPEndPoint(
                    IPHelper.GetBroadcastAddress(localhost),
                    adsUdpPort);

            Response response = await request.SendAsync(broadcast);
            List<ResponseResult> responses = await response.ReceiveMultipleAsync();

            List<RemotePlcInfo> devices = new List<RemotePlcInfo>();
            foreach (var r in responses)
            {
                RemotePlcInfo device = ParseBroadcastSearchResponse(r);
                devices.Add(device);
            }

            return devices;
        }
        private static RemotePlcInfo ParseBroadcastSearchResponse(ResponseResult rr)
        {
            var device = new RemotePlcInfo {
                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
            var amsNetId = rr.NextChunk(Segment.AMSNETID.Length, add: Segment.PORT.Length + Segment.ROUTETYPE_STATIC.Length);

            device.AmsNetId = new AmsNetId(amsNetId);

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

            var bName = rr.NextChunk(nameLen - 1, add: 1);

            device.Name = Encoding.Default.GetString(bName);

            // TCat type
            var 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
            var osVer = rr.NextChunk(Segment.L_OSVERSION);
            var osKey = (ushort)(osVer[0] * 256 + osVer[4]);

            device.OsVersion = OS_IDS.ContainsKey(osKey) ? OS_IDS[osKey] : osKey.ToString("X2");

            var isUnicode = false;

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

            var ci = tail.Length - 4;

            for (var i = ci; i > 0; i -= 4)
            {
                if (tail[i + 0] == 3 &&
                    tail[i + 2] == 4)
                {
                    isUnicode = tail[i + 4] > 2; // Tc3 uses unicode

                    device.TcVersion.Version  = tail[i + 4];
                    device.TcVersion.Revision = tail[i + 5];
                    device.TcVersion.Build    = tail[i + 6] + tail[i + 7] * 256;
                    break;
                }
            }

            // Comment
            var descMarker = rr.NextChunk(Segment.L_DESCRIPTIONMARKER);
            var len        = 0;
            var c          = rr.Buffer.Length;

            if (descMarker[0] == 2)
            {
                if (isUnicode)
                {
                    for (var 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 (var i = 0; i < c; i++)
                    {
                        if (rr.Buffer[rr.Shift + i] == 0)
                        {
                            break;
                        }

                        len++;
                    }
                }

                if (len > 0)
                {
                    var description = rr.NextChunk(len);

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

            return(device);
        }