private async Task SendDiscoveryRequestAsync() { using (UdpClient client = new UdpClient(PORT_NUMBER) { EnableBroadcast = true }) { var discoveryJson = JObject.FromObject(new { system = new { get_sysinfo = (object)null }, emeter = new { get_realtime = (object)null } }).ToString(Newtonsoft.Json.Formatting.None); var discoveryPacket = SmartHomeProtocolEncoder.Encrypt(discoveryJson).ToArray(); var bytes = discoveryPacket.Skip(4).ToArray(); int sentBytes = await client.SendAsync(bytes, bytes.Length, new IPEndPoint(IPAddress.Broadcast, PORT_NUMBER)).ConfigureAwait(false); //int sentBytes = client.Send(bytes, bytes.Length, new IPEndPoint(IPAddress.Broadcast, PORT_NUMBER)); // no bytes sents if (sentBytes == 0) { throw new InvalidOperationException(); } } }
private async Task ReceiveAsync(int waitTimeOutInMs) { if (discoveryComplete) //Prevent ObjectDisposedException/NullReferenceException when the Close() function is called { return; } UdpClient udpListener = new UdpClient(PORT_NUMBER) { EnableBroadcast = true }; // set timeout //udpListener.Client.ReceiveTimeout = Math.Max(waitTimeOutInMs, 100); //IPEndPoint ip = default; //byte[] buffer = udpListener.Receive(ref ip); UdpReceiveResult response = await udpListener.ReceiveAsync().ConfigureAwait(false); IPEndPoint ip = response.RemoteEndPoint; var message = Encoding.ASCII.GetString(SmartHomeProtocolEncoder.Decrypt(response.Buffer)); try { TPLinkSmartDevice device = null; dynamic sys_info = ((dynamic)JObject.Parse(message)).system.get_sysinfo; string model = (string)sys_info.model; if (model != null) { if (model.StartsWith("HS110", StringComparison.OrdinalIgnoreCase)) { device = new TPLinkSmartMeterPlug(ip.Address.ToString()); } else if (model.StartsWith("HS", StringComparison.OrdinalIgnoreCase)) { device = new TPLinkSmartPlug(ip.Address.ToString()); } else if (model.StartsWith("KL", StringComparison.OrdinalIgnoreCase) || model.StartsWith("LB", StringComparison.OrdinalIgnoreCase)) { device = await TPLinkKL130.CreateNew(ip.Address.ToString()); } // new device found, store in list and raise event if (device != null) { DiscoveredDevices.Add(device); OnDeviceFound(device); } } } catch (RuntimeBinderException ex) { //discovered wrong device Debug.WriteLine(ex.Message); } finally { // ensure the socket is closed even if exception happenned udpListener.Dispose(); } discoveryComplete = true; }