After launch a BLUETOOTH server written in c.
https://github.com/RyanGlScott/BluetoothTest/blob/master/C%20BlueZ%20Server/bluez_server.c
This is the output of the command sdptool browse local:
....other services....
Service Name: AVRCP CT
Service RecHandle: 0x10005
Service Class ID List:
"AV Remote" (0x110e)
Protocol Descriptor List:
"L2CAP" (0x0100)
PSM: 23
"AVCTP" (0x0017)
uint16: 0x103
Profile Descriptor List:
"AV Remote" (0x110e)
Version: 0x0100
/*MY SERVICE!!!*/
Service Name: Armatus Bluetooth server
Service Description: A HERMIT server that interfaces with the Armatus Android app
Service Provider: Armatus
Service RecHandle: 0x10006
Service Class ID List:
"Serial Port" (0x1101)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 3
Profile Descriptor List:
"Serial Port" (0x1101)
Version: 0x0100
....other services....
I'am trying to find this service using an Android app
// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// Whenever a remote Bluetooth device is found
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice bluetoothDevice =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
adapter.add(bluetoothDevice.getName() + "\n"
+ bluetoothDevice.getAddress());
if (bluetoothDevice.getName().equals("mint-0")) {
Log.d("tagmint0","bene bene");
try {
ParcelUuid[] uuids = (ParcelUuid[]) bluetoothDevice.getUuids();
for (ParcelUuid uuid : uuids) {
Log.d("x", "mintUUIDxx: " + uuid.getUuid().toString() + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
My question is, why my android application is not able to find my service even if it is visible using the command sdptool browse local?
This is the android application output
mintUUIDxx: 0000111e-0000-1000-8000-00805f9b34fb
mintUUIDxx: 00001105-0000-1000-8000-00805f9b34fb
mintUUIDxx: 00001106-0000-1000-8000-00805f9b34fb
mintUUIDxx: 0000112d-0000-1000-8000-00805f9b34fb
mintUUIDxx: 0000110e-0000-1000-8000-00805f9b34fb
mintUUIDxx: 00001112-0000-1000-8000-00805f9b34fb
mintUUIDxx: 0000111f-0000-1000-8000-00805f9b34fb
mintUUIDxx: 00000000-0000-1000-8000-00805f9b34fb
As you can see it doesn't contains the server uuid. Can someone explain me why?
bluetoothDevice.getUuids();
This method does not start a service discovery procedure to retrieve the UUIDs from the remote device. Instead, the local cached copy of the service UUIDs are returned.
Use fetchUuidsWithSdp() instead. This method perform a service discovery on the remote device to get the UUIDs supported.
if you have used the same git code then looks like you have mention different UUID in android.
In you bluez_server.c
uint32_t svc_uuid_int[] = { 0x01110000, 0x00100000, 0x80000080, 0xFB349B5F };
And android output
mintUUIDxx: 0000111e-0000-1000-8000-00805f9b34fb
Give a try by changing that line in bluez_server.c with this
uint32_t svc_uuid_int[] = { 0x0000111e, 0x00001000, 0x80000080, 0x5f9b34fb };
Related
I'm using the flutter_reactive_ble package to communicate with a ble device. All is good until I try to read the characteristic which gives me the following error:
E/flutter (28251): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: Exception: GenericFailure<CharacteristicValueUpdateError>(code: CharacteristicValueUpdateError.unknown, message: "GATT exception from MAC address EE:2F:27:FE:D2:44, with type BleGattOperation{description='CHARACTERISTIC_READ'}")
This is my code block that contains the function:
Uuid _UART_UUID = Uuid.parse("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
Uuid _UART_RX = Uuid.parse("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
Uuid _UART_TX = Uuid.parse("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
case DeviceConnectionState.connected:
{
_connected = true;
_logTexts = "${_logTexts}Connected to $id\n";
_numberOfMessagesReceived = 0;
_receivedData = [];
//READ
final _rxCharacteristic = QualifiedCharacteristic(
serviceId: _UART_UUID,
characteristicId: _UART_RX,
deviceId: event.deviceId,
);
try {
final _charResponse =
flutterReactiveBle.readCharacteristic(_rxCharacteristic);
print(_charResponse);
} catch (e) {
print("COULDN'T READ CHARACTERISTIC $e");
}
break;
}
I already tried finding other characteristic uuids to see if the problem was about the uuid, but no luck. I've been using nRF Connect to check on some parameters. The uuids I found there are the ones I'm using currently.
I have Nordic UART Service as a primary service and I have the following:
Nordic UART Service '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
Rx Characteristic '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
-'WRITE, WRITE NO RESPONSE'
Tx Characteristic '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
-'NOTIFY'
How can I fix this and sucessfully read the characteristics I need?
I think you misread the documentation. The Rx Characteristic is the Rx Characteristic of the device you are connected to. You are only allowed to write to this characteristic, which sends data to the connected device.
Data send from the connected device to your application is delivered via the Notify of the Tx Characteristic
I am building a bluetooth service discovery on Android using BluetoohDevice.fetchUuidsWithSdp().
Currently i test the code on 3 different devices:
devices "A" and "B" running Android 8.1.0
device "C" is on 5.1.1.
Each device can act as Bluetooth server
using
mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(serviceName, serviceUUID)
or as Bluetooth client
mmDevice.createRfcommSocketToServiceRecord(serviceUUID);
If a server is discovered by a client device the UUIDs of services running on the server will be fetched using fetchUuidsWithSdp().
Then i get the UUIDs in the BroadcastReceiver:
private BroadcastReceiver UUIDFetchedReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
final String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_UUID))
{
try
{
// Getting the Service UUIDs
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "UUIDFetchedReceiver: received device: " + device.getName());
for (Parcelable uuid : uuidExtra)
{
Log.d(TAG, "UUIDFetchedReceiver: Service found on " + device.getName() + " | uuid: " + uuid);
if (uuid.toString().equals("3253f2d2-f49a-11ec-b939-0242ac120002"))
{
foundSDPService(device, uuid.toString());
}
}
}
catch (NullPointerException e)
{
Log.e(TAG, "UUIDFetchedReceiver: Nu UUIDs received ");
}
}
}
};
That works on device "A" and "C" the log output there shows:
UUIDFetchedReceiver: Service found on Device B | uuid: 3253f2d2-f49a-11ec-b939-0242ac120002
On Device "B" it looks like this:
UUIDFetchedReceiver: Service found on Device A | uuid: 020012ac-4202-39b9-ec11-9af4d2f25332
Device "B" shows the same UUID but as little endian.
The code is the same and for device "A" and "B" even the Android version is the same.
Does anybody know what causes this issue and how it can be fixed?
The devices are:
A = Samsung Galaxy Tab A (2016)
B = Lenovo TB-X304L
C = LG G Flex 2
The problem seems to be similar to the one described in this Question :
Strange UUID reversal from fetchUuidsWithSdp
I have managed to make an android device and scan and enlist all bluetooth devices in the area..I have the mac address of a remote device i just discovered in form of string and i want to start the bonding process with it.. i try BluetoothDevice object and then method createBond() but its not communicating with the remote device to pair..
Here is the code
class BluetoothM: AppCompatActivity{
// mac address of remote bluetooth device
string address;
//the discovered devices are listed in a ListView so i call a listview item click method to start pairing
private void Dlist_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
//the mac address has already been assigned in the OnReceive broadcast Receiver
if (e.Position == e.Id)
{
//Get the default adapter of the device
BluetoothAdapter adapt = BluetoothAdapter.DefaultAdapter;
//Get the remote device based on its MAC address
BluetoothDevice device = adapt.GetRemoteDevice(address);
//start the pairing process for the device
device.CreateBond();
}
}
}
//This class discovers bluetooth devices and pass MAC address to our string address for use in the listview click method
[BroadcastReceiver(Name = BluetoothDevice.ActionFound, Enabled = true)]
public class DeviceDiscovered : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
string ac = intent.Action; string name;
if (BluetoothDevice.ActionFound.Equals(ac))
{
BluetoothDevice device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
//add bluetooth name and address if they do not already exist
if (!MainActivity.avail.Contains(device.Name + "\n" + device.Address))
{
MainActivity.avail.Add(device.Name + "\n" + device.Address);
ArrayAdapter arrayAdapter1 = new ArrayAdapter(context, Android.Resource.Layout.SimpleListItem1, MainActivity.avail);
MainActivity.dlist.Adapter = arrayAdapter1;
//address assigned a value
MainActivity.address = device.Address; MainActivity.name = device.Name;
MainActivity.mydevice = device;
}
}
Toast.MakeText(context, "Received the intent", ToastLength.Short).Show();
}
The remote device is not receiving this communication and i don't know why, Thank You
Check you have BLUETOOTH_ADMIN permission in Manifest. Register for ACTION_BOND_STATE_CHANGED intents to be notified when the bonding process completes, and its result. Get the result of device.CreateBond(), it returns false on immediate error, true if bonding will begin.
https://developer.android.com/reference/android/bluetooth/BluetoothDevice#createBond()
My android app(react native app named "myApp") is scanning for BLE for 10 seconds in a loop(start - wait for 10 seconds - stop)
I have noticed that after a while(something about 7 hours) my app can't find any device(although there is devices around).
When I saved and checked the logcat, I saw that after each try to scan, "myApp" tries to run registerClient() and after the scan unregisterClient() from GATT
Right before the problem starts I can see the following:
BtGatt.GattService: registerClient() - UUID=c4de3a02-66c8-41ac-bf9d-f42d8f9d160f, pid=2097, name=com.myApp
E bt_att : GATT_Register: can't Register GATT client, MAX client reached!
E bt_btif : Register with GATT stack failed.
bt_att : GATT_Register: can't Register GATT client, MAX client reached!
After more digging into the logcat I saw that there is one more client that tries to registerClient() to GATT:
BtGatt.GattService: registerClient() - UUID=9aa64bcd-402a-4474-ab5d-250e14bd77a1, pid=1311, name=com.google.android.gms.persistent
After looking for "com.google.android.gms.persistent" I found that it's google play service.
This service is trying to register to GATT but also gets the same problem(MAX client reached) until it tries to register when "myApp" is unregistered from GATT - so it have available spot and then "myApp" can't register no more as "com.google.android.gms.persistent" will not unregister.
The only thing that is resolving it is to toggle Bluetooth, and then "myApp" can register again.
Did someone encountered this problem and found any solution? maybe how to clear all clients that are registered to GATT service?
EDIT:
I'm using "LegacyScanManager" and "react native ble manager" package.
It's scan function(that is calling to "scan" function of LegacyScanManager) is:
#ReactMethod
public void scan(ReadableArray serviceUUIDs, final int scanSeconds, boolean allowDuplicates, ReadableMap options, Callback callback) {
Log.d(LOG_TAG, "scan");
if (getBluetoothAdapter() == null) {
Log.d(LOG_TAG, "No bluetooth support");
callback.invoke("No bluetooth support");
return;
}
if (!getBluetoothAdapter().isEnabled()) {
return;
}
synchronized (peripherals) {
Iterator<Map.Entry<String, Peripheral>> iterator = peripherals.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Peripheral> entry = iterator.next();
if (!entry.getValue().isConnected()) {
iterator.remove();
}
}
}
if (scanManager != null) scanManager.scan(serviceUUIDs, scanSeconds, options, callback);
}
The parameters that I'm passing :
serviceUUIDs = none(empty list),
scanSeconds = 10,
allowDuplicates = false,
options = "numberOfMatches = 3, matchMode = 1, scanMode = 0" ,
callback = my callback function from js
Thanks you!
I want to clear the blueooth cache.
I'm making application about bluetooth.
I just knowed Android bluetooth device name is cached in the phone. (when phone find the bluetooth device)
I can't find solution anywhere.
I just saw fetchUuidsWithSdp().
someone said it clears the bluetooth cache in android phone.
but I don't know how use this method and I don't think that fetchUuidsWithSdp() will clear the cache.
Please Let me know how to clear the bluetooth cache in Android or how to use fetchUuidsWithSdp().
Thanks:)
Follow the instructions of the Android Guide in order to start the discovery.
When declaring your IntentFilter, add (at least) ACTION_FOUND and ACTION_UUID :
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_UUID);
Inside your receiver call fetchUuidsWithSdp().
You will get the UUIDs inside the ACTION_UUID:
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// get fresh uuids
device.fetchUuidsWithSdp();
}
else if (BluetoothDevice.ACTION_UUID.equals(action)) {
// Get the device and teh uuids
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
if(uuidExtra !=null){
for (Parcelable uuid : uuidExtra) {
Log.d("YOUR_TAG", "Device: " + device.getName() + " ( "+ device.getAddress() +" ) - Service: " + uuid.toString());
}
}
}