/// <summary> /// Invoked once the user has selected the device to connect to. /// Once the user has selected the device, /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void ConnectButton_Click(object sender, RoutedEventArgs e) { // Make sure user has selected a device first if (resultsListView.SelectedItem != null) { rootPage.NotifyUser("Connecting to remote device. Please wait...", NotifyType.StatusMessage); } else { rootPage.NotifyUser("Please select an item to connect to", NotifyType.ErrorMessage); return; } RfcommChatDeviceDisplay deviceInfoDisp = resultsListView.SelectedItem as RfcommChatDeviceDisplay; // Perform device access checks before trying to get the device. // First, we check if consent has been explicitly denied by the user. DeviceAccessStatus accessStatus = DeviceAccessInformation.CreateFromId(deviceInfoDisp.Id).CurrentStatus; if (accessStatus == DeviceAccessStatus.DeniedByUser) { rootPage.NotifyUser("This app does not have access to connect to the remote device (please grant access in Settings > Privacy > Other Devices", NotifyType.ErrorMessage); return; } // If not, try to get the Bluetooth device try { bluetoothDevice = await BluetoothDevice.FromIdAsync(deviceInfoDisp.Id); } catch (Exception ex) { rootPage.NotifyUser(ex.Message, NotifyType.ErrorMessage); return; } // If we were unable to get a valid Bluetooth device object, // it's most likely because the user has specified that all unpaired devices // should not be interacted with. if (bluetoothDevice == null) { rootPage.NotifyUser("Bluetooth Device returned null. Access Status = " + accessStatus.ToString(), NotifyType.ErrorMessage); } // This should return a list of uncached Bluetooth services (so if the server was not active when paired, it will still be detected by this call var rfcommServices = await bluetoothDevice.GetRfcommServicesForIdAsync( RfcommServiceId.FromUuid(Constants.RfcommChatServiceUuid), BluetoothCacheMode.Uncached); if (rfcommServices.Services.Count > 0) { chatService = rfcommServices.Services[0]; } else { rootPage.NotifyUser( "Could not discover the chat service on the remote device", NotifyType.StatusMessage); return; } // Do various checks of the SDP record to make sure you are talking to a device that actually supports the Bluetooth Rfcomm Chat Service var attributes = await chatService.GetSdpRawAttributesAsync(); if (!attributes.ContainsKey(Constants.SdpServiceNameAttributeId)) { rootPage.NotifyUser( "The Chat service is not advertising the Service Name attribute (attribute id=0x100). " + "Please verify that you are running the BluetoothRfcommChat server.", NotifyType.ErrorMessage); RunButton.IsEnabled = true; return; } var attributeReader = DataReader.FromBuffer(attributes[Constants.SdpServiceNameAttributeId]); var attributeType = attributeReader.ReadByte(); if (attributeType != Constants.SdpServiceNameAttributeType) { rootPage.NotifyUser( "The Chat service is using an unexpected format for the Service Name attribute. " + "Please verify that you are running the BluetoothRfcommChat server.", NotifyType.ErrorMessage); RunButton.IsEnabled = true; return; } var serviceNameLength = attributeReader.ReadByte(); // The Service Name attribute requires UTF-8 encoding. attributeReader.UnicodeEncoding = UnicodeEncoding.Utf8; deviceWatcher.Stop(); lock (this) { chatSocket = new StreamSocket(); } try { await chatSocket.ConnectAsync(chatService.ConnectionHostName, chatService.ConnectionServiceName); SetChatUI(attributeReader.ReadString(serviceNameLength), bluetoothDevice.Name); chatWriter = new DataWriter(chatSocket.OutputStream); DataReader chatReader = new DataReader(chatSocket.InputStream); ReceiveStringLoop(chatReader); } catch (Exception ex) { switch ((uint)ex.HResult) { case (0x80070490): // ERROR_ELEMENT_NOT_FOUND rootPage.NotifyUser("Please verify that you are running the BluetoothRfcommChat server.", NotifyType.ErrorMessage); RunButton.IsEnabled = true; break; default: throw; } } }
private async void Connect(DeviceInformation devInfo) { // Perform device access checks before trying to get the device. // First, we check if consent has been explicitly denied by the user. DeviceAccessStatus accessStatus = DeviceAccessInformation.CreateFromId(devInfo.Id).CurrentStatus; if (accessStatus != DeviceAccessStatus.Allowed) { System.Diagnostics.Debug.WriteLine("Access State: " + accessStatus); System.Diagnostics.Debug.WriteLine("This app does not have access to connect to the remote device (please grant access in Settings > Privacy > Other Devices"); //return; } // TODO: Maybe automatic pairing? try { bluetoothDevice = await BluetoothDevice.FromIdAsync(devInfo.Id); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Error: Couldn't get BluetoothDevice"); return; } if (bluetoothDevice == null) { System.Diagnostics.Debug.WriteLine("Bluetooth Device returned null. Access Status = " + accessStatus.ToString()); } // This should return a list of uncached Bluetooth services (so if the server was not active when paired, it will still be detected by this call var rfcommServices = await bluetoothDevice.GetRfcommServicesForIdAsync( RfcommServiceId.FromUuid(Constants.RfcommChatServiceUuid), BluetoothCacheMode.Uncached); // Maybe change to cached??? if (rfcommServices.Services.Count > 0) { service = rfcommServices.Services[0]; } else { System.Diagnostics.Debug.WriteLine("Error: Could not discover the chat service on the remote device"); System.Diagnostics.Debug.WriteLine("Paired: " + devInfo.Pairing.IsPaired); System.Diagnostics.Debug.WriteLine("Connection Status: " + bluetoothDevice.ConnectionStatus); return; } // Do various checks of the SDP record to make sure you are talking to a device that actually supports the Bluetooth Rfcomm Chat Service var attributes = await service.GetSdpRawAttributesAsync(); if (!attributes.ContainsKey(Constants.SdpServiceNameAttributeId)) { System.Diagnostics.Debug.WriteLine( "The service is not advertising the Service Name attribute (attribute id=0x100)."); return; } var attributeReader = DataReader.FromBuffer(attributes[Constants.SdpServiceNameAttributeId]); var attributeType = attributeReader.ReadByte(); if (attributeType != Constants.SdpServiceNameAttributeType) { System.Diagnostics.Debug.WriteLine( "The Chat service is using an unexpected format for the Service Name attribute. "); return; } var serviceNameLength = attributeReader.ReadByte(); // The Service Name attribute requires UTF-8 encoding. attributeReader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; StopWatcher(); lock (this) { socket = new StreamSocket(); } try { await socket.ConnectAsync(service.ConnectionHostName, service.ConnectionServiceName); writer = new DataWriter(socket.OutputStream); reader = new DataReader(socket.InputStream); System.Diagnostics.Debug.WriteLine("Connected to Server"); isConnected = true; OnConnected(); mainLoop(); } catch (Exception ex) when((uint)ex.HResult == 0x80070490) // ERROR_ELEMENT_NOT_FOUND { System.Diagnostics.Debug.WriteLine("Please verify that you are running the BluetoothRfcommChat server."); } catch (Exception ex) when((uint)ex.HResult == 0x80072740) // WSAEADDRINUSE { System.Diagnostics.Debug.WriteLine("Please verify that there is no other RFCOMM connection to the same device."); } }
public async void ConnectAsync(RfcommChatDeviceDisplay deviceInfoDisp) { // Perform device access checks before trying to get the device. // First, we check if consent has been explicitly denied by the user. DeviceAccessStatus accessStatus = DeviceAccessInformation.CreateFromId(deviceInfoDisp.Id).CurrentStatus; if (accessStatus == DeviceAccessStatus.DeniedByUser) { throw new UnauthorizedAccessException("This app does not have access to connect to the remote device (please grant access in Settings > Privacy > Other Devices"); } // If not, try to get the Bluetooth device try { bluetoothDevice = await BluetoothDevice.FromIdAsync(deviceInfoDisp.Id); } catch (Exception ex) { throw ex; } // If we were unable to get a valid Bluetooth device object, // it's most likely because the user has specified that all unpaired devices // should not be interacted with. if (bluetoothDevice == null) { throw new InvalidOperationException("Bluetooth Device returned null. Access Status = " + accessStatus.ToString()); } // This should return a list of uncached Bluetooth services (so if the server was not active when paired, it will still be detected by this call var rfcommServices = await bluetoothDevice.GetRfcommServicesForIdAsync( RfcommServiceId.FromUuid(RfcommChatServiceUuid), BluetoothCacheMode.Uncached); if (rfcommServices.Services.Count > 0) { chatService = rfcommServices.Services[0]; } else { throw new InvalidOperationException("Could not discover the chat service on the remote device"); } // Do various checks of the SDP record to make sure you are talking to a device that actually supports the Bluetooth Rfcomm Chat Service var attributes = await chatService.GetSdpRawAttributesAsync(); if (!attributes.ContainsKey(SdpServiceNameAttributeId)) { throw new InvalidOperationException("The Chat service is not advertising the Service Name attribute (attribute id=0x100). " + "Please verify that you are running the BluetoothRfcommChat server."); } var attributeReader = DataReader.FromBuffer(attributes[SdpServiceNameAttributeId]); var attributeType = attributeReader.ReadByte(); if (attributeType != SdpServiceNameAttributeType) { throw new InvalidOperationException( "The Chat service is using an unexpected format for the Service Name attribute. " + "Please verify that you are running the BluetoothRfcommChat server."); } var serviceNameLength = attributeReader.ReadByte(); // The Service Name attribute requires UTF-8 encoding. attributeReader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; lock (this) { chatSocket = new StreamSocket(); } try { await chatSocket.ConnectAsync(chatService.ConnectionHostName, chatService.ConnectionServiceName); // TODO: powiadomienie, że połączono //SetChatUI(attributeReader.ReadString(serviceNameLength), bluetoothDevice.Name); chatWriter = new DataWriter(chatSocket.OutputStream); DataReader chatReader = new DataReader(chatSocket.InputStream); ReceiveDataLoop(chatReader); } catch (Exception ex) when((uint)ex.HResult == 0x80070490) // ERROR_ELEMENT_NOT_FOUND { throw new InvalidOperationException("Please verify that you are running the BluetoothRfcommChat server."); } catch (Exception ex) when((uint)ex.HResult == 0x80072740) // WSAEADDRINUSE { throw new InvalidOperationException("Please verify that there is no other RFCOMM connection to the same device."); } }
private async void ConnectGenericDevice() { if (ChosenDevice != null) { await CheckBluetoothStatus(true); // check bluetooth status and activate it if is turned off if (!IsBluetoothEnabled) { AddLog("Can not connect with bluetooth disabled. Turn on the Bluetooth and try again.", AppLog.LogCategory.Warning); return; } // request access to the selected device BluetoothDevice = await BluetoothLEDevice.FromIdAsync(ChosenDevice.Id); DeviceAccessStatus accessStatus = await BluetoothDevice.RequestAccessAsync(); // log AddLog("[Connection: " + accessStatus.ToString() + "]" + " Connecting to " + BluetoothDevice.Name + "...", AppLog.LogCategory.Debug); AddLog("Connecting to " + BluetoothDevice.Name + "...", AppLog.LogCategory.Info); GattCharacteristicsResult hrGattCHaracteristics = null; // try to read the device charateristics try { var gattDeviceServicesResult = await BluetoothDevice.GetGattServicesForUuidAsync(HRserviceGuid); // get services with the HR service GUID // for each service withe the given GUID try to read get foreach (GattDeviceService service in gattDeviceServicesResult.Services) { AddLog("[" + ChosenDevice.Name + "] Found service. " + "\n - Handle: " + service.AttributeHandle.ToString() + "\n - UUID: " + service.Uuid.ToString(), AppLog.LogCategory.Debug); // log if (await service.GetCharacteristicsForUuidAsync(HRCharacteristicGuid) != null) { hrGattCHaracteristics = await service.GetCharacteristicsForUuidAsync(HRCharacteristicGuid); HRReaderService = service; break; } } } catch { AddLog("Device \"" + ChosenDevice.Name + "\" does not support HR service." + "\nSelect another one from the devices list.", AppLog.LogCategory.Warning); return; } // get the HR reader characteristic if (hrGattCHaracteristics != null) { foreach (GattCharacteristic characteristic in hrGattCHaracteristics.Characteristics.Where(c => c.Uuid.Equals(HRCharacteristicGuid))) { HRReaderCharacteristic = characteristic; } } else { // log something return; } // if HR characteristic can't be found, show an error and return if (HRReaderCharacteristic == null) { AddLog("Heart rate monitor characteristic NOT found.", AppLog.LogCategory.Debug); AddLog("Could not connect to Heart Rate service of the device \"" + ChosenDevice.Name + "\".", AppLog.LogCategory.Warning); return; } // if HR characteristic have been found, then start reading process else { AddLog("Heart rate monitor characteristic found [Handle: " + HRReaderCharacteristic.AttributeHandle.ToString() + "]", AppLog.LogCategory.Debug); BeginBluetoothReadProcess(); SwitchConnectButtonToDisconnectButton(); } } else { AddLog("The button should be disabled. Kowalski analisis.", AppLog.LogCategory.Debug); return; } }
public async Task <bool> BtConnect(string deviceID) { try { //System.Diagnostics.Debug.Assert(Thread.CurrentThread.IsBackground, "SerialComm:BtConnect() cannot be called from the UI thread."); DeviceAccessStatus accessStatus = DeviceAccessInformation.CreateFromId(deviceID).CurrentStatus; if (accessStatus == DeviceAccessStatus.DeniedByUser) { //await OBD2Xam.MainPage.Instance.DisplayAlert("Error", // "This app does not have access to connect to the remote device. Please grant access in Settings > Privacy > Other Devices.", // "Cancel"); await Xamarin.Forms.Device.InvokeOnMainThreadAsync( () => { OBD2Xam.MainPage.Instance.DisplayAlert("Error", "This app does not have access to connect to the remote device. Please grant access in Settings > Privacy > Other Devices.", "Cancel"); } ); return(false); } BluetoothDevice device = await BluetoothDevice.FromIdAsync(deviceID); if (device == null) { //rootPage.NotifyUser("Bluetooth Device returned null. Access Status = " + accessStatus.ToString(), NotifyType.ErrorMessage); System.Diagnostics.Debug.WriteLine("Bluetooth Device returned null. Access Status = " + accessStatus.ToString()); System.Diagnostics.Debugger.Break(); return(false); } //System.Diagnostics.Debug.WriteLine(device.ConnectionStatus); DeviceAccessStatus das; das = await device.RequestAccessAsync(); // might not always work... //System.Diagnostics.Debugger.Break(); /* * // RequestAccessAsync() needs to executed on the UI thread, which means the UI thread cannot be blocked * // while waiting for all this other crap to run. So this code needs to be executed in backround, * // WITHOUT an await, because that would cause the UI thread to block. * bool invokeComplete = false; * Xamarin.Forms.Device.BeginInvokeOnMainThread( async () => { * das = await device.RequestAccessAsync(); * invokeComplete = true; * }); * * // now we wait for the UI thread to finish it's task, without await * // because BeginInvokeOnMainThread() isn't awaitable. * while (!invokeComplete) * { * System.Diagnostics.Debug.WriteLine("waiting..."); * System.Threading.Thread.Sleep(100); * } */ if (das == DeviceAccessStatus.Allowed) { RfcommDeviceServicesResult rfResultList = await device.GetRfcommServicesAsync().AsTask().ConfigureAwait(false); logRfTypes(rfResultList); // https://blog.j2i.net/2018/07/29/connecting-to-bluetooth-rfcomm-with-uwp/ if (rfResultList.Services.Count > 0) { foreach (var service in rfResultList.Services) { if (service.ServiceId.AsString() == Constants.BT_SERIAL_PORT_INTERFACE) { streamSocket = new StreamSocket(); await streamSocket.ConnectAsync(service.ConnectionHostName, service.ConnectionServiceName); dw = new DataWriter(streamSocket.OutputStream); sr = new StreamReader(streamSocket.InputStream.AsStreamForRead(256)); break; } } if (!IsOpen()) { throw new Exception("Service not found)"); } } } } catch (Exception exc) { if (exc.Message == "Element not found. (Exception from HRESULT: 0x80070490)") { //System.Diagnostics.Debug.WriteLine("Device not listening."); await Xamarin.Forms.Device.InvokeOnMainThreadAsync( () => { OBD2Xam.MainPage.Instance.DisplayAlert("Error", "Device not listening.", "Cancel"); } ); this.Close(); } else { System.Diagnostics.Debug.WriteLine(exc.Message); System.Diagnostics.Debugger.Break(); } } return(IsOpen()); }
/// <summary> /// Invoked once the user has selected the device to connect to. /// Once the user has selected the device, /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public async Task <bool> ConnectAsync(RomeRemoteSystem system) { // Make sure user has selected a device first if (system != null) { Debug.WriteLine("Connecting to remote device. Please wait..."); } else { Debug.WriteLine("Please select an item to connect to"); return(false); } // Perform device access checks before trying to get the device. // First, we check if consent has been explicitly denied by the user. DeviceAccessStatus accessStatus = DeviceAccessInformation.CreateFromId(system.Id).CurrentStatus; if (accessStatus == DeviceAccessStatus.DeniedByUser) { Debug.WriteLine("This app does not have access to connect to the remote device (please grant access in Settings > Privacy > Other Devices"); return(false); } // If not, try to get the Bluetooth device try { _bluetoothDevice = await BluetoothDevice.FromIdAsync(system.Id); } catch (Exception ex) { Debug.WriteLine(ex.Message); StopWatcher(); return(false); } // If we were unable to get a valid Bluetooth device object, // it's most likely because the user has specified that all unpaired devices // should not be interacted with. if (_bluetoothDevice == null) { Debug.WriteLine("Bluetooth Device returned null. Access Status = " + accessStatus.ToString()); } if (_bluetoothDevice == null) { return(false); } // This should return a list of uncached Bluetooth services (so if the server was not active when paired, it will still be detected by this call var rfcommServices = await _bluetoothDevice?.GetRfcommServicesForIdAsync( RfcommServiceId.FromUuid(Constants.SERVICE_UUID), BluetoothCacheMode.Uncached); if (rfcommServices?.Services.Count > 0) { _chatService = rfcommServices.Services[0]; } else { Debug.WriteLine("Could not discover the chat service on the remote device"); StopWatcher(); return(false); } // Do various checks of the SDP record to make sure you are talking to a device that actually supports the Bluetooth Rfcomm Chat Service var attributes = await _chatService.GetSdpRawAttributesAsync(); if (!attributes.ContainsKey(Constants.SERVICE_ATTRIBUTE_ID)) { Debug.WriteLine( "The Chat service is not advertising the Service Name attribute (attribute id=0x100). " + "Please verify that you are running the BluetoothRfcommChat server."); StopWatcher(); return(false); } var attributeReader = DataReader.FromBuffer(attributes[Constants.SERVICE_ATTRIBUTE_ID]); var attributeType = attributeReader.ReadByte(); if (attributeType != Constants.SERVICE_ATTRIBUTE_TYPE) { Debug.WriteLine( "The Chat service is using an unexpected format for the Service Name attribute. " + "Please verify that you are running the BluetoothRfcommChat server."); StopWatcher(); return(false); } var serviceNameLength = attributeReader.ReadByte(); // The Service Name attribute requires UTF-8 encoding. attributeReader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; StopWatcher(); lock (this) { _chatSocket = new StreamSocket(); } try { await _chatSocket.ConnectAsync(_chatService.ConnectionHostName, _chatService.ConnectionServiceName); Debug.WriteLine("Connected to : " + attributeReader.ReadString(serviceNameLength) + _bluetoothDevice.Name); _chatWriter = new DataWriter(_chatSocket.OutputStream); DataReader chatReader = new DataReader(_chatSocket.InputStream); ReceiveStringLoop(chatReader); return(true); } catch (Exception ex) when((uint)ex.HResult == 0x80070490) // ERROR_ELEMENT_NOT_FOUND { Debug.WriteLine("Please verify that you are running the BluetoothRfcommChat server."); StopWatcher(); } catch (Exception ex) when((uint)ex.HResult == 0x80072740) // WSAEADDRINUSE { Debug.WriteLine("Please verify that there is no other RFCOMM connection to the same device."); StopWatcher(); } return(false); }
//Connect to the chosen device private async void ConnectDevice() { if (DeviceInterfacesOutputLst.SelectedItem != null) { string DeviceID = ""; //Device ID foreach (var device in devices.Where(device => device.Name == DeviceInterfacesOutputLst.SelectedItem.ToString())) //selext the chosen device from the listview { DeviceID = device.Id; } BluetoothDevice = await BluetoothLEDevice.FromIdAsync(DeviceID); //request access to the Device DeviceAccessStatus x = await BluetoothDevice.RequestAccessAsync(); //wait for the permission OutputList.Items.Insert(0, "Connection: " + x.ToString() + " - BluetoothLE Device is " + BluetoothDevice.Name); //Create the service and characteristic values to fill with the chosen device information GattDeviceService HRservice = null; GattCharacteristicsResult HRcharacteristics = null; try //read the device characteristics, if the characteristics are not found, an exception get thrown { HRservice = BluetoothDevice.GetGattService(HRserviceGuid); HRcharacteristics = await HRservice.GetCharacteristicsAsync(); } catch { OutputList.Items.Insert(0, "Chosen device does not support HR service, choose another one"); return; } //TFind the characteristics UUID and assign them to the variable foreach (GattCharacteristic caratteristica in HRcharacteristics.Characteristics.Where(caratteristica => caratteristica.Uuid.Equals(HRMeasurement))) { HRreader = caratteristica; //assegno la caratteristica ad HRreader OutputList.Items.Insert(0, "Heart Rate Monitor characteristic found - Handle: " + HRreader.AttributeHandle.ToString()); } //check the server port data try { int serverPortInt; serverPortInt = Int32.Parse(tcpPortText.Text); serverPort = tcpPortText.Text; } catch { OutputList.Items.Insert(0, "Invalid TCP Port, using 13000"); tcpPortText.Text = "13000"; serverPort = tcpPortText.Text; } if (HRreader == null)//if the HR characteristic in not found, show an error { OutputList.Items.Insert(0, "Heart Rate Monitor characteristic not found"); } else //If the characteristic have been found, start the readings { //Requesting notify //NOTE: we are not allowed to read the value on request, we have to ask the device to be notified when the HR value change GattCommunicationStatus status = GattCommunicationStatus.ProtocolError; //setting the status as "protocol error", just in case... OutputList.Items.Insert(0, "Waiting for notify handshake..."); try { status = await HRreader.WriteClientCharacteristicConfigurationDescriptorAsync( GattClientCharacteristicConfigurationDescriptorValue.Notify); } catch { //f**k, i don't know } //We are now ready to receive the informations and send them via TCP if (status == GattCommunicationStatus.Success) { OutputList.Items.Insert(0, "Notify Activated"); OutputList.Items.Insert(0, "Now reading... give me a few seconds"); deviceConnectionState = true; serverPort = tcpPortText.Text; OutputList.Items.Insert(0, "Connecting to port " + serverPort); DispatcherTimerSetup(); read(); } else { if (status == GattCommunicationStatus.ProtocolError) { OutputList.Items.Insert(0, "Notify Failed - Protocol Error"); } if (status == GattCommunicationStatus.Unreachable) { OutputList.Items.Insert(0, "Notify Failed - Unreachable"); } if (status == GattCommunicationStatus.AccessDenied) { OutputList.Items.Insert(0, "Notify Failed - Access Denied"); } OutputList.Items.Insert(0, "Sorry, I'm far from perfect"); } } } else { OutputList.Items.Insert(0, "Select a device from the list"); //nel caso in cui non venga selezionato un dispositivo dalla lista } }