Update bt fork to be based on v5.3
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(¶ms);
|
||||
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(¶ms);
|
||||
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 (¶ms, 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
Reference in New Issue
Block a user