-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/multi_adv' into 'master'
NimbLE: Added multi advertising example See merge request espressif/esp-idf!22761
- Loading branch information
Showing
10 changed files
with
827 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# The following lines of boilerplate have to be in your project's | ||
# CMakeLists in this exact order for cmake to work correctly | ||
cmake_minimum_required(VERSION 3.16) | ||
|
||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/bluetooth/nimble/common/nimble_peripheral_utils) | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
project(ble_multi_adv) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-H4 | ESP32-S3 | | ||
| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | | ||
|
||
# BLE Multi Adv Example | ||
|
||
(See the README.md file in the upper level 'examples' directory for more information about examples.) | ||
|
||
This example support legacy as well as extended advertisement for all phy. For multi advertising, random addresses are generated for each instance. | ||
|
||
It starts 4 types of advertising: | ||
* Non connectable extended | ||
* Connectable extended | ||
* Scannable legacy | ||
* Legacy withe specified duration(5 sec) | ||
|
||
## How to Use Example | ||
|
||
Before project configuration and build, be sure to set the correct chip target using: | ||
|
||
```bash | ||
idf.py set-target <chip_name> | ||
``` | ||
|
||
### Configure the Project | ||
|
||
Open the project configuration menu: | ||
``` | ||
idf.py menuconfig | ||
``` | ||
|
||
To configure number of advertising instances: | ||
|
||
* Component config → Bluetooth → NimBLE Options → Enable BLE 5 feature → Maximum number of extended advertising instances | ||
|
||
### Hardware Required | ||
|
||
* A development board with ESP32-C3 SoC,ESP32-S3/ESP32-H4/ESP32-C2 SoC and BLE5.0 supported chips (e.g., ESP32-C3-DevKitC, etc.) | ||
* A USB cable for Power supply and programming | ||
|
||
See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. | ||
|
||
### Build and Flash | ||
|
||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. | ||
|
||
(To exit the serial monitor, type ``Ctrl-]``.) | ||
|
||
See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. | ||
|
||
|
||
## Example Output | ||
|
||
``` | ||
I (404) NimBLE_MULTI_ADV: BLE Host Task Started | ||
I (414) NimBLE_MULTI_ADV: Instance 0 started | ||
I (414) NimBLE_MULTI_ADV: Instance 1 started | ||
I (434) NimBLE_MULTI_ADV: Instance 2 started | ||
I (444) NimBLE_MULTI_ADV: Instance 3 started | ||
I (454) main_task: Returned from app_main() | ||
I (5404) NimBLE: advertise complete; reason=13 | ||
I (5404) NimBLE_MULTI_ADV: In ble_legacy_duration_cb, instance = 3 | ||
I (5404) NimBLE_MULTI_ADV: Instance 3 started | ||
I (10384) NimBLE: advertise complete; reason=13 | ||
I (10384) NimBLE_MULTI_ADV: In ble_legacy_duration_cb, instance = 3 | ||
I (10394) NimBLE_MULTI_ADV: Instance 3 started | ||
``` | ||
## Troubleshooting | ||
|
||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
set(srcs "main.c" | ||
"gatt_svr.c") | ||
|
||
idf_component_register(SRCS "${srcs}" | ||
INCLUDE_DIRS ".") |
169 changes: 169 additions & 0 deletions
169
examples/bluetooth/nimble/ble_multi_adv/main/gatt_svr.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include "host/ble_hs.h" | ||
#include "host/ble_uuid.h" | ||
#include "services/gap/ble_svc_gap.h" | ||
#include "services/gatt/ble_svc_gatt.h" | ||
#include "multi_adv.h" | ||
|
||
static const ble_uuid128_t gatt_svr_svc_uuid = | ||
BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, | ||
0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); | ||
|
||
/* A characteristic that can be subscribed to */ | ||
static uint16_t gatt_svr_chr_val_handle; | ||
static const ble_uuid128_t gatt_svr_chr_uuid = | ||
BLE_UUID128_INIT(0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, | ||
0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x33); | ||
|
||
/* A custom descriptor */ | ||
static uint8_t gatt_svr_dsc_val; | ||
static const ble_uuid128_t gatt_svr_dsc_uuid = | ||
BLE_UUID128_INIT(0x01, 0x01, 0x01, 0x01, 0x12, 0x12, 0x12, 0x12, | ||
0x23, 0x23, 0x23, 0x23, 0x34, 0x34, 0x34, 0x34); | ||
|
||
static int | ||
gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle, | ||
struct ble_gatt_access_ctxt *ctxt, | ||
void *arg); | ||
|
||
static const struct ble_gatt_svc_def gatt_svr_svcs[] = { | ||
{ | ||
/*** Service ***/ | ||
.type = BLE_GATT_SVC_TYPE_PRIMARY, | ||
.uuid = &gatt_svr_svc_uuid.u, | ||
.characteristics = (struct ble_gatt_chr_def[]) | ||
{ { | ||
/*** This characteristic can be subscribed to by writing 0x00 and 0x01 to the CCCD ***/ | ||
.uuid = &gatt_svr_chr_uuid.u, | ||
.access_cb = gatt_svc_access, | ||
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE, | ||
.val_handle = &gatt_svr_chr_val_handle, | ||
.descriptors = (struct ble_gatt_dsc_def[]) { | ||
{ | ||
.uuid = &gatt_svr_dsc_uuid.u, | ||
.att_flags = BLE_ATT_F_READ, | ||
.access_cb = gatt_svc_access, | ||
}, { | ||
0, /* No more descriptors in this characteristic */ | ||
} | ||
}, | ||
}, { | ||
0, /* No more characteristics in this service. */ | ||
} | ||
}, | ||
}, | ||
|
||
{ | ||
0, /* No more services. */ | ||
}, | ||
}; | ||
|
||
/** | ||
* Access callback whenever a characteristic/descriptor is read or written to. | ||
* Here reads and writes need to be handled. | ||
* ctxt->op tells weather the operation is read or write and | ||
* weather it is on a characteristic or descriptor, | ||
* ctxt->dsc->uuid tells which characteristic/descriptor is accessed. | ||
* attr_handle give the value handle of the attribute being accessed. | ||
* Accordingly do: | ||
* Append the value to ctxt->om if the operation is READ | ||
* Write ctxt->om to the value if the operation is WRITE | ||
**/ | ||
static int | ||
gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle, | ||
struct ble_gatt_access_ctxt *ctxt, void *arg) | ||
{ | ||
switch (ctxt->op) { | ||
case BLE_GATT_ACCESS_OP_READ_CHR: | ||
MODLOG_DFLT(INFO, "Characteristic read; conn_handle=%d attr_handle=%d\n", | ||
conn_handle, attr_handle); | ||
return 0; | ||
|
||
case BLE_GATT_ACCESS_OP_WRITE_CHR: | ||
MODLOG_DFLT(INFO, "Characteristic write; conn_handle=%d attr_handle=%d", | ||
conn_handle, attr_handle); | ||
return 0; | ||
|
||
case BLE_GATT_ACCESS_OP_READ_DSC: | ||
MODLOG_DFLT(INFO, "Descriptor read; conn_handle=%d attr_handle=%d\n", | ||
conn_handle, attr_handle); | ||
return 0; | ||
|
||
case BLE_GATT_ACCESS_OP_WRITE_DSC: | ||
goto unknown; | ||
|
||
default: | ||
goto unknown; | ||
} | ||
|
||
unknown: | ||
/* Unknown characteristic/descriptor; | ||
* The NimBLE host should not have called this function; | ||
*/ | ||
assert(0); | ||
return BLE_ATT_ERR_UNLIKELY; | ||
} | ||
|
||
void | ||
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) | ||
{ | ||
char buf[BLE_UUID_STR_LEN]; | ||
|
||
switch (ctxt->op) { | ||
case BLE_GATT_REGISTER_OP_SVC: | ||
MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n", | ||
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), | ||
ctxt->svc.handle); | ||
break; | ||
|
||
case BLE_GATT_REGISTER_OP_CHR: | ||
MODLOG_DFLT(DEBUG, "registering characteristic %s with " | ||
"def_handle=%d val_handle=%d\n", | ||
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), | ||
ctxt->chr.def_handle, | ||
ctxt->chr.val_handle); | ||
break; | ||
|
||
case BLE_GATT_REGISTER_OP_DSC: | ||
MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n", | ||
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), | ||
ctxt->dsc.handle); | ||
break; | ||
|
||
default: | ||
assert(0); | ||
break; | ||
} | ||
} | ||
|
||
int | ||
gatt_svr_init(void) | ||
{ | ||
int rc; | ||
|
||
ble_svc_gap_init(); | ||
ble_svc_gatt_init(); | ||
|
||
rc = ble_gatts_count_cfg(gatt_svr_svcs); | ||
if (rc != 0) { | ||
return rc; | ||
} | ||
|
||
rc = ble_gatts_add_svcs(gatt_svr_svcs); | ||
if (rc != 0) { | ||
return rc; | ||
} | ||
|
||
/* Setting a value for the read-only descriptor */ | ||
gatt_svr_dsc_val = 0x99; | ||
|
||
return 0; | ||
} |
Oops, something went wrong.