Example #1
0
        /// <summary>
        /// Sends a direct message to another device that has already been discovered.
        /// </summary>
        /// <typeparam name="T">The type to cast the response to.</typeparam>
        /// <param name="device">The device to send the message to.</param>
        /// <param name="message">The message to send. Make sure to override the objects ToString method.</param>
        /// <returns></returns>
        public override async Task <T> SendDirectMessage <T>(DiscoverableDevice device, object message)
        {
            try
            {
                using (var httpClient = new HttpClient())
                {
                    var uri      = $"http://{device.IpAddress}:{tcpPort}/discovery/directMessage/{message.ToString()}";
                    var response = await httpClient.GetAsync(uri);

                    response.EnsureSuccessStatusCode();
                    string content = await response.Content.ReadAsStringAsync();

                    return(JsonConvert.DeserializeObject <T>(content));
                };
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                return(default(T));
            }
        }
Example #2
0
        /// <summary>
        /// Asynchronously handle receiving a UDP packet
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="eventArguments"></param>
        async void ReceivedDiscoveryMessage(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs args)
        {
            try
            {
                // Get the data from the packet
                var result       = args.GetDataStream();
                var resultStream = result.AsStreamForRead();
                using (var reader = new StreamReader(resultStream))
                {
                    // Load the raw data into a response object
                    var potentialRequestString = await reader.ReadToEndAsync();

                    // Ignore messages from yourself
                    if (args.RemoteAddress.DisplayName != IpAddress)
                    {
                        if (debug)
                        {
                            Debug.WriteLine("Discovery System: Received UDP packet");
                            Debug.WriteLine($"   >>> {potentialRequestString}");
                        }
                    }
                    else
                    {
                        return;
                    }

                    JObject jRequest = JObject.Parse(potentialRequestString);

                    // If the message was a valid request
                    if (jRequest["command"] != null)
                    {
                        switch (jRequest.Value <string>("command").ToLower())
                        {
                        case "data":
                            // Get the intended recipients
                            var intendedRecipients = jRequest.Value <string>("recipients").Split(',');
                            // If I am in the list or it is for everyone
                            if (intendedRecipients.Any(r => r == "all" || r == name))
                            {
                                // Fire off a data event with the data payload
                                whenDataReceived.OnNext(JObject.FromObject(jRequest["data"]));
                            }
                            break;

                        case "discover":
                            // If we initiated this discovery request
                            if (args.RemoteAddress.DisplayName == IpAddress)
                            {
                                // Ignore it
                                return;
                            }

                            // If the requestor included a list of its known devices
                            if (jRequest["knownDevices"] != null)
                            {
                                // Go through each device
                                foreach (var device in jRequest["knownDevices"])
                                {
                                    // If we are already registered with the requestor
                                    if (device.Value <string>("name") == name)
                                    {
                                        // Ignore
                                        return;
                                    }
                                }
                            }

                            // Begin Broadcasting a discovery response until we get an acceptance or reach the timeout.
                            StartBroadcasting();
                            break;

                        case "identify":
                            // The device must broadcast a name and its device info
                            if (jRequest["name"] != null &&
                                jRequest["deviceInfo"] != null)
                            {
                                // Create a strongly typed model of this new device
                                var newDevice = new DiscoverableDevice();
                                newDevice.DeviceInfo = jRequest.Value <JObject>("deviceInfo");
                                newDevice.Name       = jRequest.Value <string>("name");
                                newDevice.IpAddress  = args.RemoteAddress.DisplayName;

                                // Add it to the database
                                if (debug)
                                {
                                    Debug.WriteLine($"Discovery System: Added {newDevice.Name} @ {newDevice.IpAddress}");
                                }

                                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                {
                                    // Go through the existing devices
                                    foreach (var device in Devices)
                                    {
                                        if (device.Name == newDevice.Name)
                                        {
                                            // If the IP address has changed
                                            if (device.IpAddress != newDevice.IpAddress)
                                            {
                                                // Update the smart device in the database
                                                device.IpAddress = newDevice.IpAddress;

                                                return;
                                            }
                                            else     // If its a perfect match
                                            {
                                                // Ignore the response
                                                return;
                                            }
                                        }
                                    }
                                    Devices.Add(newDevice);
                                    whenDeviceAdded.OnNext(newDevice);
                                });
                            }
                            break;

                        case "update":
                            // The device must broadcast a name and its device info
                            if (jRequest["name"] != null &&
                                jRequest["deviceInfo"] != null)
                            {
                                // Create a strongly typed model of this new device
                                var newDevice = new DiscoverableDevice();
                                newDevice.DeviceInfo = jRequest.Value <JObject>("deviceInfo");
                                newDevice.Name       = jRequest.Value <string>("name");
                                newDevice.IpAddress  = args.RemoteAddress.DisplayName;

                                // Go through the existing devices
                                foreach (var device in Devices)
                                {
                                    // If we find a match
                                    if (device.Name == newDevice.Name)
                                    {
                                        // Update the device info
                                        device.DeviceInfo = newDevice.DeviceInfo;
                                        // Update the Ip Address
                                        device.IpAddress = newDevice.IpAddress;
                                        whenDeviceUpdated.OnNext(device);
                                        // Bounce out!
                                        return;
                                    }
                                }

                                // If no matches were found, add this device
                                if (debug)
                                {
                                    Debug.WriteLine($"Discovery System: Added {newDevice.Name} @ {newDevice.IpAddress}");
                                }

                                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                {
                                    Devices.Add(newDevice);
                                    whenDeviceAdded.OnNext(newDevice);
                                });
                            }
                            break;
                        }
                        ;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Discovery System: {ex}");
                return;
            }
        }