Skip to content

Commit

Permalink
bluetooth: nrf52: Add ble_discover_uuid() API
Browse files Browse the repository at this point in the history
Add ble_discover_uuid() API to discover GATT database with specific UUID.
  • Loading branch information
SPRESENSE committed Jun 5, 2023
1 parent eebecb0 commit 1143fc6
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 33 deletions.
28 changes: 28 additions & 0 deletions sdk/modules/bluetooth/bluetooth_le_gatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,34 @@ int ble_continue_db_discovery(uint16_t start_handle, uint16_t conn_handle)
return ret;
}

/****************************************************************************
* Name: ble_discover_uuid
*
* Description:
* BLE GATT database discovery with specific UUID.
*
****************************************************************************/

int ble_discover_uuid(uint16_t conn_handle,
BLE_UUID *srv_uuid,
BLE_UUID *char_uuid)
{
int ret = BT_SUCCESS;
struct ble_hal_gattc_ops_s *ops = &(g_ble_gatt_state.ble_hal_gatt_ops->gattc);

if (ops && ops->discoverUuid)
{
ret = ops->discoverUuid(conn_handle, srv_uuid, char_uuid);
}
else
{
_err("%s [BLE][GATT] Not supported.\n", __func__);
return BT_FAIL;
}

return ret;
}

/****************************************************************************
* Name: ble_gatt_register_hal
*
Expand Down
128 changes: 97 additions & 31 deletions sdk/modules/bluetooth/hal/nrf52/ble_comm.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static void onReadRsp(BLE_Evt *pBleEvent, ble_evt_t *pBleNrfEvt);
static void onWriteRsp(BLE_Evt *pBleEvent, ble_evt_t *pBleNrfEvt);
static void onSrvDiscCompletion(BLE_Evt *pBleEvent, bleGattcDb *gattcDbDiscovery);
static int characteristicsDiscover(BLE_Evt *pBleEvent, bleGattcDb *const gattcDbDiscovery);
static bool isCharDiscoveryReqd(bleGattcDb *const gattcDbDiscovery, BLE_GattcChar *afterChar);
static bool isCharDiscoveryReqd(bleGattcDb *const gattcDbDiscovery, uint16_t last_handle);
static bool isDescDiscoveryReqd(bleGattcDb *gattcDbDiscovery, BLE_GattcDbDiscChar *currChar, BLE_GattcDbDiscChar *nextChar, BLE_GattcHandleRange *handleRange);
static int descriptorsDiscover(BLE_Evt *pBleEvent, bleGattcDb *const gattcDbDiscovery, bool *raiseDiscovComplete);

Expand Down Expand Up @@ -2136,6 +2136,7 @@ static void set_discoveried_data(BLE_GattcDbDiscovery *rcv,
srv->char_count = rcv_srv->charCount;
srv->srv_handle_range.start_handle = rcv_srv->srvHandleRange.startHandle;
srv->srv_handle_range.end_handle = rcv_srv->srvHandleRange.endHandle;
memcpy(&srv->srv_uuid, &rcv_srv->srvUuid, sizeof(BLE_UUID));

ch = &srv->characteristics[0];
rcv_ch = &rcv_srv->characteristics[0];
Expand Down Expand Up @@ -2191,6 +2192,60 @@ void setDbDiscoveryEvent(BLE_Evt *pBleEvent, uint16_t connHandle, int result, in
return;
}

static bool is_target_uuid(const ble_uuid_t *notified, ble_uuid_t *target)
{
if (target->type == BLE_UUID_TYPE_UNKNOWN)
{
/* This setting means that all information is discovered. */

return true;
}
else
{
if (BLE_UUID_EQ(notified, target))
{
return true;
}
else
{
return false;
}
}
}

static void convert_uuid_nrf2mw(const ble_uuid_t *nrf52, BLE_Uuid *mw)
{
uint8_t len;
uint8_t uuid[16];

if (nrf52->type == BLE_UUID_TYPE_BLE)
{
mw->value.baseAlias.uuidAlias = nrf52->uuid;
mw->type = BLE_UUID_TYPE_BASEALIAS_BTSIG;
}
else if (nrf52->type == BLE_UUID_TYPE_UNKNOWN)
{
/* Unknown and non-encodable 128bit UUID case. */

mw->type = BLE_UUID_TYPE_UUID128;
memset(mw->value.uuid128.uuid128, 0, 16);
}
else
{
sd_ble_uuid_encode(nrf52, &len, uuid);
if (len == 2)
{
mw->value.baseAlias.uuidAlias = (uuid[1] << 8) | uuid[0];
mw->type = BLE_UUID_TYPE_BASEALIAS_VENDOR;
}
else
{
memcpy(mw->value.uuid128.uuid128, uuid, 16);
mw->type = BLE_UUID_TYPE_UUID128;
}
}
}

static
void onPrimarySrvDiscoveryRsp(bleGattcDb *gattcDbDiscovery, BLE_Evt *pBleEvent, ble_evt_t *pBleNrfEvt)
{
Expand Down Expand Up @@ -2231,8 +2286,12 @@ void onPrimarySrvDiscoveryRsp(bleGattcDb *gattcDbDiscovery, BLE_Evt *pBleEvent,
i < num;
i++, srv++, ltbl++)
{
ltbl->srvUuid.value.baseAlias.uuidAlias = srv->uuid.uuid;
ltbl->srvUuid.type = (BLE_GATT_UUID_TYPE)srv->uuid.type;
if (is_target_uuid(&srv->uuid, &gattcDbDiscovery->target.srvUuid) == false)
{
continue;
}

convert_uuid_nrf2mw(&srv->uuid, &ltbl->srvUuid);
ltbl->srvHandleRange.startHandle = srv->handle_range.start_handle;
ltbl->srvHandleRange.endHandle = srv->handle_range.end_handle;
BLE_PRT2("Primary Service[%d] type %d uuid 0x%04X sHdl %d eHdl %d\n",
Expand Down Expand Up @@ -2268,17 +2327,15 @@ void onCharacteristicDiscoveryRsp(bleGattcDb *const gattcDbDiscovery, BLE_Evt *p
uint8_t numCharsCurrDisc = 0;
uint16_t connHandle = 0;
uint32_t i = 0;
uint32_t j = 0;
bool performDescDiscov = false;
bool raiseDiscovComplete = false;
ble_gattc_evt_t *bleGattcEvt = &(pBleNrfEvt->evt.gattc_evt);
BLE_GattcDbDiscSrv *srvBeingDiscovered = &(gattcDbDiscovery->dbDiscovery.services[gattcDbDiscovery->currSrvInd]);
BLE_GattcDbDiscChar *chtop;
BLE_GattcChar *ch;
BLE_GattcChar *ch = NULL;
const ble_gattc_evt_char_disc_rsp_t *charDiscRspEvt;
const ble_gattc_char_t *rcvch;
BLE_GattcChar *lastKnownChar = NULL;

uint16_t last_handle = BLE_GATT_INVALID_ATTRIBUTE_HANDLE;
connHandle = bleGattcEvt->conn_handle;
if (gattcDbDiscovery->currSrvInd >= BLE_DB_DISCOVERY_MAX_SRV)
{
Expand All @@ -2294,29 +2351,22 @@ void onCharacteristicDiscoveryRsp(bleGattcDb *const gattcDbDiscovery, BLE_Evt *p
numCharsPrevDisc = srvBeingDiscovered->charCount;
numCharsCurrDisc = charDiscRspEvt->count;
BLE_PRT2("onChar preCnt %d curCnt %d\n", numCharsPrevDisc, numCharsCurrDisc);
// Check if the total number of discovered characteristics are supported
if ((numCharsPrevDisc + numCharsCurrDisc) <= BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV)
chtop = &srvBeingDiscovered->characteristics[numCharsPrevDisc];
for (i = 0; i < numCharsCurrDisc; i++)
{
// Update the characteristics count.
srvBeingDiscovered->charCount += numCharsCurrDisc;
}
else
{
// The number of characteristics discovered at the peer is more than the supported maximum.
srvBeingDiscovered->charCount = BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV;
}
rcvch = &charDiscRspEvt->chars[i];
last_handle = rcvch->handle_value;

for (i = numCharsPrevDisc, j = 0; i < srvBeingDiscovered->charCount; i++, j++)
{
chtop = &srvBeingDiscovered->characteristics[i];
ch = &chtop->characteristic;
rcvch = &charDiscRspEvt->chars[j];
if (is_target_uuid(&rcvch->uuid, &gattcDbDiscovery->target.charUuid) == false)
{
continue;
}

ch = &chtop->characteristic;
memcpy(&ch->charPrope, &rcvch->char_props, sizeof(BLE_CharPrope));
ch->charDeclhandle = rcvch->handle_decl;
ch->charValhandle = rcvch->handle_value;
ch->charValUuid.type = (BLE_GATT_UUID_TYPE)rcvch->uuid.type;
ch->charValUuid.value.baseAlias.uuidAlias = rcvch->uuid.uuid;
convert_uuid_nrf2mw(&rcvch->uuid, &ch->charValUuid);

/* Initialize all descriptors handle with invalid value.
* These handles are discovered later by descriptor discovery.
Expand All @@ -2334,13 +2384,19 @@ void onCharacteristicDiscoveryRsp(bleGattcDb *const gattcDbDiscovery, BLE_Evt *p
rcvch->uuid.uuid,
rcvch->handle_value,
rcvch->handle_decl);
}

lastKnownChar = &(srvBeingDiscovered->characteristics[i - 1].characteristic);
srvBeingDiscovered->charCount++;
if (srvBeingDiscovered->charCount > BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV)
{
break;
}

chtop++;
}

// If no more characteristic discovery is required, or if the maximum number of supported
// characteristic per service has been reached, descriptor discovery will be performed.
if (!isCharDiscoveryReqd(gattcDbDiscovery, lastKnownChar) ||
if (!isCharDiscoveryReqd(gattcDbDiscovery, last_handle) ||
(srvBeingDiscovered->charCount == BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV))
{
performDescDiscov = true;
Expand Down Expand Up @@ -2612,15 +2668,15 @@ int characteristicsDiscover(BLE_Evt *pBleEvent, bleGattcDb *const gattcDbDiscove

static
bool isCharDiscoveryReqd(bleGattcDb *const gattcDbDiscovery,
BLE_GattcChar *afterChar)
uint16_t last_handle)
{
BLE_PRT2("isChar charEndHdl %d srvEndHdl %d\n", afterChar->charValhandle,
BLE_PRT2("isChar charEndHdl %d srvEndHdl %d\n", last_handle,
gattcDbDiscovery->dbDiscovery.services[gattcDbDiscovery->currSrvInd].srvHandleRange.endHandle);
if (gattcDbDiscovery->currSrvInd >= BLE_DB_DISCOVERY_MAX_SRV)
{
return false;
}
if (afterChar->charValhandle <
if (last_handle <
gattcDbDiscovery->dbDiscovery.services[gattcDbDiscovery->currSrvInd].srvHandleRange.endHandle)
{
// Handle value of the characteristic being discovered is less than the end handle of
Expand Down Expand Up @@ -2744,7 +2800,17 @@ int descriptorsDiscover(BLE_Evt *pBleEvent, bleGattcDb *const gattcDbDiscovery,

gattcDbDiscovery->currSrvInd++;
gattcDbDiscovery->currCharInd = 0;
characteristicsDiscover(pBleEvent, gattcDbDiscovery);

if (gattcDbDiscovery->currSrvInd < gattcDbDiscovery->dbDiscovery.srvCount)
{
characteristicsDiscover(pBleEvent, gattcDbDiscovery);
}
else
{
setDbDiscoveryEvent(pBleEvent,
gattcDbDiscovery->dbDiscovery.connHandle,
BLE_GATTC_RESULT_SUCCESS, 0);
}

return NRF_SUCCESS;
}
Expand Down
7 changes: 7 additions & 0 deletions sdk/modules/bluetooth/hal/nrf52/ble_comm_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ typedef struct

typedef struct
{
ble_uuid_t srvUuid;
ble_uuid_t charUuid;
} bleGattcDbTarget;

typedef struct
{
bleGattcDbTarget target;
uint8_t currCharInd;
uint8_t currSrvInd;
bool discoveryInProgress;
Expand Down
70 changes: 70 additions & 0 deletions sdk/modules/bluetooth/hal/nrf52/ble_gattc.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ static int nrf52_ble_notify(struct ble_gatt_char_s *ble_gatt_char,
static int nrf52_ble_start_db_discovery(uint16_t conn_handle);
static int nrf52_ble_continue_db_discovery(uint16_t start_handle,
uint16_t conn_handle);
static int nrf52_ble_discover_uuid(uint16_t conn_handle,
BLE_UUID *srv_uuid,
BLE_UUID *char_uuid);
static int nrf52_ble_gattc_write(struct ble_gatt_char_s *ble_gatt_char,
uint16_t handle);
static int nrf52_ble_gattc_read(struct ble_gatt_char_s *ble_gatt_char,
Expand Down Expand Up @@ -107,6 +110,7 @@ static struct ble_hal_gatt_ops_s ble_hal_gatt_ops =
.gatts.notify = nrf52_ble_notify,
.gattc.startDbDiscovery = nrf52_ble_start_db_discovery,
.gattc.continueDbDiscovery = nrf52_ble_continue_db_discovery,
.gattc.discoverUuid = nrf52_ble_discover_uuid,
.gattc.write = nrf52_ble_gattc_write,
.gattc.read = nrf52_ble_gattc_read,
.gattc.descriptor_write = nrf52_ble_descriptor_write,
Expand Down Expand Up @@ -340,6 +344,72 @@ static int nrf52_ble_continue_db_discovery(uint16_t start_handle, uint16_t conn_
return BLE_GattcContinueDbDiscovery(conn_handle, start_handle);
}

static int convert_uuid_mw2nrf(BLE_UUID *mw, ble_uuid_t *nrf52)
{
int ret;
ble_uuid128_t uuid128;

if (mw->type == BLE_UUID_TYPE_UUID128)
{
memcpy(uuid128.uuid128,
mw->value.uuid128.uuid128,
sizeof(uuid128.uuid128));
ret = sd_ble_uuid_vs_add(&uuid128, &nrf52->type);
nrf52->uuid = (mw->value.uuid128.uuid128[13] << 8)
| mw->value.uuid128.uuid128[12];
}
else
{
ret = NRF_SUCCESS;
nrf52->type = BLE_UUID_TYPE_BLE;
nrf52->uuid = mw->value.alias.uuidAlias;
}

return ret;
}

/****************************************************************************
* Name: nrf52_ble_discover_uuid
*
* Description:
* Bluetooth LE GATT client discover specific UUID
*
****************************************************************************/

static int nrf52_ble_discover_uuid(uint16_t conn_handle,
BLE_UUID *srv_uuid,
BLE_UUID *char_uuid)
{
int errCode;

errCode = convert_uuid_mw2nrf(srv_uuid, &commMem.gattcDb.target.srvUuid);
if (errCode != NRF_SUCCESS)
{
goto err;
}

errCode = convert_uuid_mw2nrf(char_uuid, &commMem.gattcDb.target.charUuid);
if (errCode != NRF_SUCCESS)
{
goto err;
}

errCode = sd_ble_gattc_primary_services_discover
(conn_handle,
SRV_DISC_START_HANDLE,
&commMem.gattcDb.target.srvUuid);
if (errCode != NRF_SUCCESS)
{
goto err;
}

return BLE_SUCCESS;

err:
memset(&commMem.gattcDb.target, 0, sizeof(bleGattcDbTarget));
return bleConvertErrorCode((uint32_t)errCode);
}

/****************************************************************************
* Name: nrf52_ble_write
*
Expand Down
14 changes: 14 additions & 0 deletions sdk/modules/include/bluetooth/ble_gatt.h
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,8 @@ int ble_descriptor_write(uint16_t conn_handle,
/**
* @brief BLE start database discovery
* Send database discovery request to peripheral (For Central role)
* In case of device/nrf52 configuration, 128-bit UUID information is not
* discovered correctly. Then, you may use ble_discover_uuid() API.
*
* @param[in] conn_handle: Bluetooth LE GATT connection handle
*
Expand All @@ -558,6 +560,8 @@ int ble_start_db_discovery(uint16_t conn_handle);
/**
* @brief BLE continue database discovery
* Send continue database discovery request to peripheral (For Central role)
* In case of device/nrf52 configuration, 128-bit UUID information is not
* discovered correctly. Then, you may use ble_discover_uuid() API.
*
* @param[in] start_handle: Bluetooth LE GATT start handle
* @param[in] conn_handle: Bluetooth LE GATT connection handle
Expand All @@ -567,4 +571,14 @@ int ble_start_db_discovery(uint16_t conn_handle);

int ble_continue_db_discovery(uint16_t start_handle, uint16_t conn_handle);

/* @brief Discover GATT database with specific UUID
* @param[in] conn_handle: BLE connection handle
* @param[in] srv_uuid: Service UUID to be discovered
* @param[in] char_uuid: Characteristic UUID to be discovered
*
* @retval error code
*/

int ble_discover_uuid(uint16_t conn_handle, BLE_UUID *srv_uuid, BLE_UUID *char_uuid);

#endif /* __MODULES_INCLUDE_BLUETOOTH_BLE_GATT_H */
Loading

0 comments on commit 1143fc6

Please sign in to comment.