Update bt fork to be based on v5.3

This commit is contained in:
jacqueline
2024-08-13 06:02:54 +00:00
committed by cooljqln
parent be9725c1c7
commit 5a02f34ed9
508 changed files with 42429 additions and 5168 deletions
+43 -9
View File
@@ -201,7 +201,7 @@ config BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION
help
Enable encryption connection
config BT_NIMBLE_SM_SC_LVL
config BT_NIMBLE_SM_LVL
int "Security level"
depends on BT_NIMBLE_SECURITY_ENABLE
default 0
@@ -341,6 +341,13 @@ menu "Memory Settings"
low-priority event buffers, then an incoming advertising report will
get dropped
config BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT
int "L2cap coc Service Data Unit Buffer count"
depends on BT_NIMBLE_ENABLED
default 1
help
This is the service data unit buffer count for l2cap coc.
endmenu
config BT_NIMBLE_GATT_MAX_PROCS
@@ -388,8 +395,7 @@ config BT_NIMBLE_RPA_TIMEOUT
depends on BT_NIMBLE_ENABLED
default 900
help
Time interval between RPA address change. This is applicable in case of
Host based RPA
Time interval between RPA address change.
menuconfig BT_NIMBLE_MESH
bool "Enable BLE mesh functionality"
@@ -492,7 +498,6 @@ config BT_NIMBLE_CRYPTO_STACK_MBEDTLS
bool "Override TinyCrypt with mbedTLS for crypto computations"
default y
depends on BT_NIMBLE_ENABLED
select MBEDTLS_ECP_RESTARTABLE
select MBEDTLS_CMAC_C
help
Enable this option to choose mbedTLS instead of TinyCrypt for crypto
@@ -523,7 +528,7 @@ config BT_NIMBLE_ENABLE_CONN_REATTEMPT
config BT_NIMBLE_MAX_CONN_REATTEMPT
int "Maximum number connection reattempts"
range 1 7
range 1 255
default 3
depends on BT_NIMBLE_ENABLED && BT_NIMBLE_ENABLE_CONN_REATTEMPT
help
@@ -591,7 +596,7 @@ if BT_NIMBLE_EXT_ADV
Enable this option to start periodic advertisement.
config BT_NIMBLE_PERIODIC_ADV_SYNC_TRANSFER
bool "Enable Transer Sync Events"
bool "Enable Transfer Sync Events"
depends on BT_NIMBLE_ENABLE_PERIODIC_ADV
default y
help
@@ -634,8 +639,9 @@ config BT_NIMBLE_PERIODIC_ADV_ENH
menuconfig BT_NIMBLE_GATT_CACHING
bool "Enable GATT caching"
depends on BT_NIMBLE_ENABLED && BT_NIMBLE_50_FEATURE_SUPPORT
select BT_NIMBLE_DYNAMIC_SERVICE
help
Enable GATT caching
Enable GATT caching
config BT_NIMBLE_GATT_CACHING_MAX_CONNS
int "Maximum connections to be cached"
depends on BT_NIMBLE_GATT_CACHING
@@ -659,7 +665,7 @@ config BT_NIMBLE_GATT_CACHING_MAX_DSCS
depends on BT_NIMBLE_GATT_CACHING
default 64
help
Set this option to set the upper limit on number of discriptors per connection to be cached.
Set this option to set the upper limit on number of descriptors per connection to be cached.
config BT_NIMBLE_WHITELIST_SIZE
int "BLE white list size"
@@ -900,7 +906,6 @@ config BT_NIMBLE_OPTIMIZE_MULTI_CONN
config BT_NIMBLE_ENC_ADV_DATA
bool "Encrypted Advertising Data"
depends on SOC_ESP_NIMBLE_CONTROLLER
select BT_NIMBLE_EXT_ADV
help
This option is used to enable encrypted advertising data.
@@ -942,9 +947,35 @@ menu "Host-controller Transport"
help
Uart port
choice BT_NIMBLE_HCI_USE_UART_BAUDRATE
prompt "Uart Hci Baud Rate"
default UART_BAUDRATE_921600
depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART
help
Uart Baud Rate
config UART_BAUDRATE_115200
bool "115200"
config UART_BAUDRATE_230400
bool "230400"
config UART_BAUDRATE_460800
bool "460800"
config UART_BAUDRATE_921600
bool "921600"
endchoice
config BT_NIMBLE_HCI_UART_BAUDRATE
depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART
int
default 115200 if UART_BAUDRATE_115200
default 230400 if UART_BAUDRATE_230400
default 460800 if UART_BAUDRATE_460800
default 921600 if UART_BAUDRATE_921600
choice BT_NIMBLE_USE_HCI_UART_PARITY
prompt "Uart PARITY"
default UART_PARITY_NONE
depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART
help
Uart Parity
@@ -960,16 +991,19 @@ menu "Host-controller Transport"
int
default 0 if !UART_PARITY_NONE
default 1 if UART_PARITY_NONE
depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART
config BT_NIMBLE_TRANSPORT_UART_PARITY_ODD
int
default 0 if !UART_PARITY_ODD
default 1 if UART_PARITY_ODD
depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART
config BT_NIMBLE_TRANSPORT_UART_PARITY_EVEN
int
default 0 if !UART_PARITY_EVEN
default 1 if UART_PARITY_EVEN
depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART
config BT_NIMBLE_UART_RX_PIN
int "UART Rx pin"
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -170,7 +170,6 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
OS_EXIT_CRITICAL(sr);
}
/*
* @brief: BT controller callback function, used to notify the upper layer that
* controller is ready to receive command
+12
View File
@@ -1,8 +1,20 @@
Brian Giori <briangiori@gmail.com> <bgiori@users.noreply.github.com>
Christopher Collins <ccollins@apache.org> <ccollins476ad@gmail.com>
Christopher Collins <ccollins@apache.org> <ccollins@iori.nightmare-heaven.no-ip.biz>
Jakub Rotkiewicz <jakub.rotkiewicz@codecoup.pl> <jakub.rotkiewicz@codecoup.pl>
Jakub Rotkiewicz <jakub.rotkiewicz@codecoup.pl> <rotkiewicz.jakub@gmail.com>
Magdalena Kasenberg <magdalena.kasenberg@codecoup.pl> <magdalena.kasenberg@codecoup.pl>
Magdalena Kasenberg <magdalena.kasenberg@codecoup.pl> <–magdalena.kasenberg@codecoup.pl>
Marko Kiiskila <marko@apache.org> <marko@runtime.io>
Michał Narajowski <michal.narajowski@codecoup.pl> <michal.narajowski@codecoup.pl>
Sterling Hughes <sterling@apache.org> <sterling@runtime.io>
Sterling Hughes <sterling@apache.org> <sterlinghughes@users.noreply.github.com>
Szymon Czapracki <szymon.czapracki@codecoup.pl> <szymonczapracki@gmail.com>
Szymon Janc <szymon.janc@codecoup.pl> <szymon.janc@gmail.com>
Vipul Rahane <vipulrahane@apache.org> <vipul@runtime.io>
Vipul Rahane <vipulrahane@apache.org> <vrahane@gmail.com>
Vipul Rahane <vipulrahane@apache.org> <vipul@proxy.com>
Will San Filippo <william.sanfilippo@juul.com> <william.sanfilippo@juul.com>
Will San Filippo <william.sanfilippo@juul.com> <will@micosa.io>
Will San Filippo <william.sanfilippo@juul.com> <wills@runtime.io>
+5 -7
View File
@@ -17,21 +17,19 @@ pts-sm.txt
uncrustify.cfg
.style_ignored_dirs
.mailmap
requirements.txt
# tinycrypt - BSD License.
tinycrypt
# Bluetooth Mesh - Apache 2.0 License
mesh
# Queue implementation - BSD License
queue.h
# mbuf implementation - BSD License
os_mbuf.c
# Bluetooth Mesh badge sample - Apache 2.0 License
mesh_badge
# Nordic nRF5 SDK - BSD License
system_nrf52.c
#BabbleSim and EDDT - Apache 2.0 License
babblesim
# CMSIS-CORE - BSD License.
cmsis_nvic.h
+10
View File
@@ -215,3 +215,13 @@ under the following license:
This product bundles tinycrypt, which is available under the "3-clause BSD"
license. For details, and bundled files see:
* ext/tinycrypt/LICENSE
This product bundles and partly derives from parts of the Nordic nRF52 SDK,
which are available under a BSD style license. Relevant files are:
* babblesim/hw/mcu/nordic/nrf52_bsim/src/system_nrf52.c
This product bundles additional files from CMSIS-CORE, but these files are
missing licensing information. The BSD license was subsequently added to
these files in later releases. These files are:
* babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cmsis_nvic.h
+29 -5
View File
@@ -25,7 +25,21 @@
## Overview
Apache NimBLE is an open-source Bluetooth 5.1 stack (both Host & Controller)
<a href="https://github.com/apache/mynewt-nimble/actions/workflows/build_targets.yml">
<img src="https://github.com/apache/mynewt-nimble/actions/workflows/build_targets.yml/badge.svg">
<a/>
<a href="https://github.com/apache/mynewt-nimble/actions/workflows/build_ports.yml">
<img src="https://github.com/apache/mynewt-nimble/actions/workflows/build_ports.yml/badge.svg">
<a/>
<a href="https://github.com/apache/mynewt-nimble/actions/workflows/newt_test_all.yml/badge.svg">
<img src="https://github.com/apache/mynewt-nimble/actions/workflows/newt_test_all.yml/badge.svg">
<a/>
<p>
Apache NimBLE is an open-source Bluetooth 5.4 stack (both Host & Controller)
that completely replaces the proprietary SoftDevice on Nordic chipsets. It is
part of [Apache Mynewt project](https://github.com/apache/mynewt-core).
@@ -41,9 +55,9 @@ Feature highlight:
## Supported hardware
Controller supports Nordic nRF51 and nRF52 chipsets. Host runs on any board
and architecture [supported](https://github.com/apache/mynewt-core#overview)
by Apache Mynewt OS.
Controller supports Nordic nRF51, nRF52 and nRF5340 chipsets as well as DA1469x (cmac)
from Renesas. Host runs on any board and architecture
[supported](https://github.com/apache/mynewt-core#overview) by Apache Mynewt OS.
## Browsing
@@ -105,6 +119,16 @@ Implements a simple BLE peripheral that supports the Nordic
UART / Serial Port Emulation service
(https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v8.x.x/doc/8.0.0/s110/html/a00072.html).
## External projects using NimBLE
Several other projects provide support for using NimBLE either by [NPL port](https://github.com/apache/mynewt-nimble/tree/master/porting) or forking:
* [The Espressif ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/nimble/index.html) contains a NimBLE port for ESP-32 devices.
* [The RIOT](https://doc.riot-os.org/group__pkg__nimble.html) operating system contains a package for using NimBLE.
* [The Open IOT SDK](https://gitlab.arm.com/iot/open-iot-sdk/sdk) contains a NimBLE [port](https://gitlab.arm.com/iot/open-iot-sdk/sdk/-/tree/main/components/bluetooth) based on [CMSIS RTOSv2](https://www.keil.com/pack/doc/CMSIS/RTOS2/html/index.html), which is an RTOS interface implemented by either Amazon Freertos, CMSIS RTX or Azure ThreadX.
If you publish a NimBLE port, please let us know to include it here!
# Getting Help
If you are having trouble using or contributing to Apache Mynewt NimBLE, or just
@@ -114,7 +138,7 @@ want to talk to a human about what you're working on, you can contact us via the
Although not a formal channel, you can also find a number of core developers
on the #mynewt channel on Freenode IRC or #general channel on [Mynewt Slack](https://mynewt.slack.com/join/shared_invite/enQtNjA1MTg0NzgyNzg3LTcyMmZiOGQzOGMxM2U4ODFmMTIwNjNmYTE5Y2UwYjQwZWIxNTE0MTUzY2JmMTEzOWFjYWZkNGM0YmM4MzAxNWQ)
Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/faq/answers)
Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/latest/mynewt_faq)
for some help troubleshooting first.
# Contributing
+7 -11
View File
@@ -1,24 +1,20 @@
# RELEASE NOTES
20 April 2022 - Apache NimBLE v1.5.0
09 August 2023 - Apache NimBLE v1.6.0
For full release notes, please visit the
[Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes).
Apache NimBLE is an open-source Bluetooth 5.3 stack (both Host & Controller) that completely
Apache NimBLE is an open-source Bluetooth 5.4 stack (both Host & Controller) that completely
replaces the proprietary SoftDevice on Nordic chipsets.
New features in this version of NimBLE include:
* Fake dual-mode option for controller
* LLCP tracing via HCI events
* Code size optimization for disabled GAP roles
* Support for PA/LNA
* LE Secure Connections Only mode
* Support for Bluetooth Core Specification 5.3
* Connection subrating
* BabbleSim support
* Various bugfixes and improvements
* Initial support for ISO broacaster
* Support for Bluetooth Core Specification 5.4
* FEM antenna control
* nRF PHY driver unification
* IPC HCI transport improvements
If working on next-generation RTOS and Bluetooth protocol stack
sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt
@@ -24,9 +24,9 @@ pkg.author: "Krzysztof Kopyściński <krzysztof.kopyscinski@codecoup.pl>"
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-nimble/nimble/host/util"
@@ -17,6 +17,10 @@
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
BLE_ROLE_BROADCASTER: 1
BLE_ROLE_CENTRAL: 0
BLE_ROLE_OBSERVER: 0
@@ -24,10 +24,10 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- nimble/host
- nimble/host/util
- nimble/host/services/gap
@@ -272,7 +272,7 @@ blecent_should_connect(const struct ble_gap_disc_desc *disc)
rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data);
if (rc != 0) {
return rc;
return 0;
}
/* The device has to advertise support for the Alert Notification
@@ -17,6 +17,10 @@
#
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# DEBUG logging is a bit noisy; use INFO.
LOG_LEVEL: 1
@@ -26,10 +26,10 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/sysinit"
- "@apache-mynewt-core/sys/id"
- nimble/host
@@ -17,6 +17,10 @@
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Disable central and observer roles.
BLE_ROLE_BROADCASTER: 1
BLE_ROLE_CENTRAL: 0
@@ -24,8 +24,8 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log/stub"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/kernel/os"
- nimble/transport
@@ -20,7 +20,9 @@ syscfg.vals:
# Default task settings
OS_MAIN_STACK_SIZE: 64
# Stub console
CONSOLE_MODE: stub
CONSOLE_IMPLEMENTATION: stub
LOG_IMPLEMENTATION: stub
STATS_IMPLEMENTATION: full
syscfg.vals.'!BLE_TRANSPORT_NETCORE':
# Use UART by default if not built on netcore
+3 -3
View File
@@ -26,10 +26,10 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/sysinit"
- "@apache-mynewt-core/sys/id"
- nimble/host
@@ -111,7 +111,7 @@ blehr_tx_hrate_stop(void)
os_callout_stop(&blehr_tx_timer);
}
/* Reset heartrate measurment */
/* Reset heartrate measurement */
static void
blehr_tx_hrate_reset(void)
{
@@ -193,9 +193,6 @@ blehr_gap_event(struct ble_gap_event *event, void *arg)
if (event->subscribe.attr_handle == hrs_hrm_handle) {
notify_state = event->subscribe.cur_notify;
blehr_tx_hrate_reset();
} else if (event->subscribe.attr_handle != hrs_hrm_handle) {
notify_state = event->subscribe.cur_notify;
blehr_tx_hrate_stop();
}
break;
@@ -17,6 +17,10 @@
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Disable central and observer roles.
BLE_ROLE_BROADCASTER: 1
BLE_ROLE_CENTRAL: 0
@@ -24,10 +24,10 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/shell"
- nimble/host
- nimble/host/services/gap
@@ -17,6 +17,10 @@
#
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Enable the shell task.
SHELL_TASK: 1
@@ -24,10 +24,10 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/shell"
- nimble/host
- nimble/host/services/gap
@@ -21,6 +21,10 @@ syscfg.defs:
value: 0
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Enable the shell task.
SHELL_TASK: 1
@@ -24,9 +24,9 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- nimble/host
- nimble/host/services/gap
- nimble/host/services/gatt
@@ -17,6 +17,10 @@
#
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Set log level to info (disable debug logging).
LOG_LEVEL: 1
@@ -24,9 +24,9 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/encoding/base64"
- "@apache-mynewt-core/sys/config"
- nimble/host
@@ -17,6 +17,10 @@
#
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Set log level to info (disable debug logging).
LOG_LEVEL: 1
@@ -24,10 +24,10 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/shell"
- nimble/host
- nimble/host/services/gap
@@ -17,6 +17,10 @@
#
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Enable the shell task.
SHELL_TASK: 1
@@ -29,10 +29,10 @@ pkg.deps:
- "@apache-mynewt-core/mgmt/imgmgr"
- "@apache-mynewt-core/mgmt/smp"
- "@apache-mynewt-core/mgmt/smp/transport/ble"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/sysinit"
- "@apache-mynewt-core/sys/id"
- nimble/host
@@ -38,6 +38,10 @@ syscfg.defs:
value: "(int[]){ LED_1, LED_2, LED_3 }"
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Disable central and observer roles.
BLE_ROLE_BROADCASTER: 1
BLE_ROLE_CENTRAL: 0
@@ -26,9 +26,9 @@ pkg.deps:
- "@mcuboot/boot/bootutil"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/id"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-nimble/nimble/host/util"
@@ -24,7 +24,7 @@
#include <string.h>
#include <console/console.h>
#include <errno.h>
#include <nrfx/hal/nrf_aar.h>
#include <hal/nrf_aar.h>
/* BLE */
#include "nimble/ble.h"
@@ -167,11 +167,13 @@ stress_l2cap_coc_accept(uint16_t peer_mtu, struct ble_l2cap_chan *chan)
console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n",
(uint32_t) chan, peer_mtu);
sdu_rx = os_msys_get_pkthdr(STRESS_COC_MTU, 0);
assert(sdu_rx != NULL);
for (int i = 0; i < MYNEWT_VAL(BLE_L2CAP_COC_SDU_BUFF_COUNT); i++) {
sdu_rx = os_msys_get_pkthdr(STRESS_COC_MTU, 0);
assert(sdu_rx != NULL);
rc = ble_l2cap_recv_ready(chan, sdu_rx);
assert(rc == 0);
rc = ble_l2cap_recv_ready(chan, sdu_rx);
assert(rc == 0);
}
}
void
@@ -35,6 +35,10 @@ syscfg.defs:
# Settings this app overrides.
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Change these settings:
# Set 0 to print all debug logs, but keep in mind that plenty of
@@ -67,6 +71,9 @@ syscfg.vals:
#
BLE_L2CAP_COC_MAX_NUM: 2
# L2CAP COC SDU buffers in RX endpoint
BLE_L2CAP_COC_SDU_BUFF_COUNT: 1
# Enable 2M PHY
BLE_LL_CFG_FEAT_LE_2M_PHY: 1
@@ -24,10 +24,10 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/shell"
- nimble/host
- nimble/host/services/gap
@@ -184,7 +184,7 @@ int btshell_l2cap_reconfig(uint16_t conn_handle, uint16_t mtu,
int btshell_gap_event(struct ble_gap_event *event, void *arg);
void btshell_sync_stats(uint16_t handle);
uint8_t btshell_get_default_own_addr_type(void);
/** GATT server. */
#define GATT_SVR_SVC_ALERT_UUID 0x1811
#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47
@@ -260,7 +260,7 @@ cmd_advertise_configure(int argc, char **argv)
params.own_addr_type = parse_arg_kv_dflt("own_addr_type",
cmd_own_addr_types,
BLE_OWN_ADDR_PUBLIC, &rc);
btshell_get_default_own_addr_type(), &rc);
if (rc != 0) {
console_printf("invalid 'own_addr_type' parameter\n");
return rc;
@@ -473,7 +473,7 @@ static const struct shell_param advertise_configure_params[] = {
{"directed", "directed advertising, usage: =[0-1], default: 0"},
{"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
{"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
{"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"},
{"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public if available, otherwise random"},
{"channel_map", "usage: =[0x00-0xff], default: 0"},
{"filter", "usage: =[none|scan|conn|both], default: none"},
{"interval_min", "usage: =[0-UINT32_MAX], default: 0"},
@@ -615,7 +615,7 @@ cmd_advertise(int argc, char **argv)
}
own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types,
BLE_OWN_ADDR_PUBLIC, &rc);
btshell_get_default_own_addr_type(), &rc);
if (rc != 0) {
console_printf("invalid 'own_addr_type' parameter\n");
return rc;
@@ -676,7 +676,7 @@ static const struct shell_param advertise_params[] = {
{"discov", "discoverable mode, usage: =[non|ltd|gen], default: gen"},
{"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
{"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
{"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"},
{"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public if available, otherwise random"},
{"channel_map", "usage: =[0x00-0xff], default: 0"},
{"filter", "usage: =[none|scan|conn|both], default: none"},
{"interval_min", "usage: =[0-UINT16_MAX], default: 0"},
@@ -752,7 +752,7 @@ cmd_connect(int argc, char **argv)
}
own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types,
BLE_OWN_ADDR_PUBLIC, &rc);
btshell_get_default_own_addr_type(), &rc);
if (rc != 0) {
console_printf("invalid 'own_addr_type' parameter\n");
return rc;
@@ -969,7 +969,7 @@ static const struct shell_param connect_params[] = {
{"extended", "usage: =[none|1M|coded|both|all], default: none"},
{"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
{"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
{"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"},
{"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public if available, otherwise random"},
{"duration", "usage: =[1-INT32_MAX], default: 0"},
{"scan_interval", "usage: =[0-UINT16_MAX], default: 0x0010"},
{"scan_window", "usage: =[0-UINT16_MAX], default: 0x0010"},
@@ -1209,7 +1209,7 @@ cmd_scan(int argc, char **argv)
return rc;
}
if (argc > 1 && strcmp(argv[1], "cancel") == 0) {
if (argc > 1 && (strcmp(argv[1], "cancel") == 0 || strcmp(argv[1], "off") == 0)) {
rc = btshell_scan_cancel();
if (rc != 0) {
console_printf("scan cancel fail: %d\n", rc);
@@ -1268,7 +1268,7 @@ cmd_scan(int argc, char **argv)
}
own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types,
BLE_OWN_ADDR_PUBLIC, &rc);
btshell_get_default_own_addr_type(), &rc);
if (rc != 0) {
console_printf("invalid 'own_addr_type' parameter\n");
return rc;
@@ -1353,6 +1353,7 @@ cmd_scan(int argc, char **argv)
#if MYNEWT_VAL(SHELL_CMD_HELP)
static const struct shell_param scan_params[] = {
{"cancel", "cancel scan procedure"},
{"off", "\"cancel\" param substitute"},
{"extended", "usage: =[none|1M|coded|both], default: none"},
{"duration", "usage: =[1-INT32_MAX], default: INT32_MAX"},
{"limited", "usage: =[0-1], default: 0"},
@@ -1361,7 +1362,7 @@ static const struct shell_param scan_params[] = {
{"window", "usage: =[0-UINT16_MAX], default: 0"},
{"filter", "usage: =[no_wl|use_wl|no_wl_inita|use_wl_inita], default: no_wl"},
{"nodups", "usage: =[0-1], default: 0"},
{"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"},
{"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public if available, otherwise random"},
{"extended_duration", "usage: =[0-UINT16_MAX], default: 0"},
{"extended_period", "usage: =[0-UINT16_MAX], default: 0"},
{"longrange_interval", "usage: =[0-UINT16_MAX], default: 0"},
@@ -2257,17 +2258,6 @@ cmd_keystore_parse_keydata(int argc, char **argv, union ble_store_key *out,
return rc;
}
out->sec.ediv = parse_arg_uint16("ediv", &rc);
if (rc != 0) {
console_printf("invalid 'ediv' parameter\n");
return rc;
}
out->sec.rand_num = parse_arg_uint64("rand", &rc);
if (rc != 0) {
console_printf("invalid 'rand' parameter\n");
return rc;
}
return 0;
default:
@@ -2316,8 +2306,6 @@ cmd_keystore_parse_valuedata(int argc, char **argv,
return rc;
}
out->sec.peer_addr = key->sec.peer_addr;
out->sec.ediv = key->sec.ediv;
out->sec.rand_num = key->sec.rand_num;
break;
}
@@ -76,6 +76,8 @@
bssnz_t struct btshell_conn btshell_conns[MYNEWT_VAL(BLE_MAX_CONNECTIONS)];
int btshell_num_conns;
static uint8_t default_own_addr_type;
static os_membuf_t btshell_svc_mem[
OS_MEMPOOL_SIZE(BTSHELL_MAX_SVCS, sizeof(struct btshell_svc))
];
@@ -2131,6 +2133,8 @@ btshell_on_sync(void)
console_printf("Failed to set identity address\n");
}
ble_hs_id_infer_auto(0, &default_own_addr_type);
#if MYNEWT_VAL(BLE_SM_SC)
int rc;
@@ -2220,19 +2224,25 @@ btshell_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
static int
btshell_l2cap_coc_accept(uint16_t conn_handle, uint16_t peer_mtu,
struct ble_l2cap_chan *chan)
struct ble_l2cap_chan *chan)
{
struct os_mbuf *sdu_rx;
int rc;
console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n",
(uint32_t) chan, peer_mtu);
sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
if (!sdu_rx) {
return BLE_HS_ENOMEM;
for (int i = 0; i < MYNEWT_VAL(BLE_L2CAP_COC_SDU_BUFF_COUNT); i++) {
sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
if (!sdu_rx) {
return BLE_HS_ENOMEM;
}
rc = ble_l2cap_recv_ready(chan, sdu_rx);
assert(rc == 0);
}
return ble_l2cap_recv_ready(chan, sdu_rx);
return rc;
}
static void
@@ -2569,6 +2579,12 @@ btshell_init_ext_adv_restart(void)
#endif
}
uint8_t
btshell_get_default_own_addr_type(void)
{
return default_own_addr_type;
}
/**
* main
*
@@ -22,6 +22,10 @@ syscfg.defs:
value: 1
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Enable the shell task.
SHELL_TASK: 1
@@ -41,5 +45,8 @@ syscfg.vals:
# Whether to save data to sys/config, or just keep it in RAM.
BLE_STORE_CONFIG_PERSIST: 0
# L2CAP COC SDU buffers in RX endpoint
BLE_L2CAP_COC_SDU_BUFF_COUNT: 1
syscfg.vals.BLE_MESH:
MSYS_1_BLOCK_COUNT: 16
@@ -26,10 +26,10 @@ pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/shell"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-nimble/nimble/host/util"
@@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* btp.h - Bluetooth tester btp headers */
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "bttester.h"
#include "btp_core.h"
#include "btp_gap.h"
#include "btp_gatt.h"
#include "btp_gattc.h"
#include "btp_l2cap.h"
#include "btp_mesh.h"
#define BTP_MTU MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX)
#define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr))
#define BTP_INDEX_NONE 0xff
#define BTP_INDEX 0x00
#define BTP_SERVICE_ID_CORE 0
#define BTP_SERVICE_ID_GAP 1
#define BTP_SERVICE_ID_GATT 2
#define BTP_SERVICE_ID_L2CAP 3
#define BTP_SERVICE_ID_MESH 4
#define BTP_SERVICE_ID_GATTC 6
#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_GATTC
#define BTP_STATUS_SUCCESS 0x00
#define BTP_STATUS_FAILED 0x01
#define BTP_STATUS_UNKNOWN_CMD 0x02
#define BTP_STATUS_NOT_READY 0x03
/* TODO indicate delay response, should be removed when all commands are
* converted to cmd+status+ev pattern
*/
#define BTP_STATUS_DELAY_REPLY 0xFF
#define SYS_LOG_DBG(fmt, ...) \
if (MYNEWT_VAL(BTTESTER_DEBUG)) { \
console_printf("[DBG] %s: " fmt "\n", \
__func__, ## __VA_ARGS__); \
}
#define SYS_LOG_INF(fmt, ...) console_printf("[INF] %s: " fmt "\n", \
__func__, ## __VA_ARGS__);
#define SYS_LOG_ERR(fmt, ...) console_printf("[WRN] %s: " fmt "\n", \
__func__, ## __VA_ARGS__);
#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define SYS_LOG_DOMAIN "bttester"
struct btp_hdr {
uint8_t service;
uint8_t opcode;
uint8_t index;
uint16_t len;
uint8_t data[0];
} __packed;
#define BTP_STATUS 0x00
struct btp_status {
uint8_t code;
} __packed;
@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* btp_core.h - Bluetooth tester Core service headers */
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Core Service */
#define BTP_CORE_READ_SUPPORTED_COMMANDS 0x01
struct btp_core_read_supported_commands_rp {
uint8_t data[0];
} __packed;
#define BTP_CORE_READ_SUPPORTED_SERVICES 0x02
struct btp_core_read_supported_services_rp {
uint8_t data[0];
} __packed;
#define BTP_CORE_REGISTER_SERVICE 0x03
struct btp_core_register_service_cmd {
uint8_t id;
} __packed;
#define BTP_CORE_UNREGISTER_SERVICE 0x04
struct btp_core_unregister_service_cmd {
uint8_t id;
} __packed;
/* events */
#define BTP_CORE_EV_IUT_READY 0x80
@@ -0,0 +1,344 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* btp_gap.h - Bluetooth tester GAP service headers */
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "nimble/ble.h"
struct adv_data {
uint8_t type;
uint8_t data_len;
const uint8_t *data;
};
#define ADV_DATA(_type, _data, _data_len) \
{ \
.type = (_type), \
.data_len = (_data_len), \
.data = (const uint8_t *)(_data), \
}
/* GAP Service */
/* commands */
#define BTP_GAP_READ_SUPPORTED_COMMANDS 0x01
struct btp_gap_read_supported_commands_rp {
uint8_t data[0];
} __packed;
#define BTP_GAP_READ_CONTROLLER_INDEX_LIST 0x02
struct btp_gap_read_controller_index_list_rp {
uint8_t num;
uint8_t index[0];
} __packed;
#define BTP_GAP_SETTINGS_POWERED 0
#define BTP_GAP_SETTINGS_CONNECTABLE 1
#define BTP_GAP_SETTINGS_FAST_CONNECTABLE 2
#define BTP_GAP_SETTINGS_DISCOVERABLE 3
#define BTP_GAP_SETTINGS_BONDABLE 4
#define BTP_GAP_SETTINGS_LINK_SEC_3 5
#define BTP_GAP_SETTINGS_SSP 6
#define BTP_GAP_SETTINGS_BREDR 7
#define BTP_GAP_SETTINGS_HS 8
#define BTP_GAP_SETTINGS_LE 9
#define BTP_GAP_SETTINGS_ADVERTISING 10
#define BTP_GAP_SETTINGS_SC 11
#define BTP_GAP_SETTINGS_DEBUG_KEYS 12
#define BTP_GAP_SETTINGS_PRIVACY 13
#define BTP_GAP_SETTINGS_CONTROLLER_CONFIG 14
#define BTP_GAP_SETTINGS_STATIC_ADDRESS 15
#define BTP_GAP_READ_CONTROLLER_INFO 0x03
struct btp_gap_read_controller_info_rp {
uint8_t address[6];
uint32_t supported_settings;
uint32_t current_settings;
uint8_t cod[3];
uint8_t name[249];
uint8_t short_name[11];
} __packed;
#define BTP_GAP_RESET 0x04
struct btp_gap_reset_rp {
uint32_t current_settings;
} __packed;
#define BTP_GAP_SET_POWERED 0x05
struct btp_gap_set_powered_cmd {
uint8_t powered;
} __packed;
struct btp_gap_set_powered_rp {
uint32_t current_settings;
} __packed;
#define BTP_GAP_SET_CONNECTABLE 0x06
struct btp_gap_set_connectable_cmd {
uint8_t connectable;
} __packed;
struct btp_gap_set_connectable_rp {
uint32_t current_settings;
} __packed;
#define BTP_GAP_SET_FAST_CONNECTABLE 0x07
struct btp_gap_set_fast_connectable_cmd {
uint8_t fast_connectable;
} __packed;
struct btp_gap_set_fast_connectable_rp {
uint32_t current_settings;
} __packed;
#define BTP_GAP_NON_DISCOVERABLE 0x00
#define BTP_GAP_GENERAL_DISCOVERABLE 0x01
#define BTP_GAP_LIMITED_DISCOVERABLE 0x02
#define BTP_GAP_SET_DISCOVERABLE 0x08
struct btp_gap_set_discoverable_cmd {
uint8_t discoverable;
} __packed;
struct btp_gap_set_discoverable_rp {
uint32_t current_settings;
} __packed;
#define BTP_GAP_SET_BONDABLE 0x09
struct btp_gap_set_bondable_cmd {
uint8_t bondable;
} __packed;
struct btp_gap_set_bondable_rp {
uint32_t current_settings;
} __packed;
#define BTP_GAP_START_ADVERTISING 0x0a
struct btp_gap_start_advertising_cmd {
uint8_t adv_data_len;
uint8_t scan_rsp_len;
uint8_t adv_data[0];
uint8_t scan_rsp[0];
/*
* This command is very unfortunate because it has two fields after variable
* data. Those needs to be handled explicitly by handler.
* uint32_t duration;
* uint8_t own_addr_type;
*/
} __packed;
struct btp_gap_start_advertising_rp {
uint32_t current_settings;
} __packed;
#define BTP_GAP_STOP_ADVERTISING 0x0b
struct btp_gap_stop_advertising_rp {
uint32_t current_settings;
} __packed;
#define BTP_GAP_DISCOVERY_FLAG_LE 0x01
#define BTP_GAP_DISCOVERY_FLAG_BREDR 0x02
#define BTP_GAP_DISCOVERY_FLAG_LIMITED 0x04
#define BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN 0x08
#define BTP_GAP_DISCOVERY_FLAG_LE_OBSERVE 0x10
#define BTP_GAP_START_DISCOVERY 0x0c
struct btp_gap_start_discovery_cmd {
uint8_t flags;
} __packed;
#define BTP_GAP_STOP_DISCOVERY 0x0d
#define BTP_GAP_CONNECT 0x0e
struct btp_gap_connect_cmd {
ble_addr_t address;
uint8_t own_addr_type;
} __packed;
#define BTP_GAP_DISCONNECT 0x0f
struct btp_gap_disconnect_cmd {
ble_addr_t address;
} __packed;
#define BTP_GAP_IO_CAP_DISPLAY_ONLY 0
#define BTP_GAP_IO_CAP_DISPLAY_YESNO 1
#define BTP_GAP_IO_CAP_KEYBOARD_ONLY 2
#define BTP_GAP_IO_CAP_NO_INPUT_OUTPUT 3
#define BTP_GAP_IO_CAP_KEYBOARD_DISPLAY 4
#define BTP_GAP_SET_IO_CAP 0x10
struct btp_gap_set_io_cap_cmd {
uint8_t io_cap;
} __packed;
#define BTP_GAP_PAIR 0x11
struct btp_gap_pair_cmd {
ble_addr_t address;
} __packed;
#define BTP_GAP_UNPAIR 0x12
struct btp_gap_unpair_cmd {
ble_addr_t address;
} __packed;
#define BTP_GAP_PASSKEY_ENTRY 0x13
struct btp_gap_passkey_entry_cmd {
ble_addr_t address;
uint32_t passkey;
} __packed;
#define BTP_GAP_PASSKEY_CONFIRM 0x14
struct btp_gap_passkey_confirm_cmd {
ble_addr_t address;
uint8_t match;
} __packed;
#define BTP_GAP_START_DIRECT_ADV 0x15
struct btp_gap_start_direct_adv_cmd {
ble_addr_t address;
uint16_t options;
} __packed;
#define BTP_GAP_CONN_PARAM_UPDATE 0x16
struct btp_gap_conn_param_update_cmd {
ble_addr_t address;
uint16_t conn_itvl_min;
uint16_t conn_itvl_max;
uint16_t conn_latency;
uint16_t supervision_timeout;
} __packed;
#define BTP_GAP_PAIRING_CONSENT_RSP 0x17
struct btp_gap_pairing_consent_rsp_cmd {
ble_addr_t address;
uint8_t consent;
} __packed;
#define BTP_GAP_OOB_LEGACY_SET_DATA 0x18
struct btp_gap_oob_legacy_set_data_cmd {
uint8_t oob_data[16];
} __packed;
#define BTP_GAP_OOB_SC_GET_LOCAL_DATA 0x19
struct btp_gap_oob_sc_get_local_data_rp {
uint8_t r[16];
uint8_t c[16];
} __packed;
#define BTP_GAP_OOB_SC_SET_REMOTE_DATA 0x1a
struct btp_gap_oob_sc_set_remote_data_cmd {
uint8_t r[16];
uint8_t c[16];
} __packed;
#define BTP_GAP_SET_MITM 0x1b
struct btp_gap_set_mitm_cmd {
uint8_t mitm;
} __packed;
#define BTP_GAP_SET_FILTER_ACCEPT_LIST 0x1c
struct btp_gap_set_filter_accept_list_cmd {
uint8_t list_len;
ble_addr_t addrs[];
} __packed;
/* events */
#define BTP_GAP_EV_NEW_SETTINGS 0x80
struct btp_gap_new_settings_ev {
uint32_t current_settings;
} __packed;
#define BTP_GAP_DEVICE_FOUND_FLAG_RSSI 0x01
#define BTP_GAP_DEVICE_FOUND_FLAG_AD 0x02
#define BTP_GAP_DEVICE_FOUND_FLAG_SD 0x04
#define BTP_GAP_EV_DEVICE_FOUND 0x81
struct btp_gap_device_found_ev {
ble_addr_t address;
int8_t rssi;
uint8_t flags;
uint16_t eir_data_len;
uint8_t eir_data[0];
} __packed;
#define BTP_GAP_EV_DEVICE_CONNECTED 0x82
struct btp_gap_device_connected_ev {
ble_addr_t address;
uint16_t conn_itvl;
uint16_t conn_latency;
uint16_t supervision_timeout;
} __packed;
#define BTP_GAP_EV_DEVICE_DISCONNECTED 0x83
struct btp_gap_device_disconnected_ev {
ble_addr_t address;
} __packed;
#define BTP_GAP_EV_PASSKEY_DISPLAY 0x84
struct btp_gap_passkey_display_ev {
ble_addr_t address;
uint32_t passkey;
} __packed;
#define BTP_GAP_EV_PASSKEY_ENTRY_REQ 0x85
struct btp_gap_passkey_entry_req_ev {
ble_addr_t address;
} __packed;
#define BTP_GAP_EV_PASSKEY_CONFIRM_REQ 0x86
struct btp_gap_passkey_confirm_req_ev {
ble_addr_t address;
uint32_t passkey;
} __packed;
#define BTP_GAP_EV_IDENTITY_RESOLVED 0x87
struct btp_gap_identity_resolved_ev {
ble_addr_t address;
uint8_t identity_address_type;
uint8_t identity_address;
} __packed;
#define BTP_GAP_EV_CONN_PARAM_UPDATE 0x88
struct btp_gap_conn_param_update_ev {
ble_addr_t address;
uint16_t conn_itvl;
uint16_t conn_latency;
uint16_t supervision_timeout;
} __packed;
#define BTP_GAP_EV_SEC_LEVEL_CHANGED 0x89
struct btp_gap_sec_level_changed_ev {
ble_addr_t address;
uint8_t level;
} __packed;
#define BTP_GAP_EV_PAIRING_CONSENT_REQ 0x8a
struct btp_gap_pairing_consent_req_ev {
ble_addr_t address;
} __packed;
#define BTP_GAP_EV_BOND_LOST 0x8b
struct btp_gap_bond_lost_ev {
ble_addr_t address;
} __packed;
#define BTP_GAP_EV_SEC_PAIRING_FAILED 0x8c
struct btp_gap_sec_pairing_failed_ev {
ble_addr_t address;
uint8_t reason;
} __packed;
@@ -0,0 +1,332 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* btp_gatt.h - Bluetooth tester GATT service headers */
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
/* GATT Service */
/* commands */
#define BTP_GATT_READ_SUPPORTED_COMMANDS 0x01
struct btp_gatt_read_supported_commands_rp {
uint8_t data[0];
} __packed;
#define BTP_GATT_SERVICE_PRIMARY 0x00
#define BTP_GATT_SERVICE_SECONDARY 0x01
#define BTP_GATT_ADD_SERVICE 0x02
struct btp_gatt_add_service_cmd {
uint8_t type;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
struct btp_gatt_add_service_rp {
uint16_t svc_id;
} __packed;
#define BTP_GATT_ADD_CHARACTERISTIC 0x03
struct btp_gatt_add_characteristic_cmd {
uint16_t svc_id;
uint8_t properties;
uint8_t permissions;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
struct btp_gatt_add_characteristic_rp {
uint16_t char_id;
} __packed;
#define BTP_GATT_ADD_DESCRIPTOR 0x04
struct btp_gatt_add_descriptor_cmd {
uint16_t char_id;
uint8_t permissions;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
struct btp_gatt_add_descriptor_rp {
uint16_t desc_id;
} __packed;
#define BTP_GATT_ADD_INCLUDED_SERVICE 0x05
struct btp_gatt_add_included_service_cmd {
uint16_t svc_id;
} __packed;
struct btp_gatt_add_included_service_rp {
uint16_t included_service_id;
} __packed;
#define BTP_GATT_SET_VALUE 0x06
struct btp_gatt_set_value_cmd {
uint16_t attr_id;
uint16_t len;
uint8_t value[0];
} __packed;
#define BTP_GATT_START_SERVER 0x07
struct btp_gatt_start_server_rp {
uint16_t db_attr_off;
uint8_t db_attr_cnt;
} __packed;
#define BTP_GATT_SET_ENC_KEY_SIZE 0x09
struct btp_gatt_set_enc_key_size_cmd {
uint16_t attr_id;
uint8_t key_size;
} __packed;
struct btp_gatt_service {
uint16_t start_handle;
uint16_t end_handle;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
struct btp_gatt_included {
uint16_t included_handle;
struct btp_gatt_service service;
} __packed;
struct btp_gatt_read_uuid_chr {
uint16_t handle;
uint8_t data[0];
} __packed;
struct btp_gatt_characteristic {
uint16_t characteristic_handle;
uint16_t value_handle;
uint8_t properties;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
struct btp_gatt_descriptor {
uint16_t descriptor_handle;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
#define BTP_GATT_EXCHANGE_MTU 0x0a
struct btp_gatt_exchange_mtu_cmd {
ble_addr_t address;
} __packed;
#define BTP_GATT_DISC_ALL_PRIM_SVCS 0x0b
struct btp_gatt_disc_all_prim_svcs_cmd {
ble_addr_t address;
} __packed;
struct btp_gatt_disc_all_prim_svcs_rp {
uint8_t services_count;
struct btp_gatt_service services[0];
} __packed;
#define BTP_GATT_DISC_PRIM_UUID 0x0c
struct btp_gatt_disc_prim_uuid_cmd {
ble_addr_t address;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
struct btp_gatt_disc_prim_uuid_rp {
uint8_t services_count;
struct btp_gatt_service services[0];
} __packed;
#define BTP_GATT_FIND_INCLUDED 0x0d
struct btp_gatt_find_included_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
} __packed;
struct btp_gatt_find_included_rp {
uint8_t services_count;
struct btp_gatt_included included[0];
} __packed;
#define BTP_GATT_DISC_ALL_CHRC 0x0e
struct btp_gatt_disc_all_chrc_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
} __packed;
struct btp_gatt_disc_chrc_rp {
uint8_t characteristics_count;
struct btp_gatt_characteristic characteristics[0];
} __packed;
#define BTP_GATT_DISC_CHRC_UUID 0x0f
struct btp_gatt_disc_chrc_uuid_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
#define BTP_GATT_DISC_ALL_DESC 0x10
struct btp_gatt_disc_all_desc_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
} __packed;
struct btp_gatt_disc_all_desc_rp {
uint8_t descriptors_count;
struct btp_gatt_descriptor descriptors[0];
} __packed;
#define BTP_GATT_READ 0x11
struct btp_gatt_read_cmd {
ble_addr_t address;
uint16_t handle;
} __packed;
struct btp_gatt_read_rp {
uint8_t att_response;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATT_READ_UUID 0x12
struct btp_gatt_read_uuid_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
#define BTP_GATT_READ_LONG 0x13
struct btp_gatt_read_long_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t offset;
} __packed;
#define BTP_GATT_READ_MULTIPLE 0x14
struct btp_gatt_read_multiple_cmd {
ble_addr_t address;
uint8_t handles_count;
uint16_t handles[0];
} __packed;
#define BTP_GATT_WRITE_WITHOUT_RSP 0x15
struct btp_gatt_write_without_rsp_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATT_SIGNED_WRITE_WITHOUT_RSP 0x16
struct btp_gatt_signed_write_without_rsp_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATT_WRITE 0x17
struct btp_gatt_write_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATT_WRITE_LONG 0x18
struct btp_gatt_write_long_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t offset;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATT_RELIABLE_WRITE 0x19
struct btp_gatt_reliable_write_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t offset;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATT_CFG_NOTIFY 0x1a
#define BTP_GATT_CFG_INDICATE 0x1b
struct btp_gatt_cfg_notify_cmd {
ble_addr_t address;
uint8_t enable;
uint16_t ccc_handle;
} __packed;
#define BTP_GATT_GET_ATTRIBUTES 0x1c
struct btp_gatt_get_attributes_cmd {
uint16_t start_handle;
uint16_t end_handle;
uint8_t type_length;
uint8_t type[0];
} __packed;
struct btp_gatt_get_attributes_rp {
uint8_t attrs_count;
uint8_t attrs[0];
} __packed;
struct btp_gatt_attr {
uint16_t handle;
uint8_t permission;
uint8_t type_length;
uint8_t type[0];
} __packed;
#define BTP_GATT_GET_ATTRIBUTE_VALUE 0x1d
struct btp_gatt_get_attribute_value_cmd {
ble_addr_t address;
uint16_t handle;
} __packed;
struct btp_gatt_get_attribute_value_rp {
uint8_t att_response;
uint16_t value_length;
uint8_t value[0];
} __packed;
#define BTP_GATT_CHANGE_DATABASE 0x1e
struct btp_gatt_change_database_cmd {
uint16_t start_handle;
uint16_t end_handle;
uint8_t visibility;
} __packed;
/* GATT events */
#define BTP_GATT_EV_NOTIFICATION 0x80
struct btp_gatt_notification_ev {
ble_addr_t address;
uint8_t type;
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATT_EV_ATTR_VALUE_CHANGED 0x81
struct btp_gatt_attr_value_changed_ev {
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
@@ -0,0 +1,243 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* btp_gattc.h - Bluetooth tester GATT Client service headers */
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
/* GATT Client Service */
/* commands */
#define BTP_GATTC_READ_SUPPORTED_COMMANDS 0x01
struct btp_gattc_read_supported_commands_rp {
uint8_t data[0];
} __packed;
#define BTP_GATTC_EXCHANGE_MTU 0x02
struct btp_gattc_exchange_mtu_cmd {
ble_addr_t address;
} __packed;
#define BTP_GATTC_DISC_ALL_PRIM_SVCS 0x03
struct btp_gattc_disc_all_prim_svcs_cmd {
ble_addr_t address;
} __packed;
#define BTP_GATTC_DISC_PRIM_UUID 0x04
struct btp_gattc_disc_prim_uuid_cmd {
ble_addr_t address;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
#define BTP_GATTC_FIND_INCLUDED 0x05
struct btp_gattc_find_included_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
} __packed;
#define BTP_GATTC_DISC_ALL_CHRC 0x06
struct btp_gattc_disc_all_chrc_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
} __packed;
#define BTP_GATTC_DISC_CHRC_UUID 0x07
struct btp_gattc_disc_chrc_uuid_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
#define BTP_GATTC_DISC_ALL_DESC 0x08
struct btp_gattc_disc_all_desc_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
} __packed;
#define BTP_GATTC_READ 0x09
struct btp_gattc_read_cmd {
ble_addr_t address;
uint16_t handle;
} __packed;
#define BTP_GATTC_READ_UUID 0x0a
struct btp_gattc_read_uuid_cmd {
ble_addr_t address;
uint16_t start_handle;
uint16_t end_handle;
uint8_t uuid_length;
uint8_t uuid[0];
} __packed;
struct btp_gattc_read_uuid_rp {
ble_addr_t address;
uint8_t status;
uint16_t data_length;
uint8_t value_length;
uint8_t data[0];
} __packed;
#define BTP_GATTC_READ_LONG 0x0b
struct btp_gattc_read_long_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t offset;
} __packed;
#define BTP_GATTC_READ_MULTIPLE 0x0c
struct btp_gattc_read_multiple_cmd {
ble_addr_t address;
uint8_t handles_count;
uint16_t handles[0];
} __packed;
#define BTP_GATTC_WRITE_WITHOUT_RSP 0x0d
struct btp_gattc_write_without_rsp_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP 0x0e
struct btp_gattc_signed_write_without_rsp_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATTC_WRITE 0x0f
struct btp_gattc_write_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATTC_WRITE_LONG 0x10
struct btp_gattc_write_long_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t offset;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATTC_RELIABLE_WRITE 0x11
struct btp_gattc_reliable_write_cmd {
ble_addr_t address;
uint16_t handle;
uint16_t offset;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATTC_CFG_NOTIFY 0x12
#define BTP_GATTC_CFG_INDICATE 0x13
struct btp_gattc_cfg_notify_cmd {
ble_addr_t address;
uint8_t enable;
uint16_t ccc_handle;
} __packed;
/* events */
#define BTP_GATTC_EV_MTU_EXCHANGED 0x80
struct btp_gattc_exchange_mtu_ev {
ble_addr_t address;
uint16_t mtu;
} __packed;
#define BTP_GATTC_DISC_ALL_PRIM_RP 0x81
struct btp_gattc_disc_prim_svcs_rp {
ble_addr_t address;
uint8_t status;
uint8_t services_count;
uint8_t data[0];
} __packed;
#define BTP_GATTC_DISC_PRIM_UUID_RP 0x82
#define BTP_GATTC_FIND_INCLUDED_RP 0x83
struct btp_gattc_find_included_rp {
ble_addr_t address;
uint8_t status;
uint8_t services_count;
struct btp_gatt_included included[0];
} __packed;
#define BTP_GATTC_DISC_ALL_CHRC_RP 0x84
#define BTP_GATTC_DISC_CHRC_UUID_RP 0x85
struct btp_gattc_disc_chrc_rp {
ble_addr_t address;
uint8_t status;
uint8_t characteristics_count;
struct btp_gatt_characteristic characteristics[0];
} __packed;
#define BTP_GATTC_DISC_ALL_DESC_RP 0x86
struct btp_gattc_disc_all_desc_rp {
ble_addr_t address;
uint8_t status;
uint8_t descriptors_count;
struct btp_gatt_descriptor descriptors[0];
} __packed;
#define BTP_GATTC_READ_RP 0x87
#define BTP_GATTC_READ_UUID_RP 0x88
#define BTP_GATTC_READ_LONG_RP 0x89
#define BTP_GATTC_READ_MULTIPLE_RP 0x8a
struct btp_gattc_read_rp {
ble_addr_t address;
uint8_t status;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_GATTC_WRITE_RP 0x8b
struct btp_gattc_write_rp {
ble_addr_t address;
uint8_t status;
} __packed;
#define BTP_GATTC_WRITE_LONG_RP 0x8c
#define BTP_GATTC_RELIABLE_WRITE_RP 0x8d
#define BTP_GATTC_CFG_NOTIFY_RP 0x8e
#define BTP_GATTC_CFG_INDICATE_RP 0x8f
struct btp_subscribe_rp {
ble_addr_t address;
uint8_t status;
} __packed;
#define BTP_GATTC_EV_NOTIFICATION_RXED 0x90
struct btp_gattc_notification_ev {
ble_addr_t address;
uint8_t type;
uint16_t handle;
uint16_t data_length;
uint8_t data[0];
} __packed;
@@ -0,0 +1,136 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* btp_l2cap.h - Bluetooth tester L2CAP service headers */
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
/* L2CAP Service */
/* commands */
#define BTP_L2CAP_READ_SUPPORTED_COMMANDS 0x01
struct btp_l2cap_read_supported_commands_rp {
uint8_t data[0];
} __packed;
#define BTP_L2CAP_CONNECT_OPT_ECFC 0x01
#define BTP_L2CAP_CONNECT_OPT_HOLD_CREDIT 0x02
#define BTP_L2CAP_CONNECT 0x02
struct btp_l2cap_connect_cmd {
ble_addr_t address;
uint16_t psm;
uint16_t mtu;
uint8_t num;
uint8_t options;
} __packed;
struct btp_l2cap_connect_rp {
uint8_t num;
uint8_t chan_ids[0];
} __packed;
#define BTP_L2CAP_DISCONNECT 0x03
struct btp_l2cap_disconnect_cmd {
uint8_t chan_id;
} __packed;
#define BTP_L2CAP_SEND_DATA 0x04
struct btp_l2cap_send_data_cmd {
uint8_t chan_id;
uint16_t data_len;
uint8_t data[];
} __packed;
#define BTP_L2CAP_TRANSPORT_BREDR 0x00
#define BTP_L2CAP_TRANSPORT_LE 0x01
#define BTP_L2CAP_LISTEN 0x05
struct btp_l2cap_listen_cmd {
uint16_t psm;
uint8_t transport;
uint16_t mtu;
uint16_t response;
} __packed;
#define BTP_L2CAP_ACCEPT_CONNECTION 0x06
struct l2cap_accept_connection_cmd {
uint8_t chan_id;
uint16_t result;
} __packed;
#define BTP_L2CAP_RECONFIGURE 0x07
struct btp_l2cap_reconfigure_cmd {
ble_addr_t address;
uint16_t mtu;
uint8_t num;
uint8_t idxs[];
} __packed;
#define BTP_L2CAP_CREDITS 0x08
struct btp_l2cap_credits_cmd {
uint8_t chan_id;
} __packed;
/* events */
#define BTP_L2CAP_EV_CONNECTION_REQ 0x80
struct btp_l2cap_connection_req_ev {
uint8_t chan_id;
uint16_t psm;
ble_addr_t address;
} __packed;
#define BTP_L2CAP_EV_CONNECTED 0x81
struct btp_l2cap_connected_ev {
uint8_t chan_id;
uint16_t psm;
uint16_t peer_mtu;
uint16_t peer_mps;
uint16_t our_mtu;
uint16_t our_mps;
ble_addr_t address;
} __packed;
#define BTP_L2CAP_EV_DISCONNECTED 0x82
struct btp_l2cap_disconnected_ev {
uint16_t result;
uint8_t chan_id;
uint16_t psm;
ble_addr_t address;
} __packed;
#define BTP_L2CAP_EV_DATA_RECEIVED 0x83
struct btp_l2cap_data_received_ev {
uint8_t chan_id;
uint16_t data_length;
uint8_t data[0];
} __packed;
#define BTP_L2CAP_EV_RECONFIGURED 0x84
struct btp_l2cap_reconfigured_ev {
uint8_t chan_id;
uint16_t peer_mtu;
uint16_t peer_mps;
uint16_t our_mtu;
uint16_t our_mps;
} __packed;
@@ -0,0 +1,205 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* btp_mesh.h - Bluetooth tester MESH service headers */
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
/* MESH Service */
/* commands */
#define BTP_MESH_READ_SUPPORTED_COMMANDS 0x01
struct btp_mesh_read_supported_commands_rp {
uint8_t data[0];
} __packed;
#define BTP_MESH_OUT_BLINK BIT(0)
#define BTP_MESH_OUT_BEEP BIT(1)
#define BTP_MESH_OUT_VIBRATE BIT(2)
#define BTP_MESH_OUT_DISPLAY_NUMBER BIT(3)
#define BTP_MESH_OUT_DISPLAY_STRING BIT(4)
#define BTP_MESH_IN_PUSH BIT(0)
#define BTP_MESH_IN_TWIST BIT(1)
#define BTP_MESH_IN_ENTER_NUMBER BIT(2)
#define BTP_MESH_IN_ENTER_STRING BIT(3)
#define BTP_MESH_CONFIG_PROVISIONING 0x02
struct btp_mesh_config_provisioning_cmd {
uint8_t uuid[16];
uint8_t static_auth[16];
uint8_t out_size;
uint16_t out_actions;
uint8_t in_size;
uint16_t in_actions;
} __packed;
#define BTP_MESH_PROVISION_NODE 0x03
struct btp_mesh_provision_node_cmd {
uint8_t net_key[16];
uint16_t net_key_idx;
uint8_t flags;
uint32_t iv_index;
uint32_t seq_num;
uint16_t addr;
uint8_t dev_key[16];
} __packed;
#define BTP_MESH_INIT 0x04
#define BTP_MESH_RESET 0x05
#define BTP_MESH_INPUT_NUMBER 0x06
struct btp_mesh_input_number_cmd {
uint32_t number;
} __packed;
#define BTP_MESH_INPUT_STRING 0x07
struct btp_mesh_input_string_cmd {
uint8_t string_len;
uint8_t string[0];
} __packed;
#define BTP_MESH_IVU_TEST_MODE 0x08
struct btp_mesh_ivu_test_mode_cmd {
uint8_t enable;
} __packed;
#define BTP_MESH_IVU_TOGGLE_STATE 0x09
#define BTP_MESH_NET_SEND 0x0a
struct btp_mesh_net_send_cmd {
uint8_t ttl;
uint16_t src;
uint16_t dst;
uint8_t payload_len;
uint8_t payload[0];
} __packed;
#define BTP_MESH_HEALTH_GENERATE_FAULTS 0x0b
struct btp_mesh_health_generate_faults_rp {
uint8_t test_id;
uint8_t cur_faults_count;
uint8_t reg_faults_count;
uint8_t current_faults[0];
uint8_t registered_faults[0];
} __packed;
#define BTP_MESH_HEALTH_CLEAR_FAULTS 0x0c
#define BTP_MESH_LPN 0x0d
struct btp_mesh_lpn_set_cmd {
uint8_t enable;
} __packed;
#define BTP_MESH_LPN_POLL 0x0e
#define BTP_MESH_MODEL_SEND 0x0f
struct btp_mesh_model_send_cmd {
uint16_t src;
uint16_t dst;
uint8_t payload_len;
uint8_t payload[0];
} __packed;
#define BTP_MESH_LPN_SUBSCRIBE 0x10
struct btp_mesh_lpn_subscribe_cmd {
uint16_t address;
} __packed;
#define BTP_MESH_LPN_UNSUBSCRIBE 0x11
struct btp_mesh_lpn_unsubscribe_cmd {
uint16_t address;
} __packed;
#define BTP_MESH_RPL_CLEAR 0x12
#define BTP_MESH_PROXY_IDENTITY 0x13
/* events */
#define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80
struct btp_mesh_out_number_action_ev {
uint16_t action;
uint32_t number;
} __packed;
#define BTP_MESH_EV_OUT_STRING_ACTION 0x81
struct btp_mesh_out_string_action_ev {
uint8_t string_len;
uint8_t string[0];
} __packed;
#define BTP_MESH_EV_IN_ACTION 0x82
struct btp_mesh_in_action_ev {
uint16_t action;
uint8_t size;
} __packed;
#define BTP_MESH_EV_PROVISIONED 0x83
#define BTP_MESH_PROV_BEARER_PB_ADV 0x00
#define BTP_MESH_PROV_BEARER_PB_GATT 0x01
#define BTP_MESH_EV_PROV_LINK_OPEN 0x84
struct btp_mesh_prov_link_open_ev {
uint8_t bearer;
} __packed;
#define BTP_MESH_EV_PROV_LINK_CLOSED 0x85
struct btp_mesh_prov_link_closed_ev {
uint8_t bearer;
} __packed;
#define BTP_MESH_EV_NET_RECV 0x86
struct btp_mesh_net_recv_ev {
uint8_t ttl;
uint8_t ctl;
uint16_t src;
uint16_t dst;
uint8_t payload_len;
uint8_t payload[0];
} __packed;
#define BTP_MESH_EV_INVALID_BEARER 0x87
struct btp_mesh_invalid_bearer_ev {
uint8_t opcode;
} __packed;
#define BTP_MESH_EV_INCOMP_TIMER_EXP 0x88
#define BTP_MESH_EV_LPN_ESTABLISHED 0x8b
struct btp_mesh_lpn_established_ev {
uint16_t net_idx;
uint16_t friend_addr;
uint8_t queue_size;
uint8_t recv_win;
} __packed;
#define BTP_MESH_EV_LPN_TERMINATED 0x8c
struct btp_mesh_lpn_terminated_ev {
uint16_t net_idx;
uint16_t friend_addr;
} __packed;
#define BTP_MESH_EV_LPN_POLLED 0x8d
struct btp_mesh_lpn_polled_ev {
uint16_t net_idx;
uint16_t friend_addr;
uint8_t retry;
} __packed;
@@ -0,0 +1,144 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* bttester.h - Bluetooth tester headers */
/*
* Copyright (c) 2015-2016 Intel Corporation
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BTTESTER_H__
#define __BTTESTER_H__
#include "syscfg/syscfg.h"
#include "host/ble_gatt.h"
#include "os/os_mbuf.h"
#include <sys/types.h>
#define BIT(n) (1UL << (n))
/* Reset os_mbuf to reusable state */
void
tester_mbuf_reset(struct os_mbuf *buf);
const char *
string_from_bytes(const void *buf, size_t len);
static inline void
tester_set_bit(uint8_t *addr, unsigned int bit)
{
uint8_t *p = addr + (bit / 8);
*p |= BIT(bit % 8);
}
static inline uint8_t
tester_test_bit(const uint8_t *addr, unsigned int bit)
{
const uint8_t *p = addr + (bit / 8);
return *p & BIT(bit % 8);
}
static inline void
tester_clear_bit(uint8_t *addr, unsigned int bit)
{
uint8_t *p = addr + (bit / 8);
*p &= ~BIT(bit % 8);
}
void
tester_init(void);
void
tester_rsp(uint8_t service, uint8_t opcode, uint8_t status);
void
tester_rsp_full(uint8_t service, uint8_t opcode, const void *rsp, size_t len);
void
tester_event(uint8_t service, uint8_t opcode, const void *data, size_t len);
/* Used to indicate that command length is variable and that validation will
* be done in handler.
*/
#define BTP_HANDLER_LENGTH_VARIABLE (-1)
struct btp_handler {
uint8_t opcode;
uint8_t index;
ssize_t expect_len;
uint8_t (*func)(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len);
};
void tester_register_command_handlers(uint8_t service,
const struct btp_handler *handlers,
size_t num);
void
tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index,
struct os_mbuf *buf);
uint8_t
tester_init_gap(void);
uint8_t
tester_unregister_gap(void);
void
tester_init_core(void);
uint8_t
tester_init_gatt(void);
uint8_t
tester_unregister_gatt(void);
int
tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle,
uint8_t indication, struct os_mbuf *om);
int
tester_gatt_subscribe_ev(uint16_t conn_handle,
uint16_t attr_handle,
uint8_t reason,
uint8_t prev_notify,
uint8_t cur_notify,
uint8_t prev_indicate,
uint8_t cur_indicate);
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
uint8_t
tester_init_l2cap(void);
uint8_t
tester_unregister_l2cap(void);
#endif
#if MYNEWT_VAL(BLE_MESH)
uint8_t
tester_init_mesh(void);
uint8_t
tester_unregister_mesh(void);
#endif /* MYNEWT_VAL(BLE_MESH) */
uint8_t
tester_init_gatt_cl(void);
uint8_t
tester_unregister_gatt_cl(void);
void
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int
gatt_svr_init(void);
#endif /* __BTTESTER_H__ */
@@ -0,0 +1,202 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* btp_core.c - Bluetooth BTP Core service */
/*
* Copyright (C) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "btp/btp.h"
static uint8_t registered_services[((BTP_SERVICE_ID_MAX - 1) / 8) + 1];
static uint8_t
supported_commands(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
struct btp_core_read_supported_commands_rp *rp = rsp;
tester_set_bit(rp->data, BTP_CORE_READ_SUPPORTED_COMMANDS);
tester_set_bit(rp->data, BTP_CORE_READ_SUPPORTED_SERVICES);
tester_set_bit(rp->data, BTP_CORE_REGISTER_SERVICE);
tester_set_bit(rp->data, BTP_CORE_UNREGISTER_SERVICE);
*rsp_len = sizeof(*rp) + 1;
return BTP_STATUS_SUCCESS;
}
static uint8_t
supported_services(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
struct btp_core_read_supported_services_rp *rp = rsp;
/* octet 0 */
tester_set_bit(rp->data, BTP_SERVICE_ID_CORE);
tester_set_bit(rp->data, BTP_SERVICE_ID_GAP);
tester_set_bit(rp->data, BTP_SERVICE_ID_GATT);
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
tester_set_bit(rp->data, BTP_SERVICE_ID_L2CAP);
#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */
#if MYNEWT_VAL(BLE_MESH)
tester_set_bit(rp->data, BTP_SERVICE_ID_MESH);
#endif /* MYNEWT_VAL(BLE_MESH) */
tester_set_bit(rp->data, BTP_SERVICE_ID_GATTC);
*rsp_len = sizeof(*rp) + 2;
return BTP_STATUS_SUCCESS;
}
static uint8_t
register_service(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_core_register_service_cmd *cp = cmd;
uint8_t status;
/* invalid service */
if ((cp->id == BTP_SERVICE_ID_CORE) || (cp->id > BTP_SERVICE_ID_MAX)) {
return BTP_STATUS_FAILED;
}
/* already registered */
if (tester_test_bit(registered_services, cp->id)) {
return BTP_STATUS_FAILED;
}
switch (cp->id) {
case BTP_SERVICE_ID_GAP:
status = tester_init_gap();
break;
case BTP_SERVICE_ID_GATT:
status = tester_init_gatt();
break;
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
case BTP_SERVICE_ID_L2CAP:
status = tester_init_l2cap();
break;
#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */
#if MYNEWT_VAL(BLE_MESH)
case BTP_SERVICE_ID_MESH:
status = tester_init_mesh();
break;
#endif /* MYNEWT_VAL(BLE_MESH) */
case BTP_SERVICE_ID_GATTC:
status = tester_init_gatt_cl();
break;
default:
status = BTP_STATUS_FAILED;
break;
}
if (status == BTP_STATUS_SUCCESS) {
tester_set_bit(registered_services, cp->id);
}
return status;
}
static uint8_t
unregister_service(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_core_unregister_service_cmd *cp = cmd;
uint8_t status;
/* invalid service ID */
if ((cp->id == BTP_SERVICE_ID_CORE) || (cp->id > BTP_SERVICE_ID_MAX)) {
return BTP_STATUS_FAILED;
}
/* not registered */
if (!tester_test_bit(registered_services, cp->id)) {
return BTP_STATUS_FAILED;
}
switch (cp->id) {
case BTP_SERVICE_ID_GAP:
status = tester_unregister_gap();
break;
case BTP_SERVICE_ID_GATT:
status = tester_unregister_gatt();
break;
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
case BTP_SERVICE_ID_L2CAP:
status = tester_unregister_l2cap();
break;
#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */
#if MYNEWT_VAL(BLE_MESH)
case BTP_SERVICE_ID_MESH:
status = tester_unregister_mesh();
break;
#endif /* MYNEWT_VAL(BLE_MESH) */
case BTP_SERVICE_ID_GATTC:
status = tester_unregister_gatt_cl();
break;
default:
status = BTP_STATUS_FAILED;
break;
}
if (status == BTP_STATUS_SUCCESS) {
tester_clear_bit(registered_services, cp->id);
}
return status;
}
static const struct btp_handler handlers[] = {
{
.opcode = BTP_CORE_READ_SUPPORTED_COMMANDS,
.index = BTP_INDEX_NONE,
.expect_len = 0,
.func = supported_commands,
},
{
.opcode = BTP_CORE_READ_SUPPORTED_SERVICES,
.index = BTP_INDEX_NONE,
.expect_len = 0,
.func = supported_services,
},
{
.opcode = BTP_CORE_REGISTER_SERVICE,
.index = BTP_INDEX_NONE,
.expect_len = sizeof(struct btp_core_register_service_cmd),
.func = register_service,
},
{
.opcode = BTP_CORE_UNREGISTER_SERVICE,
.index = BTP_INDEX_NONE,
.expect_len = sizeof(struct btp_core_unregister_service_cmd),
.func = unregister_service,
},
};
void
tester_init_core(void)
{
tester_register_command_handlers(BTP_SERVICE_ID_CORE, handlers,
ARRAY_SIZE(handlers));
tester_set_bit(registered_services, BTP_SERVICE_ID_CORE);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,760 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* l2cap.c - Bluetooth L2CAP Tester */
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "syscfg/syscfg.h"
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
#include "console/console.h"
#include "host/ble_gap.h"
#include "host/ble_l2cap.h"
#include "../../../nimble/host/src/ble_l2cap_priv.h"
#include "btp/btp.h"
#define CONTROLLER_INDEX 0
#define CHANNELS MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
#define TESTER_COC_MTU MYNEWT_VAL(BTTESTER_L2CAP_COC_MTU)
#define TESTER_COC_BUF_COUNT (3 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM))
static os_membuf_t tester_sdu_coc_mem[
OS_MEMPOOL_SIZE(TESTER_COC_BUF_COUNT, TESTER_COC_MTU)
];
struct os_mbuf_pool sdu_os_mbuf_pool;
static struct os_mempool sdu_coc_mbuf_mempool;
static bool hold_credit = false;
static struct channel {
uint8_t chan_id; /* Internal number that identifies L2CAP channel. */
uint8_t state;
struct ble_l2cap_chan *chan;
} channels[CHANNELS];
static uint8_t
recv_cb_buf[TESTER_COC_MTU + sizeof(struct btp_l2cap_data_received_ev)];
static struct channel *
get_free_channel(void)
{
uint8_t i;
struct channel *chan;
for (i = 0; i < CHANNELS; i++) {
if (channels[i].state) {
continue;
}
chan = &channels[i];
chan->chan_id = i;
return chan;
}
return NULL;
}
struct channel *
find_channel(struct ble_l2cap_chan *chan)
{
int i;
for (i = 0; i < CHANNELS; ++i) {
if (channels[i].chan == chan) {
return &channels[i];
}
}
return NULL;
}
struct channel *
get_channel(uint8_t chan_id)
{
if (chan_id >= CHANNELS) {
return NULL;
}
return &channels[chan_id];
}
static void
tester_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
{
SYS_LOG_DBG("LE CoC SDU received, chan: 0x%08lx, data len %d",
(uint32_t) chan, OS_MBUF_PKTLEN(sdu));
os_mbuf_free_chain(sdu);
if (!hold_credit) {
sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
assert(sdu != NULL);
ble_l2cap_recv_ready(chan, sdu);
}
}
static void
recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
struct os_mbuf *buf, void *arg)
{
struct btp_l2cap_data_received_ev *ev = (void *) recv_cb_buf;
struct channel *channel = find_channel(chan);
assert(channel != NULL);
ev->chan_id = channel->chan_id;
ev->data_length = OS_MBUF_PKTLEN(buf);
if (ev->data_length > TESTER_COC_MTU) {
SYS_LOG_ERR("Too large sdu received, truncating data");
ev->data_length = TESTER_COC_MTU;
}
os_mbuf_copydata(buf, 0, ev->data_length, ev->data);
tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DATA_RECEIVED,
recv_cb_buf, sizeof(*ev) + ev->data_length);
tester_l2cap_coc_recv(chan, buf);
}
static void
reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan,
struct ble_l2cap_chan_info *chan_info,
int status)
{
struct btp_l2cap_reconfigured_ev ev;
struct channel *channel;
if (status != 0) {
return;
}
channel = find_channel(chan);
assert(channel != NULL);
ev.chan_id = channel->chan_id;
ev.peer_mtu = chan_info->peer_coc_mtu;
ev.peer_mps = chan_info->peer_l2cap_mtu;
ev.our_mtu = chan_info->our_coc_mtu;
ev.our_mps = chan_info->our_l2cap_mtu;
tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_RECONFIGURED,
(uint8_t *) &ev, sizeof(ev));
}
static void
connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
struct ble_l2cap_chan_info *chan_info, void *arg)
{
struct btp_l2cap_connected_ev ev;
struct ble_gap_conn_desc desc;
struct channel *channel = find_channel(chan);
if (channel == NULL) {
channel = get_free_channel();
}
ev.chan_id = channel->chan_id;
ev.psm = chan_info->psm;
ev.peer_mtu = chan_info->peer_coc_mtu;
ev.peer_mps = chan_info->peer_l2cap_mtu;
ev.our_mtu = chan_info->our_coc_mtu;
ev.our_mps = chan_info->our_l2cap_mtu;
channel->state = 1;
channel->chan = chan;
if (!ble_gap_conn_find(conn_handle, &desc)) {
memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address));
}
tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_CONNECTED,
(uint8_t *) &ev, sizeof(ev));
}
static void
disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
struct ble_l2cap_chan_info *chan_info, void *arg)
{
struct btp_l2cap_disconnected_ev ev;
struct ble_gap_conn_desc desc;
struct channel *channel;
memset(&ev, 0, sizeof(struct btp_l2cap_disconnected_ev));
channel = find_channel(chan);
assert(channel != NULL);
channel->state = 0;
channel->chan = chan;
ev.chan_id = channel->chan_id;
ev.psm = chan_info->psm;
if (!ble_gap_conn_find(conn_handle, &desc)) {
memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address));
}
tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DISCONNECTED,
(uint8_t *) &ev, sizeof(ev));
}
static int
accept_cb(uint16_t conn_handle, uint16_t peer_mtu,
struct ble_l2cap_chan *chan)
{
struct os_mbuf *sdu_rx;
SYS_LOG_DBG("LE CoC accepting, chan: 0x%08lx, peer_mtu %d",
(uint32_t) chan, peer_mtu);
sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
if (!sdu_rx) {
return BLE_HS_ENOMEM;
}
ble_l2cap_recv_ready(chan, sdu_rx);
return 0;
}
static int
tester_l2cap_event(struct ble_l2cap_event *event, void *arg)
{
struct ble_l2cap_chan_info chan_info;
struct ble_gap_conn_desc conn;
switch (event->type) {
case BLE_L2CAP_EVENT_COC_CONNECTED:
if (ble_l2cap_get_chan_info(event->connect.chan, &chan_info)) {
assert(0);
}
if (event->connect.status) {
console_printf("LE COC error: %d\n", event->connect.status);
return 0;
}
console_printf("LE COC connected, conn: %d, chan: 0x%08lx, "
"psm: 0x%02x, scid: 0x%04x, dcid: 0x%04x, "
"our_mps: %d, our_mtu: %d, peer_mps: %d, "
"peer_mtu: %d\n", event->connect.conn_handle,
(uint32_t) event->connect.chan, chan_info.psm,
chan_info.scid, chan_info.dcid,
chan_info.our_l2cap_mtu, chan_info.our_coc_mtu,
chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu);
connected_cb(event->connect.conn_handle,
event->connect.chan, &chan_info, arg);
return 0;
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
if (ble_l2cap_get_chan_info(event->disconnect.chan,
&chan_info)) {
assert(0);
}
console_printf("LE CoC disconnected, chan: 0x%08lx\n",
(uint32_t) event->disconnect.chan);
disconnected_cb(event->disconnect.conn_handle,
event->disconnect.chan, &chan_info, arg);
return 0;
case BLE_L2CAP_EVENT_COC_ACCEPT:
ble_l2cap_get_chan_info(event->accept.chan,
&chan_info);
if (chan_info.psm == 0x00F2) {
/* TSPX_psm_authentication_required */
ble_gap_conn_find(event->accept.conn_handle, &conn);
if (!conn.sec_state.authenticated) {
return BLE_HS_EAUTHEN;
}
} else if (chan_info.psm == 0x00F3) {
/* TSPX_psm_authorization_required */
ble_gap_conn_find(event->accept.conn_handle, &conn);
if (!conn.sec_state.encrypted) {
return BLE_HS_EAUTHOR;
}
return BLE_HS_EAUTHOR;
} else if (chan_info.psm == 0x00F4) {
/* TSPX_psm_encryption_key_size_required */
ble_gap_conn_find(event->accept.conn_handle, &conn);
if (conn.sec_state.key_size < 16) {
return BLE_HS_EENCRYPT_KEY_SZ;
}
} else if (chan_info.psm == 0x00F5) {
/* TSPX_psm_encryption_required */
ble_gap_conn_find(event->accept.conn_handle, &conn);
if (conn.sec_state.key_size == 0) {
return BLE_HS_EENCRYPT;
}
}
console_printf(
"LE CoC accept, chan: 0x%08lx, handle: %u, sdu_size: %u\n",
(uint32_t) event->accept.chan,
event->accept.conn_handle,
event->accept.peer_sdu_size);
return accept_cb(event->accept.conn_handle,
event->accept.peer_sdu_size,
event->accept.chan);
case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
console_printf(
"LE CoC data received, chan: 0x%08lx, handle: %u, sdu_len: %u\n",
(uint32_t) event->receive.chan,
event->receive.conn_handle,
OS_MBUF_PKTLEN(event->receive.sdu_rx));
recv_cb(event->receive.conn_handle, event->receive.chan,
event->receive.sdu_rx, arg);
return 0;
case BLE_L2CAP_EVENT_COC_TX_UNSTALLED:
console_printf(
"LE CoC tx unstalled, chan: 0x%08lx, handle: %u, status: %d\n",
(uint32_t) event->tx_unstalled.chan,
event->tx_unstalled.conn_handle,
event->tx_unstalled.status);
return 0;
case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED:
if (ble_l2cap_get_chan_info(event->reconfigured.chan,
&chan_info)) {
assert(0);
}
console_printf("LE CoC reconfigure completed status 0x%02x, "
"chan: 0x%08lx\n", event->reconfigured.status,
(uint32_t) event->reconfigured.chan);
if (event->reconfigured.status == 0) {
console_printf("\t our_mps: %d our_mtu %d\n",
chan_info.our_l2cap_mtu, chan_info.our_coc_mtu);
}
reconfigured_ev(event->reconfigured.conn_handle,
event->reconfigured.chan,
&chan_info,
event->reconfigured.status);
return 0;
case BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED:
if (ble_l2cap_get_chan_info(event->reconfigured.chan,
&chan_info)) {
assert(0);
}
console_printf("LE CoC peer reconfigured status 0x%02x, "
"chan: 0x%08lx\n", event->reconfigured.status,
(uint32_t) event->reconfigured.chan);
if (event->reconfigured.status == 0) {
console_printf("\t peer_mps: %d peer_mtu %d\n",
chan_info.peer_l2cap_mtu,
chan_info.peer_coc_mtu);
}
reconfigured_ev(event->reconfigured.conn_handle,
event->reconfigured.chan,
&chan_info,
event->reconfigured.status);
return 0;
default:
return 0;
}
}
static uint8_t
connect(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_l2cap_connect_cmd *cp = cmd;
struct btp_l2cap_connect_rp *rp = rsp;
struct ble_gap_conn_desc desc;
struct channel *chan;
struct os_mbuf *sdu_rx[cp->num];
ble_addr_t *addr = (void *)&cp->address;
uint16_t mtu = le16toh(cp->mtu);
uint16_t psm = le16toh(cp->psm);
int rc;
int i, j;
uint8_t status = BTP_STATUS_SUCCESS;
bool ecfc = cp->options & BTP_L2CAP_CONNECT_OPT_ECFC;
hold_credit = cp->options & BTP_L2CAP_CONNECT_OPT_HOLD_CREDIT;
SYS_LOG_DBG("connect: type: %d addr: %s",
addr->type,
string_from_bytes(addr->val, 6));
rc = ble_gap_conn_find_by_addr(addr, &desc);
if (cp->num == 0 || cp->num > CHANNELS ||
mtu > TESTER_COC_MTU || mtu == 0) {
return BTP_STATUS_FAILED;
}
if (rc) {
SYS_LOG_ERR("GAP conn find failed");
return BTP_STATUS_FAILED;
}
for (i = 0; i < cp->num; i++) {
chan = get_free_channel();
if (!chan) {
SYS_LOG_ERR("No free channels");
status = BTP_STATUS_FAILED;
goto done;
}
/* temporarily mark channel as used to select next one */
chan->state = 1;
rp->chan_ids[i] = chan->chan_id;
sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
if (sdu_rx[i] == NULL) {
SYS_LOG_ERR("Failed to alloc buf");
status = BTP_STATUS_FAILED;
goto done;
}
}
if (cp->num == 1 && !ecfc) {
rc = ble_l2cap_connect(desc.conn_handle, psm,
mtu, sdu_rx[0],
tester_l2cap_event, NULL);
} else if (ecfc) {
rc = ble_l2cap_enhanced_connect(desc.conn_handle,
psm, mtu,
cp->num, sdu_rx,
tester_l2cap_event, NULL);
} else {
SYS_LOG_ERR("Invalid 'num' parameter value");
status = BTP_STATUS_FAILED;
goto done;
}
if (rc) {
SYS_LOG_ERR("L2CAP connect failed\n");
status = BTP_STATUS_FAILED;
goto done;
}
rp->num = cp->num;
*rsp_len = sizeof(*rp) + (rp->num * sizeof(rp->chan_ids[0]));
done:
/* mark selected channels as unused again */
for (i = 0; i < cp->num; i++) {
for (j = 0; j < CHANNELS; j++) {
if (rp->chan_ids[i] == channels[j].chan_id) {
channels[j].state = 0;
}
}
}
return status;
}
static uint8_t
disconnect(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_l2cap_disconnect_cmd *cp = cmd;
struct channel *chan;
int err;
SYS_LOG_DBG("");
if (cp->chan_id >= CHANNELS) {
return BTP_STATUS_FAILED;
}
chan = get_channel(cp->chan_id);
assert(chan != NULL);
err = ble_l2cap_disconnect(chan->chan);
if (err) {
return BTP_STATUS_FAILED;
}
return BTP_STATUS_SUCCESS;
}
static uint8_t
send_data(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_l2cap_send_data_cmd *cp = cmd;
struct channel *chan;
struct os_mbuf *sdu_tx = NULL;
int rc;
uint16_t data_len;
SYS_LOG_DBG("cmd->chan_id=%d", cp->chan_id);
if (cmd_len < sizeof(*cp) ||
cmd_len != sizeof(*cp) + le16toh(cp->data_len)) {
return BTP_STATUS_FAILED;
}
if (cp->chan_id >= CHANNELS) {
return BTP_STATUS_FAILED;
}
chan = get_channel(cp->chan_id);
data_len = le16toh(cp->data_len);
if (!chan) {
SYS_LOG_ERR("Invalid channel\n");
return BTP_STATUS_FAILED;
}
/* FIXME: For now, fail if data length exceeds buffer length */
if (data_len > TESTER_COC_MTU) {
SYS_LOG_ERR("Data length exceeds buffer length");
return BTP_STATUS_FAILED;
}
sdu_tx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
if (sdu_tx == NULL) {
SYS_LOG_ERR("No memory in the test sdu pool\n");
rc = BLE_HS_ENOMEM;
goto fail;
}
os_mbuf_append(sdu_tx, cp->data, data_len);
/* ble_l2cap_send takes ownership of the sdu */
rc = ble_l2cap_send(chan->chan, sdu_tx);
if (rc == 0 || rc == BLE_HS_ESTALLED) {
return BTP_STATUS_SUCCESS;
}
fail:
SYS_LOG_ERR("Unable to send data: %d", rc);
os_mbuf_free_chain(sdu_tx);
return BTP_STATUS_FAILED;
}
static uint8_t
listen(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_l2cap_listen_cmd *cp = cmd;
uint16_t mtu = htole16(cp->mtu);
uint16_t psm = htole16(cp->psm);
int rc;
SYS_LOG_DBG("");
if (psm == 0) {
return BTP_STATUS_FAILED;
}
if (mtu == 0 || mtu > TESTER_COC_MTU) {
mtu = TESTER_COC_MTU;
}
/* We do not support BR/EDR transport */
if (cp->transport == 0) {
return BTP_STATUS_FAILED;
}
rc = ble_l2cap_create_server(psm, mtu, tester_l2cap_event, NULL);
if (rc) {
return BTP_STATUS_FAILED;
}
return BTP_STATUS_SUCCESS;
}
static uint8_t
credits(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_l2cap_credits_cmd *cp = cmd;
struct channel *chan;
struct os_mbuf *sdu;
int rc;
if (cp->chan_id >= CHANNELS) {
return BTP_STATUS_FAILED;
}
chan = get_channel(cp->chan_id);
if (chan == NULL) {
return BTP_STATUS_FAILED;
}
sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
if (sdu == NULL) {
os_mbuf_free_chain(sdu);
return BTP_STATUS_FAILED;
}
rc = ble_l2cap_recv_ready(chan->chan, sdu);
if (rc != 0) {
return BTP_STATUS_FAILED;
}
return BTP_STATUS_SUCCESS;
}
static uint8_t
reconfigure(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_l2cap_reconfigure_cmd *cp = cmd;
uint16_t mtu = le16toh(cp->mtu);
struct ble_gap_conn_desc desc;
ble_addr_t *addr = (ble_addr_t *)&cp->address;
struct ble_l2cap_chan *chans[cp->num];
struct channel *channel;
int rc;
int i;
SYS_LOG_DBG("");
if (mtu == 0 || mtu > TESTER_COC_MTU) {
mtu = TESTER_COC_MTU;
}
rc = ble_gap_conn_find_by_addr(addr, &desc);
if (rc) {
SYS_LOG_ERR("GAP conn find failed");
return BTP_STATUS_FAILED;
}
if (cmd_len < sizeof(*cp) ||
cmd_len != sizeof(*cp) + cp->num) {
return BTP_STATUS_FAILED;
}
if (cp->num > CHANNELS) {
return BTP_STATUS_FAILED;
}
mtu = le16toh(cp->mtu);
if (mtu > TESTER_COC_MTU) {
return BTP_STATUS_FAILED;
}
for (i = 0; i < cp->num; ++i) {
channel = get_channel(cp->idxs[i]);
if (channel == NULL) {
return BTP_STATUS_FAILED;
}
chans[i] = channel->chan;
}
rc = ble_l2cap_reconfig(chans, cp->num, mtu);
if (rc) {
return BTP_STATUS_FAILED;
}
return BTP_STATUS_SUCCESS;
}
static uint8_t
supported_commands(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
struct btp_l2cap_read_supported_commands_rp *rp = rsp;
/* octet 0 */
tester_set_bit(rp->data, BTP_L2CAP_READ_SUPPORTED_COMMANDS);
tester_set_bit(rp->data, BTP_L2CAP_CONNECT);
tester_set_bit(rp->data, BTP_L2CAP_DISCONNECT);
tester_set_bit(rp->data, BTP_L2CAP_SEND_DATA);
tester_set_bit(rp->data, BTP_L2CAP_LISTEN);
/* octet 1 */
tester_set_bit(rp->data, BTP_L2CAP_CREDITS);
*rsp_len = sizeof(*rp) + 2;
return BTP_STATUS_SUCCESS;
}
static const struct btp_handler handlers[] = {
{
.opcode = BTP_L2CAP_READ_SUPPORTED_COMMANDS,
.index = BTP_INDEX_NONE,
.expect_len = 0,
.func = supported_commands,
},
{
.opcode = BTP_L2CAP_CONNECT,
.expect_len = sizeof(struct btp_l2cap_connect_cmd),
.func = connect,
},
{
.opcode = BTP_L2CAP_DISCONNECT,
.expect_len = sizeof(struct btp_l2cap_disconnect_cmd),
.func = disconnect,
},
{
.opcode = BTP_L2CAP_SEND_DATA,
.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
.func = send_data,
},
{
.opcode = BTP_L2CAP_LISTEN,
.expect_len = sizeof(struct btp_l2cap_listen_cmd),
.func = listen,
},
{
.opcode = BTP_L2CAP_RECONFIGURE,
.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
.func = reconfigure,
},
{
.opcode = BTP_L2CAP_CREDITS,
.expect_len = sizeof(struct btp_l2cap_credits_cmd),
.func = credits,
},
};
uint8_t
tester_init_l2cap(void)
{
int rc;
/* For testing we want to support all the available channels */
rc = os_mempool_init(&sdu_coc_mbuf_mempool, TESTER_COC_BUF_COUNT,
TESTER_COC_MTU, tester_sdu_coc_mem,
"tester_coc_sdu_pool");
assert(rc == 0);
rc = os_mbuf_pool_init(&sdu_os_mbuf_pool, &sdu_coc_mbuf_mempool,
TESTER_COC_MTU, TESTER_COC_BUF_COUNT);
assert(rc == 0);
tester_register_command_handlers(BTP_SERVICE_ID_L2CAP, handlers,
ARRAY_SIZE(handlers));
return BTP_STATUS_SUCCESS;
}
uint8_t
tester_unregister_l2cap(void)
{
return BTP_STATUS_SUCCESS;
}
#endif
File diff suppressed because it is too large Load Diff
@@ -33,347 +33,343 @@
#include "console/console.h"
#include "bttester_pipe.h"
#include "bttester.h"
#include "btp/btp.h"
#define CMD_QUEUED 2
static struct os_eventq avail_queue;
static struct os_eventq *cmds_queue;
static struct os_event bttester_ev[CMD_QUEUED];
static struct btp_buf *delayed_cmd;
struct btp_buf {
struct os_event *ev;
union {
uint8_t data[BTP_MTU];
struct btp_hdr hdr;
};
struct os_event *ev;
union {
uint8_t data[BTP_MTU];
struct btp_hdr hdr;
};
uint8_t rsp[BTP_MTU];
};
static struct btp_buf cmd_buf[CMD_QUEUED];
static void supported_commands(uint8_t *data, uint16_t len)
static struct {
const struct btp_handler *handlers;
uint8_t num;
} service_handler[BTP_SERVICE_ID_MAX + 1];
void
tester_mbuf_reset(struct os_mbuf *buf)
{
uint8_t buf[1];
struct core_read_supported_commands_rp *rp = (void *) buf;
memset(buf, 0, sizeof(buf));
tester_set_bit(buf, CORE_READ_SUPPORTED_COMMANDS);
tester_set_bit(buf, CORE_READ_SUPPORTED_SERVICES);
tester_set_bit(buf, CORE_REGISTER_SERVICE);
tester_set_bit(buf, CORE_UNREGISTER_SERVICE);
tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_COMMANDS,
BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf));
buf->om_data = &buf->om_databuf[buf->om_pkthdr_len];
buf->om_len = 0;
}
static void supported_services(uint8_t *data, uint16_t len)
static void
tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index,
const uint8_t *data, size_t len);
static void
tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index,
uint8_t status);
void
tester_register_command_handlers(uint8_t service,
const struct btp_handler *handlers,
size_t num)
{
uint8_t buf[1];
struct core_read_supported_services_rp *rp = (void *) buf;
assert(service <= BTP_SERVICE_ID_MAX);
assert(service_handler[service].handlers == NULL);
memset(buf, 0, sizeof(buf));
tester_set_bit(buf, BTP_SERVICE_ID_CORE);
tester_set_bit(buf, BTP_SERVICE_ID_GAP);
tester_set_bit(buf, BTP_SERVICE_ID_GATT);
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
tester_set_bit(buf, BTP_SERVICE_ID_L2CAP);
#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */
#if MYNEWT_VAL(BLE_MESH)
tester_set_bit(buf, BTP_SERVICE_ID_MESH);
#endif /* MYNEWT_VAL(BLE_MESH) */
tester_set_bit(buf, BTP_SERVICE_ID_GATTC);
tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_SERVICES,
BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf));
service_handler[service].handlers = handlers;
service_handler[service].num = num;
}
static void register_service(uint8_t *data, uint16_t len)
const char *
string_from_bytes(const void *buf, size_t len)
{
struct core_register_service_cmd *cmd = (void *) data;
uint8_t status;
static const char hex[] = "0123456789abcdef";
static char hexbufs[4][137];
static uint8_t curbuf;
const uint8_t *b = buf;
char *str;
int i;
switch (cmd->id) {
case BTP_SERVICE_ID_GAP:
status = tester_init_gap();
/* Rsp with success status will be handled by bt enable cb */
if (status == BTP_STATUS_FAILED) {
goto rsp;
}
return;
case BTP_SERVICE_ID_GATT:
status = tester_init_gatt();
break;
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
case BTP_SERVICE_ID_L2CAP:
status = tester_init_l2cap();
break;
#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */
#if MYNEWT_VAL(BLE_MESH)
case BTP_SERVICE_ID_MESH:
status = tester_init_mesh();
break;
#endif /* MYNEWT_VAL(BLE_MESH) */
default:
status = BTP_STATUS_FAILED;
break;
}
str = hexbufs[curbuf++];
curbuf %= ARRAY_SIZE(hexbufs);
rsp:
tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE,
status);
len = min(len, (sizeof(hexbufs[0]) - 1) / 2);
for (i = 0; i < len; i++) {
str[i * 2] = hex[b[i] >> 4];
str[i * 2 + 1] = hex[b[i] & 0xf];
}
str[i * 2] = '\0';
return str;
}
static void unregister_service(uint8_t *data, uint16_t len)
static const struct btp_handler *
find_btp_handler(uint8_t service, uint8_t opcode)
{
struct core_unregister_service_cmd *cmd = (void *) data;
uint8_t status;
if ((service > BTP_SERVICE_ID_MAX) ||
(service_handler[service].handlers == NULL)) {
return NULL;
}
switch (cmd->id) {
case BTP_SERVICE_ID_GAP:
status = tester_unregister_gap();
break;
case BTP_SERVICE_ID_GATT:
status = tester_unregister_gatt();
break;
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
case BTP_SERVICE_ID_L2CAP:
status = tester_unregister_l2cap();
break;
#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */
#if MYNEWT_VAL(BLE_MESH)
case BTP_SERVICE_ID_MESH:
status = tester_unregister_mesh();
break;
#endif /* MYNEWT_VAL(BLE_MESH) */
default:
status = BTP_STATUS_FAILED;
break;
}
for (uint8_t i = 0; i < service_handler[service].num; i++) {
if (service_handler[service].handlers[i].opcode == opcode) {
return &service_handler[service].handlers[i];
}
}
tester_rsp(BTP_SERVICE_ID_CORE, CORE_UNREGISTER_SERVICE, BTP_INDEX_NONE,
status);
return NULL;
}
static void handle_core(uint8_t opcode, uint8_t index, uint8_t *data,
uint16_t len)
static void
cmd_handler(struct os_event *ev)
{
if (index != BTP_INDEX_NONE) {
tester_rsp(BTP_SERVICE_ID_CORE, opcode, index,
BTP_STATUS_FAILED);
return;
}
const struct btp_handler *btp;
uint16_t len;
struct btp_buf *cmd;
uint8_t status;
uint16_t rsp_len = 0;
switch (opcode) {
case CORE_READ_SUPPORTED_COMMANDS:
supported_commands(data, len);
return;
case CORE_READ_SUPPORTED_SERVICES:
supported_services(data, len);
return;
case CORE_REGISTER_SERVICE:
register_service(data, len);
return;
case CORE_UNREGISTER_SERVICE:
unregister_service(data, len);
return;
default:
tester_rsp(BTP_SERVICE_ID_CORE, opcode, BTP_INDEX_NONE,
BTP_STATUS_UNKNOWN_CMD);
return;
}
if (!ev || !ev->ev_arg) {
return;
}
cmd = ev->ev_arg;
len = le16toh(cmd->hdr.len);
if (MYNEWT_VAL(BTTESTER_BTP_LOG)) {
console_printf("[DBG] received %d bytes: %s\n",
sizeof(cmd->hdr) + len,
string_from_bytes(cmd->data,
sizeof(cmd->hdr) + len));
}
btp = find_btp_handler(cmd->hdr.service, cmd->hdr.opcode);
if (btp) {
if (btp->index != cmd->hdr.index) {
status = BTP_STATUS_FAILED;
} else if ((btp->expect_len >= 0) && (btp->expect_len != len)) {
status = BTP_STATUS_FAILED;
} else {
status = btp->func(cmd->hdr.data, len,
cmd->rsp, &rsp_len);
}
assert((rsp_len + sizeof(struct btp_hdr)) <= BTP_MTU);
} else {
status = BTP_STATUS_UNKNOWN_CMD;
}
/* Allow to delay only 1 command. This is for convenience only
* of using cmd data without need of copying those in async
* functions. Should be not needed eventually.
*/
if (status == BTP_STATUS_DELAY_REPLY) {
assert(delayed_cmd == NULL);
delayed_cmd = cmd;
return;
}
if ((status == BTP_STATUS_SUCCESS) && rsp_len > 0) {
tester_send_with_index(cmd->hdr.service, cmd->hdr.opcode,
cmd->hdr.index, cmd->rsp, rsp_len);
} else {
tester_rsp_with_index(cmd->hdr.service, cmd->hdr.opcode,
cmd->hdr.index, status);
}
os_eventq_put(&avail_queue, ev);
}
static void cmd_handler(struct os_event *ev)
static uint8_t *
recv_cb(uint8_t *buf, size_t *off)
{
uint16_t len;
struct btp_buf *cmd;
struct btp_hdr *cmd = (void *) buf;
struct os_event *new_ev;
struct btp_buf *new_buf, *old_buf;
uint16_t len;
if (!ev || !ev->ev_arg) {
return;
}
if (*off < sizeof(*cmd)) {
return buf;
}
cmd = ev->ev_arg;
len = le16toh(cmd->len);
if (len > BTP_MTU - sizeof(*cmd)) {
*off = 0;
return buf;
}
len = sys_le16_to_cpu(cmd->hdr.len);
if (MYNEWT_VAL(BTTESTER_BTP_LOG)) {
console_printf("[DBG] received %d bytes: %s\n",
sizeof(cmd->hdr) + len,
bt_hex(cmd->data,
sizeof(cmd->hdr) + len));
}
if (*off < sizeof(*cmd) + len) {
return buf;
}
/* TODO
* verify if service is registered before calling handler
*/
new_ev = os_eventq_get_no_wait(&avail_queue);
if (!new_ev) {
SYS_LOG_ERR("BT tester: RX overflow");
*off = 0;
return buf;
}
switch (cmd->hdr.service) {
case BTP_SERVICE_ID_CORE:
handle_core(cmd->hdr.opcode, cmd->hdr.index,
cmd->hdr.data, len);
break;
case BTP_SERVICE_ID_GAP:
tester_handle_gap(cmd->hdr.opcode, cmd->hdr.index,
cmd->hdr.data, len);
break;
case BTP_SERVICE_ID_GATT:
tester_handle_gatt(cmd->hdr.opcode, cmd->hdr.index,
cmd->hdr.data, len);
break;
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
case BTP_SERVICE_ID_L2CAP:
tester_handle_l2cap(cmd->hdr.opcode, cmd->hdr.index,
cmd->hdr.data, len);
break;
#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */
#if MYNEWT_VAL(BLE_MESH)
case BTP_SERVICE_ID_MESH:
tester_handle_mesh(cmd->hdr.opcode, cmd->hdr.index,
cmd->hdr.data, len);
break;
#endif /* MYNEWT_VAL(BLE_MESH) */
case BTP_SERVICE_ID_GATTC:
tester_handle_gattc(cmd->hdr.opcode, cmd->hdr.index,
cmd->hdr.data, len);
break;
default:
tester_rsp(cmd->hdr.service, cmd->hdr.opcode,
cmd->hdr.index, BTP_STATUS_FAILED);
break;
}
old_buf = CONTAINER_OF(buf, struct btp_buf, data);
os_eventq_put(cmds_queue, old_buf->ev);
os_eventq_put(&avail_queue, ev);
new_buf = new_ev->ev_arg;
*off = 0;
return new_buf->data;
}
static uint8_t *recv_cb(uint8_t *buf, size_t *off)
static void
avail_queue_init(void)
{
struct btp_hdr *cmd = (void *) buf;
struct os_event *new_ev;
struct btp_buf *new_buf, *old_buf;
uint16_t len;
int i;
if (*off < sizeof(*cmd)) {
return buf;
}
os_eventq_init(&avail_queue);
len = sys_le16_to_cpu(cmd->len);
if (len > BTP_MTU - sizeof(*cmd)) {
*off = 0;
return buf;
}
for (i = 0; i < CMD_QUEUED; i++) {
cmd_buf[i].ev = &bttester_ev[i];
bttester_ev[i].ev_cb = cmd_handler;
bttester_ev[i].ev_arg = &cmd_buf[i];
if (*off < sizeof(*cmd) + len) {
return buf;
}
new_ev = os_eventq_get_no_wait(&avail_queue);
if (!new_ev) {
SYS_LOG_ERR("BT tester: RX overflow");
*off = 0;
return buf;
}
old_buf = CONTAINER_OF(buf, struct btp_buf, data);
os_eventq_put(cmds_queue, old_buf->ev);
new_buf = new_ev->ev_arg;
*off = 0;
return new_buf->data;
os_eventq_put(&avail_queue, &bttester_ev[i]);
}
}
static void avail_queue_init(void)
void
bttester_evq_set(struct os_eventq *evq)
{
int i;
os_eventq_init(&avail_queue);
for (i = 0; i < CMD_QUEUED; i++) {
cmd_buf[i].ev = &bttester_ev[i];
bttester_ev[i].ev_cb = cmd_handler;
bttester_ev[i].ev_arg = &cmd_buf[i];
os_eventq_put(&avail_queue, &bttester_ev[i]);
}
cmds_queue = evq;
}
void bttester_evq_set(struct os_eventq *evq)
void
tester_init(void)
{
cmds_queue = evq;
struct os_event *ev;
struct btp_buf *buf;
avail_queue_init();
bttester_evq_set(os_eventq_dflt_get());
ev = os_eventq_get(&avail_queue);
buf = ev->ev_arg;
if (bttester_pipe_init()) {
SYS_LOG_ERR("Failed to initialize pipe");
return;
}
bttester_pipe_register(buf->data, BTP_MTU, recv_cb);
/* core service is always available */
tester_init_core();
tester_send_with_index(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY,
BTP_INDEX_NONE, NULL, 0);
}
void tester_init(void)
static void
tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index,
const uint8_t *data, size_t len)
{
struct os_event *ev;
struct btp_buf *buf;
struct btp_hdr msg;
avail_queue_init();
bttester_evq_set(os_eventq_dflt_get());
msg.service = service;
msg.opcode = opcode;
msg.index = index;
msg.len = htole16(len);
ev = os_eventq_get(&avail_queue);
buf = ev->ev_arg;
bttester_pipe_send((uint8_t *) &msg, sizeof(msg));
if (data && len) {
bttester_pipe_send(data, len);
}
if (bttester_pipe_init()) {
SYS_LOG_ERR("Failed to initialize pipe");
return;
}
bttester_pipe_register(buf->data, BTP_MTU, recv_cb);
tester_send(BTP_SERVICE_ID_CORE, CORE_EV_IUT_READY, BTP_INDEX_NONE,
NULL, 0);
if (MYNEWT_VAL(BTTESTER_BTP_LOG)) {
console_printf("[DBG] send %d bytes hdr: %s\n", sizeof(msg),
string_from_bytes((char *) &msg, sizeof(msg)));
if (data && len) {
console_printf("[DBG] send %d bytes data: %s\n", len,
string_from_bytes((char *) data, len));
}
}
}
void tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data,
size_t len)
void
tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index,
struct os_mbuf *data)
{
struct btp_hdr msg;
struct btp_hdr msg;
msg.service = service;
msg.opcode = opcode;
msg.index = index;
msg.len = len;
msg.service = service;
msg.opcode = opcode;
msg.index = index;
msg.len = os_mbuf_len(data);
bttester_pipe_send((uint8_t *)&msg, sizeof(msg));
if (data && len) {
bttester_pipe_send(data, len);
}
if (MYNEWT_VAL(BTTESTER_BTP_LOG)) {
console_printf("[DBG] send %d bytes hdr: %s\n", sizeof(msg),
bt_hex((char *) &msg, sizeof(msg)));
if (data && len) {
console_printf("[DBG] send %d bytes data: %s\n", len,
bt_hex((char *) data, len));
}
}
bttester_pipe_send((uint8_t *) &msg, sizeof(msg));
if (data && msg.len) {
bttester_pipe_send_buf(data);
}
}
void tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index,
struct os_mbuf *data)
static void
tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index,
uint8_t status)
{
struct btp_hdr msg;
struct btp_status s;
msg.service = service;
msg.opcode = opcode;
msg.index = index;
msg.len = os_mbuf_len(data);
if (status == BTP_STATUS_SUCCESS) {
tester_send_with_index(service, opcode, index, NULL, 0);
return;
}
bttester_pipe_send((uint8_t *)&msg, sizeof(msg));
if (data && msg.len) {
bttester_pipe_send_buf(data);
}
s.code = status;
tester_send_with_index(service, BTP_STATUS, index, (uint8_t *) &s, sizeof(s));
}
void tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status)
void
tester_event(uint8_t service, uint8_t opcode, const void *data, size_t len)
{
struct btp_status s;
assert(opcode >= 0x80);
tester_send_with_index(service, opcode, BTP_INDEX, data, len);
}
if (status == BTP_STATUS_SUCCESS) {
tester_send(service, opcode, index, NULL, 0);
return;
}
void
tester_rsp_full(uint8_t service, uint8_t opcode, const void *rsp, size_t len)
{
struct btp_buf *cmd;
s.code = status;
tester_send(service, BTP_STATUS, index, (uint8_t *) &s, sizeof(s));
assert(opcode < 0x80);
assert(delayed_cmd != NULL);
tester_send_with_index(service, opcode, BTP_INDEX, rsp, len);
cmd = delayed_cmd;
delayed_cmd = NULL;
(void)memset(cmd, 0, sizeof(*cmd));
os_eventq_put(&avail_queue,
CONTAINER_OF(cmd, struct btp_buf, data)->ev);
}
void
tester_rsp(uint8_t service, uint8_t opcode, uint8_t status)
{
struct btp_buf *cmd;
assert(opcode < 0x80);
assert(delayed_cmd != NULL);
tester_rsp_with_index(service, opcode, BTP_INDEX, status);
cmd = delayed_cmd;
delayed_cmd = NULL;
(void)memset(cmd, 0, sizeof(*cmd));
os_eventq_put(&avail_queue,
CONTAINER_OF(cmd, struct btp_buf, data)->ev);
}
@@ -21,17 +21,21 @@
#define __BTTESTER_PIPE_H__
#include <stdlib.h>
#include "bttester.h"
#include "btp/bttester.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8_t *(*bttester_pipe_recv_cb)(uint8_t *buf, size_t *off);
void bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb);
int bttester_pipe_send(const uint8_t *data, int len);
int bttester_pipe_send_buf(struct os_mbuf *buf);
int bttester_pipe_init(void);
void
bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb);
int
bttester_pipe_send(const uint8_t *data, int len);
int
bttester_pipe_send_buf(struct os_mbuf *buf);
int
bttester_pipe_init(void);
#ifdef __cplusplus
}
@@ -31,42 +31,45 @@
#include "host/ble_uuid.h"
#include "host/ble_hs.h"
#include "bttester.h"
#include "btp/btp.h"
static void on_reset(int reason)
static void
on_reset(int reason)
{
MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
}
static void on_sync(void)
static void
on_sync(void)
{
MODLOG_DFLT(INFO, "Bluetooth initialized\n");
MODLOG_DFLT(INFO, "Bluetooth initialized\n");
tester_init();
tester_init();
}
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
int rc;
int rc;
#ifdef ARCH_sim
mcu_sim_parse_args(argc, argv);
mcu_sim_parse_args(argc, argv);
#endif
/* Initialize OS */
sysinit();
/* Initialize OS */
sysinit();
/* Initialize the NimBLE host configuration. */
ble_hs_cfg.reset_cb = on_reset;
ble_hs_cfg.sync_cb = on_sync;
ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb,
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
/* Initialize the NimBLE host configuration. */
ble_hs_cfg.reset_cb = on_reset;
ble_hs_cfg.sync_cb = on_sync;
ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb,
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
rc = gatt_svr_init();
assert(rc == 0);
rc = gatt_svr_init();
assert(rc == 0);
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
return 0;
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
return 0;
}
@@ -41,7 +41,7 @@ struct uart_pipe_ring {
static struct uart_dev *uart_dev;
static struct uart_pipe_ring cr_tx;
static uint8_t cr_tx_buf[MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX)];
typedef void (*console_write_char)(struct uart_dev*, uint8_t);
typedef void (*console_write_char)(struct uart_dev *, uint8_t);
static console_write_char write_char_cb;
static struct uart_pipe_ring cr_rx;
@@ -217,39 +217,39 @@ bttester_pipe_send(const uint8_t *data, int len)
int
bttester_pipe_send_buf(struct os_mbuf *buf)
{
int i, len;
struct os_mbuf *om;
int i, len;
struct os_mbuf *om;
/* Assure that there is a write cb installed; this enables to debug
* code that is faulting before the console was initialized.
*/
if (!write_char_cb) {
return -1;
}
/* Assure that there is a write cb installed; this enables to debug
* code that is faulting before the console was initialized.
*/
if (!write_char_cb) {
return -1;
}
for (om = buf; om; om = SLIST_NEXT(om, om_next)) {
len = om->om_len;
for (i = 0; i < len; ++i) {
write_char_cb(uart_dev, om->om_data[i]);
}
}
for (om = buf; om; om = SLIST_NEXT(om, om_next)) {
len = om->om_len;
for (i = 0; i < len; ++i) {
write_char_cb(uart_dev, om->om_data[i]);
}
}
uart_start_tx(uart_dev);
uart_start_tx(uart_dev);
return 0;
return 0;
}
int
bttester_pipe_init(void)
{
struct uart_conf uc = {
.uc_speed = MYNEWT_VAL(CONSOLE_UART_BAUD),
.uc_databits = 8,
.uc_stopbits = 1,
.uc_parity = UART_PARITY_NONE,
.uc_flow_ctl = MYNEWT_VAL(CONSOLE_UART_FLOW_CONTROL),
.uc_tx_char = uart_console_tx_char,
.uc_rx_char = uart_console_rx_char,
.uc_speed = MYNEWT_VAL(CONSOLE_UART_BAUD),
.uc_databits = 8,
.uc_stopbits = 1,
.uc_parity = UART_PARITY_NONE,
.uc_flow_ctl = MYNEWT_VAL(CONSOLE_UART_FLOW_CONTROL),
.uc_tx_char = uart_console_tx_char,
.uc_rx_char = uart_console_rx_char,
};
cr_tx.size = sizeof(cr_tx_buf);
@@ -262,8 +262,9 @@ bttester_pipe_init(void)
rx_ev.ev_cb = uart_console_rx_char_event;
if (!uart_dev) {
uart_dev = (struct uart_dev *)os_dev_open(MYNEWT_VAL(CONSOLE_UART_DEV),
OS_TIMEOUT_NEVER, &uc);
uart_dev =
(struct uart_dev *) os_dev_open(MYNEWT_VAL(CONSOLE_UART_DEV),
OS_TIMEOUT_NEVER, &uc);
if (!uart_dev) {
return -1;
}
@@ -274,8 +275,9 @@ bttester_pipe_init(void)
void
bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb)
{
recv_buf = buf;
recv_buf_len = len;
app_cb = cb;
recv_buf = buf;
recv_buf_len = len;
app_cb = cb;
}
#endif /* MYNEWT_VAL(BTTESTER_PIPE_UART) */
@@ -80,6 +80,10 @@ syscfg.defs:
value: 5
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
OS_MAIN_STACK_SIZE: 512
SHELL_TASK: 0
SHELL_NEWTMGR: 0
@@ -96,15 +100,15 @@ syscfg.vals:
BLE_L2CAP_COC_MAX_NUM: 2
BLE_L2CAP_SIG_MAX_PROCS: 2
BLE_L2CAP_ENHANCED_COC: 1
BLE_VERSION: 52
BLE_VERSION: 53
# Some testcases require MPS < MTU
BLE_L2CAP_COC_MPS: 100
BLE_RPA_TIMEOUT: 30
BLE_SM_BONDING: 1
BLE_SM_MITM: 0
BLE_SM_SC: 1
BLE_SM_OUR_KEY_DIST: 7
BLE_SM_THEIR_KEY_DIST: 7
BLE_SM_OUR_KEY_DIST: 3
BLE_SM_THEIR_KEY_DIST: 3
BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION: 1
BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: 9
BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL: 30
@@ -24,9 +24,9 @@ pkg.author: "Krzysztof Kopyściński <krzysztof.kopyscinski@codecoup.pl>"
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-nimble/nimble/host/util/"
@@ -17,6 +17,10 @@
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
BLE_ROLE_BROADCASTER: 0
BLE_ROLE_CENTRAL: 1
BLE_ROLE_OBSERVER: 1
@@ -0,0 +1,33 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
pkg.name: apps/dtm
pkg.type: app
pkg.description: "Bluetooth DTM shell application"
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
pkg.homepage: "https://mynewt.apache.org/"
pkg.keywords:
pkg.deps:
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/shell"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-mcumgr/cmd/img_mgmt"
- "@mcuboot/boot/bootutil"
@@ -0,0 +1,425 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "os/mynewt.h"
#include <console/console.h>
#include <parse.h>
#include <shell/shell.h>
#include "nimble/ble.h"
#include "nimble/nimble_opt.h"
#include "host/ble_hs.h"
#include "host/ble_dtm.h"
#include <img_mgmt/img_mgmt.h>
#include <bootutil/image.h>
static const struct kv_pair phy_opts[] = {
{ "1M", 0x01 },
{ "2M", 0x02 },
{ "coded", 0x03 },
{ NULL }
};
static const struct kv_pair modulation_index_opts[] = {
{ "standard", 0x00 },
{ "stable", 0x01 },
{ NULL }
};
static int
cmd_rx_test(int argc, char **argv)
{
struct ble_dtm_rx_params params;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
params.channel = parse_arg_uint8("channel", &rc);
if ((rc != 0) || (params.channel > 39)) {
console_printf("invalid channel\n");
return rc;
}
params.phy = parse_arg_kv_dflt("phy", phy_opts, 0x01, &rc);
if (rc != 0) {
console_printf("invalid 'phy' parameter\n");
return rc;
}
params.modulation_index = parse_arg_kv_dflt("modulation_index",
modulation_index_opts, 0x00, &rc);
if (rc != 0) {
console_printf("invalid 'modulation_index' parameter\n");
return rc;
}
rc = ble_dtm_rx_start(&params);
if (rc) {
console_printf("failed to start RX test\n");
return rc;
}
console_printf("RX test started\n");
return 0;
}
static int
cmd_tx_test(int argc, char **argv)
{
struct ble_dtm_tx_params params;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
params.channel = parse_arg_uint8("channel", &rc);
if ((rc != 0) || (params.channel > 39)) {
console_printf("invalid channel\n");
return rc;
}
params.phy = parse_arg_kv_dflt("phy", phy_opts, 0x01, &rc);
if (rc != 0) {
console_printf("invalid 'phy' parameter\n");
return rc;
}
params.payload = parse_arg_uint8("payload", &rc);
if ((rc != 0) || ((params.payload > 7))) {
console_printf("invalid 'payload' parameter\n");
return rc;
}
params.test_data_len = parse_arg_uint8_dflt("data_length", 0, &rc);
if (rc != 0) {
console_printf("invalid 'data_length' parameter\n");
return rc;
}
rc = ble_dtm_tx_start(&params);
if (rc) {
console_printf("failed to start TX test\n");
return rc;
}
console_printf("TX test started\n");
return 0;
}
static int
cmd_stop_test(int argc, char **argv)
{
uint16_t num_packets;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
rc = ble_dtm_stop(&num_packets);
if (rc) {
console_printf("failed to stop test\n");
return rc;
}
console_printf("Test stopped (%u packets)\n", num_packets);
return 0;
}
static int
cmd_tx_power(int argc, char **argv)
{
struct ble_hci_vs_set_tx_pwr_cp cmd;
struct ble_hci_vs_set_tx_pwr_rp rsp;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
cmd.tx_power = parse_arg_long_bounds_dflt("power",
-127, 127, 127, &rc);
if (rc != 0) {
console_printf("invalid 'power' parameter\n");
return rc;
}
rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_TX_PWR, &cmd, sizeof(cmd),
&rsp, sizeof(rsp));
if (rc) {
console_printf("failed to set TX power\n");
return rc;
}
console_printf("TX power set to %d dBm\n", rsp.tx_power);
return 0;
}
static int
cmd_set_antenna(int argc, char **argv)
{
struct ble_hci_vs_set_antenna_cp cmd;
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
cmd.antenna = parse_arg_uint8_dflt("antenna", 0, &rc);
if (rc != 0 || ((cmd.antenna > 2))) {
console_printf("invalid 'antenna' parameter\n");
return rc;
}
rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_ANTENNA, &cmd, sizeof(cmd),
NULL, 0);
if (rc) {
console_printf("failed to set antenna\n");
return rc;
}
console_printf("Antenna set to %u\n", cmd.antenna);
return 0;
}
#define BLE_HCI_OCF_VS_TEST_CARRIER (0x0020)
static bool tx_carrier_running = false;
static int
cmd_tx_carrier(int argc, char **argv)
{
uint8_t cmd[2];
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
if (tx_carrier_running) {
console_printf("TX carrier already started\n");
return 0;
}
cmd[0] = 1;
cmd[1] = parse_arg_uint8("channel", &rc);
if ((rc != 0) || (cmd[1] > 39)) {
console_printf("invalid channel\n");
return rc;
}
rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_TEST_CARRIER, &cmd, sizeof(cmd),
NULL, 0);
if (rc) {
console_printf("failed to start TX carrier\n");
return rc;
}
console_printf("TX carrier started\n");
tx_carrier_running = true;
return 0;
}
static int
cmd_stop_carrier(int argc, char **argv)
{
uint8_t cmd[2];
int rc;
rc = parse_arg_all(argc - 1, argv + 1);
if (rc != 0) {
return rc;
}
if (!tx_carrier_running) {
console_printf("TX carrier not started\n");
return 0;
}
cmd[0] = 0;
cmd[1] = 0;
rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_TEST_CARRIER, &cmd, sizeof(cmd),
NULL, 0);
if (rc) {
console_printf("failed to stop TX carrier\n");
return rc;
}
console_printf("TX carrier stopped\n");
tx_carrier_running = false;
return 0;
}
static const struct shell_param cmd_rx_test_params[] = {
{"channel", "RX channel, usage: =[0-39]"},
{"phy", "usage: =[1M|2M], default: 1M"},
{"modulation_index", "usage: =[standard|stable], default=standard"},
{NULL}
};
static const struct shell_cmd_help cmd_rx_test_help = {
.summary = "start DTM RX test",
.usage = NULL,
.params = cmd_rx_test_params,
};
static const struct shell_param cmd_tx_test_params[] = {
{"channel", "RX channel, usage: =[0-39]"},
{"phy", "usage: =[1M|2M], default: 1M"},
{"data_length", "usage: =[0-255], default: 0"},
{"payload", "usage: =[0-7]"},
{NULL}
};
static const struct shell_cmd_help cmd_tx_test_help = {
.summary = "start DTM TX test",
.usage = NULL,
.params = cmd_tx_test_params,
};
static const struct shell_cmd_help cmd_stop_test_help = {
.summary = "stop DTM test",
.usage = NULL,
.params = NULL,
};
static const struct shell_param cmd_tx_power_params[] = {
{"power", "usage: =[-127-127], default: 127"},
{NULL}
};
static const struct shell_cmd_help cmd_tx_power_help = {
.summary = "set TX power",
.usage = NULL,
.params = cmd_tx_power_params,
};
static const struct shell_param cmd_set_antenna_params[] = {
{"antenna", "usage: =[0,1,2], default: 0"},
{NULL}
};
static const struct shell_cmd_help cmd_set_antenna_help = {
.summary = "set active antenna ",
.usage = NULL,
.params = cmd_set_antenna_params,
};
static const struct shell_param cmd_tx_carrier_params[] = {
{"channel", "TX channel, usage: =[0-39]"},
{NULL}
};
static const struct shell_cmd_help cmd_tx_carrier_help = {
.summary = "TX unmodulated carrier",
.usage = NULL,
.params = cmd_tx_carrier_params,
};
static const struct shell_cmd_help cmd_stop_carrier_help = {
.summary = "stop TX unmodulated carrier",
.usage = NULL,
.params = NULL,
};
static const struct shell_cmd dtm_commands[] = {
{
.sc_cmd = "rx-test",
.sc_cmd_func = cmd_rx_test,
.help = &cmd_rx_test_help,
},
{
.sc_cmd = "tx-test",
.sc_cmd_func = cmd_tx_test,
.help = &cmd_tx_test_help,
},
{
.sc_cmd = "stop-test",
.sc_cmd_func = cmd_stop_test,
.help = &cmd_stop_test_help,
},
{
.sc_cmd = "tx-power",
.sc_cmd_func = cmd_tx_power,
.help = &cmd_tx_power_help,
},
{
.sc_cmd = "set-antenna",
.sc_cmd_func = cmd_set_antenna,
.help = &cmd_set_antenna_help,
},
{
.sc_cmd = "tx-carrier",
.sc_cmd_func = cmd_tx_carrier,
.help = &cmd_tx_carrier_help,
},
{
.sc_cmd = "stop-carrier",
.sc_cmd_func = cmd_stop_carrier,
.help = &cmd_stop_carrier_help,
},
{ }
};
static void
on_sync(void)
{
console_printf("Host and controller synced\n");
}
static void
on_reset(int reason)
{
console_printf("Error: Resetting state; reason=%d\n", reason);
}
int
main(void)
{
struct image_version the_version;
char prompt[50];
sysinit();
img_mgmt_read_info(0, &the_version, NULL, NULL);
snprintf(prompt, sizeof(prompt), "dtm_%u.%u.%u",
the_version.iv_major, the_version.iv_minor, the_version.iv_revision);
/* Initialize the NimBLE host configuration. */
ble_hs_cfg.reset_cb = on_reset;
ble_hs_cfg.sync_cb = on_sync;
shell_register(prompt, dtm_commands);
shell_register_default_module(prompt);
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
return 0;
}
@@ -0,0 +1,529 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <ctype.h>
#include <parse.h>
#include "console/console.h"
#define CMD_MAX_ARGS 16
static char *cmd_args[CMD_MAX_ARGS][2];
static int cmd_num_args;
int
parse_arg_find_idx(const char *key)
{
int i;
for (i = 0; i < cmd_num_args; i++) {
if (strcmp(cmd_args[i][0], key) == 0) {
return i;
}
}
return -1;
}
char *
parse_arg_peek(const char *key)
{
int i;
for (i = 0; i < cmd_num_args; i++) {
if (strcmp(cmd_args[i][0], key) == 0) {
return cmd_args[i][1];
}
}
return NULL;
}
char *
parse_arg_extract(const char *key)
{
int i;
for (i = 0; i < cmd_num_args; i++) {
if (strcmp(cmd_args[i][0], key) == 0) {
/* Erase parameter. */
cmd_args[i][0][0] = '\0';
return cmd_args[i][1];
}
}
return NULL;
}
/**
* Determines which number base to use when parsing the specified numeric
* string. This just avoids base '0' so that numbers don't get interpreted as
* octal.
*/
static int
parse_arg_long_base(char *sval)
{
if (sval[0] == '0' && sval[1] == 'x') {
return 0;
} else {
return 10;
}
}
long
parse_long_bounds(char *sval, long min, long max, int *out_status)
{
char *endptr;
long lval;
lval = strtol(sval, &endptr, parse_arg_long_base(sval));
if (sval[0] != '\0' && *endptr == '\0' &&
lval >= min && lval <= max) {
*out_status = 0;
return lval;
}
*out_status = EINVAL;
return 0;
}
long
parse_arg_long_bounds_peek(char *name, long min, long max, int *out_status)
{
char *sval;
sval = parse_arg_peek(name);
if (sval == NULL) {
*out_status = ENOENT;
return 0;
}
return parse_long_bounds(sval, min, max, out_status);
}
long
parse_arg_long_bounds(char *name, long min, long max, int *out_status)
{
char *sval;
sval = parse_arg_extract(name);
if (sval == NULL) {
*out_status = ENOENT;
return 0;
}
return parse_long_bounds(sval, min, max, out_status);
}
long
parse_arg_long_bounds_dflt(char *name, long min, long max,
long dflt, int *out_status)
{
long val;
int rc;
val = parse_arg_long_bounds(name, min, max, &rc);
if (rc == ENOENT) {
rc = 0;
val = dflt;
}
*out_status = rc;
return val;
}
uint64_t
parse_arg_uint64_bounds(char *name, uint64_t min, uint64_t max, int *out_status)
{
char *endptr;
char *sval;
uint64_t lval;
sval = parse_arg_extract(name);
if (sval == NULL) {
*out_status = ENOENT;
return 0;
}
lval = strtoull(sval, &endptr, parse_arg_long_base(sval));
if (sval[0] != '\0' && *endptr == '\0' &&
lval >= min && lval <= max) {
*out_status = 0;
return lval;
}
*out_status = EINVAL;
return 0;
}
long
parse_arg_long(char *name, int *out_status)
{
return parse_arg_long_bounds(name, LONG_MIN, LONG_MAX, out_status);
}
uint8_t
parse_arg_bool(char *name, int *out_status)
{
return parse_arg_long_bounds(name, 0, 1, out_status);
}
uint8_t
parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status)
{
return parse_arg_long_bounds_dflt(name, 0, 1, dflt, out_status);
}
uint8_t
parse_arg_uint8(char *name, int *out_status)
{
return parse_arg_long_bounds(name, 0, UINT8_MAX, out_status);
}
uint16_t
parse_arg_uint16(char *name, int *out_status)
{
return parse_arg_long_bounds(name, 0, UINT16_MAX, out_status);
}
uint16_t
parse_arg_uint16_peek(char *name, int *out_status)
{
return parse_arg_long_bounds_peek(name, 0, UINT16_MAX, out_status);
}
uint32_t
parse_arg_uint32(char *name, int *out_status)
{
return parse_arg_uint64_bounds(name, 0, UINT32_MAX, out_status);
}
uint64_t
parse_arg_uint64(char *name, int *out_status)
{
return parse_arg_uint64_bounds(name, 0, UINT64_MAX, out_status);
}
uint8_t
parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status)
{
uint8_t val;
int rc;
val = parse_arg_uint8(name, &rc);
if (rc == ENOENT) {
val = dflt;
rc = 0;
}
*out_status = rc;
return val;
}
uint16_t
parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status)
{
uint16_t val;
int rc;
val = parse_arg_uint16(name, &rc);
if (rc == ENOENT) {
val = dflt;
rc = 0;
}
*out_status = rc;
return val;
}
uint32_t
parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status)
{
uint32_t val;
int rc;
val = parse_arg_uint32(name, &rc);
if (rc == ENOENT) {
val = dflt;
rc = 0;
}
*out_status = rc;
return val;
}
static uint32_t
parse_time_unit_mult(const char *str)
{
if (!strcasecmp(str, "us")) {
return 1;
} else if (!strcasecmp(str, "ms")) {
return 1000;
} else if (!strcasecmp(str, "s")) {
return 1000000;
}
return 0;
}
static uint32_t
parse_time_us(const char *str, int *out_status)
{
uint32_t val = 0;
uint32_t val_div = 1;
uint32_t val_mult = 1;
uint32_t val_us;
while (isdigit((unsigned char)*str)) {
val *= 10;
val += *str - '0';
str++;
}
if (*str == '.') {
str++;
while (isdigit((unsigned char)*str)) {
val *= 10;
val += *str - '0';
val_div *= 10;
str++;
}
}
val_mult = parse_time_unit_mult(str);
if (val_mult == 0) {
*out_status = EINVAL;
return 0;
}
if (val_mult > val_div) {
val_us = val * (val_mult / val_div);
} else {
val_us = val * (val_div / val_mult);
}
*out_status = 0;
return val_us;
}
uint32_t
parse_arg_time_dflt(char *name, int step_us, uint32_t dflt, int *out_status)
{
const char *arg;
uint32_t val;
int rc;
arg = parse_arg_peek(name);
if (!arg) {
*out_status = 0;
return dflt;
}
val = parse_time_us(arg, &rc);
if (rc) {
val = parse_arg_uint32(name, &rc);
if (rc == ENOENT) {
*out_status = 0;
return dflt;
}
} else {
val /= step_us;
parse_arg_extract(name);
}
*out_status = rc;
return val;
}
const struct kv_pair *
parse_kv_find(const struct kv_pair *kvs, char *name)
{
const struct kv_pair *kv;
int i;
for (i = 0; kvs[i].key != NULL; i++) {
kv = kvs + i;
if (strcmp(name, kv->key) == 0) {
return kv;
}
}
return NULL;
}
int
parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status)
{
const struct kv_pair *kv;
char *sval;
sval = parse_arg_extract(name);
if (sval == NULL) {
*out_status = ENOENT;
return -1;
}
kv = parse_kv_find(kvs, sval);
if (kv == NULL) {
*out_status = EINVAL;
return -1;
}
*out_status = 0;
return kv->val;
}
int
parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val,
int *out_status)
{
int val;
int rc;
val = parse_arg_kv(name, kvs, &rc);
if (rc == ENOENT) {
rc = 0;
val = def_val;
}
*out_status = rc;
return val;
}
static int
parse_arg_byte_stream_delim(char *sval, char *delims, int max_len,
uint8_t *dst, int *out_len)
{
unsigned long ul;
char *endptr;
char *token;
int i;
char *tok_ptr;
i = 0;
for (token = strtok_r(sval, delims, &tok_ptr);
token != NULL;
token = strtok_r(NULL, delims, &tok_ptr)) {
if (i >= max_len) {
return EINVAL;
}
ul = strtoul(token, &endptr, 16);
if (sval[0] == '\0' || *endptr != '\0' || ul > UINT8_MAX) {
return -1;
}
dst[i] = ul;
i++;
}
*out_len = i;
return 0;
}
int
parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len)
{
char *sval;
sval = parse_arg_extract(name);
if (sval == NULL) {
return ENOENT;
}
return parse_arg_byte_stream_delim(sval, ":-", max_len, dst, out_len);
}
int
parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len,
uint8_t *dst, int *out_len)
{
char *sval;
sval = parse_arg_extract(name);
if (sval == NULL) {
return ENOENT;
}
return parse_arg_byte_stream_delim(sval, separator, max_len, dst, out_len);
}
int
parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len)
{
int actual_len;
int rc;
rc = parse_arg_byte_stream(name, len, dst, &actual_len);
if (rc != 0) {
return rc;
}
if (actual_len != len) {
return EINVAL;
}
return 0;
}
int
parse_arg_all(int argc, char **argv)
{
char *key;
char *val;
int i;
char *tok_ptr;
cmd_num_args = 0;
for (i = 0; i < argc; i++) {
key = strtok_r(argv[i], "=", &tok_ptr);
val = strtok_r(NULL, "=", &tok_ptr);
if (key != NULL && val != NULL) {
if (strlen(key) == 0) {
console_printf("Error: invalid argument: %s\n", argv[i]);
return -1;
}
if (cmd_num_args >= CMD_MAX_ARGS) {
console_printf("Error: too many arguments");
return -1;
}
cmd_args[cmd_num_args][0] = key;
cmd_args[cmd_num_args][1] = val;
cmd_num_args++;
}
}
return 0;
}
@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef PARSE_H
#define PARSE_H
#include <inttypes.h>
struct kv_pair {
char *key;
int val;
};
uint32_t parse_arg_time_dflt(char *name, int step, uint32_t dflt, int *out_status);
const struct kv_pair *parse_kv_find(const struct kv_pair *kvs, char *name);
int parse_arg_find_idx(const char *key);
char *parse_arg_extract(const char *key);
long parse_arg_long_bounds(char *name, long min, long max, int *out_status);
long parse_arg_long_bounds_dflt(char *name, long min, long max,
long dflt, int *out_status);
uint64_t parse_arg_uint64_bounds(char *name, uint64_t min,
uint64_t max, int *out_status);
long parse_arg_long(char *name, int *staus);
uint8_t parse_arg_bool(char *name, int *status);
uint8_t parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status);
uint8_t parse_arg_uint8(char *name, int *status);
uint8_t parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status);
uint16_t parse_arg_uint16(char *name, int *status);
uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status);
uint32_t parse_arg_uint32(char *name, int *out_status);
uint32_t parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status);
uint64_t parse_arg_uint64(char *name, int *out_status);
int parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status);
int parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val,
int *out_status);
int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len);
int parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len,
uint8_t *dst, int *out_len);
int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len);
int parse_arg_all(int argc, char **argv);
#endif
@@ -0,0 +1,28 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
syscfg.vals:
# Enable the shell task.
SHELL_TASK: 1
SHELL_CMD_HELP: 1
CONSOLE_HISTORY: ram
CONSOLE_HISTORY_RAM_HISTORY_SIZE: 50
BLE_LL_DTM: 1
BLE_LL_DTM_EXTENSIONS: 1
BLE_LL_CFG_FEAT_LE_2M_PHY: 1
BLE_LL_CFG_FEAT_LE_CODED_PHY: 1
@@ -31,8 +31,8 @@ pkg.deps:
- nimble/host/services/gatt
- nimble/host/store/config
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/sysinit"
- "@apache-mynewt-core/sys/id"
@@ -421,7 +421,7 @@ static void start_periodic(void)
ble_addr_t addr;
int rc;
/* For periodic we use nstance with non-connectable advertising */
/* For periodic we use instance with non-connectable advertising */
memset (&params, 0, sizeof(params));
/* advertise using random addr */
@@ -17,6 +17,10 @@
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Disable not used GAP roles (we only do non-connectable
# advertising here)
BLE_ROLE_BROADCASTER: 1
@@ -26,10 +26,10 @@ pkg.deps:
- "@apache-mynewt-core/hw/drivers/display/cfb"
- "@apache-mynewt-core/hw/drivers/display/ssd1673"
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/shell"
- nimble/host
- nimble/host/services/gap
@@ -19,6 +19,10 @@
# Package: apps/mesh_badge
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
# Enable the shell task.
SHELL_TASK: 1
@@ -25,9 +25,9 @@ pkg.author: "Krzysztof Kopyściński krzysztof.kopyscinski@codecoup.pl"
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-nimble/nimble/host/util/"
@@ -50,6 +50,7 @@ adv_event(struct ble_gap_event *event, void *arg)
MODLOG_DFLT(INFO, "connection %s; status=%d\n",
event->connect.status == 0 ? "established" : "failed",
event->connect.status);
conn_handle = event->connect.conn_handle;
break;
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
/* connected device requests update of connection parameters,
@@ -17,6 +17,10 @@
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
BLE_ROLE_BROADCASTER: 1
BLE_ROLE_CENTRAL: 0
BLE_ROLE_OBSERVER: 0
@@ -25,9 +25,9 @@ pkg.author: "Krzysztof Kopyściński <krzysztof.kopyscinski@codecoup.pl>"
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/full"
- "@apache-mynewt-core/sys/log/full"
- "@apache-mynewt-core/sys/stats/full"
- "@apache-mynewt-core/sys/console"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/log/modlog"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-nimble/nimble/host/util/"
@@ -17,6 +17,10 @@
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: full
STATS_IMPLEMENTATION: full
BLE_ROLE_BROADCASTER: 0
BLE_ROLE_CENTRAL: 0
BLE_ROLE_OBSERVER: 1
@@ -9,7 +9,6 @@
#include <stdint.h>
#include "irq_ctrl.h"
#include "irq_sources.h"
#include <nrfx.h>
#include "cmsis.h"
#include "os/sim.h"
@@ -8,7 +8,6 @@
#include <stdint.h>
#include "irq_ctrl.h"
#include "irq_sources.h"
#include "os/sim.h"
static int currently_running_irq = -1;
@@ -23,6 +22,12 @@ extern void (* const systemVectors[256])(void);
* handler and therefore its priority handling
*/
int
os_arch_in_isr(void)
{
return currently_running_irq >= 0;
}
void posix_interrupt_raised(void)
{
uint64_t irq_lock;
@@ -142,7 +142,7 @@ ble_hci_edtt_cmdevt_tx(uint8_t *hci_ev, uint8_t edtt_type)
* A BLE_ERR_[...] error code on failure.
*/
int
ble_transport_to_hs_evt(void *buf)
ble_transport_to_hs_evt_impl(void *buf)
{
return ble_hci_edtt_cmdevt_tx(buf, BLE_HCI_EDTT_EVT);
}
@@ -156,11 +156,17 @@ ble_transport_to_hs_evt(void *buf)
* A BLE_ERR_[...] error code on failure.
*/
int
ble_transport_to_hs_acl(struct os_mbuf *om)
ble_transport_to_hs_acl_impl(struct os_mbuf *om)
{
return ble_hci_edtt_acl_tx(om);
}
void
ble_transport_hs_init(void)
{
}
/**
* @brief Clean out excess bytes from the input buffer
*/
@@ -48,11 +48,8 @@ void os_arch_frame_init(struct stack_frame *sf);
#define OS_IDLE_STACK_SIZE (4000)
#endif
static inline int
os_arch_in_isr(void)
{
return hw_irq_ctrl_get_irq_status();
}
/* Implemented in irq_handler */
int os_arch_in_isr(void);
/* Include common arch definitions and APIs */
#include "os/arch/common.h"
@@ -148,7 +148,7 @@ os_arch_restore_sr(os_sr_t osr)
{
hw_irq_ctrl_change_lock(osr);
if (!osr && bsim_pend_sv) {
if (!osr && bsim_pend_sv && !os_arch_in_isr()) {
do_ctx_sw();
}
}
@@ -17,6 +17,7 @@
#
syscfg.defs:
BABBLESIM: 1
BSP_NRF52:
description: 'Set to indicate that BSP has NRF52'
value: 1
@@ -72,3 +73,4 @@ syscfg.vals.BLE_CONTROLLER:
OS_CPUTIME_FREQ: 32768
OS_CPUTIME_TIMER_NUM: 5
BLE_LL_RFMGMT_ENABLE_TIME: 1500
BLE_LL_STACK_SIZE: 4000
@@ -29,4 +29,4 @@ pkg.deps:
- "babblesim/core"
pkg.deps.BLE_CONTROLLER:
- "@apache-mynewt-nimble/nimble/drivers/nrf52"
- "@apache-mynewt-nimble/nimble/drivers/nrf5x"
@@ -22,7 +22,7 @@ if [ -z ${BSIM_COMPONENTS_PATH+x} ]; then
echo "This board requires the BabbleSim simulator. Please set" \
"the environment variable BSIM_COMPONENTS_PATH to point to its components" \
"folder. More information can be found in" \
"https://babblesim.github.io/folder_structure_and_env.html"
"https://babblesim.github.io/folder_structure_and_env.html" 1>&2
exit 1
fi
@@ -30,7 +30,7 @@ if [ -z ${BSIM_OUT_PATH+x} ]; then
echo "This board requires the BabbleSim simulator. Please set" \
"the environment variable BSIM_OUT_PATH to point to the folder where the" \
"simulator is compiled to. More information can be found in" \
"https://babblesim.github.io/folder_structure_and_env.html"
"https://babblesim.github.io/folder_structure_and_env.html" 1>&2
exit 1
fi
@@ -18,4 +18,4 @@
syscfg.vals:
BLE_LL_PUBLIC_DEV_ADDR: 0xbabb1e000001
BLE_HCI_TRANSPORT: uart
BLE_HCI_TRANSPORT_HS: uart
@@ -26,6 +26,7 @@ syscfg.vals:
EDTT_HCI_LOG_FILE: ("hci_logs")
EDTT_HCI_LOGS: 1
BLE_LL_HCI_VS_EVENT_ON_ASSERT: 0
BLE_LL_CFG_FEAT_LE_ENCRYPTION: 1
BLE_LL_CFG_FEAT_CONN_PARAM_REQ: 1
BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG: 1
@@ -47,7 +48,6 @@ syscfg.vals:
BLE_ROLE_OBSERVER: 1
BLE_VERSION: 52
BLE_CONTROLLER: 1
BLE_LL_ROLE_CENTRAL: 1
BLE_LL_ROLE_PERIPHERAL: 1
BLE_LL_ROLE_BROADCASTER: 1
@@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_FEM_
#define H_BLE_FEM_
#ifdef __cplusplus
extern "C" {
#endif
#include "syscfg/syscfg.h"
#if MYNEWT_VAL(BLE_FEM_PA)
void ble_fem_pa_init(void);
void ble_fem_pa_enable(void);
void ble_fem_pa_disable(void);
#if MYNEWT_VAL(BLE_FEM_PA_GAIN_TUNABLE)
/* Configures FEM to selected TX power and returns expected PHY TX power */
int ble_fem_pa_tx_power_set(int tx_power);
/* returns rounded FEM TX power */
int ble_fem_pa_tx_power_round(int tx_power);
#endif
#endif
#if MYNEWT_VAL(BLE_FEM_LNA)
void ble_fem_lna_init(void);
void ble_fem_lna_enable(void);
void ble_fem_lna_disable(void);
#if MYNEWT_VAL(BLE_FEM_LNA_GAIN_TUNABLE)
/* Return current value of FEM LNA RX gain (in dBm) */
int ble_fem_lna_rx_gain(void);
#endif
#endif
#if MYNEWT_VAL(BLE_FEM_ANTENNA)
/* 0 sets default antenna, any other value is FEM specific */
int ble_fem_antenna(uint8_t antenna);
#endif
#ifdef __cplusplus
}
#endif
#endif /* H_BLE_FEM_ */
@@ -107,8 +107,8 @@ struct ble_ll_obj
uint8_t ll_state;
/* Global channel map */
uint8_t chan_map_num_used;
uint8_t chan_map[BLE_LL_CHAN_MAP_LEN];
uint8_t chan_map_used;
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
/* Number of ACL data packets supported */
@@ -118,6 +118,11 @@ struct ble_ll_obj
uint16_t ll_acl_pkt_size;
#endif
#if MYNEWT_VAL(BLE_LL_ISO)
uint8_t ll_num_iso_pkts;
uint16_t ll_iso_pkt_size;
#endif
/* Preferred PHY's */
uint8_t ll_pref_tx_phys;
uint8_t ll_pref_rx_phys;
@@ -237,6 +242,12 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats;
#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
#define BLE_LL_STATE_SCAN_AUX (7)
#endif
#if MYNEWT_VAL(BLE_LL_EXT)
#define BLE_LL_STATE_EXTERNAL (8)
#endif
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
#define BLE_LL_STATE_BIG (9)
#endif
/* LL Features */
#define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001)
@@ -289,11 +300,16 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats;
#define BLE_LL_CONN_CLEAR_FEATURE(connsm, feature) (connsm->conn_features &= ~(feature))
/* All the features which can be controlled by the Host */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE)
#define BLE_LL_HOST_CONTROLLED_FEATURES (BLE_LL_FEAT_CONN_SUBRATING_HOST)
#else
#define BLE_LL_HOST_CONTROLLED_FEATURES (0)
#endif
/* LL timing */
#define BLE_LL_IFS (150) /* usecs */
#define BLE_LL_MAFS (300) /* usecs */
#define BLE_LL_MSS (150) /* usecs */
/*
* BLE LL device address. Note that element 0 of the array is the LSB and
@@ -328,6 +344,27 @@ struct ble_dev_addr
#define BLE_LL_MAX_PDU_LEN ((BLE_LL_PDU_HDR_LEN) + (BLE_LL_MAX_PAYLOAD_LEN))
#define BLE_LL_CRCINIT_ADV (0x555555)
#define BLE_LL_CONN_HANDLE(t, h) ((((t) << 8) & BLE_LL_CONN_HANDLE_TYPE_MASK) | \
((h) & BLE_LL_CONN_HANDLE_IDX_MASK))
#define BLE_LL_CONN_HANDLE_TYPE_MASK (0x0700)
#define BLE_LL_CONN_HANDLE_IDX_MASK (0x00ff)
#define BLE_LL_CONN_HANDLE_TYPE(conn_h) (((conn_h) & BLE_LL_CONN_HANDLE_TYPE_MASK) >> 8)
#define BLE_LL_CONN_HANDLE_IDX(conn_h) ((conn_h) & BLE_LL_CONN_HANDLE_IDX_MASK)
#define BLE_LL_CONN_HANDLE_TYPE_ACL (0x00)
#define BLE_LL_CONN_HANDLE_TYPE_CIS (0x01)
#define BLE_LL_CONN_HANDLE_TYPE_BIS (0x02)
#define BLE_LL_CONN_HANDLE_TYPE_BIS_SYNC (0x03)
#define BLE_LL_CONN_HANDLE_IS_ACL(ch) \
(BLE_LL_CONN_HANDLE_TYPE(ch) == BLE_LL_CONN_HANDLE_TYPE_ACL)
#define BLE_LL_CONN_HANDLE_IS_CIS(ch) \
(BLE_LL_CONN_HANDLE_TYPE(ch) == BLE_LL_CONN_HANDLE_TYPE_CIS)
#define BLE_LL_CONN_HANDLE_IS_BIS(ch) \
(BLE_LL_CONN_HANDLE_TYPE(ch) == BLE_LL_CONN_HANDLE_TYPE_BIS)
#define BLE_LL_CONN_HANDLE_IS_BIS_SYNC(ch) \
(BLE_LL_CONN_HANDLE_TYPE(ch) == BLE_LL_CONN_HANDLE_TYPE_BIS_SYNC)
/* Access address for advertising channels */
#define BLE_ACCESS_ADDR_ADV (0x8E89BED6)
@@ -468,6 +505,7 @@ struct ble_dev_addr
/* ACAD data types */
#define BLE_LL_ACAD_CHANNEL_MAP_UPDATE_IND 0x28
#define BLE_LL_ACAD_BIGINFO 0x2C
struct ble_ll_acad_channel_map_update_ind {
uint8_t map[5];
@@ -488,10 +526,6 @@ int ble_ll_is_valid_random_addr(const uint8_t *addr);
int ble_ll_is_valid_own_addr_type(uint8_t own_addr_type,
const uint8_t *random_addr);
/* Calculate the amount of time in microseconds a PDU with payload length of
* 'payload_len' will take to transmit on a PHY 'phy_mode'. */
uint32_t ble_ll_pdu_tx_time_get(uint16_t payload_len, int phy_mode);
/* Calculate maximum octets of PDU payload which can be transmitted during
* 'usecs' on a PHY 'phy_mode'. */
uint16_t ble_ll_pdu_max_tx_octets_get(uint32_t usecs, int phy_mode);
@@ -559,8 +593,11 @@ void ble_ll_state_set(uint8_t ll_state);
/* Get the link layer state */
uint8_t ble_ll_state_get(void);
/* Send an event to LL task */
void ble_ll_event_send(struct ble_npl_event *ev);
/* Add an event to LL task */
void ble_ll_event_add(struct ble_npl_event *ev);
/* Remove an event from LL task */
void ble_ll_event_remove(struct ble_npl_event *ev);
/* Hand received pdu's to LL task */
void ble_ll_rx_pdu_in(struct os_mbuf *rxpdu);
@@ -589,10 +626,6 @@ int ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len);
/* Read set of states supported by the Link Layer */
uint64_t ble_ll_read_supp_states(void);
/* Check if octets and time are valid. Returns 0 if not valid */
int ble_ll_chk_txrx_octets(uint16_t octets);
int ble_ll_chk_txrx_time(uint16_t time);
/* Random numbers */
int ble_ll_rand_init(void);
void ble_ll_rand_sample(uint8_t rnum);
@@ -199,6 +199,20 @@ int ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len,
uint8_t *rspbuf, uint8_t *rsplen);
/* Get advertising instance with periodic advertising configured */
struct ble_ll_adv_sm *ble_ll_adv_sync_get(uint8_t handle);
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
struct ble_ll_iso_big;
/* Add BIG to periodic advertising instance */
int ble_ll_adv_sync_big_add(struct ble_ll_adv_sm *advsm,
struct ble_ll_iso_big *big);
/* Remove BIG from periodic advertising instance */
int ble_ll_adv_sync_big_remove(struct ble_ll_adv_sm *advsm,
struct ble_ll_iso_big *big);
#endif /* BLE_LL_ISO_BROADCASTER */
/* Called to notify adv code about RPA rotation */
void ble_ll_adv_rpa_timeout(void);
@@ -98,44 +98,44 @@ struct ble_ll_conn_enc_data
#endif
/* Connection state machine flags. */
union ble_ll_conn_sm_flags {
struct {
uint32_t pkt_rxd:1;
uint32_t terminate_ind_txd:1;
uint32_t terminate_ind_rxd:1;
uint32_t terminate_ind_rxd_acked:1;
uint32_t allow_periph_latency:1;
uint32_t periph_set_last_anchor:1;
uint32_t awaiting_host_reply:1;
uint32_t terminate_started:1;
uint32_t conn_update_sched:1;
uint32_t host_expects_upd_event:1;
uint32_t version_ind_sent:1;
uint32_t rxd_version_ind:1;
uint32_t chanmap_update_scheduled:1;
uint32_t conn_empty_pdu_txd:1;
uint32_t last_txd_md:1;
uint32_t conn_req_txd:1;
uint32_t send_ltk_req:1;
uint32_t encrypted:1;
uint32_t encrypt_chg_sent:1;
uint32_t le_ping_supp:1;
uint32_t csa2_supp:1;
uint32_t host_phy_update: 1;
uint32_t phy_update_sched: 1;
uint32_t ctrlr_phy_update: 1;
uint32_t phy_update_event: 1;
uint32_t peer_phy_update: 1; /* XXX:combine with ctrlr udpate bit? */
uint32_t aux_conn_req: 1;
uint32_t rxd_features:1;
uint32_t pending_hci_rd_features:1;
uint32_t pending_initiate_dle:1;
uint32_t subrate_trans:1;
uint32_t subrate_ind_txd:1;
uint32_t subrate_host_req:1;
} cfbit;
uint32_t conn_flags;
} __attribute__((packed));
struct ble_ll_conn_sm_flags {
uint32_t pkt_rxd : 1;
uint32_t last_txd_md : 1;
uint32_t empty_pdu_txd : 1;
uint32_t periph_use_latency : 1;
uint32_t periph_set_last_anchor : 1;
uint32_t csa2 : 1;
uint32_t encrypted : 1;
uint32_t encrypt_ltk_req : 1;
uint32_t encrypt_event_sent : 1;
uint32_t version_ind_txd : 1;
uint32_t version_ind_rxd : 1;
uint32_t features_rxd : 1;
uint32_t features_host_req : 1;
uint32_t terminate_started : 1;
uint32_t terminate_ind_txd : 1;
uint32_t terminate_ind_rxd : 1;
uint32_t terminate_ind_rxd_acked : 1;
uint32_t conn_update_sched : 1;
uint32_t conn_update_use_cp : 1;
uint32_t conn_update_host_w4reply : 1;
uint32_t conn_update_host_w4event : 1;
uint32_t chanmap_update_sched : 1;
uint32_t phy_update_sched : 1;
uint32_t phy_update_self_initiated : 1;
uint32_t phy_update_peer_initiated : 1;
uint32_t phy_update_host_initiated : 1;
uint32_t phy_update_host_w4event : 1;
uint32_t le_ping_supp : 1;
#if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE)
uint32_t pending_initiate_dle : 1;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE)
uint8_t subrate_trans : 1;
uint8_t subrate_ind_txd : 1;
uint8_t subrate_host_req : 1;
#endif
};
/**
* Structure used for PHY data inside a connection.
@@ -204,7 +204,7 @@ struct ble_ll_conn_subrate_req_params {
struct ble_ll_conn_sm
{
/* Connection state machine flags */
union ble_ll_conn_sm_flags csmflags;
struct ble_ll_conn_sm_flags flags;
/* Current connection handle, state and role */
uint16_t conn_handle;
@@ -227,8 +227,10 @@ struct ble_ll_conn_sm
uint16_t rem_max_rx_time;
uint16_t eff_max_tx_time;
uint16_t eff_max_rx_time;
uint16_t ota_max_rx_time;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
uint16_t host_req_max_tx_time;
uint16_t host_req_max_rx_time;
#endif
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
@@ -238,14 +240,14 @@ struct ble_ll_conn_sm
#endif
/* Used to calculate data channel index for connection */
uint8_t chanmap[BLE_LL_CHAN_MAP_LEN];
uint8_t chan_map[BLE_LL_CHAN_MAP_LEN];
uint8_t req_chanmap[BLE_LL_CHAN_MAP_LEN];
uint16_t chanmap_instant;
uint16_t channel_id; /* TODO could be union with hop and last chan used */
uint8_t hop_inc;
uint8_t data_chan_index;
uint8_t last_unmapped_chan;
uint8_t num_used_chans;
uint8_t chan_map_used;
/* Ack/Flow Control */
uint8_t tx_seqnum; /* note: can be 1 bit */
@@ -287,8 +289,7 @@ struct ble_ll_conn_sm
/* Connection timing */
uint16_t conn_itvl;
uint16_t supervision_tmo;
uint16_t min_ce_len;
uint16_t max_ce_len;
uint32_t max_ce_len_ticks;
uint16_t tx_win_off;
uint32_t anchor_point;
uint8_t anchor_point_usecs; /* XXX: can this be uint8_t ?*/
@@ -310,7 +311,8 @@ struct ble_ll_conn_sm
uint16_t subrate_base_event;
uint16_t subrate_factor;
uint16_t cont_num;
uint16_t last_pdu_event;
uint16_t cont_num_left;
uint8_t has_nonempty_pdu;
union {
struct ble_ll_conn_subrate_params subrate_trans;
@@ -377,6 +379,7 @@ struct ble_ll_conn_sm
/* For connection update procedure */
struct ble_ll_conn_upd_req conn_update_req;
uint16_t conn_update_anchor_offset_req;
/* XXX: for now, just store them all */
struct ble_ll_conn_params conn_cp;
@@ -388,29 +391,13 @@ struct ble_ll_conn_sm
#endif
#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
SLIST_ENTRY(ble_ll_conn_sm) css_sle;
uint16_t css_slot_idx;
uint16_t css_slot_idx_pending;
uint8_t css_period_idx;
#endif
};
/* Flags */
#define CONN_F_UPDATE_SCHED(csm) ((csm)->csmflags.cfbit.conn_update_sched)
#define CONN_F_EMPTY_PDU_TXD(csm) ((csm)->csmflags.cfbit.conn_empty_pdu_txd)
#define CONN_F_LAST_TXD_MD(csm) ((csm)->csmflags.cfbit.last_txd_md)
#define CONN_F_CONN_REQ_TXD(csm) ((csm)->csmflags.cfbit.conn_req_txd)
#define CONN_F_ENCRYPTED(csm) ((csm)->csmflags.cfbit.encrypted)
#define CONN_F_ENC_CHANGE_SENT(csm) ((csm)->csmflags.cfbit.encrypt_chg_sent)
#define CONN_F_LE_PING_SUPP(csm) ((csm)->csmflags.cfbit.le_ping_supp)
#define CONN_F_TERMINATE_STARTED(csm) ((csm)->csmflags.cfbit.terminate_started)
#define CONN_F_CSA2_SUPP(csm) ((csm)->csmflags.cfbit.csa2_supp)
#define CONN_F_HOST_PHY_UPDATE(csm) ((csm)->csmflags.cfbit.host_phy_update)
#define CONN_F_PHY_UPDATE_SCHED(csm) ((csm)->csmflags.cfbit.phy_update_sched)
#define CONN_F_CTRLR_PHY_UPDATE(csm) ((csm)->csmflags.cfbit.ctrlr_phy_update)
#define CONN_F_PHY_UPDATE_EVENT(csm) ((csm)->csmflags.cfbit.phy_update_event)
#define CONN_F_PEER_PHY_UPDATE(csm) ((csm)->csmflags.cfbit.peer_phy_update)
#define CONN_F_AUX_CONN_REQ(csm) ((csm)->csmflags.cfbit.aux_conn_req)
/* Role */
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
#define CONN_IS_CENTRAL(csm) (csm->conn_role == BLE_LL_CONN_ROLE_CENTRAL)
@@ -454,6 +441,9 @@ struct ble_ll_conn_sm *ble_ll_conn_find_by_handle(uint16_t handle);
struct ble_ll_conn_sm *ble_ll_conn_find_by_peer_addr(const uint8_t* addr,
uint8_t addr_type);
/* Perform channel map update on all connections (applies to central role) */
void ble_ll_conn_chan_map_update(void);
/* required for unit testing */
uint8_t ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency);
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_LL_CRYPTO_
#define H_BLE_LL_CRYPTO_
#ifdef __cplusplus
extern "C" {
#endif
int
ble_ll_crypto_cmac(const uint8_t *key, const uint8_t *in, int len,
uint8_t *out);
static inline int
ble_ll_crypto_h6(const uint8_t *w, const uint8_t *key_id, uint8_t *out)
{
return ble_ll_crypto_cmac(w, key_id, 4, out);
}
static inline int
ble_ll_crypto_h7(const uint8_t *salt, const uint8_t *w, uint8_t *out)
{
return ble_ll_crypto_cmac(salt, w, 16, out);
}
int ble_ll_crypto_h8(const uint8_t *k, const uint8_t *s, const uint8_t *key_id,
uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif /* H_BLE_LL_CRYPTO_ */
@@ -333,8 +333,9 @@ void ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle,
int ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status);
void ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm);
void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm);
void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm);
void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm, bool initial);
void ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line);
void ble_ll_hci_ev_send_vs_printf(uint8_t id, const char *fmt, ...);
void ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count,
void *pdu, size_t length);
@@ -350,6 +351,11 @@ void ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm,
void ble_ll_hci_ev_subrate_change(struct ble_ll_conn_sm *connsm, uint8_t status);
#endif
#if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED)
void ble_ll_hci_ev_send_vs_css_slot_changed(uint16_t conn_handle,
uint16_t slot_idx);
#endif
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_LL_EXT_
#define H_BLE_LL_EXT_
#ifdef __cplusplus
extern "C" {
#endif
#if MYNEWT_VAL(BLE_LL_EXT)
/* Quickstart guide:
* - create scheduling item with sched_type set to BLE_LL_SCHED_EXTERNAL
* - use sched_ext_type to differentiate between different types of custom items
* - insert into scheduler using ble_ll_sched_insert()
* - set LL state to BLE_LL_STATE_EXTERNAL when item is being executed
* - set LL state back to BLE_LL_STATE_IDLE when item is done
*/
struct ble_ll_sched_item;
/* Called when LL package is initialized (before ll_task is started) */
void ble_ll_ext_init(void);
/* Called when LL is reset (i.e. HCI_Reset) */
void ble_ll_ext_reset(void);
/* Called when LL is in "external" state and PHY starts to receive a PDU */
int ble_ll_ext_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr);
/* Called when LL is in "external" state and PHY finished to receive a PDU */
int ble_ll_ext_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr);
/* Called when PDU received in "external" state reaches LL */
void ble_ll_ext_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr);
/* Called when LL is in "external" state and was preempted */
void ble_ll_ext_halt(void);
/* Called when LL is in "external" state and PHY failed to receive a PDU */
void ble_ll_ext_wfr_timer_exp(void);
/* Called when an "external" scheduling item was removed from scheduler queue */
void ble_ll_ext_sched_removed(struct ble_ll_sched_item *sch);
#endif
#ifdef __cplusplus
}
#endif
#endif /* H_BLE_LL_EXT_ */
@@ -27,10 +27,6 @@ extern "C" {
#include "nimble/hci_common.h"
#include "nimble/transport.h"
/* For supported commands */
#define BLE_LL_SUPP_CMD_LEN (47)
extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN];
/* The largest event the controller will send. */
#define BLE_LL_MAX_EVT_LEN MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)
@@ -42,7 +38,7 @@ extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN];
*/
#define BLE_LL_CFG_NUM_HCI_CMD_PKTS (1)
typedef void (*ble_ll_hci_post_cmd_complete_cb)(void);
typedef void (*ble_ll_hci_post_cmd_complete_cb)(void *user_data);
#if MYNEWT_VAL(BLE_LL_HCI_VS)
typedef int (* ble_ll_hci_vs_cb_t)(uint16_t ocf,
@@ -61,6 +57,10 @@ struct ble_ll_hci_vs_cmd {
/* Initialize LL HCI */
void ble_ll_hci_init(void);
int ble_ll_hci_cmd_rx(uint8_t *cmdbuf);
int ble_ll_hci_acl_rx(struct os_mbuf *om);
int ble_ll_hci_iso_rx(struct os_mbuf *om);
/* Used to determine if the LE event is enabled/disabled */
bool ble_ll_hci_is_le_event_enabled(unsigned int subev);
@@ -80,8 +80,13 @@ int ble_ll_hci_chk_phy_masks(uint8_t all_phys, uint8_t tx_phys, uint8_t rx_phys,
/* Returns true if Extended Advertising HCI commands are in use */
bool ble_ll_hci_adv_mode_ext(void);
/* Get TX power compensation rounded to integer dB */
int8_t ble_ll_get_tx_pwr_compensation(void);
/* Check if max octets/time are within allowed range */
int ble_ll_hci_check_dle(uint16_t max_octets, uint16_t max_time);
void ble_ll_hci_supp_cmd_get(uint8_t *buf);
/* Used to set post HCI command hook */
void ble_ll_hci_post_cmd_cb_set(ble_ll_hci_post_cmd_complete_cb cb, void *user_data);
#if MYNEWT_VAL(BLE_LL_HCI_VS)
void ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds);
@@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_LL_ISO_BIG_
#define H_BLE_LL_ISO_BIG_
#ifdef __cplusplus
extern "C" {
#endif
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
struct ble_ll_iso_big;
struct ble_ll_iso_bis;
int ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr,
uint32_t base_ticks, uint8_t base_rem_us);
int ble_ll_iso_big_biginfo_len(struct ble_ll_iso_big *big);
struct ble_ll_iso_bis *ble_ll_iso_big_find_bis_by_handle(uint16_t conn_handle);
struct ble_ll_isoal_mux *ble_ll_iso_big_find_mux_by_handle(uint16_t conn_handle);
int ble_ll_iso_big_last_tx_timestamp_get(struct ble_ll_iso_bis *bis,
uint16_t *packet_seq_num,
uint32_t *timestamp);
void ble_ll_iso_big_chan_map_update(void);
void ble_ll_iso_big_halt(void);
int ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_iso_big_hci_terminate(const uint8_t *cmdbuf, uint8_t len);
void ble_ll_iso_big_hci_evt_complete(void);
void ble_ll_iso_big_init(void);
void ble_ll_iso_big_reset(void);
#endif /* BLE_LL_ISO_BROADCASTER */
#ifdef __cplusplus
}
#endif
#endif /* H_BLE_LL_ISO_BIG_ */
@@ -0,0 +1,84 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_LL_ISOAL_
#define H_BLE_LL_ISOAL_
#ifdef __cplusplus
extern "C" {
#endif
#if MYNEWT_VAL(BLE_LL_ISO)
struct ble_ll_isoal_mux {
/* Max PDU length */
uint8_t max_pdu;
/* Number of expected SDUs per ISO interval */
uint8_t sdu_per_interval;
/* Number of expected PDUs per SDU */
uint8_t pdu_per_sdu;
/* Number of SDUs required to fill complete BIG/CIG event (i.e. with pt) */
uint8_t sdu_per_event;
/* Number of SDUs available for current event */
uint8_t sdu_in_event;
STAILQ_HEAD(, os_mbuf_pkthdr) sdu_q;
struct os_mbuf *frag;
uint32_t sdu_counter;
uint32_t event_tx_timestamp;
uint32_t last_tx_timestamp;
uint16_t last_tx_packet_seq_num;
};
void
ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux, uint8_t max_pdu,
uint32_t iso_interval_us, uint32_t sdu_interval_us,
uint8_t bn, uint8_t pte);
void ble_ll_isoal_mux_free(struct ble_ll_isoal_mux *mux);
int ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux,
uint32_t timestamp);
int ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux);
int
ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx,
uint8_t *llid, void *dptr);
/* HCI command handlers */
int ble_ll_isoal_hci_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen,
uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_isoal_hci_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen,
uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_isoal_hci_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen,
uint8_t *rspbuf, uint8_t *rsplen);
void ble_ll_isoal_init(void);
void ble_ll_isoal_reset(void);
int ble_ll_isoal_data_in(struct os_mbuf *om);
#endif /* BLE_LL_ISO */
#ifdef __cplusplus
}
#endif
#endif /* H_BLE_LL_ISOAL_ */
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_LL_PDU_
#define H_BLE_LL_PDU_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Header mask for keystream generation */
#define BLE_LL_PDU_HEADERMASK_DATA (0xe3)
#define BLE_LL_PDU_HEADERMASK_BIS (0xc3)
#define BLE_LL_PDU_HEADERMASK_CIS (0xa3)
#define BLE_LL_PDU_PREAMBLE_1M_LEN (1)
#define BLE_LL_PDU_PREAMBLE_2M_LEN (2)
#define BLE_LL_PDU_AA_LEN (4)
#define BLE_LL_PDU_HEADER_LEN (2)
#define BLE_LL_PDU_CRC_LEN (3)
uint32_t ble_ll_pdu_syncword_us(uint8_t phy_mode);
uint32_t ble_ll_pdu_us(uint8_t payload_len, uint8_t phy_mode);
#ifdef __cplusplus
}
#endif
#endif /* H_BLE_LL_PDU_ */
@@ -235,11 +235,6 @@ void ble_ll_scan_wfr_timer_exp(void);
/* Called when scan could be interrupted */
void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
/* Called to parse extended advertising*/
void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data);
#endif
/* Called to halt currently running scan */
void ble_ll_scan_halt(void);
@@ -29,8 +29,8 @@ extern "C" {
struct ble_ll_scan_aux_data;
void ble_ll_scan_aux_init(void);
int ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time,
uint8_t pdu_time_rem, uint32_t aux_ptr);
int ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_ticks,
uint8_t pdu_rem_us, uint32_t aux_ptr);
int ble_ll_scan_aux_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr);
int ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok);
void ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr);

Some files were not shown because too many files have changed in this diff Show More