NimBLE: Demo of using write blob in ble phy example

This commit is contained in:
isha.pardikar@espressif.com 2023-03-21 12:40:31 +05:30
parent ee70990288
commit c7fa23b7b4
6 changed files with 115 additions and 15 deletions

View File

@ -11,6 +11,10 @@ This example performs below functionalities:
* Change the default LE PHY to 2M/Coded and establish a connection on that PHY. Then perform GATT read operation against the specified peer. Disconnect the link once this is completed.
* GATT operations performed:
1. Read on LE PHY characteristic.
2. Write blob on LE PHY characteristic.
This example aims at understanding how to establish connections on preferred PHY and changing LE PHY once the connection is established.
To test this demo, use any BLE GATT server app that advertises support for the LE PHY service (0xABF2) and includes it in the GATT database. Also make sure device supports extended advertising.

View File

@ -26,12 +26,86 @@ void ble_store_config_init(void);
/**
* Performs GATT operation against the specified peer:
* 1. Reads the Supported LE PHY characteristic.
* 2. After read is completed, performs write blob
*
* If the peer does not support a required service, characteristic, or
* descriptor, then the peer lied when it claimed support for the alert
* notification service! When this happens, or if a GATT procedure fails,
* descriptor, then the peer lied when it claimed support for the LE
* PHY service! When this happens, or if a GATT procedure fails,
* this function immediately terminates the connection.
*/
static int
blecent_on_write(uint16_t conn_handle,
const struct ble_gatt_error *error,
struct ble_gatt_attr *attr,
void *arg)
{
MODLOG_DFLT(INFO, "Write complete; status=%d conn_handle=%d", error->status,
conn_handle);
if (error->status == 0) {
MODLOG_DFLT(INFO, " attr_handle=%d", attr->handle);
}
MODLOG_DFLT(INFO, "\n");
return 0;
}
static int
blecent_on_read(uint16_t conn_handle,
const struct ble_gatt_error *error,
struct ble_gatt_attr *attr,
void *arg)
{
MODLOG_DFLT(INFO, "Read complete; status=%d conn_handle=%d", error->status,
conn_handle);
if (error->status == 0) {
MODLOG_DFLT(INFO, " attr_handle=%d value=", attr->handle);
print_mbuf(attr->om);
}
MODLOG_DFLT(INFO, "\n");
/* Write 1000 bytes to the LE PHY characteristic.*/
const struct peer_chr *chr;
int len = 1000;
uint8_t value[len];
int rc;
struct os_mbuf *txom;
const struct peer *peer = peer_find(conn_handle);
chr = peer_chr_find_uuid(peer,
BLE_UUID16_DECLARE(LE_PHY_UUID16),
BLE_UUID16_DECLARE(LE_PHY_CHR_UUID16));
if (chr == NULL) {
MODLOG_DFLT(ERROR, "Error: Peer doesn't support the Alert "
"Notification Control Point characteristic\n");
goto err;
}
/* Fill the value array with data */
for (int i = 0; i < len; i++) {
value[i] = i;
}
txom = ble_hs_mbuf_from_flat(&value, len);
if (!txom) {
MODLOG_DFLT(ERROR, "Insufficient memory");
goto err;
}
rc = ble_gattc_write_long(conn_handle, chr->chr.val_handle, 0,
txom, blecent_on_write, NULL);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Error: Failed to write characteristic; rc=%d\n",
rc);
goto err;
}
return 0;
err:
/* Terminate the connection. */
return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
static void
blecent_read(const struct peer *peer)
{
@ -49,7 +123,7 @@ blecent_read(const struct peer *peer)
}
rc = ble_gattc_read(peer->conn_handle, chr->chr.val_handle,
NULL, NULL);
blecent_on_read, NULL);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Error: Failed to read characteristic; rc=%d\n",
rc);

View File

@ -11,3 +11,4 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=y
CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER=y

View File

@ -5,11 +5,7 @@
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example performs below functionalities:
* Establishes a connection on LE 1M PHY and switch to LE 2M PHY once connection is established. Then perform GATT read operation against the specified peer. Disconnect the link once this is completed.
* Change the default LE PHY to 2M/Coded and establish a connection on that PHY. Then perform GATT read operation against the specified peer. Disconnect the link once this is completed.
This example performs advertises on different PHY, accepts connection from client app and gets disconnected. It then advertises on different PHY and does the same.
This example aims at understanding how to establish connections on preferred PHY and changing LE PHY once the connection is established.

View File

@ -13,6 +13,8 @@
#include "services/gatt/ble_svc_gatt.h"
#include "phy_prph.h"
static uint8_t *le_phy_val;
static uint16_t gatt_svr_chr_val_handle;
static int
gatt_svr_chr_access_le_phy(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt,
@ -28,7 +30,9 @@ static const struct ble_gatt_svc_def gatt_svr_svcs_le_phy[] = {
/*** Characteristic */
.uuid = BLE_UUID16_DECLARE(LE_PHY_CHR_UUID16),
.access_cb = gatt_svr_chr_access_le_phy,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
.val_handle = &gatt_svr_chr_val_handle,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE
| BLE_GATT_CHR_F_WRITE_ENC,
}, {
0, /* No more characteristics in this service. */
}
@ -48,7 +52,8 @@ gatt_svr_chr_access_le_phy(uint16_t conn_handle, uint16_t attr_handle,
const ble_uuid_t *uuid;
int rand_num;
int rc;
int len;
uint16_t copied_len;
uuid = ctxt->chr->uuid;
/* Determine which characteristic is being accessed by examining its
@ -56,12 +61,31 @@ gatt_svr_chr_access_le_phy(uint16_t conn_handle, uint16_t attr_handle,
*/
if (ble_uuid_cmp(uuid, BLE_UUID16_DECLARE(LE_PHY_CHR_UUID16)) == 0) {
assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
/* Respond with a 32-bit random number. */
switch (ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_CHR:
rand_num = rand();
rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num);
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
case BLE_GATT_ACCESS_OP_WRITE_CHR:
len = OS_MBUF_PKTLEN(ctxt->om);
if (len > 0) {
le_phy_val = (uint8_t *)malloc(len * sizeof(uint8_t));
if (le_phy_val) {
rc = ble_hs_mbuf_to_flat(ctxt->om, le_phy_val, len, &copied_len);
if (rc == 0) {
MODLOG_DFLT(INFO, "Write received of len = %d", copied_len);
return 0;
} else {
MODLOG_DFLT(ERROR, "Failed to receive write characteristic");
}
}
}
break;
default:
break;
}
}
/* Unknown characteristic; the nimble stack should not have called this

View File

@ -11,3 +11,4 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=y
CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER=y