private async Task ExecuteDiscoveryTask()
		{
			int repeatTime = EndpointController.REPEAT_DISCOVERY_TASK / 2;

			while (running)
			{
				Debug.WriteLine("#> [DiscoveryCloudletMulticast]: Started Cloudlet Discovery using Multicast UDP");
				retry = 0;

				DatagramSocket socketSent = null;
				DatagramSocket socketReplay = null;
				try
				{
					socketSent = new DatagramSocket();
					await socketSent.BindEndpointAsync(null, string.Empty);
					socketSent.JoinMulticastGroup(ip);

					socketReplay = new DatagramSocket();
					socketReplay.MessageReceived += SocketOnMessageReceived;
					await socketReplay.BindServiceNameAsync(replyCloudletPort.ToString());

					using (DataWriter writer = new DataWriter(await socketSent.GetOutputStreamAsync(ip, multicastPort.ToString())))
					{
						while (retry < 60 && running)
						{
							writer.WriteString("mpos_cloudlet_req");
							await writer.StoreAsync();
							await writer.FlushAsync();

							await Task.Delay(500);
							retry++;
						}
					}
				}
				catch (IOException e)
				{
					Debug.WriteLine("## [DiscoveryCloudletMulticast]: Any problem with i/o in multicast system!\n" + e.ToString());
				}
				finally
				{
					socketSent.Dispose();
					socketReplay.Dispose();

					socketSent = null;
					socketReplay = null;
				}

				if (running)
				{
					Debug.WriteLine(">> [DiscoveryCloudletMulticast]: Retry Discovery Cloudlet, in " + repeatTime + " ms");
					await Task.Delay(repeatTime);
				}
				else
				{
					Debug.WriteLine("#> [DiscoveryCloudletMulticast]: Finished Discovery Cloudlet");
				}
			}
		}
예제 #2
0
 private void CloseListenerSocket()
 {
     if (listenerSocket == null)
     {
         return;
     }
     listenerSocket.Dispose();
     listenerSocket = null;
 }
        private async Task DoWakeOnLan(string macAddress, string ipAddress, string port)
        {
            var socket = new DatagramSocket();

            await socket.BindServiceNameAsync("0");

            var o = await socket.GetOutputStreamAsync(new HostName(ipAddress), port);
            var writer = new DataWriter(o);
            writer.WriteBytes(GetBuffer(macAddress));
            await writer.StoreAsync();

            socket.Dispose();
        }
예제 #4
0
        async partial void SendTimeRequest()
        {
            var            socket      = new Windows.Networking.Sockets.DatagramSocket();
            AsyncUdpResult asyncResult = null;

            try
            {
                var buffer = new byte[48];
                buffer[0] = 0x1B;

                socket.MessageReceived += Socket_Completed_Receive;
                asyncResult             = new AsyncUdpResult(socket);

                await socket.ConnectAsync(new Windows.Networking.HostName(_ServerAddress), "123").AsTask().ConfigureAwait(false);

                using (var udpWriter = new DataWriter(socket.OutputStream))
                {
                    udpWriter.WriteBytes(buffer);
                    await udpWriter.StoreAsync().AsTask().ConfigureAwait(false);

                    udpWriter.WriteBytes(buffer);
                    await udpWriter.StoreAsync().AsTask().ConfigureAwait(false);

                    asyncResult.Wait(OneSecond);
                }
            }
            catch (Exception ex)
            {
                try
                {
                    if (socket != null)
                    {
                        ExecuteWithSuppressedExceptions(() => socket.MessageReceived -= this.Socket_Completed_Receive);
                        ExecuteWithSuppressedExceptions(() => socket.Dispose());
                    }
                }
                finally
                {
                    OnErrorOccurred(ExceptionToNtpNetworkException(ex));
                }
            }
            finally
            {
                asyncResult?.Dispose();
            }
        }
예제 #5
0
		async partial void SendTimeRequest()
		{
			var socket = new Windows.Networking.Sockets.DatagramSocket();
			AsyncUdpResult asyncResult = null;
			try
			{
				var buffer = new byte[48];
				buffer[0] = 0x1B;

				socket.MessageReceived += Socket_Completed_Receive;
				asyncResult = new AsyncUdpResult(socket);
			
				await socket.ConnectAsync(new Windows.Networking.HostName(_ServerAddress), "123").AsTask().ConfigureAwait(false);

				using (var udpWriter = new DataWriter(socket.OutputStream))
				{
					udpWriter.WriteBytes(buffer);
					await udpWriter.StoreAsync().AsTask().ConfigureAwait(false);

					udpWriter.WriteBytes(buffer);
					await udpWriter.StoreAsync().AsTask().ConfigureAwait(false);

					asyncResult.Wait(OneSecond);
				}
			}
			catch (Exception ex)
			{
				try
				{
					if (socket != null)
					{
						ExecuteWithSuppressedExceptions(() => socket.MessageReceived -= this.Socket_Completed_Receive);
						ExecuteWithSuppressedExceptions(() => socket.Dispose());
					}
				}
				finally
				{
					OnErrorOccurred(ExceptionToNtpNetworkException(ex));
				}
			}
			finally
			{
				asyncResult?.Dispose();
			}
		}
예제 #6
0
        private void StartListener_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(ServiceName.Text))
            {
                _rootPage.NotifyUser("Please provide a service name.", NotifyType.ErrorMessage);
                return;
            }

            if (listenerSocket != null)
            {
                _rootPage.NotifyUser("A listener socket is already set up.", NotifyType.ErrorMessage);
                return;
            }

            var isMulticastSocket = MulticastRadioButton.IsChecked == true;

            listenerSocket = new Windows.Networking.Sockets.DatagramSocket();
            listenerSocket.MessageReceived += MessageReceived;

            if (isMulticastSocket)
            {
                listenerSocket.Control.MulticastOnly = true;
            }

            try
            {
            }
            catch (Exception exception)
            {
                listenerSocket.Dispose();
                listenerSocket = null;

                if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
                {
                    throw;
                }

                _rootPage.NotifyUser("Start listening failed with error: " + exception.Message,
                                     NotifyType.ErrorMessage);
            }
        }
예제 #7
0
 public static IObservable<ZeroconfRecord> Resolve(string protocol)
 {
     return Observable.Create<ZeroconfRecord>(async observer =>
         {
             var socket = new DatagramSocket();
             var s = Observable
                 .FromEventPattern
                 <TypedEventHandler<DatagramSocket, DatagramSocketMessageReceivedEventArgs>,
                     DatagramSocketMessageReceivedEventArgs>(
                         x => socket.MessageReceived += x, _ => socket.Dispose())
                 .Select(ProcessMessage)
                 .Where(x => x != null)
                 .Subscribe(observer);
             await socket.BindServiceNameAsync("5353");
             socket.JoinMulticastGroup(new HostName("224.0.0.251"));
             var os = await socket.GetOutputStreamAsync(new HostName("224.0.0.251"), "5353");
             var writer = new DataWriter(os);
             WriteQueryMessage(protocol, writer);
             writer.StoreAsync();
             return s;
         });
 }
        /// <summary>
        /// This is the click handler for the 'StartListener' button.
        /// </summary>
        /// <param name="sender">Object for which the event was generated.</param>
        /// <param name="e">Event's parameters.</param>
        private async void StartListener_Click(object sender, RoutedEventArgs e)
        {
            if (String.IsNullOrEmpty(ServiceName.Text))
            {
                rootPage.NotifyUser("Please provide a service name.", NotifyType.ErrorMessage);
                return;
            }

            if (listenerSocket != null)
            {
                rootPage.NotifyUser("A listener socket is already set up.", NotifyType.ErrorMessage);
                return;
            }

            bool isMulticastSocket = (MulticastRadioButton.IsChecked == true);
            listenerSocket = new DatagramSocket();
            listenerSocket.MessageReceived += MessageReceived;

            if (isMulticastSocket)
            {
                // DatagramSockets conduct exclusive (SO_EXCLUSIVEADDRUSE) binds by default, effectively blocking
                // any other UDP socket on the system from binding to the same local port. This is done to prevent
                // other applications from eavesdropping or hijacking a DatagramSocket's unicast traffic.
                //
                // Setting the MulticastOnly control option to 'true' enables a DatagramSocket instance to share its
                // local port with any Win32 sockets that are bound using SO_REUSEADDR/SO_REUSE_MULTICASTPORT and
                // with any other DatagramSocket instances that have MulticastOnly set to true. However, note that any
                // attempt to use a multicast-only DatagramSocket instance to send or receive unicast data will result
                // in an exception being thrown.
                //
                // This control option is particularly useful when implementing a well-known multicast-based protocol,
                // such as mDNS and UPnP, since it enables a DatagramSocket instance to coexist with other applications
                // running on the system that also implement that protocol.
                listenerSocket.Control.MulticastOnly = true;
            }

            // Start listen operation.
            try
            {
                await listenerSocket.BindServiceNameAsync(ServiceName.Text);

                if (isMulticastSocket)
                {
                    // Join the multicast group to start receiving datagrams being sent to that group.
                    listenerSocket.JoinMulticastGroup(new HostName(RemoteAddress.Text));

                    rootPage.NotifyUser(
                        "Listening on port " + listenerSocket.Information.LocalPort + " and joined to multicast group",
                        NotifyType.StatusMessage);
                }
                else
                {
                    rootPage.NotifyUser(
                        "Listening on port " + listenerSocket.Information.LocalPort,
                        NotifyType.StatusMessage);
                }

                // Enable scenario steps that require us to have an active listening socket.
                SendMessageButton.IsEnabled = true;
                CloseListenerButton.IsEnabled = true;
            }
            catch (Exception exception)
            {
                listenerSocket.Dispose();
                listenerSocket = null;

                // If this is an unknown status it means that the error is fatal and retry will likely fail.
                if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
                {
                    throw;
                }

                rootPage.NotifyUser(
                    "Start listening failed with error: " + exception.Message,
                    NotifyType.ErrorMessage);
            }
        }
		private async void SocketOnMessageReceived(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs args)
		{
			using (var reader = new StreamReader(args.GetDataStream().AsStreamForRead(bufferSize)))
			{
				Debug.WriteLine("#> [DiscoveryCloudletMulticast]: Wait Reply...");
				string message = await reader.ReadToEndAsync();
				if (message.Contains("="))
				{
					string[] extractMessage = message.Split(new char[] { '=' });
					Stop();

					MposFramework.Instance.EndpointController.FoundCloudlet(extractMessage[1]);
					Debug.WriteLine("#> [ReceiveReplyCloudlet]: Finished Reply Cloudlet listen");
				}
			}
			socket.Dispose();
		}
예제 #10
0
		/// <summary>
		///     Searches for an available devices of specified type.
		/// </summary>
		/// <param name="searchTarget">
		///     The type of the devices to search for.
		/// </param>
		/// <param name="timeForResponse">
		///     The time (in seconds) of a search.
		/// </param>
		/// <returns>
		///     An observable collection which contains search results.
		/// </returns>
		public IObservable<SearchResponseMessage> Search(string searchTarget, int timeForResponse)
		{
			return Observable.Create<SearchResponseMessage>(async observer =>
			{
				var searchSocket = new DatagramSocket();

				// Handling responses from found devices
				searchSocket.MessageReceived += async (sender, args) =>
				{
					var dataReader = args.GetDataReader();
					dataReader.InputStreamOptions = InputStreamOptions.Partial;

					if (dataReader.UnconsumedBufferLength == 0)
					{
						await dataReader.LoadAsync(1024);
					}

					var message = dataReader.ReadString(dataReader.UnconsumedBufferLength);

					try
					{
						var response = SearchResponseMessage.Create(message);

						observer.OnNext(response);
					}
					catch (ArgumentException ex)
					{
						logger.Instance().Warning(ex, "The received M-Search response has been ignored.", "Message".As(message));
					}
				};

				await searchSocket.BindServiceNameAsync("0");
				searchSocket.JoinMulticastGroup(this.multicastHost);

				var request = MSearchRequestFormattedString.F(searchTarget, timeForResponse);
				var buffer = Encoding.UTF8.GetBytes(request).AsBuffer();

				// Sending the search request to a multicast group
				var outputStream = await searchSocket.GetOutputStreamAsync(this.multicastHost, MulticastPort.ToString());
				await outputStream.WriteAsync(buffer);
				await outputStream.WriteAsync(buffer);

				// Stop listening for a devices when timeout for responses is expired
				Observable.Timer(TimeSpan.FromSeconds(timeForResponse)).Subscribe(s =>
				{
					observer.OnCompleted();
					searchSocket.Dispose();
				});

				logger.Instance().Debug("M-Search request has been sent. [multicastHost={0}, searchTarget={1}]".F(multicastHost.DisplayName, searchTarget));
				return searchSocket.Dispose;
			});
		}
예제 #11
0
 public async Task SendMessage(byte[] message, string host, string port)
 {
     sender = new DatagramSocket();
     try
     {
         using (var stream = await sender.GetOutputStreamAsync(new HostName(host), port))
         {
             var writer = new DataWriter(stream);
             writer.WriteBytes(message);
             await writer.StoreAsync();
             playPage.DisplayMessages(name + " :Send message");
         }
     }
     catch (Exception ex)
     {
         playPage.DisplayMessages(name + " :Error: Send Message\n" + ex.ToString());
     }
     sender.Dispose();
 }
예제 #12
0
        /// <summary>
        /// Search devices and retrieve their device info.
        /// </summary>
        /// <param name="timeoutSec">Seconds to wait before invokation of OnTimeout.</param>
        /// <param name="OnServerFound">Success callback. This will be invoked for each devices until OnTimeout is invoked.</param>
        /// <param name="OnTimeout">Timeout callback.</param>
        public async void SearchDevices(int timeoutSec, Action<DeviceInfo> OnServerFound, Action OnTimeout)
        {
            if (OnServerFound == null || OnTimeout == null)
            {
                throw new ArgumentNullException();
            }

            Debug.WriteLine("DeviceFinder.SearchDevices");

            if (timeoutSec < 2)
            {
                timeoutSec = 2;
            }

            const int MX = 1;

            var ssdp_data = new StringBuilder()
                .Append("M-SEARCH * HTTP/1.1").Append("\r\n")
                .Append("HOST: ").Append(multicast_address).Append(":").Append(ssdp_port.ToString()).Append("\r\n")
                .Append("MAN: ").Append("\"ssdp:discover\"").Append("\r\n")
                .Append("MX: ").Append(MX.ToString()).Append("\r\n")
                .Append("ST: urn:schemas-sony-com:service:ScalarWebAPI:1").Append("\r\n")
                //.Append("ST: ssdp:all").Append("\r\n") // For debug
                .Append("\r\n")
                .ToString();
            byte[] data_byte = Encoding.UTF8.GetBytes(ssdp_data);
            //Debug.WriteLine(ssdp_data);

            bool timeout_called = false;

            var DD_Handler = new AsyncCallback(ar =>
            {
                if (timeout_called)
                {
                    return;
                }

                var req = ar.AsyncState as HttpWebRequest;

                try
                {
                    var res = req.EndGetResponse(ar) as HttpWebResponse;
                    using (var reader = new StreamReader(res.GetResponseStream(), Encoding.UTF8))
                    {
                        try
                        {
                            var info = AnalyzeDD(reader.ReadToEnd());
                            NotifyFoundAsync(info, OnServerFound);
                        }
                        catch (Exception)
                        {
                            //Invalid XML.
                        }
                    }
                }
                catch (WebException)
                {
                    //Invalid DD location or network error.
                }
            });

#if WINDOWS_PHONE
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.SendBufferSize = data_byte.Length;

            SocketAsyncEventArgs snd_event_args = new SocketAsyncEventArgs();
            snd_event_args.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(multicast_address), ssdp_port);
            snd_event_args.SetBuffer(data_byte, 0, data_byte.Length);

            SocketAsyncEventArgs rcv_event_args = new SocketAsyncEventArgs();
            rcv_event_args.SetBuffer(new byte[result_buffer], 0, result_buffer);

            var SND_Handler = new EventHandler<SocketAsyncEventArgs>((sender, e) =>
            {
                if (e.SocketError == SocketError.Success && e.LastOperation == SocketAsyncOperation.SendTo)
                {
                    socket.ReceiveBufferSize = result_buffer;
                    socket.ReceiveAsync(rcv_event_args);
                }
            });
            snd_event_args.Completed += SND_Handler;

            var RCV_Handler = new EventHandler<SocketAsyncEventArgs>((sender, e) =>
            {
                if (e.SocketError == SocketError.Success && e.LastOperation == SocketAsyncOperation.Receive)
                {
                    string result = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
                    //Debug.WriteLine(result);

                    GetDDAsync(DD_Handler, result);

                    socket.ReceiveAsync(e);
                }
            });
            rcv_event_args.Completed += RCV_Handler;
            socket.SendToAsync(snd_event_args);
#elif NETFX_CORE
            var sock = new DatagramSocket();
            sock.MessageReceived += (sender, args) =>
            {
                if (timeout_called || args == null)
                {
                    return;
                }
                var reader = args.GetDataReader();
                string data = reader.ReadString(reader.UnconsumedBufferLength);
                Debug.WriteLine(data);

                GetDDAsync(DD_Handler, data);
            };
            try
            {
                await sock.BindServiceNameAsync(ssdp_port.ToString());
            }
            catch (Exception)
            {
                Debug.WriteLine("Duplicate search is not supported");
                return;
            }
            var host = new HostName(multicast_address);
            sock.JoinMulticastGroup(host);
            try
            {
                var output = await sock.GetOutputStreamAsync(host, ssdp_port.ToString());
                await output.WriteAsync(data_byte.AsBuffer());
                await sock.OutputStream.FlushAsync();
            }
            catch (Exception)
            {
                Debug.WriteLine("Failed to send multicast");
                return;
            }
#endif

            await RunTimeoutInvokerAsync(timeoutSec, () =>
            {
                Debug.WriteLine("SSDP Timeout");
                timeout_called = true;
#if WINDOWS_PHONE
                snd_event_args.Completed -= SND_Handler;
                rcv_event_args.Completed -= RCV_Handler;
                socket.Close();
#elif NETFX_CORE
                sock.Dispose();
#endif
                OnTimeout.Invoke();
            });
        }