コード例 #1
0
        /// <summary>
        /// Try to find ISCP devices on network.
        /// </summary>
        /// Waits for <paramref name="timeout"/> seconds, then returns all devices found,
        /// in form of a list of <see cref="IReceiver"/>s.
        public static List <IReceiver> Discover(double timeout, Func <IPAddress, int, string, IReceiver> constructor)
        {
            int onkyoPort = 60128;

            byte[] onkyoMagic = (new EiscpPacket("!xECNQSTN")).Bytes;

            var foundReceivers = new List <IReceiver>();


            // Broadcast magic
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            using (socket)
            {
                socket.Blocking        = false; // So we can use Poll
                socket.EnableBroadcast = true;
                socket.Bind(new IPEndPoint(IPAddress.Any, 0));
                socket.SendTo(onkyoMagic, new IPEndPoint(IPAddress.Broadcast, onkyoPort));

                EndPoint addr = new IPEndPoint(IPAddress.Broadcast, onkyoPort);
                byte[]   data = new byte[1024];
                int      read = 0;
                while (true)
                {
                    int microsecondTimeout = (int)(timeout * 1000000);
                    if (!socket.Poll(microsecondTimeout, SelectMode.SelectRead))
                    {
                        break;
                    }
                    read = socket.ReceiveFrom(data, ref addr);

                    string response = Encoding.ASCII.GetString(EiscpPacket.Parse(data));
                    // Return string looks something like this:
                    // !1ECNTX-NR609/60128/DX
                    GroupCollection info = Regex.Match(response.Trim(),
                                                       @"!" +
                                                       @"(?<device_category>\d)" +
                                                       @"ECN" +
                                                       @"(?<model_name>[^/]*)/" +
                                                       @"(?<iscp_port>\d{5})/" +
                                                       @"(?<area_code>\w{2})/" +
                                                       @"(?<identifier>.*)"
                                                       ).Groups;

                    int    port  = Int32.Parse(info["iscp_port"].Value);
                    string model = info["model_name"].Value;

                    // Give the user a ready-made receiver instance. It will only
                    // connect on demand, when actually used.
                    IReceiver receiver = constructor((addr as IPEndPoint).Address, port, model);
                    foundReceivers.Add(receiver);
                }
            }

            return(foundReceivers);
        }
コード例 #2
0
        /// Return the next message sent by the receiver, or, after
        /// <paramref name="timeout"/> has passed, return <c>null</c>.
        public virtual byte[] Get(double timeout = 0.1)
        {
            EnsureSocketConnected();

            int microsecondTimeout = (int)(timeout * 1000000);

            if (commandSocket.Poll(microsecondTimeout, SelectMode.SelectRead))
            {
                byte[] headerBytes = new byte[16];
                commandSocket.Receive(headerBytes);

                Header header = EiscpPacket.ParseHeader(headerBytes);

                byte[] message = new byte[header.messageSize];
                commandSocket.Receive(message);

                return(IscpMessage.Parse(message));
            }

            return(null);
        }