drivers/nble: Implement NBLE GATT discover response
Implement GATT nble_gattc_disc_rsp() function, may be tested with bluetooth shell app. Change-Id: I80c9596e83310902de40f6e91d2ecd4b5d2f3292 Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This commit is contained in:
parent
b47df6e800
commit
ba169c5819
2 changed files with 234 additions and 2 deletions
|
@ -21,6 +21,7 @@
|
|||
#include <bluetooth/gatt.h>
|
||||
#include <bluetooth/log.h>
|
||||
|
||||
#include "conn.h"
|
||||
#include "conn_internal.h"
|
||||
#include "gatt_internal.h"
|
||||
|
||||
|
@ -394,6 +395,9 @@ int bt_gatt_discover(struct bt_conn *conn,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
BT_DBG("conn %p start 0x%04x end 0x%04x", conn, params->start_handle,
|
||||
params->end_handle);
|
||||
|
||||
switch (params->type) {
|
||||
case BT_GATT_DISCOVER_PRIMARY:
|
||||
case BT_GATT_DISCOVER_INCLUDE:
|
||||
|
@ -419,6 +423,222 @@ int bt_gatt_discover(struct bt_conn *conn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t parse_include(struct bt_conn *conn, const uint8_t *data,
|
||||
uint8_t len)
|
||||
{
|
||||
struct bt_gatt_discover_params *params = conn->gatt_discover;
|
||||
uint16_t end_handle = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; len > 0; i++) {
|
||||
const struct nble_gattc_included *att = (void *)data;
|
||||
struct bt_gatt_attr *attr = NULL;
|
||||
struct bt_gatt_include gatt_include;
|
||||
|
||||
gatt_include.start_handle = att->range.start_handle;
|
||||
gatt_include.end_handle = att->range.end_handle;
|
||||
end_handle = gatt_include.end_handle;
|
||||
|
||||
BT_DBG("start 0x%04x end 0x%04x", att->range.start_handle,
|
||||
att->range.end_handle);
|
||||
|
||||
/*
|
||||
* 4.5.1 If the service UUID is a 16-bit Bluetooth UUID
|
||||
* it is also returned in the response.
|
||||
*/
|
||||
switch (att->uuid.uuid.type) {
|
||||
case BT_UUID_TYPE_16:
|
||||
gatt_include.uuid = &att->uuid.uuid;
|
||||
break;
|
||||
case BT_UUID_TYPE_128:
|
||||
/* Data is not available at this point */
|
||||
break;
|
||||
}
|
||||
|
||||
attr = (&(struct bt_gatt_attr)
|
||||
BT_GATT_INCLUDE_SERVICE(&gatt_include));
|
||||
attr->handle = att->handle;
|
||||
|
||||
data += sizeof(*att);
|
||||
len -= sizeof(*att);
|
||||
|
||||
if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return end_handle;
|
||||
}
|
||||
|
||||
static uint16_t parse_service(struct bt_conn *conn, const uint8_t *data,
|
||||
uint8_t len)
|
||||
{
|
||||
struct bt_gatt_discover_params *params = conn->gatt_discover;
|
||||
uint16_t end_handle = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; len > 0; i++) {
|
||||
const struct nble_gattc_primary *att = (void *)data;
|
||||
struct bt_gatt_service gatt_service;
|
||||
struct bt_gatt_attr *attr = NULL;
|
||||
|
||||
gatt_service.end_handle = att->range.end_handle;
|
||||
gatt_service.uuid = params->uuid;
|
||||
end_handle = gatt_service.end_handle;
|
||||
|
||||
attr = (&(struct bt_gatt_attr)
|
||||
BT_GATT_PRIMARY_SERVICE(&gatt_service));
|
||||
attr->handle = att->handle;
|
||||
|
||||
data += sizeof(*att);
|
||||
len -= sizeof(*att);
|
||||
|
||||
if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return end_handle;
|
||||
}
|
||||
|
||||
static uint16_t parse_characteristic(struct bt_conn *conn, const uint8_t *data,
|
||||
uint8_t len)
|
||||
{
|
||||
struct bt_gatt_discover_params *params = conn->gatt_discover;
|
||||
uint16_t end_handle = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; len > 0; i++) {
|
||||
const struct nble_gattc_characteristic *att = (void *)data;
|
||||
struct bt_gatt_attr *attr = NULL;
|
||||
|
||||
attr = (&(struct bt_gatt_attr)
|
||||
BT_GATT_CHARACTERISTIC(&att->uuid.uuid, att->prop));
|
||||
attr->handle = att->handle;
|
||||
end_handle = att->handle;
|
||||
|
||||
data += sizeof(*att);
|
||||
len -= sizeof(*att);
|
||||
|
||||
if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return end_handle;
|
||||
}
|
||||
|
||||
static uint16_t parse_descriptor(struct bt_conn *conn, const uint8_t *data,
|
||||
uint8_t len)
|
||||
{
|
||||
struct bt_gatt_discover_params *params = conn->gatt_discover;
|
||||
uint16_t end_handle = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; len > 0; i++) {
|
||||
const struct nble_gattc_descriptor *att = (void *)data;
|
||||
struct bt_gatt_attr *attr = NULL;
|
||||
|
||||
attr = (&(struct bt_gatt_attr)
|
||||
BT_GATT_DESCRIPTOR(&att->uuid.uuid, 0, NULL, NULL, NULL));
|
||||
attr->handle = att->handle;
|
||||
end_handle = att->handle;
|
||||
|
||||
data += sizeof(*att);
|
||||
len -= sizeof(*att);
|
||||
|
||||
if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return end_handle;
|
||||
}
|
||||
|
||||
|
||||
void on_nble_gattc_discover_rsp(const struct nble_gattc_disc_rsp *rsp,
|
||||
const uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
uint16_t end_handle = 0;
|
||||
struct bt_gatt_discover_params *params;
|
||||
struct bt_conn *conn;
|
||||
int status;
|
||||
|
||||
conn = bt_conn_lookup_handle(rsp->conn_handle);
|
||||
if (!conn) {
|
||||
BT_ERR("Unable to find conn for handle %u", rsp->conn_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
params = conn->gatt_discover;
|
||||
|
||||
/* Status maybe error or indicate end of discovery */
|
||||
if (rsp->status) {
|
||||
BT_DBG("status %d", rsp->status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
BT_DBG("conn %p handle %u status %d len %u", conn, conn->handle,
|
||||
rsp->status, data_len);
|
||||
|
||||
switch (rsp->type) {
|
||||
case BT_GATT_DISCOVER_INCLUDE:
|
||||
end_handle = parse_include(conn, data, data_len);
|
||||
break;
|
||||
case BT_GATT_DISCOVER_PRIMARY:
|
||||
end_handle = parse_service(conn, data, data_len);
|
||||
break;
|
||||
case BT_GATT_DISCOVER_CHARACTERISTIC:
|
||||
end_handle = parse_characteristic(conn, data, data_len);
|
||||
break;
|
||||
case BT_GATT_DISCOVER_DESCRIPTOR:
|
||||
end_handle = parse_descriptor(conn, data, data_len);
|
||||
break;
|
||||
default:
|
||||
BT_ERR("Wrong discover type %d", rsp->type);
|
||||
bt_conn_unref(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!end_handle) {
|
||||
goto stop;
|
||||
}
|
||||
|
||||
/* Stop if end_handle is over the range */
|
||||
if (end_handle >= params->end_handle) {
|
||||
BT_WARN("Handle goes over the range: 0x%04x >= 0x%04x",
|
||||
end_handle, params->end_handle);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Continue discovery from last found handle */
|
||||
params->start_handle = end_handle;
|
||||
if (params->start_handle < UINT16_MAX) {
|
||||
params->start_handle++;
|
||||
}
|
||||
|
||||
/* This pointer would keep new params set in the function below */
|
||||
conn->gatt_discover = NULL;
|
||||
|
||||
status = bt_gatt_discover(conn, params);
|
||||
if (status) {
|
||||
BT_ERR("Unable to continue discovering, status %d", status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
bt_conn_unref(conn);
|
||||
return;
|
||||
|
||||
done:
|
||||
/* End of discovery */
|
||||
params->func(conn, NULL, params);
|
||||
|
||||
stop:
|
||||
conn->gatt_discover = NULL;
|
||||
bt_conn_unref(conn);
|
||||
}
|
||||
|
||||
|
||||
int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params)
|
||||
{
|
||||
return -ENOSYS;
|
||||
|
|
|
@ -169,7 +169,19 @@ struct nble_gattc_prim_svc {
|
|||
*/
|
||||
struct nble_gattc_rsp {
|
||||
int status;
|
||||
uint16_t conn_handle; /**< GAP connection handle */
|
||||
uint16_t conn_handle;
|
||||
};
|
||||
|
||||
struct nble_gattc_primary {
|
||||
uint16_t handle;
|
||||
struct nble_gatt_handle_range range;
|
||||
struct bt_uuid_128 uuid;
|
||||
};
|
||||
|
||||
struct nble_gattc_included {
|
||||
uint16_t handle;
|
||||
struct nble_gatt_handle_range range;
|
||||
struct bt_uuid_128 uuid;
|
||||
};
|
||||
|
||||
struct nble_gattc_disc_rsp {
|
||||
|
@ -205,7 +217,7 @@ struct nble_gattc_characteristic {
|
|||
* GATTC descriptor.
|
||||
*/
|
||||
struct nble_gattc_descriptor {
|
||||
uint16_t handle; /**< descriptor handle */
|
||||
uint16_t handle; /**< descriptor handle */
|
||||
struct bt_uuid_128 uuid; /**< uuid of the descriptor */
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue