While scanning for advertising data with startLeScan method,
this method also request to pheripheral device for scan response data.
I only want to scan for advertising data.
I don't want to send response request to peripheral device.
and peripheral device can't change advertise mode.
According Bluetooth 4.0 Core spec, There exists passive scan mode.
https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=282159
And also, android has parameter that determines scan type.
And Active Scanning is android's default scan mode.
http://androidxref.com/5.1.1_r6/xref/external/bluetooth/bluedroid/stack/btm/btm_ble_gap.c#327
How to use passive scan mode?
or
Possible to change or add in btm_ble_gap.c in external folder?
please help. thanks.
Even if the Bluetooth stack internally supports passive scan, there is no public API available to use for apps for some reason.
Related
I'm performing a UUID filtered scan on Android (mobile device A) and I have two test cases.
One uses an app called BLE Scanner on another Android device (mobile device b) to create a BLE server with two test Services (each with their own unique UUID). The other is via an Arduino BLE server with a custom UUID for it's service.
If I use mobile device B's BLE Scanner app and scan for the arduino I can find it, connect to it and see the Services along with each services UUID. It has Generic Attribute, Generic Access and a custom service (the one I set). So that's great.
If I use mobile device A and perform a BLE filtered scan using the three services (Generic Attribute UUID, Generic Access UUID and the custom service UUID) the Arduino doesn't show up in the scan at all.
If I use mobile device A and perform a BLE filtered scan using the UUID's from the test server created via the BLE Scanner app on mobile device B, mobile devices B's BLE server does show up in the scan.
So I'm confused. Mobile Device A's filtered scanning seems to work to find the server created via the BLE Scanner app with the assigned custom UUIDs created by the BLE Scanner App, but for the Arduino BLE server it fails to show up.
Is it perhaps because the BLE Scanner app doesn't do filtered scan to find/connect to the Arduino BLE Server that it is able to work? In which case is it not possible to do a filtered scan using the known Service UUID's on the Arduino? Or is there a hidden UUID I'm missing or does the UUID need to be contained in the advertisement data / manufacturing data?
Turns out the discrepancy was due to the fact that the device that failed to show up in a filter scan was because the advertisement data did not have the UUID set/provided in it so the scan just excluded it all together.
Once I added the UUID to the advertisement data it showed up in the scan.
In my case I had to follow the sample here for BLE library with Arduino.
https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_server/BLE_server.ino
I am new to Bluetooth, but have been working for a month or so on a Android Client that connects to a BLE peripheral to write data to a characteristic.
My BLE peripheral is a nrf52832 (Nordic) device and I have loaded the BLE_SM (security manager) example project so that I can use bonding/pairing for secure communications.
My Android code pairs/bonds successfully to the peripheral, but from what I can see the peripheral now stops advertising. I'm not sure if this is normal or it's because I received a gap.onDisconnection event of type REMOTE_USER_TERMINATED_CONNECTION.
Irrespective I am bonded so you would think I could now not need to scan anymore for the device and could just call device.connectGatt(), but it is not working and my callback gets a GATT STATE_DISCONNECTED event.
I read in another post that had pasted the following from Nordic (Tutorial):
It is not possible to connect to a peripheral which is not
advertising, even though one knows its address from before. This is
because the peripheral will only turn on the receiver for a set amount
of time after transmitting an advertisement. This time is used to
listen for connection requests and scan requests.
If this is in fact true, it seems I would be unable to stop the peripheral continually advertising, which is not helpful if I am trying to reduce the peripheral's power consumption.
The citation is 100% true. Connection setup has nothing to do with if the device is bonded or not (assuming you don't use directed advertising). If the peripheral is neither connected nor advertising, the radio is completely off and therefore a central can't connect.
If you want to minimize power consumption, make sure you don't advertise when you don't need to. Depending on your use case, can you have anything triggering advertising? For example a button or a sensor event?
If you need to advertise all the time, you can try use a longer advertising interval to save battery, but this will increase discovery and connection setup time.
Currently, I am developing an app which is communicating with one BLE Hardware which is receiving commands and responding back the command response. To Simulate hardware, We have developed one iOS Simulator app, which is working in Peripheral and responding back on requested command. But Somehow, As and when I try to write to the write characteristics, I got the status = BluetoothGatt .GATT_REQUEST_NOT_SUPPORTED in the onCharacteristicWrite callback. But somehow, I came to know that we need to implement the Central and Peripheral roles into Android app.
But I am still not sure, Do we need to implement Peripheral role as well to send and receive data in multiple packets.
I am developing the app using following nice blog post:
- https://medium.com/#avigezerit/bluetooth-low-energy-on-android-22bc7310387a
- https://android.jlelse.eu/android-bluetooth-low-energy-communication-simplified-d4fc67d3d26e
- https://www.bignerdranch.com/blog/bluetooth-low-energy-on-android-part-2/
And using following repo as learning point of view:
- https://github.com/bignerdranch/android-bluetooth-testbed/tree/a/android-ble-part-3
Thanks in advance!
Typically your phone app is the central and it communicates with a peripheral device over Bluetooth. If you want to send data to the peripheral, you can write a characteristic in the phone app, given writing is enabled for that characteristic. Your central can get data from the peripheral in 2 ways: it can either read a characteristic (if it's enabled) from the peripheral or receive notifications from the peripheral (if it's enabled). So if all you have is a central (phone app) and a peripheral (some kind of Bluetooth device) and you want to send data back and forth, you don't need to have both central and peripheral roles in the phone app. If you have some special stuff going on, it might be different for you, I don't know. I'm talking about a typical setup.
If you want to send commands to the peripheral, you could write those commands to a characteristic. The peripheral could in turn respond with notifications. This is basically the way I develop a Bluetooth solution, but it can be different depending what you want to achieve.
It takes two devices to communicate with each other.
Device A:
It will be Peripheral device which will be advertising the data. i.e.: Beacons, BLE Hardware
Device B:
It will be Central device which will send request for read,write. i.e.: Mobile
Setup for Device A:
If you don't have Peripheral, there is a way to make your android mobile to act like a Peripheral if your device is supporting that advance feature.
So before beginning, you may simply check that by using following app:
https://play.google.com/store/apps/details?id=com.kyriakosalexandrou.bluetoothsupportcheck
To make your device act like Peripheral, you may install following app which simply simulates the GATT and advertising:
https://play.google.com/store/apps/details?id=com.ble.peripheral.sim
Important: Setup service and characteristics based on your requirements, make sure characteristic is write enabled if you want write data on it.
There isn't much documentation in regards to setting up a pin with a Bluetooth Low Energy peripheral device. In my Gatt service I have set the BluetoothGattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM and receive a GATT_INSUFFICIENT_PERMISSION message in my log upon attempting to write to the Bluetooth Write Characteristic I have set up. I was wondering what the process is for enabling encryption for the peripheral.
Thanks
Bluetooth LE requires to devices to be bonded (paired) before they can successfully encrypt transmissions used to read/write a given characteristic. Android does not handle this process for you, so you will need to initiate pairing between the two devices before any GATT transactions are attempted.
With the current Android Things previews, development of the Settings app (which generally handles much of the device pairing process) is heavily in flux. As such, traditional workflows for pairing a device are likely not to work at the moment until these changes are complete.
You could try initiating a pairing request from your Android Things device via createBond(), listening to the ACTION_PAIRING_REQUEST broadcast, and applying the necessary PIN code with setPin(). Some combination of those may work for you in the short term until a more official solution is available.
I am developing an Android app which behaves as Bluetooth peripheral role with a service.
When I start advertising, other Android devices searching for devices offering this service, can see my device (and can pair to it without pin) - ok.
But how to enable PIN pairing?
You can force the device has to be paired, when using specific characteristics by protecting them with PERMISSION_READ_ENCRYPTED_MITM or PERMISSION_WRITE_ENCRYPTED_MITM.
The client/central side can force pairing by calling BluetoothDevice.creteBond().
The pairing method itself is determinated by the bluetooth protocol (see this thread)
You dont actually require pairing to be done to transmit/receive data via ble, take a look into this tutorial