mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-31 10:30:58 +00:00
feat(west): introduce zephyr into firmware monorepo
[no changelog]
This commit is contained in:
parent
e196413bb7
commit
09a894e0b6
9
.gitignore
vendored
9
.gitignore
vendored
@ -11,3 +11,12 @@ __pycache__/
|
||||
proto.gv*
|
||||
.DS_Store
|
||||
crypto/tests/libtrezor-crypto.so.dSYM/
|
||||
/west/.west/
|
||||
/west/bootloader/
|
||||
/west/modules/
|
||||
/west/nrf/
|
||||
/west/nrfxlib/
|
||||
/west/test/
|
||||
/west/tools/
|
||||
/west/zephyr/
|
||||
/west/trezor/build/
|
||||
|
@ -8,6 +8,7 @@ ignore-paths=
|
||||
crypto,
|
||||
legacy,
|
||||
storage,
|
||||
west,
|
||||
fail-under=10.0
|
||||
jobs=0
|
||||
load-plugins=trezor_pylint_plugin
|
||||
|
@ -5,6 +5,7 @@ ignore: |
|
||||
vendor/
|
||||
/common/defs/ethereum/chains/
|
||||
/common/defs/ethereum/tokens/
|
||||
/west/
|
||||
|
||||
rules:
|
||||
# fix for truthy warning on github action files
|
||||
|
@ -3,3 +3,4 @@
|
||||
^\./crypto/
|
||||
^\./legacy/
|
||||
^\./storage/
|
||||
^\./west/workspace/
|
||||
|
9
west/trezor/CMakeLists.txt
Normal file
9
west/trezor/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# This CMake file is picked by the Zephyr build system because it is defined
|
||||
# as the module CMake entry point (see zephyr/module.yml).
|
||||
|
||||
|
||||
zephyr_include_directories(include)
|
||||
|
7
west/trezor/Kconfig
Normal file
7
west/trezor/Kconfig
Normal file
@ -0,0 +1,7 @@
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# This Kconfig file is picked by the Zephyr build system because it is defined
|
||||
# as the module Kconfig entry point (see zephyr/module.yml). You can browse
|
||||
# module options by going to Zephyr -> Modules in Kconfig.
|
||||
|
72
west/trezor/README.md
Normal file
72
west/trezor/README.md
Normal file
@ -0,0 +1,72 @@
|
||||
# Trezor BLE Gateway
|
||||
|
||||
Welcome to the **Trezor BLE Gateway** project!
|
||||
This repository contains the source code and instructions to build and flash the application onto the `t3w1_nrf52833` board.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Install the toolchain](#install-the-toolchain)
|
||||
- [Launch the nRF Shell](#launch-the-nrf-shell)
|
||||
- [Initialize the Workspace](#initialize-the-workspace)
|
||||
- [Update nRF Connect SDK Modules](#update-nrf-connect-sdk-modules)
|
||||
- [Build the Application](#build-the-application)
|
||||
- [Flash the Application](#flash-the-application)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have met the following requirements:
|
||||
|
||||
- **nrfutil**: Install [nrfutil](https://docs.nordicsemi.com/bundle/nrfutil/page/README.html). This tool is essential for managing the nRF Connect SDK and toolchains.
|
||||
- **Git**: Ensure you have Git installed for cloning repositories.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Follow these steps to set up the project on your local machine.
|
||||
|
||||
### Install the toolchain
|
||||
|
||||
Using nrfutil, install the required toolchain for the nRF Connect SDK:
|
||||
```sh
|
||||
nrfutil toolchain-manager install --ncs-version v2.6.2
|
||||
```
|
||||
|
||||
### Launch the nRF Shell
|
||||
|
||||
First, launch the nRF shell using the `nrfutil` toolchain manager:
|
||||
|
||||
```sh
|
||||
nrfutil toolchain-manager launch --shell
|
||||
```
|
||||
|
||||
### Initialize the Workspace
|
||||
Initialize your West workspace for the Trezor BLE Gateway project:
|
||||
```sh
|
||||
cd west
|
||||
west init -l ./trezor
|
||||
```
|
||||
|
||||
### Update nRF Connect SDK Modules
|
||||
|
||||
Update the modules:
|
||||
```sh
|
||||
west update
|
||||
```
|
||||
|
||||
|
||||
### Building the Application
|
||||
Build the application for the t3w1_revA_nrf52832 board:
|
||||
```sh
|
||||
cd trezor
|
||||
west build ./trezor-ble -b t3w1_revA_nrf52832
|
||||
```
|
||||
|
||||
|
||||
### Flashing the Application
|
||||
Flash the compiled application onto the board:
|
||||
```sh
|
||||
west flash
|
||||
```
|
14
west/trezor/boards/arm/t3w1_d1_nrf52833/Kconfig.defconfig
Normal file
14
west/trezor/boards/arm/t3w1_d1_nrf52833/Kconfig.defconfig
Normal file
@ -0,0 +1,14 @@
|
||||
# nRF52833 DK NRF52833 board configuration
|
||||
|
||||
# Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if BOARD_T3W1_D1_NRF52833
|
||||
|
||||
config BOARD
|
||||
default "t3w1_d1_nrf52833"
|
||||
|
||||
config BT_CTLR
|
||||
default BT
|
||||
|
||||
endif # BOARD_T3W1_NRF52833
|
@ -0,0 +1,7 @@
|
||||
# nRF52833 DK NRF52833 board configuration
|
||||
|
||||
# Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_T3W1_D1_NRF52833
|
||||
select SOC_NRF52833_QIAA
|
12
west/trezor/boards/arm/t3w1_d1_nrf52833/board.cmake
Normal file
12
west/trezor/boards/arm/t3w1_d1_nrf52833/board.cmake
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000")
|
||||
board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000")
|
||||
|
||||
set(OPENOCD_NRF5_SUBFAMILY "nrf52")
|
||||
|
||||
include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake)
|
8
west/trezor/boards/arm/t3w1_d1_nrf52833/board.yml
Normal file
8
west/trezor/boards/arm/t3w1_d1_nrf52833/board.yml
Normal file
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board:
|
||||
name: t3w1_d1_nrf52833
|
||||
vendor: vendor
|
||||
socs:
|
||||
- name: nrf52833
|
@ -0,0 +1,7 @@
|
||||
# Copyright (c) 2024 Nordic Semiconductor
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Suppress "unique_unit_address_if_enabled" to handle the following overlaps:
|
||||
# - power@40000000 & clock@40000000 & bprot@40000000
|
||||
# - acl@4001e000 & flash-controller@4001e000
|
||||
list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled")
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&pinctrl {
|
||||
uart0_default: uart0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 0, 27)>,
|
||||
<NRF_PSEL(UART_RTS, 0, 8)>;
|
||||
};
|
||||
group2 {
|
||||
psels = <NRF_PSEL(UART_RX, 0, 26)>,
|
||||
<NRF_PSEL(UART_CTS, 0, 6)>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
uart0_sleep: uart0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 0, 27)>,
|
||||
<NRF_PSEL(UART_RX, 0, 26)>,
|
||||
<NRF_PSEL(UART_RTS, 0, 8)>,
|
||||
<NRF_PSEL(UART_CTS, 0, 6)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
spi0_default: spi0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 1, 5)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 0, 19)>,
|
||||
<NRF_PSEL(SPIM_MISO, 1, 3)>;
|
||||
};
|
||||
};
|
||||
|
||||
spi0_sleep: spi0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 1, 5)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 0, 19)>,
|
||||
<NRF_PSEL(SPIM_MISO, 1, 3)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
};
|
145
west/trezor/boards/arm/t3w1_d1_nrf52833/t3w1_d1_nrf52833.dts
Normal file
145
west/trezor/boards/arm/t3w1_d1_nrf52833/t3w1_d1_nrf52833.dts
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <nordic/nrf52833_qiaa.dtsi>
|
||||
#include "t3w1_d1_nrf52833-pinctrl.dtsi"
|
||||
#include <zephyr/dt-bindings/input/input-event-codes.h>
|
||||
|
||||
/ {
|
||||
model = "T3W1 D1 NRF52833";
|
||||
compatible = "nordic,t3w1_d1_nrf52833";
|
||||
|
||||
chosen {
|
||||
zephyr,console = &uart0;
|
||||
zephyr,shell-uart = &uart0;
|
||||
zephyr,uart-mcumgr = &uart0;
|
||||
zephyr,bt-mon-uart = &uart0;
|
||||
zephyr,bt-c2h-uart = &uart0;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,code-partition = &slot0_partition;
|
||||
zephyr,ieee802154 = &ieee802154;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
led0: led_0 {
|
||||
gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
|
||||
label = "Green LED 0";
|
||||
};
|
||||
led1: led_1 {
|
||||
gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
|
||||
label = "Green LED 1";
|
||||
};
|
||||
out0: out_0 {
|
||||
gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
|
||||
label = "FW Running";
|
||||
};
|
||||
};
|
||||
|
||||
buttons {
|
||||
compatible = "gpio-keys";
|
||||
button0: button_0 {
|
||||
gpios = <&gpio1 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
|
||||
label = "Push button switch 0";
|
||||
zephyr,code = <INPUT_KEY_0>;
|
||||
};
|
||||
trezor_ready: trezor_ready {
|
||||
gpios = <&gpio0 30 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
|
||||
label = "Trezor ready";
|
||||
zephyr,code = <INPUT_KEY_1>;
|
||||
};
|
||||
};
|
||||
|
||||
/* These aliases are provided for compatibility with samples */
|
||||
aliases {
|
||||
led0 = &led0;
|
||||
led1 = &led1;
|
||||
sw0 = &button0;
|
||||
bootloader-led0 = &led0;
|
||||
mcuboot-button0 = &button0;
|
||||
mcuboot-led0 = &led0;
|
||||
watchdog0 = &wdt0;
|
||||
};
|
||||
};
|
||||
|
||||
&adc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uicr {
|
||||
gpio-as-nreset;
|
||||
};
|
||||
|
||||
&gpiote {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <1000000>;
|
||||
pinctrl-0 = <&uart0_default>;
|
||||
pinctrl-1 = <&uart0_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
hw-flow-control;
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "okay";
|
||||
pinctrl-0 = <&spi0_default>;
|
||||
pinctrl-1 = <&spi0_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
cs-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
|
||||
reg_my_spi_master: spi-dev-a@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&ieee802154 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
boot_partition: partition@0 {
|
||||
label = "mcuboot";
|
||||
reg = <0x00000000 0xC000>;
|
||||
};
|
||||
slot0_partition: partition@c000 {
|
||||
label = "image-0";
|
||||
reg = <0x0000C000 0x37000>;
|
||||
};
|
||||
slot1_partition: partition@43000 {
|
||||
label = "image-1";
|
||||
reg = <0x00043000 0x37000>;
|
||||
};
|
||||
storage_partition: partition@7a000 {
|
||||
label = "storage";
|
||||
reg = <0x0007A000 0x00006000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
zephyr_udc0: &usbd {
|
||||
compatible = "nordic,nrf-usbd";
|
||||
status = "okay";
|
||||
};
|
@ -0,0 +1,16 @@
|
||||
identifier: t3w1_d1_nrf52833
|
||||
name: tw31-d1-NRF52833
|
||||
type: mcu
|
||||
arch: arm
|
||||
ram: 128
|
||||
flash: 512
|
||||
toolchain:
|
||||
- zephyr
|
||||
- gnuarmemb
|
||||
- xtools
|
||||
supported:
|
||||
- usb_device
|
||||
- ble
|
||||
- gpio
|
||||
- watchdog
|
||||
- counter
|
@ -0,0 +1,22 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Enable MPU
|
||||
CONFIG_ARM_MPU=y
|
||||
|
||||
# Enable hardware stack protection
|
||||
CONFIG_HW_STACK_PROTECTION=y
|
||||
|
||||
# Enable RTT
|
||||
CONFIG_USE_SEGGER_RTT=y
|
||||
|
||||
# enable GPIO
|
||||
CONFIG_GPIO=y
|
||||
|
||||
# enable uart driver
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
# enable console
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_UART_CONSOLE=y
|
||||
|
||||
CONFIG_PINCTRL=y
|
14
west/trezor/boards/arm/t3w1_revA_nrf52832/Kconfig.defconfig
Normal file
14
west/trezor/boards/arm/t3w1_revA_nrf52832/Kconfig.defconfig
Normal file
@ -0,0 +1,14 @@
|
||||
# T3W1 REVA NRF52833 board configuration
|
||||
|
||||
# Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if BOARD_T3W1_REVA_NRF52832
|
||||
|
||||
config BOARD
|
||||
default "t3w1_revA_nrf52832"
|
||||
|
||||
config BT_CTLR
|
||||
default BT
|
||||
|
||||
endif # BOARD_T3W1_REVA_NRF52832
|
@ -0,0 +1,7 @@
|
||||
# T3W1 REVA NRF52832 board configuration
|
||||
|
||||
# Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_T3W1_REVA_NRF52832
|
||||
select SOC_NRF52832_CIAA
|
12
west/trezor/boards/arm/t3w1_revA_nrf52832/board.cmake
Normal file
12
west/trezor/boards/arm/t3w1_revA_nrf52832/board.cmake
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board_runner_args(jlink "--device=nRF52832_xxAA" "--speed=4000")
|
||||
board_runner_args(pyocd "--target=nrf52832" "--frequency=4000000")
|
||||
|
||||
set(OPENOCD_NRF5_SUBFAMILY "nrf52")
|
||||
|
||||
include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake)
|
8
west/trezor/boards/arm/t3w1_revA_nrf52832/board.yml
Normal file
8
west/trezor/boards/arm/t3w1_revA_nrf52832/board.yml
Normal file
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board:
|
||||
name: t3w1_revA_nrf52832
|
||||
vendor: vendor
|
||||
socs:
|
||||
- name: nrf52832
|
@ -0,0 +1,7 @@
|
||||
# Copyright (c) 2024 Nordic Semiconductor
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Suppress "unique_unit_address_if_enabled" to handle the following overlaps:
|
||||
# - power@40000000 & clock@40000000 & bprot@40000000
|
||||
# - acl@4001e000 & flash-controller@4001e000
|
||||
list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled")
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&pinctrl {
|
||||
uart0_default: uart0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 0, 6)>,
|
||||
<NRF_PSEL(UART_RTS, 0, 7)>;
|
||||
};
|
||||
group2 {
|
||||
psels = <NRF_PSEL(UART_RX, 0, 9)>,
|
||||
<NRF_PSEL(UART_CTS, 0, 8)>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
uart0_sleep: uart0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 0, 6)>,
|
||||
<NRF_PSEL(UART_RX, 0, 9)>,
|
||||
<NRF_PSEL(UART_RTS, 0, 7)>,
|
||||
<NRF_PSEL(UART_CTS, 0, 8)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
spi0_default: spi0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 0, 3)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 0, 1)>,
|
||||
<NRF_PSEL(SPIM_MISO, 0, 2)>;
|
||||
};
|
||||
};
|
||||
|
||||
spi0_sleep: spi0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 0, 3)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 0, 1)>,
|
||||
<NRF_PSEL(SPIM_MISO, 0, 2)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
};
|
132
west/trezor/boards/arm/t3w1_revA_nrf52832/t3w1_revA_nrf52832.dts
Normal file
132
west/trezor/boards/arm/t3w1_revA_nrf52832/t3w1_revA_nrf52832.dts
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <nordic/nrf52832_ciaa.dtsi>
|
||||
#include "t3w1_revA_nrf52832-pinctrl.dtsi"
|
||||
#include <zephyr/dt-bindings/input/input-event-codes.h>
|
||||
|
||||
/ {
|
||||
model = "T3W1 REVA NRF52832";
|
||||
compatible = "nordic,t3w1_revA_nrf52832";
|
||||
|
||||
chosen {
|
||||
zephyr,console = &uart0;
|
||||
zephyr,shell-uart = &uart0;
|
||||
zephyr,uart-mcumgr = &uart0;
|
||||
zephyr,bt-mon-uart = &uart0;
|
||||
zephyr,bt-c2h-uart = &uart0;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,code-partition = &slot0_partition;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
led0: led_0 {
|
||||
gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
|
||||
label = "Green LED 0";
|
||||
};
|
||||
led1: led_1 {
|
||||
gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
|
||||
label = "Green LED 1";
|
||||
};
|
||||
out0: out_0 {
|
||||
gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
|
||||
label = "FW Running";
|
||||
};
|
||||
};
|
||||
|
||||
buttons {
|
||||
compatible = "gpio-keys";
|
||||
button0: button_0 {
|
||||
gpios = <&gpio0 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
|
||||
label = "Push button switch 0";
|
||||
zephyr,code = <INPUT_KEY_0>;
|
||||
};
|
||||
trezor_ready: trezor_ready {
|
||||
gpios = <&gpio0 29 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
|
||||
label = "Trezor ready";
|
||||
zephyr,code = <INPUT_KEY_1>;
|
||||
};
|
||||
};
|
||||
|
||||
/* These aliases are provided for compatibility with samples */
|
||||
aliases {
|
||||
led0 = &led0;
|
||||
led1 = &led1;
|
||||
sw0 = &button0;
|
||||
bootloader-led0 = &led0;
|
||||
mcuboot-button0 = &button0;
|
||||
mcuboot-led0 = &led0;
|
||||
watchdog0 = &wdt0;
|
||||
};
|
||||
};
|
||||
|
||||
&adc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uicr {
|
||||
gpio-as-nreset;
|
||||
nfct-pins-as-gpios;
|
||||
};
|
||||
|
||||
&gpiote {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <1000000>;
|
||||
pinctrl-0 = <&uart0_default>;
|
||||
pinctrl-1 = <&uart0_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
hw-flow-control;
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "okay";
|
||||
pinctrl-0 = <&spi0_default>;
|
||||
pinctrl-1 = <&spi0_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
cs-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
||||
reg_my_spi_master: spi-dev-a@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
boot_partition: partition@0 {
|
||||
label = "mcuboot";
|
||||
reg = <0x00000000 0xc000>;
|
||||
};
|
||||
slot0_partition: partition@c000 {
|
||||
label = "image-0";
|
||||
reg = <0x0000C000 0x37000>;
|
||||
};
|
||||
slot1_partition: partition@43000 {
|
||||
label = "image-1";
|
||||
reg = <0x00043000 0x37000>;
|
||||
};
|
||||
storage_partition: partition@7a000 {
|
||||
label = "storage";
|
||||
reg = <0x0007a000 0x00006000>;
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
identifier: t3w1_revA_nrf52832
|
||||
name: tw31-revA-NRF52832
|
||||
type: mcu
|
||||
arch: arm
|
||||
ram: 64
|
||||
flash: 512
|
||||
toolchain:
|
||||
- zephyr
|
||||
- gnuarmemb
|
||||
- xtools
|
||||
supported:
|
||||
- ble
|
||||
- gpio
|
||||
- watchdog
|
||||
- counter
|
@ -0,0 +1,22 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Enable MPU
|
||||
CONFIG_ARM_MPU=y
|
||||
|
||||
# Enable hardware stack protection
|
||||
CONFIG_HW_STACK_PROTECTION=y
|
||||
|
||||
# Enable RTT
|
||||
CONFIG_USE_SEGGER_RTT=y
|
||||
|
||||
# enable GPIO
|
||||
CONFIG_GPIO=y
|
||||
|
||||
# enable uart driver
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
# enable console
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_UART_CONSOLE=y
|
||||
|
||||
CONFIG_PINCTRL=y
|
23
west/trezor/dts/bindings/sensor/zephyr,example-sensor.yaml
Normal file
23
west/trezor/dts/bindings/sensor/zephyr,example-sensor.yaml
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
An example sensor that reads the GPIO level defined in input-gpios. The
|
||||
purpose of this sensor is to demonstrate how to create out-of-tree drivers.
|
||||
|
||||
Example definition in devicetree:
|
||||
|
||||
example-sensor {
|
||||
compatible = "zephyr,example-sensor";
|
||||
input-gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
|
||||
};
|
||||
|
||||
compatible: "zephyr,example-sensor"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
input-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: Input GPIO to be sensed.
|
49
west/trezor/scripts/example_west_command.py
Normal file
49
west/trezor/scripts/example_west_command.py
Normal file
@ -0,0 +1,49 @@
|
||||
# Copyright (c) 2019 Foundries.io
|
||||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'''example_west_command.py
|
||||
|
||||
Example of a west extension in the example-application repository.'''
|
||||
|
||||
from west.commands import WestCommand # your extension must subclass this
|
||||
from west import log # use this for user output
|
||||
|
||||
class ExampleWestCommand(WestCommand):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
'example-west-command', # gets stored as self.name
|
||||
'an example west extension command', # self.help
|
||||
# self.description:
|
||||
'''\
|
||||
A multi-line description of example-west-command.
|
||||
|
||||
You can split this up into multiple paragraphs and they'll get
|
||||
reflowed for you. You can also pass
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter when calling
|
||||
parser_adder.add_parser() below if you want to keep your line
|
||||
endings.''')
|
||||
|
||||
def do_add_parser(self, parser_adder):
|
||||
# This is a bit of boilerplate, which allows you full control over the
|
||||
# type of argparse handling you want. The "parser_adder" argument is
|
||||
# the return value of an argparse.ArgumentParser.add_subparsers() call.
|
||||
parser = parser_adder.add_parser(self.name,
|
||||
help=self.help,
|
||||
description=self.description)
|
||||
|
||||
# Add some example options using the standard argparse module API.
|
||||
parser.add_argument('-o', '--optional', help='an optional argument')
|
||||
parser.add_argument('required', help='a required argument')
|
||||
|
||||
return parser # gets stored as self.parser
|
||||
|
||||
def do_run(self, args, unknown_args):
|
||||
# This gets called when the user runs the command, e.g.:
|
||||
#
|
||||
# $ west my-command-name -o FOO BAR
|
||||
# --optional is FOO
|
||||
# required is BAR
|
||||
log.inf('--optional is', args.optional)
|
||||
log.inf('required is', args.required)
|
6
west/trezor/scripts/west-commands.yml
Normal file
6
west/trezor/scripts/west-commands.yml
Normal file
@ -0,0 +1,6 @@
|
||||
west-commands:
|
||||
- file: scripts/example_west_command.py
|
||||
commands:
|
||||
- name: example-west-command
|
||||
class: ExampleWestCommand
|
||||
help: an example west extension command
|
8
west/trezor/tests/lib/custom/CMakeLists.txt
Normal file
8
west/trezor/tests/lib/custom/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, Legrand North America, LLC.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(app_lib_custom_test)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
2
west/trezor/tests/lib/custom/prj.conf
Normal file
2
west/trezor/tests/lib/custom/prj.conf
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_ZTEST=y
|
||||
CONFIG_CUSTOM=y
|
38
west/trezor/tests/lib/custom/src/main.c
Normal file
38
west/trezor/tests/lib/custom/src/main.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Legrand North America, LLC.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file test custom_lib library
|
||||
*
|
||||
* This suite verifies that the methods provided with the custom_lib
|
||||
* library works correctly.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
#include <app/lib/custom.h>
|
||||
|
||||
ZTEST(custom_lib, test_get_value) {
|
||||
/* Verify standard behavior */
|
||||
zassert_equal(custom_get_value(INT_MIN), INT_MIN,
|
||||
"get_value failed input of INT_MIN");
|
||||
zassert_equal(custom_get_value(INT_MIN + 1), INT_MIN + 1,
|
||||
"get_value failed input of INT_MIN + 1");
|
||||
zassert_equal(custom_get_value(-1), -1, "get_value failed input of -1");
|
||||
zassert_equal(custom_get_value(1), 1, "get_value failed input of 1");
|
||||
zassert_equal(custom_get_value(INT_MAX - 1), INT_MAX - 1,
|
||||
"get_value failed input of INT_MAX - 1");
|
||||
zassert_equal(custom_get_value(INT_MAX), INT_MAX,
|
||||
"get_value failed input of INT_MAX");
|
||||
|
||||
/* Verify override behavior */
|
||||
zassert_equal(custom_get_value(0), CONFIG_CUSTOM_GET_VALUE_DEFAULT,
|
||||
"get_value failed input of 0");
|
||||
}
|
||||
|
||||
ZTEST_SUITE(custom_lib, NULL, NULL, NULL, NULL, NULL);
|
9
west/trezor/tests/lib/custom/testcase.yaml
Normal file
9
west/trezor/tests/lib/custom/testcase.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
common:
|
||||
tags: extensibility
|
||||
integration_platforms:
|
||||
- custom_plank
|
||||
- qemu_cortex_m0
|
||||
tests:
|
||||
lib.custom: {}
|
||||
lib.custom.non_default:
|
||||
extra_args: CONFIG_CUSTOM_GET_VALUE_DEFAULT=6
|
26
west/trezor/trezor-ble/CMakeLists.txt
Normal file
26
west/trezor/trezor-ble/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
#
|
||||
# Copyright (c) 2018 Nordic Semiconductor
|
||||
#
|
||||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(NONE)
|
||||
|
||||
# NORDIC SDK APP START
|
||||
target_sources(app PRIVATE
|
||||
src/main.c
|
||||
src/connection.c
|
||||
src/advertising.c
|
||||
src/events.c
|
||||
src/uart.c
|
||||
src/spi.c
|
||||
src/int_comm.c
|
||||
src/trz_nus.c
|
||||
)
|
||||
|
||||
|
||||
# NORDIC SDK APP END
|
||||
|
||||
zephyr_library_include_directories(.)
|
43
west/trezor/trezor-ble/Kconfig
Normal file
43
west/trezor/trezor-ble/Kconfig
Normal file
@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (c) 2018 Nordic Semiconductor
|
||||
#
|
||||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
#
|
||||
|
||||
source "Kconfig.zephyr"
|
||||
|
||||
menu "Nordic UART BLE GATT service sample"
|
||||
|
||||
config BT_NUS_THREAD_STACK_SIZE
|
||||
int "Thread stack size"
|
||||
default 1024
|
||||
help
|
||||
Stack size used in each of the two threads
|
||||
|
||||
config BT_NUS_UART_BUFFER_SIZE
|
||||
int "UART payload buffer element size"
|
||||
default 40
|
||||
help
|
||||
Size of the payload buffer in each RX and TX FIFO element
|
||||
|
||||
config BT_NUS_SECURITY_ENABLED
|
||||
bool "Enable security"
|
||||
default y
|
||||
select BT_SMP
|
||||
help
|
||||
"Enable BLE security for the UART service"
|
||||
|
||||
config BT_NUS_UART_RX_WAIT_TIME
|
||||
int "Timeout for UART RX complete event"
|
||||
default 50000
|
||||
help
|
||||
Wait for RX complete event time in microseconds
|
||||
|
||||
config BT_NUS_UART_ASYNC_ADAPTER
|
||||
bool "Enable UART async adapter"
|
||||
select SERIAL_SUPPORT_ASYNC
|
||||
help
|
||||
Enables asynchronous adapter for UART drives that supports only
|
||||
IRQ interface.
|
||||
|
||||
endmenu
|
5
west/trezor/trezor-ble/VERSION
Normal file
5
west/trezor/trezor-ble/VERSION
Normal file
@ -0,0 +1,5 @@
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 0
|
||||
PATCHLEVEL = 0
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION =
|
16
west/trezor/trezor-ble/app.yaml
Normal file
16
west/trezor/trezor-ble/app.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
# This file is provided so that the application can be compiled using Twister,
|
||||
# the Zephyr testing tool. In this file, multiple combinations can be specified,
|
||||
# so that you can easily test all of them locally or in CI.
|
||||
sample:
|
||||
description: Trezor BLE gateway
|
||||
name: W001
|
||||
common:
|
||||
sysbuild: true
|
||||
build_only: true
|
||||
integration_platforms:
|
||||
- t3w1_d1_nrf52833, t3w1_revA_nrf52832
|
||||
tests:
|
||||
app.default: {}
|
||||
app.debug:
|
||||
extra_overlay_confs:
|
||||
- debug.conf
|
6
west/trezor/trezor-ble/boards/t3w1_d1_nrf52833.conf
Normal file
6
west/trezor/trezor-ble/boards/t3w1_d1_nrf52833.conf
Normal file
@ -0,0 +1,6 @@
|
||||
#
|
||||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
#
|
||||
|
11
west/trezor/trezor-ble/boards/t3w1_d1_nrf52833.overlay
Normal file
11
west/trezor/trezor-ble/boards/t3w1_d1_nrf52833.overlay
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
*/
|
||||
/ {
|
||||
chosen {
|
||||
nordic,nus-uart = &uart0;
|
||||
};
|
||||
};
|
||||
|
6
west/trezor/trezor-ble/boards/t3w1_revA_nrf52832.conf
Normal file
6
west/trezor/trezor-ble/boards/t3w1_revA_nrf52832.conf
Normal file
@ -0,0 +1,6 @@
|
||||
#
|
||||
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
#
|
||||
|
11
west/trezor/trezor-ble/boards/t3w1_revA_nrf52832.overlay
Normal file
11
west/trezor/trezor-ble/boards/t3w1_revA_nrf52832.overlay
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
*/
|
||||
/ {
|
||||
chosen {
|
||||
nordic,nus-uart = &uart0;
|
||||
};
|
||||
};
|
||||
|
12
west/trezor/trezor-ble/debug.conf
Normal file
12
west/trezor/trezor-ble/debug.conf
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# This is a Kconfig fragment which can be used to enable debug-related options
|
||||
# in the application. See the README for more details.
|
||||
|
||||
# compiler
|
||||
CONFIG_DEBUG_OPTIMIZATIONS=y
|
||||
|
||||
# logging
|
||||
CONFIG_LOG=y
|
||||
CONFIG_APP_LOG_LEVEL_DBG=y
|
91
west/trezor/trezor-ble/prj.conf
Normal file
91
west/trezor/trezor-ble/prj.conf
Normal file
@ -0,0 +1,91 @@
|
||||
#
|
||||
# Copyright (c) 2018 Nordic Semiconductor
|
||||
#
|
||||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
#
|
||||
CONFIG_CLOCK_CONTROL=y
|
||||
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
|
||||
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y
|
||||
CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD=4000
|
||||
|
||||
# Enable the UART driver
|
||||
CONFIG_UART_ASYNC_API=y
|
||||
CONFIG_NRFX_UARTE0=y
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
# Enable the SPI driver
|
||||
CONFIG_SPI=y
|
||||
CONFIG_NRFX_SPIM0=y
|
||||
CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58=y
|
||||
|
||||
CONFIG_GPIO=y
|
||||
|
||||
|
||||
|
||||
CONFIG_HEAP_MEM_POOL_SIZE=2048
|
||||
|
||||
|
||||
|
||||
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_PERIPHERAL=y
|
||||
CONFIG_BT_DEVICE_NAME="TrezorZephyr"
|
||||
CONFIG_BT_DEVICE_APPEARANCE=833
|
||||
CONFIG_BT_MAX_CONN=1
|
||||
CONFIG_BT_MAX_PAIRED=8
|
||||
CONFIG_BT_SMP=y
|
||||
# CONFIG_BT_SMP_APP_PAIRING_ACCEPT=y
|
||||
CONFIG_BT_SMP_ENFORCE_MITM=y
|
||||
CONFIG_BT_SMP_SC_ONLY=y
|
||||
CONFIG_BT_FILTER_ACCEPT_LIST=y
|
||||
CONFIG_BT_BONDING_REQUIRED=y
|
||||
CONFIG_BT_PRIVACY=y
|
||||
CONFIG_BT_TINYCRYPT_ECC=y
|
||||
CONFIG_BT_LL_SW_SPLIT=y
|
||||
|
||||
#CONFIG_BT_DEBUG_SMP=y
|
||||
|
||||
#PHY update needed for updating PHY request
|
||||
CONFIG_BT_PHY_UPDATE=y
|
||||
CONFIG_BT_USER_PHY_UPDATE=y
|
||||
|
||||
# HCI ACL buffers size
|
||||
# BT_L2CAP_RX_MTU = CONFIG_BT_BUF_ACL_RX_SIZE - BT_L2CAP_HDR_SIZE
|
||||
CONFIG_BT_BUF_ACL_RX_SIZE=251
|
||||
|
||||
# L2CAP SDU/PDU TX MTU
|
||||
CONFIG_BT_L2CAP_TX_MTU=247
|
||||
|
||||
|
||||
# Enable bonding
|
||||
CONFIG_BT_SETTINGS=y
|
||||
CONFIG_FLASH=y
|
||||
CONFIG_FLASH_PAGE_LAYOUT=y
|
||||
CONFIG_FLASH_MAP=y
|
||||
CONFIG_NVS=y
|
||||
CONFIG_SETTINGS=y
|
||||
|
||||
# Enable DK LED and Buttons library
|
||||
CONFIG_DK_LIBRARY=y
|
||||
|
||||
# This example requires more stack
|
||||
CONFIG_MAIN_STACK_SIZE=1152
|
||||
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
|
||||
|
||||
# NFC
|
||||
CONFIG_NFCT_PINS_AS_GPIOS=y
|
||||
|
||||
CONFIG_POLL=y
|
||||
|
||||
|
||||
# Config logger
|
||||
CONFIG_LOG=y
|
||||
CONFIG_RTT_CONSOLE=y
|
||||
CONFIG_UART_CONSOLE=n
|
||||
CONFIG_USE_SEGGER_RTT=y
|
||||
CONFIG_LOG_BACKEND_RTT=y
|
||||
CONFIG_LOG_BACKEND_UART=n
|
||||
CONFIG_LOG_PRINTK=n
|
||||
|
||||
CONFIG_NANOPB=n
|
||||
CONFIG_ASSERT=y
|
150
west/trezor/trezor-ble/src/advertising.c
Normal file
150
west/trezor/trezor-ble/src/advertising.c
Normal file
@ -0,0 +1,150 @@
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "connection.h"
|
||||
#include "int_comm.h"
|
||||
#include "trz_nus.h"
|
||||
|
||||
#define LOG_MODULE_NAME fw_int_advertising
|
||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
|
||||
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
|
||||
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
|
||||
|
||||
bool advertising = false;
|
||||
bool advertising_wl = false;
|
||||
int bond_cnt = 0;
|
||||
int bond_cnt_tmp = 0;
|
||||
|
||||
uint8_t manufacturer_data[8] = {0xff, 0xff, 0, 3, 'T', '3', 'W', '1'};
|
||||
|
||||
static const struct bt_data advertising_data[] = {
|
||||
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
|
||||
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
|
||||
};
|
||||
|
||||
static const struct bt_data scan_response_data[] = {
|
||||
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL),
|
||||
BT_DATA(BT_DATA_MANUFACTURER_DATA, manufacturer_data, 8),
|
||||
};
|
||||
|
||||
static void add_to_whitelist(const struct bt_bond_info *info, void *user_data) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
bt_addr_le_to_str(&info->addr, addr, sizeof(addr));
|
||||
|
||||
int err = bt_le_filter_accept_list_add(&info->addr);
|
||||
if (err) {
|
||||
LOG_WRN("whitelist add: %s FAILED!\n", addr);
|
||||
} else {
|
||||
LOG_INF("whitelist add: %s\n", addr);
|
||||
}
|
||||
|
||||
bond_cnt_tmp++;
|
||||
}
|
||||
|
||||
void advertising_setup_wl(void) {
|
||||
bt_le_filter_accept_list_clear();
|
||||
bond_cnt_tmp = 0;
|
||||
bt_foreach_bond(BT_ID_DEFAULT, add_to_whitelist, NULL);
|
||||
bond_cnt = bond_cnt_tmp;
|
||||
}
|
||||
|
||||
void advertising_start(bool wl) {
|
||||
if (advertising) {
|
||||
if (wl != advertising_wl) {
|
||||
LOG_WRN("Restarting advertising");
|
||||
bt_le_adv_stop();
|
||||
} else {
|
||||
LOG_WRN("Already advertising");
|
||||
|
||||
send_status_event();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int err;
|
||||
|
||||
manufacturer_data[3] = 0x03; // todo color
|
||||
|
||||
if (wl) {
|
||||
advertising_setup_wl();
|
||||
LOG_INF("Advertising with whitelist");
|
||||
|
||||
manufacturer_data[2] = 0x00;
|
||||
|
||||
err = bt_le_adv_start(
|
||||
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_SCANNABLE |
|
||||
BT_LE_ADV_OPT_FILTER_CONN |
|
||||
BT_LE_ADV_OPT_FILTER_SCAN_REQ,
|
||||
160, 1600, NULL),
|
||||
advertising_data, ARRAY_SIZE(advertising_data), scan_response_data,
|
||||
ARRAY_SIZE(scan_response_data));
|
||||
} else {
|
||||
LOG_INF("Advertising no whitelist");
|
||||
|
||||
manufacturer_data[2] = 0x01;
|
||||
|
||||
err = bt_le_adv_start(
|
||||
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_SCANNABLE,
|
||||
160, 1600, NULL),
|
||||
advertising_data, ARRAY_SIZE(advertising_data), scan_response_data,
|
||||
ARRAY_SIZE(scan_response_data));
|
||||
}
|
||||
if (err) {
|
||||
LOG_ERR("Advertising failed to start (err %d)", err);
|
||||
send_status_event();
|
||||
return;
|
||||
}
|
||||
advertising = true;
|
||||
advertising_wl = wl;
|
||||
|
||||
// oob_fetch_addr();
|
||||
|
||||
send_status_event();
|
||||
}
|
||||
|
||||
void advertising_stop(void) {
|
||||
if (!advertising) {
|
||||
LOG_WRN("Not advertising");
|
||||
|
||||
send_status_event();
|
||||
return;
|
||||
}
|
||||
|
||||
int err = bt_le_adv_stop();
|
||||
if (err) {
|
||||
LOG_ERR("Advertising failed to stop (err %d)", err);
|
||||
send_status_event();
|
||||
return;
|
||||
}
|
||||
advertising = false;
|
||||
advertising_wl = false;
|
||||
send_status_event();
|
||||
}
|
||||
|
||||
bool is_advertising(void) { return advertising; }
|
||||
|
||||
bool is_advertising_whitelist(void) { return advertising_wl; }
|
||||
|
||||
void advertising_init(void) {
|
||||
LOG_INF("Advertising init");
|
||||
advertising_setup_wl();
|
||||
}
|
||||
|
||||
void erase_bonds(void) {
|
||||
int err = bt_unpair(BT_ID_DEFAULT, BT_ADDR_LE_ANY);
|
||||
if (err) {
|
||||
LOG_INF("Cannot delete bonds (err: %d)\n", err);
|
||||
} else {
|
||||
bt_le_filter_accept_list_clear();
|
||||
bond_cnt = 0;
|
||||
LOG_INF("Bonds deleted successfully \n");
|
||||
}
|
||||
}
|
||||
|
||||
int advertising_get_bond_count(void) { return bond_cnt; }
|
12
west/trezor/trezor-ble/src/advertising.h
Normal file
12
west/trezor/trezor-ble/src/advertising.h
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void advertising_start(bool wl);
|
||||
void advertising_stop(void);
|
||||
bool is_advertising(void);
|
||||
bool is_advertising_whitelist(void);
|
||||
void advertising_init(void);
|
||||
void advertising_setup_wl(void);
|
||||
int advertising_get_bond_count(void);
|
||||
void erase_bonds(void);
|
169
west/trezor/trezor-ble/src/connection.c
Normal file
169
west/trezor/trezor-ble/src/connection.c
Normal file
@ -0,0 +1,169 @@
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include <dk_buttons_and_leds.h>
|
||||
|
||||
#include "advertising.h"
|
||||
#include "connection.h"
|
||||
#include "int_comm.h"
|
||||
|
||||
#define LOG_MODULE_NAME fw_int_connection
|
||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
|
||||
static struct bt_conn *current_conn;
|
||||
static struct bt_conn *auth_conn;
|
||||
|
||||
void connected(struct bt_conn *conn, uint8_t err) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
if (err) {
|
||||
LOG_ERR("Connection failed (err %u)", err);
|
||||
return;
|
||||
}
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
LOG_INF("Connected %s", addr);
|
||||
|
||||
current_conn = bt_conn_ref(conn);
|
||||
|
||||
// struct bt_le_conn_param params = BT_LE_CONN_PARAM_INIT(6,6,0,400);
|
||||
//
|
||||
// bt_conn_le_param_update(conn, ¶ms);
|
||||
|
||||
// err = bt_conn_le_phy_update(current_conn, BT_CONN_LE_PHY_PARAM_2M);
|
||||
// if (err) {
|
||||
// LOG_ERR("Phy update request failed: %d", err);
|
||||
// }
|
||||
|
||||
send_status_event();
|
||||
}
|
||||
|
||||
void disconnected(struct bt_conn *conn, uint8_t reason) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
LOG_INF("Disconnected: %s (reason %u)", addr, reason);
|
||||
|
||||
if (auth_conn) {
|
||||
bt_conn_unref(auth_conn);
|
||||
auth_conn = NULL;
|
||||
}
|
||||
|
||||
if (current_conn) {
|
||||
bt_conn_unref(current_conn);
|
||||
current_conn = NULL;
|
||||
}
|
||||
|
||||
send_status_event();
|
||||
}
|
||||
|
||||
bool is_connected(void) { return current_conn != NULL; }
|
||||
|
||||
void disconnect(void) {
|
||||
if (current_conn) {
|
||||
LOG_INF("Remotely disconnected");
|
||||
bt_conn_disconnect(current_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
|
||||
bt_conn_unref(current_conn);
|
||||
}
|
||||
}
|
||||
|
||||
void num_comp_reply(bool accept) {
|
||||
if (auth_conn != NULL) {
|
||||
if (accept) {
|
||||
bt_conn_auth_passkey_confirm(auth_conn);
|
||||
LOG_INF("Numeric Match, conn %p", (void *)auth_conn);
|
||||
} else {
|
||||
bt_conn_auth_cancel(auth_conn);
|
||||
LOG_INF("Numeric Reject, conn %p", (void *)auth_conn);
|
||||
bt_conn_disconnect(auth_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
|
||||
}
|
||||
|
||||
bt_conn_unref(auth_conn);
|
||||
auth_conn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void passkey_to_str(uint8_t buf[6], unsigned int passkey) {
|
||||
buf[5] = (passkey % 10) + '0';
|
||||
buf[4] = ((passkey / 10) % 10) + '0';
|
||||
buf[3] = ((passkey / 100) % 10) + '0';
|
||||
buf[2] = ((passkey / 1000) % 10) + '0';
|
||||
buf[1] = ((passkey / 10000) % 10) + '0';
|
||||
buf[0] = ((passkey / 100000) % 10) + '0';
|
||||
}
|
||||
|
||||
void auth_passkey_display(struct bt_conn *conn, unsigned int passkey) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
uint8_t passkey_str[6];
|
||||
passkey_to_str(passkey_str, passkey);
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
// pb_comm_enqueue(PASSKEY_DISPLAY, passkey_str, 6);
|
||||
}
|
||||
|
||||
void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
auth_conn = bt_conn_ref(conn);
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
uint8_t passkey_str[6];
|
||||
passkey_to_str(passkey_str, passkey);
|
||||
send_pairing_request_event(passkey_str, 6);
|
||||
|
||||
send_status_event();
|
||||
}
|
||||
|
||||
void auth_cancel(struct bt_conn *conn) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
disconnect();
|
||||
|
||||
send_pairing_cancelled_event();
|
||||
send_status_event();
|
||||
|
||||
LOG_INF("Pairing cancelled: %s", addr);
|
||||
}
|
||||
|
||||
void pairing_complete(struct bt_conn *conn, bool bonded) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
// oob_signal();
|
||||
// bt_le_oob_set_sc_flag(false);
|
||||
// bt_le_oob_set_legacy_flag(false);
|
||||
|
||||
if (bonded) {
|
||||
advertising_setup_wl();
|
||||
}
|
||||
|
||||
LOG_INF("Pairing completed: %s, bonded: %d", addr, bonded);
|
||||
}
|
||||
|
||||
void pairing_failed(struct bt_conn *conn, enum bt_security_err reason) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
// oob_signal();
|
||||
// bt_le_oob_set_sc_flag(false);
|
||||
// bt_le_oob_set_legacy_flag(false);
|
||||
|
||||
LOG_INF("Pairing failed conn: %s, reason %d", addr, reason);
|
||||
}
|
||||
|
||||
struct bt_conn *conn_get_current(void) { return current_conn; }
|
30
west/trezor/trezor-ble/src/connection.h
Normal file
30
west/trezor/trezor-ble/src/connection.h
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
|
||||
void connected(struct bt_conn *conn, uint8_t err);
|
||||
|
||||
void disconnect(void);
|
||||
|
||||
void disconnected(struct bt_conn *conn, uint8_t reason);
|
||||
|
||||
bool is_connected(void);
|
||||
|
||||
void num_comp_reply(bool accept);
|
||||
void auth_passkey_display(struct bt_conn *conn, unsigned int passkey);
|
||||
void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey);
|
||||
void auth_cancel(struct bt_conn *conn);
|
||||
void pairing_complete(struct bt_conn *conn, bool bonded);
|
||||
void pairing_failed(struct bt_conn *conn, enum bt_security_err reason);
|
||||
|
||||
void num_comp_reply(bool accept);
|
||||
struct bt_conn *conn_get_current(void);
|
13
west/trezor/trezor-ble/src/events.c
Normal file
13
west/trezor/trezor-ble/src/events.c
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#define K_POOL_EVENTS_CNT (4)
|
||||
|
||||
static struct k_poll_event events[K_POOL_EVENTS_CNT];
|
||||
|
||||
void events_poll(void) { k_poll(events, ARRAY_SIZE(events), K_FOREVER); }
|
||||
|
||||
void events_init(void) {}
|
||||
|
||||
struct k_poll_event* events_get(int idx) { return &events[idx]; }
|
11
west/trezor/trezor-ble/src/events.h
Normal file
11
west/trezor/trezor-ble/src/events.h
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#define INT_COMM_EVENT_NUM 3
|
||||
|
||||
void events_poll(void);
|
||||
|
||||
void events_init(void);
|
||||
|
||||
struct k_poll_event* events_get(int idx);
|
161
west/trezor/trezor-ble/src/int_comm.c
Normal file
161
west/trezor/trezor-ble/src/int_comm.c
Normal file
@ -0,0 +1,161 @@
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/sys/crc.h>
|
||||
|
||||
#include "advertising.h"
|
||||
#include "connection.h"
|
||||
#include "events.h"
|
||||
#include "int_comm_defs.h"
|
||||
#include "uart.h"
|
||||
|
||||
#define LOG_MODULE_NAME fw_int_comm
|
||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
|
||||
static K_SEM_DEFINE(int_comm_ok, 0, 1);
|
||||
|
||||
void send_packet(uint8_t message_type, const uint8_t *tx_data, uint8_t len) {
|
||||
uart_data_t *tx = k_malloc(sizeof(*tx));
|
||||
|
||||
if (tx == NULL) {
|
||||
LOG_WRN("Not able to allocate UART send data buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DBG("ALLOC: Sending UART data");
|
||||
|
||||
tx->len = len + OVERHEAD_SIZE;
|
||||
|
||||
tx->data[0] = message_type;
|
||||
tx->data[1] = tx->len;
|
||||
memcpy(&tx->data[COMM_HEADER_SIZE], tx_data, len);
|
||||
|
||||
uint8_t crc = crc8(tx->data, tx->len - 1, 0x07, 0x00, false);
|
||||
|
||||
tx->data[tx->len - 1] = crc;
|
||||
|
||||
uart_send(tx);
|
||||
}
|
||||
|
||||
void send_status_event(void) {
|
||||
// ble_version_t version = {0};
|
||||
//
|
||||
// sd_ble_version_get(&version);
|
||||
LOG_WRN(
|
||||
"Sending status event: connected: %d, advertising: %d, "
|
||||
"advertising_whitelist: %d, peer_count: %d",
|
||||
is_connected(), is_advertising(), is_advertising_whitelist(),
|
||||
advertising_get_bond_count());
|
||||
|
||||
event_status_msg_t msg = {0};
|
||||
msg.msg_id = INTERNAL_EVENT_STATUS;
|
||||
msg.connected = is_connected();
|
||||
msg.advertising = is_advertising();
|
||||
msg.advertising_whitelist = is_advertising_whitelist();
|
||||
msg.peer_count = advertising_get_bond_count();
|
||||
msg.sd_version_number = 0;
|
||||
msg.sd_company_id = 0;
|
||||
msg.sd_subversion_number = 0;
|
||||
msg.app_version = 0;
|
||||
msg.bld_version = 0;
|
||||
|
||||
send_packet(INTERNAL_EVENT, (uint8_t *)&msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void send_success_event(void) {
|
||||
uint8_t tx_data[] = {
|
||||
INTERNAL_EVENT_SUCCESS,
|
||||
};
|
||||
send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data));
|
||||
}
|
||||
|
||||
void send_pairing_cancelled_event(void) {
|
||||
uint8_t tx_data[1] = {0};
|
||||
|
||||
tx_data[0] = INTERNAL_EVENT_PAIRING_CANCELLED;
|
||||
|
||||
send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data));
|
||||
}
|
||||
|
||||
void send_pairing_request_event(uint8_t *data, uint16_t len) {
|
||||
uint8_t tx_data[7] = {0};
|
||||
|
||||
tx_data[0] = INTERNAL_EVENT_PAIRING_REQUEST;
|
||||
tx_data[1] = data[0];
|
||||
tx_data[2] = data[1];
|
||||
tx_data[3] = data[2];
|
||||
tx_data[4] = data[3];
|
||||
tx_data[5] = data[4];
|
||||
tx_data[6] = data[5];
|
||||
|
||||
send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data));
|
||||
}
|
||||
|
||||
uint16_t get_message_type(const uint8_t *rx_data) {
|
||||
return (rx_data[3] << 8) | rx_data[4];
|
||||
}
|
||||
|
||||
void process_command(uint8_t *data, uint16_t len) {
|
||||
uint8_t cmd = data[0];
|
||||
switch (cmd) {
|
||||
case INTERNAL_CMD_SEND_STATE:
|
||||
send_status_event();
|
||||
break;
|
||||
case INTERNAL_CMD_ADVERTISING_ON:
|
||||
advertising_start(data[1] != 0);
|
||||
break;
|
||||
case INTERNAL_CMD_ADVERTISING_OFF:
|
||||
advertising_stop();
|
||||
break;
|
||||
case INTERNAL_CMD_ERASE_BONDS:
|
||||
erase_bonds();
|
||||
send_success_event();
|
||||
break;
|
||||
case INTERNAL_CMD_DISCONNECT:
|
||||
disconnect();
|
||||
send_success_event();
|
||||
case INTERNAL_CMD_ACK:
|
||||
// pb_msg_ack();
|
||||
break;
|
||||
case INTERNAL_CMD_ALLOW_PAIRING:
|
||||
num_comp_reply(true);
|
||||
send_success_event();
|
||||
break;
|
||||
case INTERNAL_CMD_REJECT_PAIRING:
|
||||
num_comp_reply(false);
|
||||
send_success_event();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void int_comm_start(void) { k_sem_give(&int_comm_ok); }
|
||||
|
||||
void int_comm_thread(void) {
|
||||
/* Don't go any further until BLE is initialized */
|
||||
k_sem_take(&int_comm_ok, K_FOREVER);
|
||||
|
||||
for (;;) {
|
||||
// events_poll();
|
||||
|
||||
// if (events_get(INT_COMM_EVENT_NUM)->state == K_POLL_STATE_SIGNALED) {
|
||||
|
||||
uart_data_t *buf = uart_get_data_int();
|
||||
process_command(buf->data, buf->len);
|
||||
k_free(buf);
|
||||
|
||||
// k_poll_signal_reset(events_get(INT_COMM_EVENT_NUM)->signal);
|
||||
// events_get(INT_COMM_EVENT_NUM)->state = K_POLL_STATE_NOT_READY;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
K_THREAD_DEFINE(int_comm_thread_id, CONFIG_BT_NUS_THREAD_STACK_SIZE,
|
||||
int_comm_thread, NULL, NULL, NULL, 7, 0, 0);
|
21
west/trezor/trezor-ble/src/int_comm.h
Normal file
21
west/trezor/trezor-ble/src/int_comm.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef INT_COMM__
|
||||
#define INT_COMM__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void process_command(uint8_t *data, uint16_t len);
|
||||
|
||||
void send_status_event(void);
|
||||
|
||||
void send_pairing_request_event(uint8_t *data, uint16_t len);
|
||||
void send_pairing_cancelled_event(void);
|
||||
|
||||
void int_comm_start(void);
|
||||
|
||||
void int_comm_thread(void);
|
||||
|
||||
void send_packet(uint8_t message_type, const uint8_t *tx_data, uint16_t len);
|
||||
|
||||
void pb_msg_ack(void);
|
||||
|
||||
#endif
|
52
west/trezor/trezor-ble/src/int_comm_defs.h
Normal file
52
west/trezor/trezor-ble/src/int_comm_defs.h
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
#ifndef __INT_COMM_DEFS__
|
||||
#define __INT_COMM_DEFS__
|
||||
|
||||
#define BLE_PACKET_SIZE (244)
|
||||
#define USB_DATA_SIZE (64)
|
||||
|
||||
#define COMM_HEADER_SIZE (2)
|
||||
#define COMM_FOOTER_SIZE (1)
|
||||
#define OVERHEAD_SIZE (COMM_HEADER_SIZE + COMM_FOOTER_SIZE)
|
||||
#define UART_PACKET_SIZE (USB_DATA_SIZE + OVERHEAD_SIZE)
|
||||
|
||||
#define EXTERNAL_MESSAGE (0xA0)
|
||||
#define INTERNAL_EVENT (0xA1)
|
||||
|
||||
typedef struct {
|
||||
uint8_t msg_id;
|
||||
uint8_t connected;
|
||||
uint8_t advertising;
|
||||
uint8_t advertising_whitelist;
|
||||
|
||||
uint8_t peer_count;
|
||||
uint8_t reserved[2];
|
||||
uint8_t sd_version_number;
|
||||
|
||||
uint16_t sd_company_id;
|
||||
uint16_t sd_subversion_number;
|
||||
|
||||
uint32_t app_version;
|
||||
uint32_t bld_version;
|
||||
|
||||
} event_status_msg_t;
|
||||
|
||||
typedef enum {
|
||||
INTERNAL_EVENT_STATUS = 0x01,
|
||||
INTERNAL_EVENT_SUCCESS = 0x02,
|
||||
INTERNAL_EVENT_FAILURE = 0x03,
|
||||
INTERNAL_EVENT_PAIRING_REQUEST = 0x04,
|
||||
INTERNAL_EVENT_PAIRING_CANCELLED = 0x05,
|
||||
} InternalEvent_t;
|
||||
|
||||
typedef enum {
|
||||
INTERNAL_CMD_SEND_STATE = 0x00,
|
||||
INTERNAL_CMD_ADVERTISING_ON = 0x01,
|
||||
INTERNAL_CMD_ADVERTISING_OFF = 0x02,
|
||||
INTERNAL_CMD_ERASE_BONDS = 0x03,
|
||||
INTERNAL_CMD_DISCONNECT = 0x04,
|
||||
INTERNAL_CMD_ACK = 0x05,
|
||||
INTERNAL_CMD_ALLOW_PAIRING = 0x06,
|
||||
INTERNAL_CMD_REJECT_PAIRING = 0x07,
|
||||
} InternalCmd_t;
|
||||
#endif
|
263
west/trezor/trezor-ble/src/main.c
Normal file
263
west/trezor/trezor-ble/src/main.c
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* @brief Nordic UART Bridge Service (NUS) sample
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include <soc.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
|
||||
#include <dk_buttons_and_leds.h>
|
||||
|
||||
#include <zephyr/settings/settings.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "advertising.h"
|
||||
#include "connection.h"
|
||||
#include "events.h"
|
||||
#include "int_comm.h"
|
||||
#include "spi.h"
|
||||
#include "trz_nus.h"
|
||||
#include "uart.h"
|
||||
|
||||
#define LOG_MODULE_NAME fw
|
||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
|
||||
#define STACKSIZE CONFIG_BT_NUS_THREAD_STACK_SIZE
|
||||
#define PRIORITY 7
|
||||
|
||||
#define RUN_STATUS_LED DK_LED1
|
||||
#define RUN_LED_BLINK_INTERVAL 1000
|
||||
|
||||
#define FW_RUNNING_SIG DK_LED3
|
||||
#define CON_STATUS_LED DK_LED2
|
||||
|
||||
static K_SEM_DEFINE(ble_init_ok, 0, 1);
|
||||
static K_SEM_DEFINE(led_init_ok, 0, 1);
|
||||
|
||||
#define AUTH_SC_FLAG 0x08
|
||||
|
||||
static void security_changed(struct bt_conn *conn, bt_security_t level,
|
||||
enum bt_security_err err) {
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
if (!err) {
|
||||
LOG_INF("Security changed: %s level %u", addr, level);
|
||||
} else {
|
||||
LOG_WRN("Security failed: %s level %u err %d", addr, level, err);
|
||||
}
|
||||
}
|
||||
|
||||
BT_CONN_CB_DEFINE(conn_callbacks) = {
|
||||
.connected = connected,
|
||||
.disconnected = disconnected,
|
||||
.security_changed = security_changed,
|
||||
};
|
||||
|
||||
// static enum bt_security_err pairing_accept(struct bt_conn *conn,
|
||||
// const struct bt_conn_pairing_feat
|
||||
// *const feat)
|
||||
//{
|
||||
// if (feat->oob_data_flag && (!(feat->auth_req & AUTH_SC_FLAG))) {
|
||||
// bt_le_oob_set_legacy_flag(true);
|
||||
// }
|
||||
//
|
||||
// return BT_SECURITY_ERR_SUCCESS;
|
||||
//
|
||||
// }
|
||||
|
||||
static struct bt_conn_auth_cb conn_auth_callbacks = {
|
||||
// .pairing_accept = pairing_accept,
|
||||
.passkey_display = auth_passkey_display,
|
||||
.passkey_confirm = auth_passkey_confirm,
|
||||
.cancel = auth_cancel,
|
||||
};
|
||||
|
||||
static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
|
||||
.pairing_complete = pairing_complete, .pairing_failed = pairing_failed};
|
||||
|
||||
static void bt_receive_cb(struct bt_conn *conn, const uint8_t *const data,
|
||||
uint16_t len) {
|
||||
if ((dk_get_buttons() & DK_BTN2_MSK) == 0) {
|
||||
LOG_INF("Trezor not ready, rejecting data");
|
||||
// send_error_response();
|
||||
return;
|
||||
}
|
||||
|
||||
char addr[BT_ADDR_LE_STR_LEN] = {0};
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, ARRAY_SIZE(addr));
|
||||
|
||||
LOG_DBG("Received data from: %s, %d", addr, len);
|
||||
|
||||
spi_send(data, len);
|
||||
}
|
||||
|
||||
static struct bt_nus_cb nus_cb = {
|
||||
.received = bt_receive_cb,
|
||||
};
|
||||
|
||||
void error(void) {
|
||||
dk_set_leds_state(DK_ALL_LEDS_MSK, DK_NO_LEDS_MSK);
|
||||
|
||||
while (true) {
|
||||
/* Spin for ever */
|
||||
k_sleep(K_MSEC(1000));
|
||||
}
|
||||
}
|
||||
|
||||
void button_changed(uint32_t button_state, uint32_t has_changed) {}
|
||||
|
||||
static void configure_gpio(void) {
|
||||
int err;
|
||||
|
||||
err = dk_buttons_init(button_changed);
|
||||
if (err) {
|
||||
LOG_ERR("Cannot init buttons (err: %d)", err);
|
||||
}
|
||||
|
||||
err = dk_leds_init();
|
||||
if (err) {
|
||||
LOG_ERR("Cannot init LEDs (err: %d)", err);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int err = 0;
|
||||
|
||||
LOG_INF("Initializing");
|
||||
|
||||
configure_gpio();
|
||||
|
||||
err = uart_init();
|
||||
if (err) {
|
||||
error();
|
||||
}
|
||||
|
||||
spi_init();
|
||||
|
||||
err = bt_conn_auth_cb_register(&conn_auth_callbacks);
|
||||
if (err) {
|
||||
printk("Failed to register authorization callbacks.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
|
||||
if (err) {
|
||||
printk("Failed to register authorization info callbacks.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = bt_enable(NULL);
|
||||
if (err) {
|
||||
error();
|
||||
}
|
||||
|
||||
LOG_INF("Bluetooth initialized");
|
||||
|
||||
k_sem_give(&ble_init_ok);
|
||||
|
||||
if (IS_ENABLED(CONFIG_SETTINGS)) {
|
||||
settings_load();
|
||||
}
|
||||
|
||||
err = bt_nus_init(&nus_cb);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to initialize UART service (err: %d)", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bt_set_name("TrezorGAP");
|
||||
|
||||
events_init();
|
||||
advertising_init();
|
||||
int_comm_start();
|
||||
|
||||
dk_set_led(FW_RUNNING_SIG, 1);
|
||||
// dk_set_led(FW_RUNNING_SIG, 0);
|
||||
// while(true) {
|
||||
// dk_set_led(FW_RUNNING_SIG, 1);
|
||||
// dk_set_led(FW_RUNNING_SIG, 0);
|
||||
// }
|
||||
send_status_event();
|
||||
|
||||
// oob_init();
|
||||
|
||||
k_sem_give(&led_init_ok);
|
||||
|
||||
for (;;) {
|
||||
events_poll();
|
||||
printk("Event occurred\n");
|
||||
|
||||
// oob_process();
|
||||
// int_comm_thread();
|
||||
}
|
||||
}
|
||||
|
||||
void ble_write_thread(void) {
|
||||
/* Don't go any further until BLE is initialized */
|
||||
k_sem_take(&ble_init_ok, K_FOREVER);
|
||||
|
||||
for (;;) {
|
||||
/* Wait indefinitely for data to be sent over bluetooth */
|
||||
uart_data_t *buf = uart_get_data_ext();
|
||||
|
||||
if (bt_nus_send(conn_get_current(), buf)) {
|
||||
LOG_WRN("Failed to send data over BLE connection: %d", buf->len);
|
||||
k_free(buf);
|
||||
}
|
||||
|
||||
LOG_DBG("Freeing UART data");
|
||||
}
|
||||
}
|
||||
|
||||
void led_thread(void) {
|
||||
bool connected = false;
|
||||
int blink_status = 0;
|
||||
/* Don't go any further until BLE is initialized */
|
||||
k_sem_take(&led_init_ok, K_FOREVER);
|
||||
|
||||
for (;;) {
|
||||
blink_status++;
|
||||
dk_set_led(RUN_STATUS_LED, (blink_status) % 2);
|
||||
|
||||
connected = is_connected();
|
||||
|
||||
if (connected) {
|
||||
dk_set_led_on(CON_STATUS_LED);
|
||||
} else {
|
||||
if (is_advertising() && !is_advertising_whitelist()) {
|
||||
dk_set_led(CON_STATUS_LED, (blink_status) % 2);
|
||||
} else {
|
||||
dk_set_led_off(CON_STATUS_LED);
|
||||
}
|
||||
}
|
||||
|
||||
k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
K_THREAD_DEFINE(ble_write_thread_id, STACKSIZE, ble_write_thread, NULL, NULL,
|
||||
NULL, PRIORITY, 0, 0);
|
||||
|
||||
K_THREAD_DEFINE(led_thread_id, STACKSIZE, led_thread, NULL, NULL, NULL,
|
||||
PRIORITY, 0, 0);
|
499
west/trezor/trezor-ble/src/oob.c
Normal file
499
west/trezor/trezor-ble/src/oob.c
Normal file
@ -0,0 +1,499 @@
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
|
||||
#include <nfc/t4t/ndef_file.h>
|
||||
#include <nfc_t4t_lib.h>
|
||||
|
||||
#include <nfc/ndef/ch.h>
|
||||
#include <nfc/ndef/ch_msg.h>
|
||||
#include <nfc/ndef/le_oob_rec.h>
|
||||
#include <nfc/ndef/le_oob_rec_parser.h>
|
||||
#include <nfc/ndef/msg.h>
|
||||
|
||||
#include <nfc/tnep/ch.h>
|
||||
#include <nfc/tnep/tag.h>
|
||||
|
||||
#include "events.h"
|
||||
|
||||
#define NDEF_MSG_BUF_SIZE 256
|
||||
#define AUTH_SC_FLAG 0x08
|
||||
|
||||
// #define NFC_FIELD_LED DK_LED2
|
||||
// #define CON_STATUS_LED DK_LED1
|
||||
//
|
||||
// #define KEY_BOND_REMOVE_MASK DK_BTN4_MSK
|
||||
|
||||
#define NFC_NDEF_LE_OOB_REC_PARSER_BUFF_SIZE 150
|
||||
#define NFC_TNEP_BUFFER_SIZE 1024
|
||||
|
||||
static struct bt_le_oob oob_local;
|
||||
static struct k_work adv_work;
|
||||
static uint8_t conn_cnt;
|
||||
static uint8_t tk_value[NFC_NDEF_LE_OOB_REC_TK_LEN];
|
||||
static uint8_t remote_tk_value[NFC_NDEF_LE_OOB_REC_TK_LEN];
|
||||
static struct bt_le_oob oob_remote;
|
||||
|
||||
/* Bonded address queue. */
|
||||
K_MSGQ_DEFINE(bonds_queue, sizeof(bt_addr_le_t), CONFIG_BT_MAX_PAIRED, 4);
|
||||
|
||||
static struct k_poll_signal pair_signal;
|
||||
static uint8_t tnep_buffer[NFC_TNEP_BUFFER_SIZE];
|
||||
static uint8_t tnep_swap_buffer[NFC_TNEP_BUFFER_SIZE];
|
||||
static bool use_remote_tk;
|
||||
static bool adv_permission;
|
||||
|
||||
static int tk_value_generate(void) {
|
||||
int err;
|
||||
|
||||
err = bt_rand(tk_value, sizeof(tk_value));
|
||||
if (err) {
|
||||
printk("Random TK value generation failed: %d\n", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void pair_key_generate_init(void) {
|
||||
k_poll_signal_init(&pair_signal);
|
||||
k_poll_event_init(events_get(NFC_TNEP_EVENTS_NUMBER), K_POLL_TYPE_SIGNAL,
|
||||
K_POLL_MODE_NOTIFY_ONLY, &pair_signal);
|
||||
}
|
||||
|
||||
static int paring_key_generate(void) {
|
||||
int err;
|
||||
|
||||
printk("Generating new pairing keys\n");
|
||||
|
||||
err = bt_le_oob_get_local(BT_ID_DEFAULT, &oob_local);
|
||||
if (err) {
|
||||
printk("Error while fetching local OOB data: %d\n", err);
|
||||
}
|
||||
|
||||
return tk_value_generate();
|
||||
}
|
||||
|
||||
static void paring_key_process(void) {
|
||||
int err;
|
||||
|
||||
if (events_get(NFC_TNEP_EVENTS_NUMBER)->state == K_POLL_STATE_SIGNALED) {
|
||||
err = paring_key_generate();
|
||||
if (err) {
|
||||
printk("Pairing key generation error: %d\n", err);
|
||||
}
|
||||
|
||||
k_poll_signal_reset(events_get(NFC_TNEP_EVENTS_NUMBER)->signal);
|
||||
events_get(NFC_TNEP_EVENTS_NUMBER)->state = K_POLL_STATE_NOT_READY;
|
||||
}
|
||||
}
|
||||
|
||||
static void bond_find(const struct bt_bond_info *info, void *user_data) {
|
||||
int err;
|
||||
struct bt_conn *conn;
|
||||
|
||||
/* Filter already connected peers. */
|
||||
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &info->addr);
|
||||
if (conn) {
|
||||
bt_conn_unref(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
err = k_msgq_put(&bonds_queue, (void *)&info->addr, K_NO_WAIT);
|
||||
if (err) {
|
||||
printk("No space in the queue for the bond\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback function for handling NFC events.
|
||||
*/
|
||||
static void nfc_callback(void *context, nfc_t4t_event_t event,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint32_t flags) {
|
||||
ARG_UNUSED(context);
|
||||
ARG_UNUSED(data);
|
||||
ARG_UNUSED(flags);
|
||||
|
||||
switch (event) {
|
||||
case NFC_T4T_EVENT_FIELD_ON:
|
||||
printk("NFC callback 1\n");
|
||||
nfc_tnep_tag_on_selected();
|
||||
// dk_set_led_on(NFC_FIELD_LED);
|
||||
|
||||
// adv_permission = true;
|
||||
|
||||
break;
|
||||
|
||||
case NFC_T4T_EVENT_FIELD_OFF:
|
||||
printk("NFC callback 2\n");
|
||||
nfc_tnep_tag_on_selected();
|
||||
// dk_set_led_off(NFC_FIELD_LED);
|
||||
break;
|
||||
|
||||
case NFC_T4T_EVENT_NDEF_READ:
|
||||
printk("NFC callback 3\n");
|
||||
// if (adv_permission) {
|
||||
// advertising_start();
|
||||
// adv_permission = false;
|
||||
// }
|
||||
|
||||
break;
|
||||
|
||||
case NFC_T4T_EVENT_NDEF_UPDATED:
|
||||
printk("NFC callback 4\n");
|
||||
if (data_length > 0) {
|
||||
nfc_tnep_tag_rx_msg_indicate(nfc_t4t_ndef_file_msg_get(data),
|
||||
data_length);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** .. include_startingpoint_pair_msg_rst */
|
||||
static int tnep_initial_msg_encode(struct nfc_ndef_msg_desc *msg) {
|
||||
int err;
|
||||
struct nfc_ndef_ch_msg_records ch_records;
|
||||
static struct nfc_ndef_le_oob_rec_payload_desc rec_payload;
|
||||
|
||||
NFC_NDEF_LE_OOB_RECORD_DESC_DEF(oob_rec, '0', &rec_payload);
|
||||
NFC_NDEF_CH_AC_RECORD_DESC_DEF(oob_ac, NFC_AC_CPS_ACTIVE, 1, "0", 0);
|
||||
NFC_NDEF_CH_HS_RECORD_DESC_DEF(hs_rec, NFC_NDEF_CH_MSG_MAJOR_VER,
|
||||
NFC_NDEF_CH_MSG_MINOR_VER, 1);
|
||||
|
||||
memset(&rec_payload, 0, sizeof(rec_payload));
|
||||
|
||||
rec_payload.addr = &oob_local.addr;
|
||||
rec_payload.le_sc_data = &oob_local.le_sc_data;
|
||||
rec_payload.tk_value = tk_value;
|
||||
rec_payload.local_name = bt_get_name();
|
||||
rec_payload.le_role =
|
||||
NFC_NDEF_LE_OOB_REC_LE_ROLE(NFC_NDEF_LE_OOB_REC_LE_ROLE_PERIPH_ONLY);
|
||||
rec_payload.appearance =
|
||||
NFC_NDEF_LE_OOB_REC_APPEARANCE(CONFIG_BT_DEVICE_APPEARANCE);
|
||||
rec_payload.flags = NFC_NDEF_LE_OOB_REC_FLAGS(BT_LE_AD_NO_BREDR);
|
||||
|
||||
ch_records.ac = &NFC_NDEF_CH_AC_RECORD_DESC(oob_ac);
|
||||
ch_records.carrier = &NFC_NDEF_LE_OOB_RECORD_DESC(oob_rec);
|
||||
ch_records.cnt = 1;
|
||||
|
||||
err = nfc_ndef_ch_msg_hs_create(msg, &NFC_NDEF_CH_RECORD_DESC(hs_rec),
|
||||
&ch_records);
|
||||
|
||||
printk("mac0: %X:%X:%X:%X:%X:%X\n", rec_payload.addr->a.val[5],
|
||||
rec_payload.addr->a.val[4], rec_payload.addr->a.val[3],
|
||||
rec_payload.addr->a.val[2], rec_payload.addr->a.val[1],
|
||||
rec_payload.addr->a.val[0]);
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return nfc_tnep_initial_msg_encode(msg, NULL, 0);
|
||||
}
|
||||
/** .. include_endpoint_pair_msg_rst */
|
||||
|
||||
static int check_oob_carrier(const struct nfc_tnep_ch_record *ch_record,
|
||||
const struct nfc_ndef_record_desc **oob_data) {
|
||||
const struct nfc_ndef_ch_ac_rec *ac_rec = NULL;
|
||||
|
||||
for (size_t i = 0; i < ch_record->count; i++) {
|
||||
if (nfc_ndef_le_oob_rec_check(ch_record->carrier[i])) {
|
||||
*oob_data = ch_record->carrier[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!oob_data) {
|
||||
printk("Connection Handover Requester not supporting OOB BLE\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Look for the corresponding Alternative Carrier Record. */
|
||||
for (size_t i = 0; i < ch_record->count; i++) {
|
||||
if (((*oob_data)->id_length == ch_record->ac[i].carrier_data_ref.length) &&
|
||||
(memcmp((*oob_data)->id, ch_record->ac[i].carrier_data_ref.data,
|
||||
(*oob_data)->id_length) == 0)) {
|
||||
ac_rec = &ch_record->ac[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!ac_rec) {
|
||||
printk("No Alternative Carrier Record for OOB LE carrier\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check carrier state */
|
||||
if ((ac_rec->cps != NFC_AC_CPS_ACTIVE) &&
|
||||
(ac_rec->cps != NFC_AC_CPS_ACTIVATING)) {
|
||||
printk("LE OBB Carrier inactive\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lesc_oob_data_set(struct bt_conn *conn,
|
||||
struct bt_conn_oob_info *oob_info) {
|
||||
int err;
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
struct bt_conn_info info;
|
||||
|
||||
err = bt_conn_get_info(conn, &info);
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct bt_le_oob_sc_data *oob_data_local =
|
||||
oob_info->lesc.oob_config != BT_CONN_OOB_REMOTE_ONLY
|
||||
? &oob_local.le_sc_data
|
||||
: NULL;
|
||||
struct bt_le_oob_sc_data *oob_data_remote =
|
||||
oob_info->lesc.oob_config != BT_CONN_OOB_LOCAL_ONLY
|
||||
? &oob_remote.le_sc_data
|
||||
: NULL;
|
||||
|
||||
if (oob_data_remote && bt_addr_le_cmp(info.le.remote, &oob_remote.addr)) {
|
||||
bt_addr_le_to_str(info.le.remote, addr, sizeof(addr));
|
||||
printk("No OOB data available for remote %s", addr);
|
||||
bt_conn_auth_cancel(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
if (oob_data_local && bt_addr_le_cmp(info.le.local, &oob_local.addr)) {
|
||||
bt_addr_le_to_str(info.le.local, addr, sizeof(addr));
|
||||
printk("No OOB data available for local %s", addr);
|
||||
bt_conn_auth_cancel(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
err = bt_le_oob_set_sc_data(conn, oob_data_local, oob_data_remote);
|
||||
if (err) {
|
||||
printk("Error while setting OOB data: %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
// static void legacy_tk_value_set(struct bt_conn *conn)
|
||||
//{
|
||||
// int err;
|
||||
// const uint8_t *tk = use_remote_tk ? remote_tk_value : tk_value;
|
||||
//
|
||||
// err = bt_le_oob_set_legacy_tk(conn, tk);
|
||||
// if (err) {
|
||||
// printk("TK value set error: %d\n", err);
|
||||
// }
|
||||
//
|
||||
// use_remote_tk = false;
|
||||
// }
|
||||
|
||||
void auth_oob_data_request(struct bt_conn *conn,
|
||||
struct bt_conn_oob_info *info) {
|
||||
printk("OOB data requested\n");
|
||||
|
||||
if (info->type == BT_CONN_OOB_LE_SC) {
|
||||
printk("LESC OOB data requested\n");
|
||||
lesc_oob_data_set(conn, info);
|
||||
}
|
||||
|
||||
// if (info->type == BT_CONN_OOB_LE_LEGACY) {
|
||||
// printk("Legacy TK value requested\n");
|
||||
// legacy_tk_value_set(conn);
|
||||
// }
|
||||
}
|
||||
|
||||
static int oob_le_data_handle(const struct nfc_ndef_record_desc *rec,
|
||||
bool request) {
|
||||
int err;
|
||||
const struct nfc_ndef_le_oob_rec_payload_desc *oob;
|
||||
uint8_t desc_buf[NFC_NDEF_LE_OOB_REC_PARSER_BUFF_SIZE];
|
||||
uint32_t desc_buf_len = sizeof(desc_buf);
|
||||
|
||||
err = nfc_ndef_le_oob_rec_parse(rec, desc_buf, &desc_buf_len);
|
||||
if (err) {
|
||||
printk("Error during NDEF LE OOB Record parsing, err: %d.\n", err);
|
||||
}
|
||||
|
||||
oob = (struct nfc_ndef_le_oob_rec_payload_desc *)desc_buf;
|
||||
|
||||
nfc_ndef_le_oob_rec_printout(oob);
|
||||
|
||||
if ((*oob->le_role != NFC_NDEF_LE_OOB_REC_LE_ROLE_CENTRAL_ONLY) &&
|
||||
(*oob->le_role != NFC_NDEF_LE_OOB_REC_LE_ROLE_CENTRAL_PREFFERED)) {
|
||||
printk("Unsupported Device LE Role\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (oob->le_sc_data) {
|
||||
bt_le_oob_set_sc_flag(true);
|
||||
oob_remote.le_sc_data = *oob->le_sc_data;
|
||||
bt_addr_le_copy(&oob_remote.addr, oob->addr);
|
||||
}
|
||||
|
||||
if (oob->tk_value) {
|
||||
bt_le_oob_set_legacy_flag(true);
|
||||
memcpy(remote_tk_value, oob->tk_value, sizeof(remote_tk_value));
|
||||
use_remote_tk = request;
|
||||
}
|
||||
|
||||
// advertising_start();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** .. include_startingpoint_nfc_tnep_ch_tag_rst */
|
||||
static int carrier_prepare(void) {
|
||||
static struct nfc_ndef_le_oob_rec_payload_desc rec_payload;
|
||||
|
||||
NFC_NDEF_LE_OOB_RECORD_DESC_DEF(oob_rec, '0', &rec_payload);
|
||||
NFC_NDEF_CH_AC_RECORD_DESC_DEF(oob_ac, NFC_AC_CPS_ACTIVE, 1, "0", 0);
|
||||
|
||||
memset(&rec_payload, 0, sizeof(rec_payload));
|
||||
|
||||
rec_payload.addr = &oob_local.addr;
|
||||
rec_payload.le_sc_data = &oob_local.le_sc_data;
|
||||
rec_payload.tk_value = tk_value;
|
||||
rec_payload.local_name = bt_get_name();
|
||||
rec_payload.le_role =
|
||||
NFC_NDEF_LE_OOB_REC_LE_ROLE(NFC_NDEF_LE_OOB_REC_LE_ROLE_PERIPH_ONLY);
|
||||
rec_payload.appearance =
|
||||
NFC_NDEF_LE_OOB_REC_APPEARANCE(CONFIG_BT_DEVICE_APPEARANCE);
|
||||
rec_payload.flags = NFC_NDEF_LE_OOB_REC_FLAGS(BT_LE_AD_NO_BREDR);
|
||||
|
||||
return nfc_tnep_ch_carrier_set(&NFC_NDEF_CH_AC_RECORD_DESC(oob_ac),
|
||||
&NFC_NDEF_LE_OOB_RECORD_DESC(oob_rec), 1);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NFC_TAG_CH_REQUESTER)
|
||||
static int tnep_ch_request_prepare(void) {
|
||||
bt_le_adv_stop();
|
||||
return carrier_prepare();
|
||||
}
|
||||
|
||||
static int tnep_ch_select_received(const struct nfc_tnep_ch_record *ch_select,
|
||||
bool inactive) {
|
||||
int err;
|
||||
const struct nfc_ndef_record_desc *oob_data = NULL;
|
||||
|
||||
if (!ch_select->count) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* All alternative carrier are inactive */
|
||||
if (inactive) {
|
||||
/* Try send request again. */
|
||||
return carrier_prepare();
|
||||
}
|
||||
|
||||
err = check_oob_carrier(ch_select, &oob_data);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = oob_le_data_handle(oob_data, false);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(CONFIG_NFC_TAG_CH_REQUESTER) */
|
||||
|
||||
static int tnep_ch_request_received(const struct nfc_tnep_ch_request *ch_req) {
|
||||
int err;
|
||||
const struct nfc_ndef_record_desc *oob_data = NULL;
|
||||
|
||||
if (!ch_req->ch_record.count) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = check_oob_carrier(&ch_req->ch_record, &oob_data);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
bt_le_adv_stop();
|
||||
|
||||
err = oob_le_data_handle(oob_data, true);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return carrier_prepare();
|
||||
}
|
||||
|
||||
static struct nfc_tnep_ch_cb ch_cb = {
|
||||
#if defined(CONFIG_NFC_TAG_CH_REQUESTER)
|
||||
.request_msg_prepare = tnep_ch_request_prepare,
|
||||
.select_msg_recv = tnep_ch_select_received,
|
||||
#endif
|
||||
.request_msg_recv = tnep_ch_request_received};
|
||||
/** .. include_endpoint_nfc_tnep_ch_tag_rst */
|
||||
|
||||
static void nfc_init(void) {
|
||||
int err;
|
||||
|
||||
/* TNEP init */
|
||||
err = nfc_tnep_tag_tx_msg_buffer_register(tnep_buffer, tnep_swap_buffer,
|
||||
sizeof(tnep_buffer));
|
||||
if (err) {
|
||||
printk("Cannot register tnep buffer, err: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = nfc_tnep_tag_init(events_get(0), NFC_TNEP_EVENTS_NUMBER,
|
||||
nfc_t4t_ndef_rwpayload_set);
|
||||
if (err) {
|
||||
printk("Cannot initialize TNEP protocol, err: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set up NFC */
|
||||
err = nfc_t4t_setup(nfc_callback, NULL);
|
||||
if (err) {
|
||||
printk("Cannot setup NFC T4T library!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = nfc_tnep_tag_initial_msg_create(2, tnep_initial_msg_encode);
|
||||
if (err) {
|
||||
printk("Cannot create initial TNEP message, err: %d\n", err);
|
||||
}
|
||||
|
||||
err = nfc_tnep_ch_service_init(&ch_cb);
|
||||
if (err) {
|
||||
printk("TNEP CH Service init error: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start sensing NFC field */
|
||||
err = nfc_t4t_emulation_start();
|
||||
if (err) {
|
||||
printk("Cannot start emulation!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printk("NFC configuration done\n");
|
||||
}
|
||||
|
||||
void oob_init(void) {
|
||||
paring_key_generate();
|
||||
pair_key_generate_init();
|
||||
nfc_init();
|
||||
}
|
||||
|
||||
void oob_process(void) {
|
||||
nfc_tnep_tag_process();
|
||||
paring_key_process();
|
||||
}
|
||||
|
||||
// K_THREAD_DEFINE(oob_thread_id, CONFIG_BT_NUS_THREAD_STACK_SIZE, oob_thread,
|
||||
// NULL, NULL,
|
||||
// NULL, 7, 0, 0);
|
||||
|
||||
void oob_signal(void) { k_poll_signal_raise(&pair_signal, 0); }
|
||||
|
||||
void oob_fetch_addr(void) { bt_le_oob_get_local(BT_ID_DEFAULT, &oob_local); }
|
14
west/trezor/trezor-ble/src/oob.h
Normal file
14
west/trezor/trezor-ble/src/oob.h
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
|
||||
void auth_oob_data_request(struct bt_conn *conn, struct bt_conn_oob_info *info);
|
||||
|
||||
void oob_init(void);
|
||||
|
||||
void oob_signal(void);
|
||||
|
||||
void oob_process(void);
|
||||
|
||||
void oob_fetch_addr(void);
|
108
west/trezor/trezor-ble/src/spi.c
Normal file
108
west/trezor/trezor-ble/src/spi.c
Normal file
@ -0,0 +1,108 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/sys/crc.h>
|
||||
|
||||
#include "int_comm_defs.h"
|
||||
#include "spi.h"
|
||||
|
||||
#define MY_SPI_MASTER DT_NODELABEL(spi0)
|
||||
|
||||
static K_SEM_DEFINE(spi_comm_ok, 0, 1);
|
||||
static K_FIFO_DEFINE(fifo_spi_tx_data);
|
||||
|
||||
typedef struct {
|
||||
void *fifo_reserved;
|
||||
uint8_t data[BLE_PACKET_SIZE + 2];
|
||||
uint16_t len;
|
||||
} spi_data_t;
|
||||
|
||||
const struct device *spi_dev;
|
||||
static struct k_poll_signal spi_done_sig =
|
||||
K_POLL_SIGNAL_INITIALIZER(spi_done_sig);
|
||||
|
||||
struct spi_cs_control spim_cs = {
|
||||
.gpio = SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(reg_my_spi_master)),
|
||||
.delay = 0,
|
||||
};
|
||||
|
||||
static const struct spi_config spi_cfg = {
|
||||
.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB,
|
||||
.frequency = 8000000,
|
||||
.slave = 0,
|
||||
.cs =
|
||||
{
|
||||
.gpio = SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(reg_my_spi_master)),
|
||||
.delay = 0,
|
||||
},
|
||||
};
|
||||
|
||||
void spi_init(void) {
|
||||
spi_dev = DEVICE_DT_GET(MY_SPI_MASTER);
|
||||
if (!device_is_ready(spi_dev)) {
|
||||
printk("SPI master device not ready!\n");
|
||||
}
|
||||
if (!device_is_ready(spim_cs.gpio.port)) {
|
||||
printk("SPI master chip select device not ready!\n");
|
||||
}
|
||||
|
||||
k_sem_give(&spi_comm_ok);
|
||||
}
|
||||
|
||||
void spi_send(const uint8_t *data, uint32_t len) {
|
||||
if (len != 244) {
|
||||
// unexpected length
|
||||
return;
|
||||
}
|
||||
|
||||
spi_data_t *tx = k_malloc(sizeof(*tx));
|
||||
|
||||
if (!tx) {
|
||||
printk("Not able to allocate SPI send data buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
tx->len = len + 2;
|
||||
tx->data[0] = EXTERNAL_MESSAGE;
|
||||
memcpy(&tx->data[1], data, len);
|
||||
|
||||
uint8_t crc = crc8(tx->data, len + 1, 0x07, 0x00, false);
|
||||
tx->data[len + 1] = crc;
|
||||
|
||||
k_fifo_put(&fifo_spi_tx_data, tx);
|
||||
}
|
||||
|
||||
void spi_thread(void) {
|
||||
/* Don't go any further until BLE is initialized */
|
||||
k_sem_take(&spi_comm_ok, K_FOREVER);
|
||||
|
||||
for (;;) {
|
||||
/* Wait indefinitely for data to process */
|
||||
spi_data_t *buf = k_fifo_get(&fifo_spi_tx_data, K_FOREVER);
|
||||
|
||||
const struct spi_buf tx_buf = {
|
||||
.buf = buf->data,
|
||||
.len = buf->len,
|
||||
};
|
||||
|
||||
const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1};
|
||||
|
||||
spi_transceive(spi_dev, &spi_cfg, &tx, NULL);
|
||||
printk("SPI Data sent\n");
|
||||
|
||||
k_free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
K_THREAD_DEFINE(spi_thread_id, CONFIG_BT_NUS_THREAD_STACK_SIZE, spi_thread,
|
||||
NULL, NULL, NULL, 7, 0, 0);
|
6
west/trezor/trezor-ble/src/spi.h
Normal file
6
west/trezor/trezor-ble/src/spi.h
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void spi_init(void);
|
||||
void spi_send(const uint8_t* data, uint32_t len);
|
90
west/trezor/trezor-ble/src/trz_nus.c
Normal file
90
west/trezor/trezor-ble/src/trz_nus.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
*/
|
||||
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "trz_nus.h"
|
||||
|
||||
LOG_MODULE_REGISTER(trznus);
|
||||
|
||||
static struct bt_nus_cb nus_cb;
|
||||
|
||||
static void nus_ccc_cfg_changed(const struct bt_gatt_attr *attr,
|
||||
uint16_t value) {
|
||||
if (nus_cb.send_enabled) {
|
||||
LOG_DBG("Notification has been turned %s",
|
||||
value == BT_GATT_CCC_NOTIFY ? "on" : "off");
|
||||
nus_cb.send_enabled(value == BT_GATT_CCC_NOTIFY
|
||||
? BT_NUS_SEND_STATUS_ENABLED
|
||||
: BT_NUS_SEND_STATUS_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t on_receive(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *buf, uint16_t len, uint16_t offset,
|
||||
uint8_t flags) {
|
||||
LOG_DBG("Received data, handle %d, conn %p", attr->handle, (void *)conn);
|
||||
|
||||
if (nus_cb.received) {
|
||||
nus_cb.received(conn, buf, len);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static void on_sent(struct bt_conn *conn, void *user_data) {
|
||||
uart_data_t *data = (uart_data_t *)user_data;
|
||||
|
||||
k_free(data);
|
||||
|
||||
LOG_DBG("Data send, conn %p", (void *)conn);
|
||||
|
||||
if (nus_cb.sent) {
|
||||
nus_cb.sent(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/* UART Service Declaration */
|
||||
BT_GATT_SERVICE_DEFINE(
|
||||
nus_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_NUS_SERVICE),
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_NUS_TX, BT_GATT_CHRC_NOTIFY,
|
||||
BT_GATT_PERM_READ_ENCRYPT, NULL, NULL, NULL),
|
||||
BT_GATT_CCC(nus_ccc_cfg_changed,
|
||||
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_NUS_RX,
|
||||
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
||||
BT_GATT_PERM_READ_ENCRYPT |
|
||||
BT_GATT_PERM_WRITE_ENCRYPT,
|
||||
NULL, on_receive, NULL), );
|
||||
|
||||
int bt_nus_init(struct bt_nus_cb *callbacks) {
|
||||
if (callbacks) {
|
||||
nus_cb.received = callbacks->received;
|
||||
nus_cb.sent = callbacks->sent;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_nus_send(struct bt_conn *conn, uart_data_t *data) {
|
||||
struct bt_gatt_notify_params params = {0};
|
||||
const struct bt_gatt_attr *attr = &nus_svc.attrs[2];
|
||||
|
||||
params.attr = attr;
|
||||
params.data = data->data;
|
||||
params.len = data->len;
|
||||
params.func = on_sent;
|
||||
params.user_data = (void *)data;
|
||||
|
||||
if (conn && bt_gatt_is_subscribed(conn, attr, BT_GATT_CCC_NOTIFY)) {
|
||||
return bt_gatt_notify_cb(conn, ¶ms);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
137
west/trezor/trezor-ble/src/trz_nus.h
Normal file
137
west/trezor/trezor-ble/src/trz_nus.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
|
||||
*/
|
||||
|
||||
#ifndef BT_NUS_H_
|
||||
#define BT_NUS_H_
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @defgroup bt_nus Nordic UART (NUS) GATT Service
|
||||
* @{
|
||||
* @brief Nordic UART (NUS) GATT Service API.
|
||||
*/
|
||||
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/uuid.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief UUID of the NUS Service. **/
|
||||
#define BT_UUID_NUS_VAL \
|
||||
BT_UUID_128_ENCODE(0x8c000001, 0xa59b, 0x4d58, 0xa9ad, 0x073df69fa1b1)
|
||||
|
||||
/** @brief UUID of the TX Characteristic. **/
|
||||
#define BT_UUID_NUS_TX_VAL \
|
||||
BT_UUID_128_ENCODE(0x8c000003, 0xa59b, 0x4d58, 0xa9ad, 0x073df69fa1b1)
|
||||
|
||||
/** @brief UUID of the RX Characteristic. **/
|
||||
#define BT_UUID_NUS_RX_VAL \
|
||||
BT_UUID_128_ENCODE(0x8c000002, 0xa59b, 0x4d58, 0xa9ad, 0x073df69fa1b1)
|
||||
|
||||
#define BT_UUID_NUS_SERVICE BT_UUID_DECLARE_128(BT_UUID_NUS_VAL)
|
||||
#define BT_UUID_NUS_RX BT_UUID_DECLARE_128(BT_UUID_NUS_RX_VAL)
|
||||
#define BT_UUID_NUS_TX BT_UUID_DECLARE_128(BT_UUID_NUS_TX_VAL)
|
||||
|
||||
/** @brief NUS send status. */
|
||||
enum bt_nus_send_status {
|
||||
/** Send notification enabled. */
|
||||
BT_NUS_SEND_STATUS_ENABLED,
|
||||
/** Send notification disabled. */
|
||||
BT_NUS_SEND_STATUS_DISABLED,
|
||||
};
|
||||
|
||||
/** @brief Pointers to the callback functions for service events. */
|
||||
struct bt_nus_cb {
|
||||
/** @brief Data received callback.
|
||||
*
|
||||
* The data has been received as a write request on the NUS RX
|
||||
* Characteristic.
|
||||
*
|
||||
* @param[in] conn Pointer to connection object that has received data.
|
||||
* @param[in] data Received data.
|
||||
* @param[in] len Length of received data.
|
||||
*/
|
||||
void (*received)(struct bt_conn *conn, const uint8_t *const data,
|
||||
uint16_t len);
|
||||
|
||||
/** @brief Data sent callback.
|
||||
*
|
||||
* The data has been sent as a notification and written on the NUS TX
|
||||
* Characteristic.
|
||||
*
|
||||
* @param[in] conn Pointer to connection object, or NULL if sent to all
|
||||
* connected peers.
|
||||
*/
|
||||
void (*sent)(struct bt_conn *conn);
|
||||
|
||||
/** @brief Send state callback.
|
||||
*
|
||||
* Indicate the
|
||||
* CCCD descriptor status of the NUS TX characteristic.
|
||||
*
|
||||
* @param[in] status Send notification status.
|
||||
*/
|
||||
void (*send_enabled)(enum bt_nus_send_status status);
|
||||
};
|
||||
|
||||
/**@brief Initialize the service.
|
||||
*
|
||||
* @details This function registers a GATT service with two characteristics,
|
||||
* TX and RX. A remote device that is connected to this service
|
||||
* can send data to the RX Characteristic. When the remote enables
|
||||
* notifications, it is notified when data is sent to the TX
|
||||
* Characteristic.
|
||||
*
|
||||
* @param[in] callbacks Struct with function pointers to callbacks for service
|
||||
* events. If no callbacks are needed, this parameter can
|
||||
* be NULL.
|
||||
*
|
||||
* @retval 0 If initialization is successful.
|
||||
* Otherwise, a negative value is returned.
|
||||
*/
|
||||
int bt_nus_init(struct bt_nus_cb *callbacks);
|
||||
|
||||
/**@brief Send data.
|
||||
*
|
||||
* @details This function sends data to a connected peer, or all connected
|
||||
* peers.
|
||||
*
|
||||
* @param[in] conn Pointer to connection object, or NULL to send to all
|
||||
* connected peers.
|
||||
* @param[in] buf Pointer to a data buffer.
|
||||
*
|
||||
* @retval 0 If the data is sent.
|
||||
* Otherwise, a negative value is returned.
|
||||
*/
|
||||
int bt_nus_send(struct bt_conn *conn, uart_data_t *data);
|
||||
|
||||
/**@brief Get maximum data length that can be used for @ref bt_nus_send.
|
||||
*
|
||||
* @param[in] conn Pointer to connection Object.
|
||||
*
|
||||
* @return Maximum data length.
|
||||
*/
|
||||
static inline uint32_t bt_nus_get_mtu(struct bt_conn *conn) {
|
||||
/* According to 3.4.7.1 Handle Value Notification off the ATT protocol.
|
||||
* Maximum supported notification is ATT_MTU - 3 */
|
||||
return bt_gatt_get_mtu(conn) - 3;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
*@}
|
||||
*/
|
||||
|
||||
#endif /* BT_NUS_H_ */
|
360
west/trezor/trezor-ble/src/uart.c
Normal file
360
west/trezor/trezor-ble/src/uart.c
Normal file
@ -0,0 +1,360 @@
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
|
||||
#include <dk_buttons_and_leds.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/settings/settings.h>
|
||||
#include <zephyr/sys/crc.h>
|
||||
|
||||
#include "events.h"
|
||||
#include "int_comm.h"
|
||||
#include "int_comm_defs.h"
|
||||
#include "uart.h"
|
||||
|
||||
#define LOG_MODULE_NAME fw_uart
|
||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
|
||||
#define UART_WAIT_FOR_BUF_DELAY K_MSEC(50)
|
||||
#define UART_WAIT_FOR_RX CONFIG_BT_NUS_UART_RX_WAIT_TIME
|
||||
|
||||
static const struct device *uart = DEVICE_DT_GET(DT_CHOSEN(nordic_nus_uart));
|
||||
|
||||
static K_FIFO_DEFINE(fifo_uart_tx_data);
|
||||
static K_FIFO_DEFINE(fifo_uart_rx_data);
|
||||
static K_FIFO_DEFINE(fifo_uart_rx_data_int);
|
||||
|
||||
static struct k_work_delayable uart_work;
|
||||
|
||||
static volatile bool g_uart_rx_running = false;
|
||||
|
||||
static void uart_cb(const struct device *dev, struct uart_event *evt,
|
||||
void *user_data) {
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
static size_t aborted_len;
|
||||
uart_data_t *buf;
|
||||
static uint8_t *aborted_buf;
|
||||
static bool disable_req;
|
||||
static uint8_t rx_phase = 0;
|
||||
static uint8_t rx_msg_type = 0;
|
||||
static uint8_t rx_data_len = 0;
|
||||
static uint8_t rx_len = 0;
|
||||
static uint8_t crc = 0;
|
||||
|
||||
switch (evt->type) {
|
||||
case UART_TX_DONE:
|
||||
LOG_DBG("UART_TX_DONE");
|
||||
|
||||
if (evt->data.tx.buf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt->data.tx.len == 0) {
|
||||
buf = CONTAINER_OF(evt->data.tx.buf, uart_data_t, data[0]);
|
||||
|
||||
LOG_DBG("Free uart data");
|
||||
k_free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aborted_buf) {
|
||||
buf = CONTAINER_OF(aborted_buf, uart_data_t, data[0]);
|
||||
aborted_buf = NULL;
|
||||
aborted_len = 0;
|
||||
} else {
|
||||
buf = CONTAINER_OF(evt->data.tx.buf, uart_data_t, data[0]);
|
||||
}
|
||||
|
||||
LOG_DBG("Free uart data");
|
||||
k_free(buf);
|
||||
|
||||
buf = k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uart_tx(uart, buf->data, buf->len, SYS_FOREVER_MS)) {
|
||||
LOG_WRN("FREE: Failed to send data over UART");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UART_RX_RDY:
|
||||
// LOG_WRN("UART_RX_RDY");
|
||||
buf = CONTAINER_OF(evt->data.rx.buf, uart_data_t, data[0]);
|
||||
buf->len += evt->data.rx.len;
|
||||
|
||||
switch (rx_phase) {
|
||||
case 0:
|
||||
if (buf->len == 1 && (buf->data[0] == INTERNAL_EVENT ||
|
||||
buf->data[0] == EXTERNAL_MESSAGE)) {
|
||||
rx_phase = 1;
|
||||
rx_msg_type = buf->data[0];
|
||||
crc = crc8(buf->data, buf->len, 0x07, 0x00, false);
|
||||
} else {
|
||||
rx_phase = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (buf->len == 1) {
|
||||
rx_data_len = buf->data[0];
|
||||
crc = crc8(buf->data, buf->len, 0x07, crc, false);
|
||||
rx_phase = 2;
|
||||
} else {
|
||||
rx_phase = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (buf->len != rx_data_len - COMM_HEADER_SIZE) {
|
||||
rx_phase = 0;
|
||||
}
|
||||
|
||||
crc = crc8(buf->data, buf->len - 1, 0x07, crc, false);
|
||||
|
||||
if (crc != buf->data[buf->len - 1]) {
|
||||
LOG_WRN("UART_RX CRC ERROR");
|
||||
rx_phase = 0;
|
||||
}
|
||||
|
||||
rx_phase = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
// if (disable_req) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
|
||||
// (evt->data.rx.buf[buf->len - 1] == '\r')) {
|
||||
// disable_req = true;
|
||||
// uart_rx_disable(uart);
|
||||
// }
|
||||
|
||||
break;
|
||||
|
||||
case UART_RX_DISABLED:
|
||||
LOG_DBG("UART_RX_DISABLED");
|
||||
disable_req = false;
|
||||
|
||||
LOG_DBG("UART_RX_MALLOC");
|
||||
buf = k_malloc(sizeof(*buf));
|
||||
|
||||
if (buf) {
|
||||
switch (rx_phase) {
|
||||
case 0:
|
||||
rx_len = 1;
|
||||
break;
|
||||
case 1:
|
||||
rx_len = 1;
|
||||
break;
|
||||
case 2:
|
||||
rx_len = rx_data_len - COMM_HEADER_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
rx_len = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
buf->len = 0;
|
||||
uart_rx_enable(uart, buf->data, rx_len, SYS_FOREVER_US);
|
||||
} else {
|
||||
LOG_WRN("Not able to allocate UART receive buffer");
|
||||
k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
|
||||
g_uart_rx_running = false;
|
||||
}
|
||||
|
||||
// buf = k_malloc(sizeof(*buf));
|
||||
// if (buf) {
|
||||
// buf->len = 0;
|
||||
// } else {
|
||||
// LOG_WRN("Not able to allocate UART receive
|
||||
// buffer");
|
||||
//
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// uart_rx_enable(uart, buf->data, sizeof(buf->data),
|
||||
// UART_WAIT_FOR_RX);
|
||||
|
||||
break;
|
||||
|
||||
// case UART_RX_BUF_REQUEST:
|
||||
// LOG_INF("UART_RX_BUF_REQUEST");
|
||||
// buf = k_malloc(sizeof(*buf));
|
||||
//
|
||||
//
|
||||
// if (buf) {
|
||||
//
|
||||
// switch (rx_phase) {
|
||||
// case 0:
|
||||
// rx_len = 1;
|
||||
// break;
|
||||
// case 1:
|
||||
// rx_len = 2;
|
||||
// break;
|
||||
// default:
|
||||
// rx_len = 1;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// buf->len = 0;
|
||||
// LOG_INF("Providing buf %d", rx_len);
|
||||
// uart_rx_buf_rsp(uart, buf->data, rx_len);
|
||||
// } else {
|
||||
// LOG_WRN("Not able to allocate UART receive
|
||||
// buffer");
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
|
||||
case UART_RX_BUF_RELEASED:
|
||||
LOG_DBG("UART_RX_BUF_RELEASED");
|
||||
buf = CONTAINER_OF(evt->data.rx_buf.buf, uart_data_t, data[0]);
|
||||
|
||||
if (rx_phase == 3 && buf->len > 0) {
|
||||
buf->len -= COMM_FOOTER_SIZE;
|
||||
if (rx_msg_type == EXTERNAL_MESSAGE) {
|
||||
k_fifo_put(&fifo_uart_rx_data, buf);
|
||||
} else if (rx_msg_type == INTERNAL_EVENT) {
|
||||
k_fifo_put(&fifo_uart_rx_data_int, buf);
|
||||
} else {
|
||||
// LOG_WRN("UART_RX BAD MASSAGE TYPE");
|
||||
k_free(buf);
|
||||
}
|
||||
rx_data_len = 0;
|
||||
rx_len = 0;
|
||||
rx_msg_type = 0;
|
||||
rx_phase = 0;
|
||||
} else {
|
||||
k_free(buf);
|
||||
}
|
||||
break;
|
||||
case UART_RX_STOPPED:
|
||||
LOG_DBG("UART_RX_STOPPED");
|
||||
g_uart_rx_running = false;
|
||||
rx_data_len = 0;
|
||||
rx_len = 0;
|
||||
rx_msg_type = 0;
|
||||
rx_phase = 0;
|
||||
k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
|
||||
break;
|
||||
|
||||
case UART_TX_ABORTED:
|
||||
LOG_DBG("UART_TX_ABORTED");
|
||||
if (!aborted_buf) {
|
||||
aborted_buf = (uint8_t *)evt->data.tx.buf;
|
||||
}
|
||||
|
||||
aborted_len += evt->data.tx.len;
|
||||
buf = CONTAINER_OF(aborted_buf, uart_data_t, data[0]);
|
||||
|
||||
uart_tx(uart, &buf->data[aborted_len], buf->len - aborted_len,
|
||||
SYS_FOREVER_MS);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int uart_start_rx(void) {
|
||||
int err;
|
||||
uart_data_t *rx;
|
||||
|
||||
rx = k_malloc(sizeof(*rx));
|
||||
if (rx) {
|
||||
rx->len = 0;
|
||||
} else {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
// receive message type
|
||||
err = uart_rx_enable(uart, rx->data, 1, SYS_FOREVER_US);
|
||||
if (err) {
|
||||
LOG_ERR("Cannot enable uart reception (err: %d)", err);
|
||||
/* Free the rx buffer only because the tx buffer will be handled in the
|
||||
* callback */
|
||||
k_free(rx);
|
||||
} else {
|
||||
g_uart_rx_running = true;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void uart_work_handler(struct k_work *item) {
|
||||
uart_data_t *buf;
|
||||
|
||||
buf = k_malloc(sizeof(*buf));
|
||||
if (buf) {
|
||||
buf->len = 0;
|
||||
} else {
|
||||
LOG_WRN("Not able to allocate UART receive buffer");
|
||||
k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
|
||||
return;
|
||||
}
|
||||
|
||||
uart_rx_enable(uart, buf->data, 1, SYS_FOREVER_US);
|
||||
}
|
||||
|
||||
int uart_init(void) {
|
||||
int err;
|
||||
|
||||
if (!device_is_ready(uart)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
k_work_init_delayable(&uart_work, uart_work_handler);
|
||||
|
||||
struct uart_config cfg = {
|
||||
.baudrate = 1000000,
|
||||
.parity = UART_CFG_PARITY_NONE,
|
||||
.stop_bits = UART_CFG_STOP_BITS_1,
|
||||
.data_bits = UART_CFG_DATA_BITS_8,
|
||||
.flow_ctrl = UART_CFG_FLOW_CTRL_RTS_CTS,
|
||||
|
||||
};
|
||||
|
||||
uart_configure(uart, &cfg);
|
||||
|
||||
err = uart_callback_set(uart, uart_cb, NULL);
|
||||
if (err) {
|
||||
LOG_ERR("Cannot initialize UART callback");
|
||||
return err;
|
||||
}
|
||||
|
||||
return uart_start_rx();
|
||||
}
|
||||
|
||||
void uart_send_ext(uart_data_t *tx) { k_fifo_put(&fifo_uart_rx_data, tx); }
|
||||
|
||||
uart_data_t *uart_get_data_ext(void) {
|
||||
return k_fifo_get(&fifo_uart_rx_data, K_FOREVER);
|
||||
}
|
||||
|
||||
uart_data_t *uart_get_data_int(void) {
|
||||
return k_fifo_get(&fifo_uart_rx_data_int, K_FOREVER);
|
||||
}
|
||||
//
|
||||
// uart_data_t *uart_get_data_pb(void)
|
||||
//{
|
||||
// return k_fifo_get(&fifo_uart_rx_data_pb, K_MSEC(100));
|
||||
//}
|
||||
//
|
||||
// void uart_data_pb_flush(void){
|
||||
// while(uart_get_data_pb() != NULL);
|
||||
//}
|
||||
|
||||
void uart_send(uart_data_t *tx) {
|
||||
int err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
|
||||
if (err) {
|
||||
k_fifo_put(&fifo_uart_tx_data, tx);
|
||||
}
|
||||
}
|
22
west/trezor/trezor-ble/src/uart.h
Normal file
22
west/trezor/trezor-ble/src/uart.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef UART_H
|
||||
#define UART_H
|
||||
|
||||
#define UART_BUF_SIZE 247
|
||||
|
||||
typedef struct {
|
||||
void *fifo_reserved;
|
||||
uint8_t data[UART_BUF_SIZE];
|
||||
uint16_t len;
|
||||
} uart_data_t;
|
||||
|
||||
int uart_init(void);
|
||||
|
||||
uart_data_t *uart_get_data_ext(void);
|
||||
uart_data_t *uart_get_data_int(void);
|
||||
// uart_data_t * uart_get_data_pb(void);
|
||||
// void uart_data_pb_flush(void);
|
||||
|
||||
void uart_send(uart_data_t *data);
|
||||
void uart_send_ext(uart_data_t *tx);
|
||||
|
||||
#endif
|
21
west/trezor/west.yml
Normal file
21
west/trezor/west.yml
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
manifest:
|
||||
self:
|
||||
west-commands: scripts/west-commands.yml
|
||||
|
||||
remotes:
|
||||
- name: ncs
|
||||
url-base: https://github.com/nrfconnect
|
||||
|
||||
projects:
|
||||
- name: nrf
|
||||
remote: ncs
|
||||
repo-path: sdk-nrf
|
||||
revision: v2.7.0
|
||||
import: true
|
||||
- name: mcuboot
|
||||
url: https://github.com/hiviah/mcuboot
|
||||
path: bootloader/mcuboot
|
||||
revision: edfe1e1465dbc698bf9a195816247913490ab391
|
20
west/trezor/zephyr/module.yml
Normal file
20
west/trezor/zephyr/module.yml
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
build:
|
||||
# Path to the Kconfig file that will be sourced into Zephyr Kconfig tree under
|
||||
# Zephyr > Modules > example-application. Path is relative from root of this
|
||||
# repository.
|
||||
kconfig: Kconfig
|
||||
# Path to the folder that contains the CMakeLists.txt file to be included by
|
||||
# Zephyr build system. The `.` is the root of this repository.
|
||||
cmake: .
|
||||
settings:
|
||||
# Additional roots for boards and DTS files. Zephyr will use the
|
||||
# `<board_root>/boards` for additional boards. The `.` is the root of this
|
||||
# repository.
|
||||
board_root: .
|
||||
# Zephyr will use the `<dts_root>/dts` for additional dts files and
|
||||
# `<dts_root>/dts/bindings` for additional dts binding files. The `.` is
|
||||
# the root of this repository.
|
||||
dts_root: .
|
Loading…
Reference in New Issue
Block a user