Bluetooth Low Energy (a.k.a Bluetooth LE, BTLE, Bluetooth Smart)

Gatt Client support

01 Dec 2015

Thanks Rohit and Vincent! That's a really helpful example, much appreciated.

01 Dec 2015

Thanks Rohit and Vincent! That's a really helpful example, much appreciated.

EDIT: Duplicate.

03 Dec 2015

Quick question on the connect method operation:

I did a couple tests and it looks like that if you issue a connect call to a peripheral address that was advertising, but isn't anymore, it will create an indefinite pending connection to that device. If that peripheral pops up in the future, it will automatically connect to it. Is there any way to cancel this pending connection and do something like a timeout (e.g. "If I can't connect within 30 seconds to this peripheral, stop trying.")?

04 Dec 2015

@jay: if you set a timeout in the scanning parameters (refer to GAP apis), then this timeout would apply to the connection attempt.

04 Dec 2015

Hey Rohit,

Hmmm, so if I set the timeout in the scanning parameters to 5 seconds, upon issuing a connect, the central will stop trying if it cannot connect within 5 seconds?

The problem with this, I think, is that that timeout also applies to the scan. I need to be continuously scanning all the time, but setting a timeout of 5 seconds in the scanning parameters seems to also turn the scan off after 5 seconds.

Is there any way to modify the connection timeout while leaving the scan timeout at 0 (disabled)?

04 Dec 2015

Hi Jay,

Register a time out callback if you haven't already and then set a scanning timeout of say 5 secs. Then when you get a timeout for scanning done, trigger a task to start scanning again.

The gap timeout callback is really useful, it takes passes Gap::TimeoutSource_t tTimeOutSource as a parameter so you can perform an action based on the cause. For example in app I build a list of devices from the advertising callback and then sort them by rssi when I get a gap timeout callback with Gap::TIMEOUT_SRC_SCAN as the source.

Allen

04 Dec 2015

Great solution Allen! That's really helpful and perfectly solves the problem, thanks for that.

08 Dec 2015

Any insight on how to subscribe to a notify characteristic?

08 Dec 2015

Hi Jay,

The proper implementation of this feature will be added really soon (a matter of days).

08 Dec 2015

Haha, sounds great. Thanks Vincent, looking forward to the update!

08 Dec 2015

Another quick question:

I've noticed that sometimes the onServiceDiscoveryTerminated callback will be fired and then a couple of my onCharacteristicDiscovered callbacks will be fired after that.

Is there any functionality to determine when service discovery has finished and all callbacks have been delivered? My use-case is that I need to connect to a device and determine if that device supports my service and characteristics. So I'd like to check in onServiceDiscoveryTerminated if the characteristics I care about have been found. But unfortunately that won't work since the characteristic callbacks can still be delivered after the termination callback has fired.

06 Jan 2016

Vincent (pan-) Coubard wrote:

Hi Jay,

The proper implementation of this feature will be added really soon (a matter of days).

Any update on this implementation, Vincent?

07 Jan 2016

Hi Jay,

Unfortunately, it is taking more time than expected (other priorities). I have implemented Characteristic Descriptors discovery, this is the main block for notification registration. This feature is not yet available has a yotta module nor in mbed classic but it will be released today.

Implementation of notification registration will follow next week.

Vincent

19 Jan 2016

Thanks Vincent!

I'm also encountering an odd bug, I'm wondering if anyone can help out.

I have a central application that is working perfectly using the S130. It continually scans, reports devices, connects and disconnect, etc. I decided that for my purposes I'd also like to have a completely separate iBeacon that does not interact in any way with the central I have. To save money, I figured since the S130 has the ability to concurrently run a central and peripheral, I'd just run the iBeacon on the same chip and have no programmatic interaction at all (except using the same BLE instance). Here's my code for the iBeacon:

void startIBeaconAdvertising(uint16_t majorNumber, uint16_t minorNumber)
{
    this->_ble.gap().clearAdvertisingPayload();
	
    iBeacon *ibeacon = new iBeacon(this->_ble, ServiceUUID, majorNumber, minorNumber, IBEACON_TX_POWER);
    this->_ble.gap().setAdvertisingInterval(IBEACON_ADV_INTERVAL);
    this->_ble.gap().setAdvertisingTimeout(0);
    ble_error_t error = this->_ble.gap().startAdvertising();
    if (error != BLE_ERROR_NONE)
    {
        this->queueError(FailedToStartIBeaconAdvertising, error);
    }
}

This works great for a short while. The central scans, connects, and disconnects appropriately and I see the iBeacon advertising properly. But the issue occurs after 1 connection with the central. Suddenly it stops reporting any discoveries. The weird part is, if I simply comment the "startAdvertising" call for the iBeacon, the central will behave properly and never fail to report discoveries.

I was under the assumption that the peripheral and central would be operating completely independently, but that seems like it's not the case. Anyone know what's going on here?

19 Jan 2016

Hello Jay,

I reproduce your issue at the first try, but I manage to make it work by decreasing the scan interval and the scan windows. Could you try this ?

Vincent

19 Jan 2016

Hey Vincent,

Great insight! I had the following parameters:

Central: Scan Interval: 5000ms Scan Window: 4000ms

iBeacon: Advertising Interval: 100ms

I actually opted to increase the advertising interval of the iBeacon to 500ms and leave the central parameters the same. That also solved the problem! It's weird that that fixes the issue, I'm curious as to why that's the case; perhaps a faster advertising creates more events for the softdevice that prevent it from processing central events?

Nevertheless, I much appreciate the help!

29 Jan 2016

Hi guys,

Do you have any example code relating to subsribing to a notification, can you even point me at the callback which I presume I need to register?

I am currently trying to connect to a BLE Heart rate monitor and read the measurement charactieristic which is notification based. I can connect and discover the heart rate measurement characteristic.

Thanks,

A

29 Jan 2016

Answering my own question after reading through the ble api code.

I presume I just need to register an Hvx callback with m_ble.gattClient().onHVX(); and then within that check the type and handle to see if it is the characteristic I am looking for. I then just read the data.

Will give it a shot tomorrow.

01 Feb 2016

Having trouble enabling the CCCD so that the Gatt Server ( in my case a Wahoo Tickr BLE HRM ) enables the notifications.

At the moment I can connect and have discovered the service and characteristic but I don't get any HVX callbacks.

I am trying to enable notifications with the following... that is of course assuming the CCCD is there. According to this https://devzone.nordicsemi.com/tutorials/17/ble-characteristics-a-beginners-tutorial/ ( Table 1 ) the CCCD should immediately follow the HRM measurement characteristic.

any ideas?

title

case CMD_READ_HRM:
                if ( ( pCtrl->hPeriphConnHandle != INVALID_CONNECTION_HANDLE ) &&
                     ( pCtrl->pPeriphHRM             != NULL                      )    )
                {
                  // Setup CCCD to enable HRM notifications
                  uint16_t uValue = BLE_HVX_NOTIFICATION;
                  m_ble.gattClient().write( GattClient::GATT_OP_WRITE_REQ,
                                            pCtrl->hPeriphConnHandle,
                                            pCtrl->pPeriphHRM->getValueHandle() + 1, 
                                            sizeof(uint16_t),                                
                                            reinterpret_cast<const uint8_t *>(&uValue));                       
                }

In the meantime I am going to play with some of the code to see if I can discover the CCCD via the discoverDescriptors callback instead of using the hack above

09 Feb 2016

Hi everyone,

We are trying to use the Nordic mbed 51822 in central mode, and connect to a peripheral device. We tested the LEDBlinker and LEDBlink apps - it worked perfectly with two Nordic devices. (Note - the UUID was 16-bit in the blinker example)

We then wanted to connect it to another device running a BlueGiga BLE113 chip. The UUIDs on this device are much longer - 128-bits for Services and Characteristics.

While we are able to *read* the 16-bit characteristics (Manufacture String, Battery, etc) - we are having trouble trying to 'write' to the GATT. We found a pointer to the correct DiscoveredCharacteristic and then used the write() function to test a variety of values.

Some specific questions-

1) Do these libraries function with a 128-bit long UUID? 2) Do you have any insight into how to write these characteristics?

Thanks-

01 Mar 2016

Hi Everyone,

@Rohit, Thanks a lot of sharing the GATT Client API details. I am tinkering with your BLE_Observer example and I am trying to connect to peripheral and everything just works fine. At times, the connection just hangs before the service discovery or characteristic discovery and doesn't go any further. How do I drop this connection ?

Thanks

10 Jun 2016

I'm seeing some interesting behavior with service discovery:

Sometimes when I launch service discovery, it will call the callbacks in the following order:

onServiceDiscovered onServiceDiscoveryTerminated onCharacteristicDiscovered (1st characteristic I care about) onCharacteristicDiscovered (2nd characteristic I care about)

Upon discovering the two characteristics I care about, I'd like to subscribe to one of them. However, if I attempt to do this immediately after the second onCharacteristicDiscovered is called, I will often get the BLE_STACK_BUSY error. I have implemented a check to isServiceDiscoveryActive to definitively check that service discovery is no longer active (likely the source of the stack being busy). Unfortunately, this often continues to return true long after (>4 seconds) all characteristics are discovered and onServiceDiscoveryTerminated is called.

How can I ensure that service discovery has finished and I will not get a BLE_STACK_BUSY error to safely subscribe to the characteristic?

24 Aug 2017

Hi everybody, I am having a bit of a problem with reading characteristic larger than 22 bytes from the peripheral. I have tried to implement this on basis of ble_LEDBlinker code for the central unit. I am using Nordic NRF51 Dongle as the central unit and SwitchScience TY51822R3 as peripheral. I am quite sure that peripheral is able to store the characteristic that is 192 bytes long, since I am able to read it correctly using the nRF Connect application with the same dongle acting as central unit (of course, with different firmware on the dongle). I understand that BT packages cannot be as long as 192 bytes, but there should be some function that should allow central to read this data in consectutive packages until complete characteristic is read (and not only first 22 bytes). I thank you in advance for any advice or guidance that you can provide me.

Best, Matija