Why does bluetooth device watcher find not available devices? - c#

I use deviceWatcher on windows 10 to find available bluetooth (BLE) devices. Available devices are corretly found. DeviceWatcher also find devices that were found in recent searching, but they are not available now (not powered and out of range). They are also found after restart of my application. Does someone know what may cause it?
Device watcher initialization:
private List<DeviceInformation> Devices = new List<DeviceInformation>();
private DeviceWatcher deviceWatcher;
private void StartBleDeviceWatcher()
{
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.Bluetooth.Le.IsConnectable" };
string aqsAllBluetoothLEDevices = "(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")";
deviceWatcher = DeviceInformation.CreateWatcher(aqsAllBluetoothLEDevices, requestedProperties, DeviceInformationKind.AssociationEndpoint);
deviceWatcher.Added += DeviceWatcher_Added;
deviceWatcher.Updated += DeviceWatcher_Updated;
Devices.Clear();
deviceWatcher.Start();
}
private void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate deviceInfo)
{
}
private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation deviceInfo)
{
Devices.Add(deviceInfo);
comboBox_AddItem(comboBox_devices, " MAC: " + deviceInfo.Id.Substring(44) + " | Name: " + deviceInfo.Name);
}

Related

Retrieving value from bluetooth BLE device

In my windows forms app I am starting to enumerate list of devices as follows:
DeviceWatcher deviceWatcher =
DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
// Register event handlers before starting the watcher.
// Added, Updated and Removed are required to get all nearby devices
deviceWatcher.Added += DeviceWatcher_Added;
// EnumerationCompleted and Stopped are optional to implement.
deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
deviceWatcher.Stopped += DeviceWatcher_Stopped;
// Start the watcher.
deviceWatcher.Start();
when a device is found I am retrieving the service and characteristic as follows:
BluetoothLEDevice btdev;
List<DeviceInformation> lst = new List<DeviceInformation>();
GattCharacteristic ch;
private async void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
{
if (args.Name == "Bluno")
{
btdev = await BluetoothLEDevice.FromIdAsync(args.Id);
GattDeviceServicesResult result = await btdev.GetGattServicesAsync();
Guid customGuid = new Guid("0000dfb0-0000-1000-8000-00805f9b34fb");
foreach (GattDeviceService service in result.Services)
{
if (customGuid == service.Uuid)
{
GattCharacteristicsResult cresult = await service.GetCharacteristicsAsync();
ch = cresult.Characteristics.Where(x => x.Uuid == new Guid("0000dfb1-0000-1000-8000-00805f9b34fb")).FirstOrDefault();
ch.ValueChanged += Ch_ValueChanged;
}
}
}
}
the issue is that it is not firing the ValueChanged event even if the BLE device continuously sending multiple values per second.
help appreciated

Unable to connect Bluetooth device using c#

I'm using 32 feet library to develop Bluetooth communication WPF app, and able to pair the device but not working to connect it and ended up with an exception like below.
Note: I've tried to connect the devices like my mobile and my PC, but both are giving the same errors as explained below.
I've seen somewhere about this issue and they mentioned like, this issue may be because of 32 feet library is not compatible with the Bluetooth device that I've in my PC.
But actually, I've tested this in some other PC's which are running with Windows 7 OS - 64 bit and getting the same error message.
Anyone help me out. Thank you.
Error Message: The requested address is not valid in its context ECD09F51114A:0000110100001000800000805f9b34fb
My code sample:
Guid uId = new Guid("0000110E-0000-1000-8000-00805f9b34fb");
bool receiverStarted = false;
private List<BluetoothDeviceInfo> deviceList;
private List<string> deviceNames;
private BluetoothDeviceInfo deviceInfo;
private string myPin = "1234";
private BluetoothClient sender;
private void BtnScan_Click(object sender, RoutedEventArgs e)
{
ScanAvailableDevices();
}
private void ScanAvailableDevices()
{
lstAvailableDevices.ItemsSource = null;
lstAvailableDevices.Items.Clear();
deviceList.Clear();
deviceNames.Clear();
Thread senderThread = new Thread(new ThreadStart(Scan));
senderThread.Start();
}
private void Scan()
{
UpdateStatus("Starting scan...");
sender = new BluetoothClient();
availableDevices = sender.DiscoverDevicesInRange();
UpdateStatus("Scan completed.");
UpdateStatus(availableDevices.Length.ToString() + " device(s) discovered");
foreach(BluetoothDeviceInfo device in availableDevices)
{
deviceList.Add(device);
deviceNames.Add(device.DeviceName);
}
UpdateAvailableDevices();
}
private void UpdateAvailableDevices()
{
Func<int> devicesDelegate = delegate ()
{
lstAvailableDevices.ItemsSource = deviceNames;
return 0;
};
Dispatcher.BeginInvoke((Action)(() =>
{
devicesDelegate.Invoke();
}));
}
private void PairDevice()
{
deviceInfo = deviceList[lstAvailableDevices.SelectedIndex];
if (CanPair())
{
UpdateStatus("Device paired..");
UpdateStatus("Starting to connect the device");
Thread senderThread = new Thread(new ThreadStart(SenderConnectThread));
senderThread.Start();
}
}
private bool CanPair()
{
if(!deviceInfo.Authenticated)
{
if(!BluetoothSecurity.PairRequest(deviceInfo.DeviceAddress,myPin))
{
return false;
}
}
return true;
}
private void LstAvailableDevices_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
deviceInfo = deviceList[lstAvailableDevices.SelectedIndex];
UpdateStatus(deviceInfo.DeviceName + " was selected, attempting connect");
if (CanPair())
{
UpdateStatus("Device paired..");
UpdateStatus("Starting connect thread");
Thread senderThread = new Thread(new ThreadStart(ClientConnectThread));
senderThread.Start();
}
else
{
UpdateStatus("Pair failed");
}
}
private void ClientConnectThread()
{
BluetoothClient sender = new BluetoothClient();
BluetoothAddress address = deviceInfo.DeviceAddress;
//sender.SetPin(deviceInfo.DeviceAddress, myPin);
var endPoint = new BluetoothEndPoint(address, uId);
sender.Connect(endPoint);
//Another way that I've tried
BluetoothClient client = new BluetoothClient();
UpdateStatus("Attempting connect");
//client.Connect(deviceInfo.DeviceAddress, uId);
client.BeginConnect(deviceInfo.DeviceAddress, uId, this.BluetoothClientConnectCallback, client);
}
void BluetoothClientConnectCallback(IAsyncResult result)
{
BluetoothClient senderE = (BluetoothClient)result.AsyncState;
senderE.EndConnect(result);
Stream stream = senderE.GetStream();
while (true)
{
while (!ready) ;
byte[] message = Encoding.ASCII.GetBytes(txtSenderMessage.Text);
stream.Write(message, 0, message.Length);
}
}
There are libraries in UWP where you can easily make a connection between your desktop and other devices , you can easily handle the Bluetooth Adapter.
There are multiple downloads for 32 feet
Try these
Downloading
https://github.com/inthehand/32feet
Downloads are available here on the Downloads tab. Packages are also available at NuGet:-
InTheHand.Devices.Bluetooth - Modern (v4.x) - Preview NuGet version
32feet.NET - Legacy (v3.x) NuGet version
32feet.NET.Phone - Windows Phone NuGet version
InTheHand.Devices.Enumeration (Windows 8 / Windows Phone Device Pickers) NuGet version
Folks, I'm able to pair and connect it using the same application running in different PC and acting it as a server. Earlier I've tried this without having the same application running in the target PC and thus it's giving the error that I mentioned above.
Thanks guys for your time and support.

Detect USB Eject event with WMI

I use code like here Detecting USB drive insertion and removal using windows service and c# to detect when a USB device is plugged in / removed.
But when the user "ejects" the device leaving it plugged in I get no notification at all.
Of course when I try to access such a drive it will fail.
Is there a different WMI Event I can use to get a notification about this situation?
The link #Jimi posted brings me a (BIG) step further.
public void AddWMIWatcher() {
WqlEventQuery query = new WqlEventQuery();
ManagementScope scope = new ManagementScope("root\\CIMV2");
query.EventClassName = "__InstanceOperationEvent";
query.WithinInterval = new TimeSpan(0, 0, 3);
query.Condition = #"TargetInstance ISA 'Win32_DiskDrive' ";
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query);
watcher.EventArrived += Watcher_EventArrived;
watcher.Query = query;
watcher.Start();
}
private void Watcher_EventArrived(object sender, EventArrivedEventArgs e) {
ManagementBaseObject baseObject = e.NewEvent;
if(baseObject.ClassPath.ClassName.Equals("__InstanceCreationEvent")) {
Console.WriteLine("A drive was connected");
}
else if(baseObject.ClassPath.ClassName.Equals("__InstanceDeletionEvent")) {
Console.WriteLine("A drive was removed");
}
else if(baseObject.ClassPath.ClassName.Equals("__InstanceModificationEvent")) {
Console.WriteLine("A drive was changed");
//that is what I'm looking for
}
I get an __InstanceModificationEvent - the only thing I have to find out is how to get the affected drive (letter) out of this event.

Arduino and C# Serial Port "Crash"

I am trying to create a communication between an Arduino Leonardo and C#.
Just now, the Arduino's software sends a simple message (in loop) on the serial port:
void setup() {
Serial.begin(9600);
analogReference(INTERNAL);
}
void loop() {
Serial.println("test");
delay(500);
}
C# try only to read these messages and print them on the shell:
public class Program
{
private SerialPort mySerialPort;
static void Main(string[] args)
{
Program p = new Program();
Console.WriteLine("PORTS: " + String.Join(" ", p.getSerialPortsList())+ ", enter to start.");
Console.Read();
p.SerialRead("COM6");
}
public String[] getSerialPortsList()
{
string[] ports = SerialPort.GetPortNames();
return ports;
}
public void SerialRead(String com)
{
mySerialPort = new SerialPort(com, 9600, Parity.None, 8, StopBits.One);
Console.Read();
Console.WriteLine("Incoming Data:");
SerialRead sr = new SerialRead();
Thread rs = new Thread(sr.StartRead);
sr.SetMySerialPort(mySerialPort);
rs.Start();
while (!rs.IsAlive);
Console.Read();
sr.SetSuspendThread(true);
rs.Join();
}
}
public class SerialRead
{
private Boolean suspendThread = false;
SerialPort mySerialPort;
public void StartRead()
{
mySerialPort.Open();
Thread.Sleep(500);
int i = 0;
while (!suspendThread)
{
i++;
Console.WriteLine(i + ": " + mySerialPort.ReadLine());
Thread.Sleep(500);
}
}
public void SetMySerialPort(SerialPort mysp){ mySerialPort = mysp; }
public void SetSuspendThread(Boolean a){ suspendThread = a; }
}
The output of this C# software depends. If I use the serial monitor on the Arduino IDE, then I receive the string's stream correctly (one each 500ms).
Otherwise, the C# software freezes. Sometimes, I receive a couple of strings as we can see this figure; but almost all time, the software does not give any string, as we can see here. After that the software freezes (thus, if I press enter the shell does not response).
Can you suggest a solution in order to get a fluent flow of string, and -as a consequence- read each message sent by Arduino on the serial port?
I am using Window 10 x64 as OS and the COM6 (it is an USB 2.0).
I found the solution and I share it in order to help people with the same problem.
C# does not activate as default the RTS and the DTR serial port.
Thus, adding
mySerialPort.DtrEnable = true;
mySerialPort.RtsEnable = true;
after the serial port declaration, everything works fine.
This is a really good example:
Serial Port Polling and Data handling
The Serial Port got an event called DataRecived, so you dont have to sleep your thread.
Something like this:
serialPort.DataReceived +=SerialPortDataReceived;
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine(serialPort.ReadLine());
}

Using C# to access phone folders and read/write

Sorry if someone just posts a link to the answer, but I was really struggling to google this.
I can't figure out how to detect mobile phones when they're plugged in and then access their storage. The former is just something I don't know where to start looking and the second befuddles me a little because I'm used to accessing storage with a drive letter. The phones I've used (iPhone 4S and a few different Samsung galaxy's and notes) don't have a drive letter. So where would I start?
I use C# but I'm comfortable with the dllimports etc.
I've now done this code from the thread I linked in a comment above, nice and easy to throw into a program.
using System;
using System.Management;
using System.Threading;
namespace USBDeviceTester
{
class Program
{
static void Main(string[] args)
{
Thread myThread = new Thread(new ThreadStart(ThreadWorker));
myThread.Start();
}
public static void ThreadWorker()
{
WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery);
insertWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent);
insertWatcher.Start();
WqlEventQuery removeQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery);
removeWatcher.EventArrived += new EventArrivedEventHandler(DeviceRemovedEvent);
removeWatcher.Start();
// Do something while waiting for events
System.Threading.Thread.Sleep(20000000);
}
private static void DeviceInsertedEvent(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("");
Console.WriteLine(" --- DEVICE INSERTED ---");
Console.WriteLine("");
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
foreach (var property in instance.Properties)
{
Console.WriteLine(property.Name + " = " + property.Value);
}
Console.WriteLine("");
}
static void DeviceRemovedEvent(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("");
Console.WriteLine(" --- DEVICE REMOVED ---");
Console.WriteLine("");
//ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
//foreach (var property in instance.Properties)
//{
// Console.WriteLine(property.Name + " = " + property.Value);
//}
}
}
}
Which returns information as so:
--- DEVICE REMOVED ---
--- DEVICE INSERTED ---
Availability =
Caption = Apple Mobile Device USB Driver
ClassCode =
ConfigManagerErrorCode = 0
ConfigManagerUserConfig = False
CreationClassName = Win32_USBHub
CurrentAlternateSettings =
CurrentConfigValue =
Description = Apple Mobile Device USB Driver
DeviceID = USB\VID_05AC&PID_12A0\3ABFD2ED02E3982B5F4455FD684716A6D4958A74
ErrorCleared =
ErrorDescription =
GangSwitched =
InstallDate =
LastErrorCode =
Name = Apple Mobile Device USB Driver
NumberOfConfigs =
NumberOfPorts =
PNPDeviceID = USB\VID_05AC&PID_12A0\3ABFD2ED02E3982B5F4455FD684716A6D4958A74
PowerManagementCapabilities =
PowerManagementSupported =
ProtocolCode =
Status = OK
StatusInfo =
SubclassCode =
SystemCreationClassName = Win32_ComputerSystem
SystemName = MyComputerName
USBVersion =

Categories