/// <summary> /// Stop the scan and notify the caller that it has ended /// </summary> private void StopScan() { Log("Stop BLE scan"); BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.Scanner; if (_scanning && scanner != null && _skfScanCallback != null) { // Hold onto this scan callback so we can flush it before any following scan _previousScanCallback = _skfScanCallback; scanner.StopScan(_skfScanCallback); _scanTimer?.Stop(); _scanning = false; // Invoke the caller's callback so they know the scan finished DiscoveryFinished?.Invoke(this, new EventArgs()); } // Clear the event handlers if (_skfScanCallback != null) { Log(string.Format("StopScan: {0} callbacks cleared", _skfScanCallback.ClearCallers())); // _skfScanCallback.Dispose(); _skfScanCallback = null; } //_scanTimer?.Dispose(); _scanTimer = null; }
/// <summary> /// Scan for a single device using its address /// </summary> /// <param name="iDiscoveryFinished">Event handler for caller to be notified when the scan has completed</param> /// <param name="iDeviceAddress">Device address in the form of a GUID string</param> /// <param name="iScanSeconds">Number of seconds to scan; set to zero for indefinite</param> /// <returns></returns> public bool ScanSingleDevice(EventHandler iDiscoveryFinished, string iDeviceAddress, int iScanSeconds = 0) { // Hold the event handler DiscoveryFinished = iDiscoveryFinished ?? throw new ArgumentNullException("Disovery finished event handler must be specified"); try { // Clear list of received devices FoundDevices.Clear(); // Ensure it has stopped StopScan(); BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.Scanner; ScanSettings settings = new ScanSettings.Builder() .SetLegacy(false) .SetScanMode(ScanSettings.ScanModeLowLatency) .SetUseHardwareBatchingIfSupported(false).Build(); List <ScanFilter> filters = new List <ScanFilter>(); // Add filter to return only the specified device filters.Add(new ScanFilter.Builder().SetDeviceAddress(iDeviceAddress).Build()); _skfScanCallback = new NordicScanCallBack(); // Add in the event handlers _skfScanCallback.ScanResult += Receiver_ScanResult; _skfScanCallback.ScanFailure += Receiver_ScanFailure; // Scan scanner.StartScan(filters, settings, _skfScanCallback); _scanning = true; if (iScanSeconds != 0) { // Use a timer to end the scan _scanTimer = new Timer(iScanSeconds * 1000); _scanTimer.Elapsed += _scanTimer_Elapsed; _scanTimer.AutoReset = false; _scanTimer.Start(); } return(true); } catch (Exception ex) { Log(string.Format("Exception thrown in ScanSingleDevice: {0}", ex.Message)); return(false); } }
/// <summary> /// Initiate a BLE scan /// </summary> /// <param name="iDiscoveryFinished">Event handler for caller to be notified when the scan has completed</param> /// <param name="iScanSeconds">Number of seconds to scan; set to zero for indefinite</param> /// <param name="iServiceId">Optional service ID (GUID string) to filter scan results; set to null to skip</param> /// <param name="iManufacturerId">Optional filter on manufacturer ID; set to zero or omit to skip</param> /// <returns>True if apparently successul</returns> public bool Scan(EventHandler iDiscoveryFinished, int iScanSeconds, string iServiceId = null, int iManufacturerId = 0) { // Hold the event handler DiscoveryFinished = iDiscoveryFinished ?? throw new ArgumentNullException("Disovery finished event handler must be specified"); // Ensure the adaptor is present CreateAdaptor(); try { // Clear list of received devices FoundDevices.Clear(); // Ensure it has stopped StopScan(); BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.Scanner; // If there was a previous scan, flush its results before we start another //if (_previousScanCallback != null) //{ // scanner.FlushPendingScanResults(_previousScanCallback); // _previousScanCallback = null; //} ScanSettings settings = new ScanSettings.Builder() .SetLegacy(false) .SetScanMode(ScanSettings.ScanModeLowLatency) //.SetReportDelay(1000) .SetUseHardwareBatchingIfSupported(false).Build(); List <ScanFilter> filters = new List <ScanFilter>(); if (!string.IsNullOrEmpty(iServiceId)) { ParcelUuid mUuid = ParcelUuid.FromString(iServiceId); filters.Add(new ScanFilter.Builder().SetServiceUuid(mUuid).Build()); } if (iManufacturerId != 0) { filters.Add(new ScanFilter.Builder().SetManufacturerData(iManufacturerId, new byte[1] { 0 }, new byte[1] { 0 }).Build()); } _skfScanCallback = new NordicScanCallBack(); // Add in the event handlers _skfScanCallback.ScanResult += Receiver_ScanResult; _skfScanCallback.ScanFailure += Receiver_ScanFailure; // Scan scanner.StartScan(filters, settings, _skfScanCallback); _scanning = true; if (iScanSeconds != 0) { // Use a timer to end the scan _scanTimer = new Timer(iScanSeconds * 1000); _scanTimer.Elapsed += _scanTimer_Elapsed; _scanTimer.AutoReset = false; _scanTimer.Start(); } return(true); } catch (Exception ex) { Log(string.Format("Exception thrown in Scan: {0}", ex.Message)); return(false); } }