diff --git a/examples/bluetooth/nimble/ble_phy/phy_cent/README.md b/examples/bluetooth/nimble/ble_phy/phy_cent/README.md index 4e40e757ed..b41cc01cf2 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_cent/README.md +++ b/examples/bluetooth/nimble/ble_phy/phy_cent/README.md @@ -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. diff --git a/examples/bluetooth/nimble/ble_phy/phy_cent/main/main.c b/examples/bluetooth/nimble/ble_phy/phy_cent/main/main.c index 76810c3aa9..09609abdaa 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_cent/main/main.c +++ b/examples/bluetooth/nimble/ble_phy/phy_cent/main/main.c @@ -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); diff --git a/examples/bluetooth/nimble/ble_phy/phy_cent/sdkconfig.defaults b/examples/bluetooth/nimble/ble_phy/phy_cent/sdkconfig.defaults index 81960c1079..7c4edca729 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_cent/sdkconfig.defaults +++ b/examples/bluetooth/nimble/ble_phy/phy_cent/sdkconfig.defaults @@ -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 diff --git a/examples/bluetooth/nimble/ble_phy/phy_prph/README.md b/examples/bluetooth/nimble/ble_phy/phy_prph/README.md index e1ef201188..d723a212d1 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_prph/README.md +++ b/examples/bluetooth/nimble/ble_phy/phy_prph/README.md @@ -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. diff --git a/examples/bluetooth/nimble/ble_phy/phy_prph/main/gatt_svr.c b/examples/bluetooth/nimble/ble_phy/phy_prph/main/gatt_svr.c index ce3db2a024..c5c5f45d17 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_prph/main/gatt_svr.c +++ b/examples/bluetooth/nimble/ble_phy/phy_prph/main/gatt_svr.c @@ -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); + 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; - /* Respond with a 32-bit random number. */ - 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 diff --git a/examples/bluetooth/nimble/ble_phy/phy_prph/sdkconfig.defaults b/examples/bluetooth/nimble/ble_phy/phy_prph/sdkconfig.defaults index 81960c1079..7c4edca729 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_prph/sdkconfig.defaults +++ b/examples/bluetooth/nimble/ble_phy/phy_prph/sdkconfig.defaults @@ -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