Is it possible to connect to a paired peripheral when the peripheral is not discoverable?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Reading the Android documentation here: http://developer.android.com/guide/topics/connectivity/bluetooth.html#FindingDevices

Once a connection is made with a remote device for the first time, a pairing request is automatically presented to the user. When a device is paired, the basic information about that device (such as the device name, class, and MAC address) is saved and can be read using the Bluetooth APIs. Using the known MAC address for a remote device, a connection can be initiated with it at any time without performing discovery (assuming the device is within range).

Or am  I confusing Bluetooth classic with BLE?  I'm asking because what I'm experiencing is I'm unable to connect to my paired Anaren atmosphere board with discoverable off.

Thanks!

0 Likes
1 Solution
Anonymous
Not applicable

Hi James,

Sorry for not getting back to you sooner.  I'm still on family leave but just wanted to acknowledge your message.  Btw, we did have a solution which toggles enabling pairing on the device at the press of a button.  Seems to work for what we're looking for.

Thanks for the clarification.

Victor

View solution in original post

0 Likes
9 Replies
Anonymous
Not applicable

Hello.

Yes you can connect to a device even if it is not "discoverable".

If you programming your Android application, you can get a list of paired/bonded or connected devices using Bluetooth APIs.

You must know the BD address of the BLE device you are trying to connect to in order to figure out which of the paired devices you will connect.

However, I think your BLE device needs to ready to be connected to the Android device. For example, it can't already be in a connected state if it is acting as a peripheral.

Let us know if this helps. Thank you.

James

0 Likes
Anonymous
Not applicable

Thanks for the response jamesle1.  I have a peripheral paired with my nexus 5 with Android 5.1.1 and I can only connect to the device when the peripheral is discoverable.  Is there a specific configuration that needs to be done?

FYI - I'm running on an Anaren Atmosphere dev kit.

Basically, I'm toggling between when pressing a button:

     bleprofile_Discoverable(HIGH_UNDIRECTED_DISCOVERABLE, ble_remote_addr);

and

     bleprofile_Discoverable(NO_DISCOVERABLE, ble_remote_addr);

Config is as follows:

const BLE_PROFILE_CFG anaren_control_cfg =

{

/*.fine_timer_interval            =*/ BLE_INTERVAL_FINE_TIMER, // ms

/*.default_adv                    =*/ 4, // HIGH_UNDIRECTED_DISCOVERABLE

/*.button_adv_toggle              =*/ 0, // pairing button make adv toggle (if 1) or always on (if 0)

/*.high_undirect_adv_interval     =*/ 32, // slots

/*.low_undirect_adv_interval      =*/ 1024, // slots

/*.high_undirect_adv_duration     =*/ 30, // seconds

/*.low_undirect_adv_duration      =*/ 300, // seconds

/*.high_direct_adv_interval       =*/ 0, // seconds

/*.low_direct_adv_interval        =*/ 0, // seconds

/*.high_direct_adv_duration       =*/ 0, // seconds

/*.low_direct_adv_duration        =*/ 0, // seconds

/*.local_name                     =*/ BLE_LOCAL_NAME,    // [LOCAL_NAME_LEN_MAX];

/*.cod                            =*/ BIT16_TO_8(APPEARANCE_GENERIC_TAG), 0x00, // [COD_LEN];

/*.ver                            =*/ BLE_VERSION,     // [VERSION_LEN];

/*.encr_required                  =*/ BLE_SECURITY_FLAGS, // data encrypted and device sends security request on every connection

/*.disc_required                  =*/ 0, // if 1, disconnection after confirmation

/*.test_enable                    =*/ 0, // TEST MODE is enabled when 1

/*.tx_power_level                 =*/ BLE_TX_POWER_LEVEL, // dbm

/*.con_idle_timeout               =*/ 3, // second  0-> no timeout

/*.powersave_timeout              =*/ 0, // second  0-> no timeout

/*.hdl                            =*/ { 0x00, 0x0063, 0x00, 0x00, 0x00 }, // [HANDLE_NUM_MAX];

/*.serv                           =*/ { 0x00, UUID_SERVICE_BATTERY, 0x00, 0x00, 0x00 },

/*.cha                            =*/ { 0x00, UUID_CHARACTERISTIC_BATTERY_LEVEL, 0x00, 0x00, 0x00 },

/*.findme_locator_enable          =*/ 0, // if 1 Find me locator is enable

/*.findme_alert_level             =*/ 0, // alert level of find me

/*.client_grouptype_enable        =*/ 0, // if 1 grouptype read can be used

/*.linkloss_button_enable         =*/ 0, // if 1 linkloss button is enable

/*.pathloss_check_interval        =*/ 0, // second

/*.alert_interval                 =*/ 0, // interval of alert

/*.high_alert_num                 =*/ 0, // number of alert for each interval

/*.mild_alert_num                 =*/ 0, // number of alert for each interval

/*.status_led_enable              =*/ 0, // if 1 status LED is enable

/*.status_led_interval            =*/ 0, // second

/*.status_led_con_blink           =*/ 0, // blink num of connection

/*.status_led_dir_adv_blink       =*/ 0, // blink num of dir adv

/*.status_led_un_adv_blink        =*/ 0, // blink num of undir adv

/*.led_on_ms                      =*/ 0, // led  on duration in ms

/*.led_off_ms                     =*/ 0, // led blink off duration in ms

/*.buz_on_ms                      =*/ 100, // buzzer on duration in ms

/*.button_power_timeout           =*/ 0, // seconds

/*.button_client_timeout          =*/ 0, // seconds

/*.button_discover_timeout        =*/ 0, // seconds

/*.button_filter_timeout          =*/ 0, // seconds

#ifdef BLE_UART_LOOPBACK_TRACE

/*.button_uart_timeout            =*/ 15, // seconds

#endif

};

This is what I get from the Android side when the connection fails:

09-25 10:25:05.982    8550-8572/com.ciklum.bleclientsample D/BluetoothGatt﹕ connect() - device: 20:73:7A:17:19:A2, auto: false

09-25 10:25:05.982    8550-8572/com.ciklum.bleclientsample D/BluetoothGatt﹕ registerApp()

09-25 10:25:05.988    8550-8572/com.ciklum.bleclientsample D/BluetoothGatt﹕ registerApp() - UUID=cf09645b-fa48-4024-9f09-5758860655e9

09-25 10:25:05.990    8550-8568/com.ciklum.bleclientsample D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=5

09-25 10:25:05.990    8550-8572/com.ciklum.bleclientsample V/Communicator﹕ Gatt

09-25 10:25:35.997    8550-8567/com.ciklum.bleclientsample D/BluetoothGatt﹕ onClientConnectionState() - status=133 clientIf=5 device=20:73:7A:17:19:A2

09-25 10:25:35.997    8550-8567/com.ciklum.bleclientsample V/Communicator﹕ onConnectionStateChange: 133

09-25 10:25:35.997    8550-8567/com.ciklum.bleclientsample V/MainActivity﹕ OnDisonnected

Status 133 seems to be a pretty common error, but doesn't really explain what's happening.

0 Likes
Anonymous
Not applicable

Which Android app are you using? Are you using your own app that you can program?

I'm sure there are several causes for 133 status ( I think it stands for GATT_ERROR ).

One of the solutions I found was using close() method of BluetoothGatt instead of disconnect() when you are disconnecting from the BLE device.

The difference between them is that close() will free up the resources on the BLE device, rendering them as available for others to use.

After the first connection, are you calling this method? Without this method, any subsequent connection tries might fail.

Also there is something I've found about Android devices. I'm not sure if this is true for all Android devices or if this is different for newer OS versions, but I've gotten the same results using Nexus 7 and 9 both with Android 5.1.1. After the first pairing is done (meaning before: BLE device doesn't show in the paired devices list in the Bluetooth Setting; after: BLE device shows up in the paired device list), the BLE device does not disconnect from the Android device even when close()/disconnect() method is called. Even after the Android app closes, the BLE device will stay connected to the Android device. In order to disconnect, you have to get out of range, disable Bluetooth in Android, or reset the BLE device. I doubt that this is your problem, but maybe you can check this as well.

Let me know if this helps. Thank you.

James

0 Likes
Anonymous
Not applicable

jamesle1 wrote:

Which Android app are you using? Are you using your own app that you can program?

Writing my own native app who is using the Anaren Atmosphere board for their development.


jamesle1 wrote:

Which Android app are you using? Are you using your own app that you can program?

I'm sure there are several causes for 133 status ( I think it stands for GATT_ERROR ).

One of the solutions I found was using close() method of BluetoothGatt instead of disconnect() when you are disconnecting from the BLE device.

The difference between them is that close() will free up the resources on the BLE device, rendering them as available for others to use.

After the first connection, are you calling this method? Without this method, any subsequent connection tries might fail.

I call disconnect() first then from my GattCallback upon disconnect, I call close().   Doesn't affect the way it reconnects to the peripheral (at least in this context).

jamesle1 wrote:

Also there is something I've found about Android devices. I'm not sure if this is true for all Android devices or if this is different for newer OS versions, but I've gotten the same results using Nexus 7 and 9 both with Android 5.1.1. After the first pairing is done (meaning before: BLE device doesn't show in the paired devices list in the Bluetooth Setting; after: BLE device shows up in the paired device list), the BLE device does not disconnect from the Android device even when close()/disconnect() method is called. Even after the Android app closes, the BLE device will stay connected to the Android device. In order to disconnect, you have to get out of range, disable Bluetooth in Android, or reset the BLE device. I doubt that this is your problem, but maybe you can check this as well.

Let me know if this helps. Thank you.

James

I've seen this behavior on my Nexus 5.  When the Nexus 5 first pairs with the peripheral from the Bluetooth Settings menu, it connects but does not disconnect upon a successful pairing.  It doesn't keep me from connecting with my application, though (Note: I have the peripheral discoverable to pair).  I'm still able to call connectGatt() and discover services.

I can go out of range or disable/enable bluetooth on my Nexus 5 and it kills the connection on the peripheral.  At this point, unless the peripheral is discoverable, I will not be able to connect to the peripheral again.

Does Broadcom have any existing examples where a mobile app should be able to connect to a peripheral that's not discoverable?

To provide some background:

I'd like to think this is pretty standard use case for BLE devices.    I'm following the pairing model for bluetooth speakers, where user presses a button on the speakers to set the speaker discoverable for a short period and let them pair.  But I'm stuck with not being able to connect when the peripheral is no longer discoverable.  What would be the recommended approach for this?

Let's say I'm implementing AppX for Android Play store which controls a smart consumer product

UserA  purchases PeripheralA

UserB purchases PeripheralB

UserA and UserB download AppX for their mobile devices.

UserA should be able to read and write to Peripheral A, but not PeripheralB and vice versa.

Thanks!

0 Likes
Anonymous
Not applicable

As far as I know, we don't have any existing examples where a mobile app connects to a peripheral that's not discoverable.

I'll try to work on a simple app and post the source code by Friday.

Can you post the firmware application that you are putting on the Anaren Atmosphere board?

If not, I'll just use hello_sensor to test.

You asked for the recommended approach for connecting to the peripheral.

An easy solution, no matter how silly it sounds>_<, would be to simply make the BLE device discoverable again:

either bsy a push of button or by timer on the BLE device.
But I'll look into connecting undiscoverable device.

James

0 Likes
Anonymous
Not applicable

It sort of defeats the purpose of controlling a peripheral wirelessly if I would have to press a button everytime I want to establish a connection

We're using a modified version of their buzzer example with some additional code to turn on/off LEDs when the device is discoverable:

Buzzer Piano Example - Anaren Atmosphere Wiki

It's ok if you use the hello_sensor project as long as we can understand what sort of configuration needs to be done.  Really appreciate the help

We're also looking at lesmp_setPairingNotPermitted/lesmp_clearPairingNotPermitted to see if we can't connect when the peripheral is non-discoverable, we can leave it discoverable but unable to pair.  Pairing will then be allowed at the press of a button. 

0 Likes
Anonymous
Not applicable

Hello. I'm sorry it took so long to reply back.

I tried to write a demo Android app that connects to a BLE device that is not advertising, undiscoverable.

I ran into the same problem as you did. Getting 133 status on onConnectionStateChange callback.

So I did some research about this, and turns out you CANNOT connect to BLE devices that is not advertising.

Please note that this is not what I said when I replied to you in the beginning.

So I sincerely apologize for not giving you the true fact before.

In order to connect to a BLE device, the BLE device needs to be advertising.

This is because the link layer(L2CAP) of the BLE stack checks for connection requests from the central device(Android) after it sends the advertisement packets. When it is not advertising, I think the connection requests from Android get ignored. So you get 133 status on Android as a result.

If you want to connect to your BLE device, you have to make it discoverable.

As you are probably already aware, there are few different discoverable modes in our API.

  • NO_DISCOVERABLE       
  • LOW_DIRECTED_DISCOVERABLE   
  • HIGH_DIRECTED_DISCOVERABLE
  • LOW_UNDIRECTED_DISCOVERABLE
  • HIGH_UNDIRECTED_DISCOVERABLE
  • MANDATORY_DISCOVERABLE

For your application, may I suggest you to either leave the BLE device discoverable all the time or just advertise in periods using a timer on the module if you really don't want the press of the button to be part of the user interaction.

As for as the snippet from the Android documentation

(which made me thought that it is possible to connect to undiscoverable BLE device, b/c of their API)

Once a connection is made with a remote device for the first time, a pairing request is automatically presented to the user. When a device is paired, the basic information about that device (such as the device name, class, and MAC address) is saved and can be read using the Bluetooth APIs. Using the known MAC address for a remote device, a connection can be initiated with it at any time without performing discovery (assuming the device is within range).

it just means that your Android device doesn't have to be scanning in order to connect to a BLE device that is in discoverable mode already. After the initial pairing, your app can get a list of paired devices by using getBondedDevices() of BluetoothAdapter. This returns a set of BluetoothDevice's.

Considering this user case:

UserA  purchases PeripheralA

UserB purchases PeripheralB

UserA and UserB download AppX for their mobile devices.

UserA should be able to read and write to Peripheral A, but not PeripheralB and vice versa.

your mobile app can go through the list of bonded device and if certain device is of the name of your device(im assuming PeripheralA and PeripheralB have same names), you can attempt to connect to it without having to turn on scanning in Android. If not, then you can start scanning for the user to choose which device to connect to.

I'm so sorry about the confusion.

I hope this helps a little bit.

Please let us know if there are anything else, we can help you with.

Thank you.

James

0 Likes
Anonymous
Not applicable

Hello.

Did everything work out for you?

James

0 Likes
Anonymous
Not applicable

Hi James,

Sorry for not getting back to you sooner.  I'm still on family leave but just wanted to acknowledge your message.  Btw, we did have a solution which toggles enabling pairing on the device at the press of a button.  Seems to work for what we're looking for.

Thanks for the clarification.

Victor

0 Likes