Seems strange that these event handlers would affect an error thrown when I close the app. Below is most of the life cycle from constructor and events. The scancallback basically just saves some info to the db, and then calls connect if the device was previously connected.
public WclAdapter()
{
_wclApi = new wclAPI();
_wclApi.Load();
_wclBluetoothDiscovery = new wclBluetoothDiscovery();
_wclBluetoothDiscovery.OnDiscoveryStarted += wclBluetoothDiscovery_OnDiscoveryStarted;
_wclBluetoothDiscovery.OnDiscoveryComplete += wclBluetoothDiscovery_OnDiscoveryComplete;
_wclBluetoothDiscovery.OnDeviceFound += wclBluetoothDiscover_OnDeviceFound;
_wclBluetoothDiscovery.OnDeviceLost += wclBluetoothDiscover_OnDeviceLost;
}
public void Connect(string address, int messageSize, Action onConnected, Action<byte[]> onMessage, Action<BluetoothError> onError)
{
//fire connecting event
if (Connecting != null)
{
Connecting(this, new DeviceStatusEventArgs { Address = address });
}
//try to clear client if it exists already
if (_clients.ContainsKey(address))
{
wclClient client;
if (!_clients.TryRemove(address, out client))
{
if (Error != null)
{
Error(this, new DeviceStatusEventArgs { Address = address, Message = "Unable to clear old bluetooth client." });
}
}
}
//setup call backs
var bc = new wclClient();
if (!_clients.TryAdd(address, bc))
{
if (Error != null)
{
Error(this, new DeviceStatusEventArgs { Address = address, Message = "Unable to save new bluetooth client." });
}
}
bc.OnDisconnect += (sender, args) =>
{
if (Disconnected != null && !_isShuttingDown)
{
Disconnected(this, new DeviceStatusEventArgs { Address = address });
}
};
bc.OnData += (sender, args) =>
{
//buffer data till full message received
foreach (var b in args.Data)
{
_buffer.Add(b);
if (b != Convert.ToByte('\n') || _buffer.Count != messageSize)
{
continue;
}
onMessage(_buffer.ToArray());
_buffer.Clear();
}
};
bc.OnConnect += (sender, args) =>
{
//if it didn't complete, bounce it back to disconnect
if (args.Error != wclErrors.WCL_E_SUCCESS)
{
if (Error != null)
{
Error(this, new DeviceStatusEventArgs { Address = address, Message = wclErrors.wclGetErrorMessage(args.Error) });
}
bc.Disconnect();
return;
}
//fire connected event
if (Connected != null)
{
Connected(this, new DeviceStatusEventArgs { Address = address });
}
};
//start connection
var radio = GetSelectedRadio(_wclBluetoothDiscovery);
if (radio != null)
{
bc.BluetoothParams.Address = string.Format("({0})", address);
bc.BluetoothParams.Radio = radio;
bc.BluetoothParams.Service = wclUUIDs.SerialPortServiceClass_UUID;
bc.Transport = wclTransport.trBluetooth;
bc.ConnectTimeout = 30000; //ms
var errorCode = bc.Connect();
//if it didn't complete, bounce it back to disconnect
if (errorCode != wclErrors.WCL_E_SUCCESS)
{
if (Error != null)
{
Error(this, new DeviceStatusEventArgs { Address = address, Message = wclErrors.wclGetErrorMessage(errorCode) });
}
bc.Disconnect();
}
}
}
public void StartScan(IScanCallback scanCallback, bool toggleRadios = true)
{
WriteDiagnosticEntryAction("Beginning scan of devices");
IsScanning = true;
if (ScanStarted != null)
{
ScanStarted(this, EventArgs.Empty);
}
ScanCallback = scanCallback;
var radio = GetSelectedRadio(_wclBluetoothDiscovery);
if (radio != null)
{
var errorCode = _wclBluetoothDiscovery.Discovery(radio);
if (errorCode != wclErrors.WCL_E_SUCCESS)
{
if (ScanError != null)
{
ScanError(this, new ScanErrorEventArgs { Message = wclErrors.wclGetErrorMessage(errorCode) });
}
}
}
}
private wclBluetoothRadio GetSelectedRadio(wclBluetoothDiscovery discovery)
{
wclBluetoothRadio radio = null;
var radios = new wclBluetoothRadios();
if (discovery.EnumRadios(radios) == wclErrors.WCL_E_SUCCESS && radios.Count > 0)
{
radio = new wclBluetoothRadio();
radio.Assign(radios[0]);
}
if (radio == null)
{
if (Error != null)
{
Error(this, new DeviceStatusEventArgs { Address = null, Message = "No Bluetooth API was found." });
}
}
return radio;
}
private void wclBluetoothDiscovery_OnDiscoveryComplete(object sender, wclBluetoothDiscoveryCompleteEventArgs e)
{
if (ScanCallback != null)
{
var count = e.Devices.Count;
var devices = new List<WclDevice>((int)count);
for (var i = 0U; i < count; i++)
{
string name = null;
e.Devices.GetName(e.Radio, ref name);
devices.Add(new WclDevice(name, e.Devices.Address.Replace("(", string.Empty).Replace(")", string.Empty), 0, new byte[] { }));
}
foreach (var device in devices)
{
ScanCallback.Callback(device);
}
}
WriteDiagnosticEntryAction("Completed scan of devices");
IsScanning = false;
if (ScanCompleted != null)
{
ScanCompleted(this, EventArgs.Empty);
}
}
private void wclBluetoothDiscovery_OnDiscoveryStarted(object sender, wclBluetoothDiscoveryStartedEventArgs e)
{
IsScanning = true;
if (ScanStarted != null)
{
ScanStarted(this, EventArgs.Empty);
}
}
private void wclBluetoothDiscover_OnDeviceLost(object sender, wclBluetoothDiscoveryDeviceEventArgs args)
{
WriteDiagnosticEntryAction(string.Format("Device Lost, {0}", args.Device.Address));
}
private void wclBluetoothDiscover_OnDeviceFound(object sender, wclBluetoothDiscoveryDeviceEventArgs args)
{
WriteDiagnosticEntryAction(string.Format("Device Found, {0}", args.Device.Address));
}