public static async Task <IEnumerable <RestDevice> > Discover(int timeout = 7) { var tcs = new TaskCompletionSource <IEnumerable <RestDevice> >(); var rests = new Dictionary <ulong, RestDevice>(); var advertisements = new Dictionary <ulong, BluetoothLEAdvertisementReceivedEventArgs>(); var ble_watcher = new BluetoothLEAdvertisementWatcher { ScanningMode = BluetoothLEScanningMode.Active }; ble_watcher.Received += (obj, adv) => { // name is received in one advertisement, manufacturer data in a different one if (!advertisements.ContainsKey(adv.BluetoothAddress)) { advertisements[adv.BluetoothAddress] = adv; } // accumulate the required info in the cache var cached = advertisements[adv.BluetoothAddress]; if (cached.Advertisement.LocalName == "" && adv.Advertisement.LocalName != "") { cached.Advertisement.LocalName = adv.Advertisement.LocalName; } if (cached.Advertisement.ManufacturerData.Count == 0 && adv.Advertisement.ManufacturerData.Count == 1) { cached.Advertisement.ManufacturerData.Add(adv.Advertisement.ManufacturerData[0]); } // check if the device is a Rest if (IsRestAdvertisement(cached.Advertisement) && !rests.ContainsKey(cached.BluetoothAddress)) { Dbg("discovered rest device: " + cached.BluetoothAddress.ToString("X")); var rest = new RestDevice(cached.Advertisement.LocalName, cached.BluetoothAddress); rests.Add(cached.BluetoothAddress, rest); } }; ble_watcher.Stopped += (obj, e) => { Dbg("discovery complete"); tcs.SetResult(rests.Values); }; ble_watcher.Start(); Dbg("starting discovery"); // wait until timeout await Task.Delay(timeout * 1000); ble_watcher.Stop(); return(await tcs.Task); }
public static RestDeviceData FromBuffer(IBuffer buffer) { var retval = new RestDeviceData(); var data = new byte[buffer.Length]; DataReader.FromBuffer(buffer).ReadBytes(data); //RestDevice.Dbg("manufacturer data: " + BitConverter.ToString(data)); int i = 0; // data index while (i < data.Length) { switch (data[i]) { case B_HEADER1: case B_HEADER2: // TODO: verify header i += 3; break; case B_COLOR: retval.Color = Color.FromArgb(data[i + 4], data[i + 1], data[i + 2], data[i + 3]); i += 5; break; case B_EVENT_NEXT: // TODO: parse next event i += 6; break; case B_PRESET_POWER: // TODO: parse preset retval.Power = (data[i + 1] & 0b1100_0000) != 0b1100_0000; i += 2; break; case B_AUDIO: retval.AudioTrack = (AudioTrack)data[i + 1]; retval.Volume = data[i + 2]; i += 3; break; case B_TIME: // TODO: parse time i += 5; break; case B_EVENT_ACTIVE: // TODO: parse active event i += 2; break; case 0: i += 1; break; default: RestDevice.Dbg("unknown data id: " + data[i].ToString("X")); i += 1; break; } } RestDevice.Dbg($"power:{retval.Power}, color:{retval.Color}, vol:{retval.Volume}, trk: {retval.AudioTrack}"); return(retval); }