diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c9758012c..927d9cbbb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,6 +22,7 @@ repos: rev: v2.2.5 hooks: - id: codespell + args: [--ignore-words-list=aci] - repo: https://github.com/pre-commit/mirrors-clang-format rev: v16.0.6 diff --git a/Makefile.defines b/Makefile.defines index b600857b5..b89da61f9 100644 --- a/Makefile.defines +++ b/Makefile.defines @@ -180,6 +180,8 @@ DEFINES += SCREEN_SIZE_NANO DEFINES += HAVE_BAGL endif # TARGET_NANOS +DEFINES += OS_IO_SEPH_BUFFER_SIZE=352 + ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_NANOS2)) # Screen is directly connected to the SE DEFINES += HAVE_SE_SCREEN diff --git a/Makefile.rules b/Makefile.rules index 5963947df..fed648989 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -37,6 +37,8 @@ define check_duplicate = $(if $(LIST), $(info [WARNING] Found duplicate files in SDK and APP: ${LIST})) endef +SDK_SOURCE_PATH += io io_legacy protocol lib_u2f_legacy + # adding the correct target header to sources SDK_SOURCE_PATH += target/$(TARGET)/include diff --git a/Makefile.standard_app b/Makefile.standard_app index 75e54db72..0f35b3a72 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -25,7 +25,7 @@ ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX TARGET_FLE HAVE_APPLICATION_FLAG_BOLOS_SETTINGS = 1 DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 HAVE_BLE_APDU DEFINES += BLE_SEGMENT_SIZE=32 - SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl + SDK_SOURCE_PATH += lib_blewbxx endif endif @@ -36,6 +36,7 @@ ifeq ($(ENABLE_NFC), 1) ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME), TARGET_STAX TARGET_FLEX)) HAVE_APPLICATION_FLAG_BOLOS_SETTINGS = 1 DEFINES += HAVE_NFC + SDK_SOURCE_PATH += lib_nfc endif endif @@ -82,17 +83,6 @@ else DEFINES += PRINTF\(...\)= endif -##################################################################### -# IO SEPROXY BUFFER SIZE # -##################################################################### -ifneq ($(DISABLE_DEFAULT_IO_SEPROXY_BUFFER_SIZE), 1) - ifeq ($(TARGET_NAME), TARGET_NANOS) - DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128 - else - DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300 - endif -endif - ##################################################################### # NBGL # ##################################################################### @@ -121,19 +111,30 @@ ifeq ($(ENABLE_NBGL_KEYPAD), 1) DEFINES += NBGL_KEYPAD endif +##################################################################### +# OS IO STACK USE # +##################################################################### +ifneq ($(DISABLE_OS_IO_STACK_USE), 1) +DEFINES += USE_OS_IO_STACK +endif + ##################################################################### # STANDARD DEFINES # ##################################################################### DEFINES += $(DEFINES_LIB) DEFINES += MAJOR_VERSION=$(APPVERSION_M) MINOR_VERSION=$(APPVERSION_N) PATCH_VERSION=$(APPVERSION_P) DEFINES += IO_HID_EP_LENGTH=64 +DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=OS_IO_SEPH_BUFFER_SIZE + + +SDK_SOURCE_PATH += io +SDK_SOURCE_PATH += protocol ifeq ($(DISABLE_STANDARD_APP_DEFINES), 1) DISABLE_STANDARD_SNPRINTF = 1 DISABLE_STANDARD_USB = 1 DISABLE_STANDARD_WEBUSB = 1 DISABLE_STANDARD_BAGL_UX_FLOW = 1 - DISABLE_STANDARD_SEPROXYHAL = 1 endif ifneq ($(DISABLE_STANDARD_SNPRINTF), 1) @@ -143,7 +144,7 @@ endif ifneq ($(DISABLE_STANDARD_USB), 1) DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=4 HAVE_USB_APDU DEFINES += USB_SEGMENT_SIZE=64 - SDK_SOURCE_PATH += lib_stusb lib_stusb_impl + SDK_SOURCE_PATH += lib_stusb endif ifneq ($(DISABLE_STANDARD_WEBUSB), 1) @@ -153,8 +154,13 @@ ifneq ($(DISABLE_STANDARD_WEBUSB), 1) DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=$(WEBUSB_URL_SIZE_B) WEBUSB_URL=$(WEBUSB_URL) endif +ifneq ($(DISABLE_STANDARD_USB), 1) + DEFINES += HAVE_IO_U2F + SDK_SOURCE_PATH += lib_u2f +endif + ifneq ($(DISABLE_STANDARD_BAGL_UX_FLOW), 1) -ifneq ($(USE_NBGL), 1) +ifndef USE_NBGL DEFINES += HAVE_UX_FLOW endif endif @@ -255,7 +261,7 @@ include $(BOLOS_SDK)/Makefile.defines include $(BOLOS_SDK)/Makefile.glyphs load: all - python3 -m ledgerblue.loadApp $(APP_LOAD_PARAMS) + python3 -m ledgerblue.loadApp $(APP_LOAD_PARAMS) --rootPrivateKey f028458b39af92fea938486ecc49562d0e7731b53d9b25e2701183e4f2adc991 load-offline: all python3 -m ledgerblue.loadApp $(APP_LOAD_PARAMS) --offline diff --git a/include/ledger_protocol.h b/include/ledger_protocol.h deleted file mode 100644 index 765dff7da..000000000 --- a/include/ledger_protocol.h +++ /dev/null @@ -1,64 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#pragma once - -/* Includes ------------------------------------------------------------------*/ -#include - -/* Exported enumerations -----------------------------------------------------*/ -enum { - APDU_STATUS_WAITING, - APDU_STATUS_NEED_MORE_DATA, - APDU_STATUS_COMPLETE, -}; - -/* Exported types, structures, unions ----------------------------------------*/ -typedef struct ledger_protocol_s { - const uint8_t *tx_apdu_buffer; - - uint16_t tx_apdu_length; - uint16_t tx_apdu_sequence_number; - uint16_t tx_apdu_offset; - - uint8_t tx_chunk[156 + 2]; - uint8_t tx_chunk_length; - - uint8_t *rx_apdu_buffer; - uint16_t rx_apdu_buffer_max_length; - uint8_t rx_apdu_status; - uint16_t rx_apdu_sequence_number; - uint16_t rx_apdu_length; - uint16_t rx_apdu_offset; - - uint8_t *rx_dst_buffer; - - uint16_t mtu; - uint8_t mtu_negotiated; -} ledger_protocol_t; - -/* Exported defines --------------------------------------------------------*/ - -/* Exported macros------------------------------------------------------------*/ - -/* Exported variables --------------------------------------------------------*/ - -/* Exported functions prototypes--------------------------------------------- */ -void LEDGER_PROTOCOL_init(ledger_protocol_t *ctx); -void LEDGER_PROTOCOL_rx(ledger_protocol_t *ctx, const uint8_t *buffer, uint16_t length); -void LEDGER_PROTOCOL_tx(ledger_protocol_t *ctx, const uint8_t *buffer, uint16_t length); diff --git a/include/os.h b/include/os.h index a329e07b8..873510979 100644 --- a/include/os.h +++ b/include/os.h @@ -128,63 +128,4 @@ int snprintf(char *str, size_t str_size, const char *format, ...); int compute_address_location(int address); #endif -// syscall test -// SYSCALL void dummy_1(unsigned int* p PLENGTH(2+len+15+ len + 16 + sizeof(io_send_t) + 1 ), -// unsigned int len); - -/* ----------------------------------------------------------------------- */ -/* - I/O I2C - */ -/* ----------------------------------------------------------------------- */ - -#ifdef HAVE_IO_I2C - -#define IO_I2C_SPEED_STD 0 -#define IO_I2C_SPEED_FAST 1 -#define IO_I2C_SPEED_FASTPLUS 2 -#define IO_I2C_SPEED_HS 3 -#define IO_I2C_MASTER 0x80 -/** - * Configure the I2C peripheral. - * @param speed_and_master enables to set the bus speed. And to select if the peripheral will act as - * master (issuing Start and Stop condition upon need) or slave mode. - * @param address In master mode, this parameter sets the target I2C device's address. In slave - * mode, the address is the desired I2C bus address for the interface. The address is always a 7bit - * address (excluding the transfer direction bit). - */ -SYSCALL void io_i2c_setmode(unsigned int speed_and_master, unsigned int address); - -/** - * Setup the I2C peripheral for: - * - In slave mode, receiving a WRITE transaction of maxlength bytes at most. Upon WRITE transaction - * end, an SEPROXYHAL_TAG_I2C_EVENT is issued with the received data. It has to be received through - * ::io_seph_recv. - * - In master mode, this call is nop. - */ -SYSCALL void io_i2c_prepare(unsigned int maxlength); - -#define IO_I2C_FLAGS_READ 0 -#define IO_I2C_FLAGS_WRITE 1 -#define IO_I2C_FLAGS_START 2 -#define IO_I2C_FLAGS_STOP 4 -/** - * Request to execute a transfer: - * - In slave mode, this call is non-blocking. It only enables to reply to a READ transaction of at - * most length bytes. After the Stop condition is issued from the master, a SEPROXYHAL_TAG_I2C_EVENT - * event containing the effectively transferred length is issued and can be retrieved through - * ::io_seph_recv. To restart or continue the transfer requires another call to ::io_i2c_xfer. - * - In master mode, this call is blocking and triggers the transaction as requested through the - * flags parameter. The READ or WRITE transaction will place or transmit data from the given buffer - * and length. Depending on the passed start/stop flags, corresponding bus condition are executed. - */ -SYSCALL void io_i2c_xfer(void *buffer PLENGTH(length), unsigned int length, unsigned int flags); - -#ifndef BOLOS_RELEASE -#ifdef BOLOS_DEBUG -SYSCALL void io_i2c_dumpstate(void); -SYSCALL void io_debug(char *chars, unsigned int len); -#endif // BOLOS_DEBUG -#endif // BOLOS_RELEASE - -#endif // HAVE_IO_I2C - #endif // OS_H diff --git a/include/os_io.h b/include/os_io.h deleted file mode 100644 index 3e01e7e64..000000000 --- a/include/os_io.h +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once -#include -#include -#include "app_config.h" -#include "bolos_target.h" -#include "os_math.h" -#include "decorators.h" -/* ----------------------------------------------------------------------- */ -/* - GLOBALS - */ -/* ----------------------------------------------------------------------- */ - -// the global apdu buffer -#ifdef HAVE_IO_U2F -#define IMPL_IO_APDU_BUFFER_SIZE (3 + 32 + 32 + 15 + 255) -#else -#define IMPL_IO_APDU_BUFFER_SIZE (5 + 255) -#endif -#ifdef CUSTOM_IO_APDU_BUFFER_SIZE -#define IO_APDU_BUFFER_SIZE MAX(IMPL_IO_APDU_BUFFER_SIZE, CUSTOM_IO_APDU_BUFFER_SIZE) -#else -#define IO_APDU_BUFFER_SIZE IMPL_IO_APDU_BUFFER_SIZE -#endif - -typedef struct apdu_buffer_s { - uint8_t *buf; - uint16_t len; -} apdu_buffer_t; - -extern unsigned char G_io_apdu_buffer[IO_APDU_BUFFER_SIZE]; - -// send tx_len bytes (atr or rapdu) and retrieve the length of the next command apdu (over the -// requested channel) -#define CHANNEL_APDU 0 -#define CHANNEL_KEYBOARD 1 -#define CHANNEL_SPI 2 -#define IO_RESET_AFTER_REPLIED 0x80 -#define IO_RECEIVE_DATA 0x40 -#define IO_RETURN_AFTER_TX 0x20 -#define IO_ASYNCH_REPLY 0x10 // avoid apdu state reset if tx_len == 0 when we're expected to reply -#define IO_FINISHED 0x08 // inter task communication value -#define IO_CONTINUE_RX 0x04 -#define IO_FLAGS 0xFC -unsigned short io_exchange(unsigned char channel_and_flags, unsigned short tx_len); - -typedef enum { - IO_APDU_MEDIA_NONE = 0, // not correctly in an apdu exchange - IO_APDU_MEDIA_USB_HID = 1, - IO_APDU_MEDIA_BLE, - IO_APDU_MEDIA_NFC, - IO_APDU_MEDIA_USB_CCID, - IO_APDU_MEDIA_USB_WEBUSB, - IO_APDU_MEDIA_RAW, - IO_APDU_MEDIA_U2F, -} io_apdu_media_t; - -#ifndef USB_SEGMENT_SIZE -#ifdef IO_HID_EP_LENGTH -#define USB_SEGMENT_SIZE IO_HID_EP_LENGTH -#else -#error IO_HID_EP_LENGTH and USB_SEGMENT_SIZE not defined -#endif -#endif -#ifndef BLE_SEGMENT_SIZE -#define BLE_SEGMENT_SIZE USB_SEGMENT_SIZE -#endif -// common usb endpoint buffer -extern unsigned char G_io_usb_ep_buffer[MAX(USB_SEGMENT_SIZE, BLE_SEGMENT_SIZE)]; - -/** - * Return 1 when the event has been processed, 0 else - */ -// io callback in the application called when an interrupt based channel has received data to be -// processed -unsigned char io_event(unsigned char channel); - -#ifdef HAVE_SE_TOUCH - -typedef struct io_touch_info_s { - uint16_t x; - uint16_t y; - uint8_t state; - uint8_t w; - uint8_t h; - uint8_t swipe; -} io_touch_info_t; - -// bitfield for exclusion borders, for touch_exclude_borders() (if a bit is set, means that pixels -// on this border are not taken into account) -#define LEFT_BORDER 1 -#define RIGHT_BORDER 2 -#define TOP_BORDER 4 -#define BOTTOM_BORDER 8 - -#ifdef HAVE_SE_TOUCH - -typedef enum io_touch_debug_mode_e { - TOUCH_DEBUG_END = 0, - TOUCH_DEBUG_READ_RAW_DATA = 1, - TOUCH_DEBUG_READ_DIFF_DATA = 2, - TOUCH_DEBUG_READ_SENSOR_BUFFER = 3, -} io_touch_debug_mode_t; - -SYSCALL void touch_get_last_info(io_touch_info_t *info); -SYSCALL void touch_set_state(bool enable); -SYSCALL uint8_t touch_exclude_borders(uint8_t excluded_borders); -#ifdef HAVE_TOUCH_READ_DEBUG_DATA_SYSCALL -SYSCALL uint8_t touch_switch_debug_mode_and_read(io_touch_debug_mode_t mode, - uint8_t buffer_type, - uint8_t *read_buffer); -#endif -#endif -#endif // HAVE_SE_TOUCH diff --git a/include/os_io_nfc.h b/include/os_io_nfc.h deleted file mode 100644 index 7f461aa64..000000000 --- a/include/os_io_nfc.h +++ /dev/null @@ -1,95 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#ifndef OS_IO_NFC_H -#define OS_IO_NFC_H - -#include "arch.h" - -#include "os_io_seproxyhal.h" - -/* Public API for reader application --------------------------------------- */ -#ifdef HAVE_NFC_READER - -enum card_tech { - NFC_A, - NFC_B -}; - -struct card_info { - enum card_tech tech; - uint8_t nfcid[7]; - size_t nfcid_len; -}; - -enum nfc_event { - CARD_DETECTED, - CARD_REMOVED, -}; - -typedef void (*nfc_evt_callback_t)(enum nfc_event event, struct card_info *info); -typedef void (*nfc_resp_callback_t)(bool error, bool timeout, uint8_t *resp_data, size_t resp_len); - -/* Functions */ - -/* return false in case of error - in that case, callback will not be called */ -bool io_nfc_reader_send(const uint8_t *cmd_data, - size_t cmd_len, - nfc_resp_callback_t callback, - int timeout_ms); - -/* Return false if nfc reader can not be started in current conditions */ -bool io_nfc_reader_start(nfc_evt_callback_t callback); -void io_nfc_reader_stop(void); -bool io_nfc_is_reader(void); - -#endif // HAVE_NFC_READER - -/* SDK internal API --------------------------------------- */ - -#ifdef HAVE_NFC_READER - -struct nfc_reader_context { - nfc_resp_callback_t resp_callback; - nfc_evt_callback_t evt_callback; - bool reader_mode; - bool event_happened; - bool response_received; - unsigned int remaining_ms; - enum nfc_event last_event; - struct card_info card; - uint8_t *apdu_rx; - size_t apdu_rx_len; // Used length - size_t apdu_rx_max_size; // Max size of buffer -}; - -extern struct nfc_reader_context G_io_reader_ctx; -#endif // HAVE_NFC_READER - -void io_nfc_init(void); -void io_nfc_recv_event(void); -void io_nfc_send_response(const uint8_t *packet, uint16_t packet_length); - -#ifdef HAVE_NFC_READER -void io_nfc_event(void); -void io_nfc_ticker(void); -void io_nfc_process_events(void); -#endif // HAVE_NFC_READER - -#endif diff --git a/include/os_io_seproxyhal.h b/include/os_io_seproxyhal.h index 0587289bb..99bb54e94 100644 --- a/include/os_io_seproxyhal.h +++ b/include/os_io_seproxyhal.h @@ -1,343 +1,18 @@ +/* @BANNER@ */ -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ +#pragma once -#ifndef OS_IO_SEPROXYHAL_H -#define OS_IO_SEPROXYHAL_H +/* Includes ------------------------------------------------------------------*/ +#include "os_io_legacy.h" -#if defined(HAVE_BOLOS) -#include "bolos_privileged_ux.h" -#endif // HAVE_BOLOS +/* Exported enumerations -----------------------------------------------------*/ -#include "bolos_target.h" -#include "decorators.h" -#include "os_io.h" -#include "os_ux.h" -#include "os_print.h" -#include "os_types.h" +/* Exported types, structures, unions ----------------------------------------*/ -#ifdef HAVE_SERIALIZED_NBGL -#include "nbgl_serialize.h" -#endif +/* Exported defines --------------------------------------------------------*/ -#ifdef OS_IO_SEPROXYHAL +/* Exported macros------------------------------------------------------------*/ -#include "seproxyhal_protocol.h" +/* Exported variables --------------------------------------------------------*/ -// helper macro to swap values, without intermediate value -#define SWAP(a, b) \ - { \ - a ^= b; \ - b ^= a; \ - a ^= b; \ - } - -extern unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; - -SYSCALL void io_seph_send(const unsigned char *buffer PLENGTH(length), unsigned short length); - -// return 1 if the previous seproxyhal exchange has been terminated with a status (packet which -// starts with 011x xxxx) else 0, which means the exchange needs to be closed. -SYSCALL unsigned int io_seph_is_status_sent(void); - -// not to be called by application (application is triggered using io_event instead), resered for -// seproxyhal -#define IO_CACHE 1 -SYSCALL unsigned short io_seph_recv(unsigned char *buffer PLENGTH(maxlength), - unsigned short maxlength, - unsigned int flags); - -#define io_seproxyhal_spi_send io_seph_send -#define io_seproxyhal_spi_is_status_sent io_seph_is_status_sent -#define io_seproxyhal_spi_recv io_seph_recv - -// HAL init, not meant to be called by applications, which shall call ::io_seproxyhal_init instead -void io_seph_init(void); - -// init all (io/ux/etc) -void io_seproxyhal_init(void); - -// only reinit ux related globals -void io_seproxyhal_init_ux(void); - -// only init button handling related variables (not to be done when switching screen to avoid the -// release triggering unwanted behavior) -void io_seproxyhal_init_button(void); - -// delegate function for generic io_exchange -unsigned short io_exchange_al(unsigned char channel_and_flags, unsigned short tx_len); - -// Allow application to overload how the io_exchange function automatically replies to get app name -// and version -unsigned int os_io_seproxyhal_get_app_name_and_version(void); - -#if defined(HAVE_LEDGER_PKI) -unsigned int os_io_seproxyhal_pki_load_certificate(uint8_t *buffer, - size_t buffer_len, - uint8_t init); -#endif // HAVE_LEDGER_PKI - -// for delegation of Native NFC / USB -unsigned char io_event(unsigned char channel); - -#ifdef HAVE_BLE -void BLE_power(unsigned char powered, const char *discovered_name); -#endif // HAVE_BLE - -#ifdef __cplusplus -extern "C" void USB_power(unsigned char enabled); -#else -void USB_power(unsigned char enabled); -#endif - -void io_seproxyhal_handle_usb_event(void); -void io_seproxyhal_handle_usb_ep_xfer_event(void); -uint16_t io_seproxyhal_get_ep_rx_size(uint8_t epnum); - -// process event for io protocols when waiting for a ux operation to end -// return 1 when event replied, 0 else -unsigned int io_seproxyhal_handle_event(void); - -// reply a general status last command -void io_seproxyhal_general_status(void); - -// reply a MORE COMMANDS status for the proxyhal to wait for more data later -void os_io_seproxyhal_general_status_processing(void); - -// legacy function to send over EP 0x82 -void io_usb_send_apdu_data(unsigned char *buffer, unsigned short length); -void io_usb_send_apdu_data_ep0x83(unsigned char *buffer, unsigned short length); - -// trigger a transfer over an usb endpoint and waits for it to occur if timeout is != 0 -void io_usb_send_ep(unsigned int ep, - unsigned char *buffer, - unsigned short length, - unsigned int timeout); - -void io_usb_ccid_reply(unsigned char *buffer, unsigned short length); - -#ifdef HAVE_SERIALIZED_NBGL -void io_seproxyhal_send_nbgl_serialized(nbgl_serialized_event_type_e event, nbgl_obj_t *obj); -#endif - -#define NO_TIMEOUT (0UL) -// Function that allow applications to modulate the APDU handling timeout -// timeout is disabled by default. -// having an APDU handling timeout is useful to solve multiple media interactions. -void io_set_timeout(unsigned int timeout); - -#ifdef HAVE_NFC -// Needs to be aligned with RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN defined on mcu side in platform.h -#define NFC_APDU_MAX_SIZE 1024 -void io_seproxyhal_nfc_power(bool forceInit); -#endif - -#ifdef HAVE_SE_TOUCH -#ifdef HAVE_TOUCH_READ_DEBUG_DATA_SYSCALL -#ifdef HAVE_GT1151_TOUCH -bolos_bool_t io_seproxyhal_touch_debug_read_sensi(uint8_t *sensi_data); -bolos_bool_t io_seproxyhal_touch_debug_read_diff_data(uint8_t *sensi_data); -bolos_bool_t io_seproxyhal_touch_debug_end(void); -#endif -#ifdef HAVE_EWD720_TOUCH -bolos_bool_t io_seproxyhal_touch_debug_read_offset_data(uint8_t *offset_data); -#endif -#endif -#endif - -typedef enum { - APDU_IDLE, - APDU_BLE, - APDU_BLE_WAIT_NOTIFY, -#ifdef HAVE_NFC - APDU_NFC, -#endif - APDU_NFC_M24SR, - APDU_NFC_M24SR_SELECT, - APDU_NFC_M24SR_FIRST, - APDU_NFC_M24SR_RAPDU, - APDU_USB_HID, - APDU_USB_CCID, - APDU_U2F, - APDU_RAW, - APDU_USB_WEBUSB, -} io_apdu_state_e; - -#ifdef HAVE_IO_U2F -#include "u2f_service.h" -extern u2f_service_t G_io_u2f; -#endif // HAVE_IO_U2F - -/** - * Ledger Bluetooth Low Energy APDU Protocol - * Characteristic content: - * [______________________________] - * TT SSSS VVVV................VV - * - * All fields are big endian encoded. - * TT: 1 byte content tag - * SSSS: 2 bytes sequence number, big endian encoded (start @ 0). - * VVVV..VV: variable length content. When SSSS is 0, the first two bytes encodes in big endian the - * total length of the APDU to transport. - * - * Command/Response APDU are split in chunks to fill up the bluetooth's characteristic - * - * APDU are using either standard or extended header. up to the application to check the total - * received length and the lc field - * - * Tags: - * Direction:* T:0x05 S= V= APDU - * (command/response) packet. - * - * Example: - * -------- - * Wrapping of Command APDU: - * E0 FF 12 13 14 - * 15 16 17 18 19 1A 1B 1C - * 1D 1E 1F 20 21 22 23 24 - * 25 26 27 28 29 2A 2B 2C - * 2D 2E 2F 30 31 32 33 34 - * 35 - * Result in 3 chunks (20 bytes at most): - * 0500000026E0FF12131415161718191A1B1C1D1E - * 0500011F202122232425262728292A2B2C2D2E2F - * 050002303132333435 - * - * - * Wrapping of Response APDU: - * 15 16 17 18 19 1a 1b 1c - * 1d 1e 1f 20 21 22 23 24 - * 25 26 27 28 29 2a 2b 2c - * 2d 2e 2f 30 31 32 33 34 - * 35 90 00 - * Result in 3 chunks (20 bytes at most): - * 050000002315161718191a1b1c1d1e1f20212223 - * 0500012425262728292a2b2c2d2e2f3031323334 - * 050002359000 - */ - -/** - * Wait until a UX call returns a definitve status. Handle all event packets in between - */ -#if !defined(APP_UX) -unsigned int os_ux_blocking(bolos_ux_params_t *params); -#endif // !defined(APP_UX) - -/** - * Global type that enables to map memory onto the application zone instead of over the os for os - * side - */ -typedef struct io_seph_s { - io_apdu_state_e apdu_state; // by default - unsigned short apdu_length; // total length to be received - unsigned short io_flags; // flags to be set when calling io_exchange - io_apdu_media_t apdu_media; - - unsigned int ms; - -#ifdef HAVE_IO_USB - unsigned char usb_ep_xfer_len[IO_USB_MAX_ENDPOINTS]; - struct { - unsigned short timeout; // up to 64k milliseconds (64 sec) - } usb_ep_timeouts[IO_USB_MAX_ENDPOINTS]; -#endif // HAVE_IO_USB - -#ifdef HAVE_BLE_APDU - unsigned short ble_xfer_timeout; -#endif // HAVE_BLE_APDU - -#ifdef HAVE_BLE - // cached here to avoid unavailable zone deref within IO task - unsigned int plane_mode; - unsigned char ble_ready; - unsigned char name_changed; - unsigned char enabling_advertising; - unsigned char disabling_advertising; -#endif // HAVE_BLE - - unsigned char transfer_mode; -} io_seph_app_t; - -extern io_seph_app_t G_io_app; - -// deprecated -#define G_io_apdu_media G_io_app.apdu_media -// deprecated -#define G_io_apdu_state G_io_app.apdu_state - -#ifdef HAVE_IO_TASK -/** - * IO task entry point - */ -void io_task(void); -/** - * IO task initializez - */ -void io_start(void); -#endif // HAVE_IO_TASK - -void io_seproxyhal_setup_ticker(unsigned int interval_ms); -void io_seproxyhal_power_off(bool criticalBattery); -void io_seproxyhal_se_reset(void); -void io_seproxyhal_disable_io(void); -void io_seproxyhal_enable_io(void); - -#ifdef HAVE_PIEZO_SOUND -typedef enum tune_index_e { - TUNE_RESERVED, - TUNE_BOOT, - TUNE_CHARGING, - TUNE_LEDGER_MOMENT, - TUNE_ERROR, - TUNE_NEUTRAL, - TUNE_LOCK, - TUNE_SUCCESS, - TUNE_LOOK_AT_ME, - TUNE_TAP_CASUAL, - TUNE_TAP_NEXT, - NB_TUNES // Keep at last position -} tune_index_e; - -void io_seproxyhal_play_tune(tune_index_e tune_index); - -#endif // HAVE_PIEZO_SOUND - -#ifdef HAVE_BLE -void io_seph_ble_enable(unsigned char enable); -void io_seph_ble_clear_bond_db(void); -void io_seph_ble_name_changed(void); -void io_seph_ux_accept_pairing(unsigned char status); -#endif // HAVE_BLE -void io_seph_ux_redisplay(void); - -/** - * Function to ensure a I/O channel is not timeouting waiting for operations after a long time - * without SEPH packet exchanges - */ -void io_seproxyhal_io_heartbeat(void); - -// IO task related function -unsigned int os_io_seph_recv_and_process(unsigned int dont_process_ux_events); - -#ifdef HAVE_PRINTF -// Sends a character to the MCU and waits for the MCU acknowledgement. -void mcu_usb_prints(const char *str, unsigned int charcount); -#endif // HAVE_PRINTF - -#endif // OS_IO_SEPROXYHAL - -#endif // OS_IO_SEPROXYHAL_H +/* Exported functions prototypes--------------------------------------------- */ diff --git a/include/os_io_usb.h b/include/os_io_usb.h index d9b6d99c2..f32a480ca 100644 --- a/include/os_io_usb.h +++ b/include/os_io_usb.h @@ -1,66 +1,19 @@ +/* @BANNER@ */ -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ +#pragma once -#ifndef OS_IO_USB_H -#define OS_IO_USB_H +/* Includes ------------------------------------------------------------------*/ +#include "os_io_legacy.h" -#include "os_io_seproxyhal.h" -#include "os_io.h" +/* Exported enumerations -----------------------------------------------------*/ -#ifdef HAVE_USB_APDU +/* Exported types, structures, unions ----------------------------------------*/ -/* ----------------------------------------------------------------------- */ -/* - IO FUNCTIONS - */ -/* ----------------------------------------------------------------------- */ -typedef void (*io_send_t)(unsigned char *buffer, unsigned short length); +/* Exported defines --------------------------------------------------------*/ +#define io_usb_hid_init (void) -typedef unsigned short (*io_recv_t)(unsigned char *buffer, unsigned short maxlenth); +/* Exported macros------------------------------------------------------------*/ -typedef enum io_usb_hid_receive_status_e { - IO_USB_APDU_RESET, - IO_USB_APDU_MORE_DATA, - IO_USB_APDU_RECEIVED, -} io_usb_hid_receive_status_t; +/* Exported variables --------------------------------------------------------*/ -extern volatile unsigned int G_io_usb_hid_total_length; - -void io_usb_hid_init(void); - -/** - * Receive next HID transport packet, returns IO_USB_APDU_RECEIVED when a complete APDU has been - * received in the G_io_apdu_buffer To be called typically upon USB OUT event - */ -io_usb_hid_receive_status_t io_usb_hid_receive(io_send_t sndfct, - unsigned char *buffer, - unsigned short l, - apdu_buffer_t *apdu_buffer); - -/** - * Mark the last chunk transmitted as sent. - * To be called typically upon USB IN ACK event - */ -void io_usb_hid_sent(io_send_t sndfct); - -/** - * Request transmission of an APDU from the G_io_apdu_buffer using the HID transport protocol - */ -void io_usb_hid_send(io_send_t sndfct, unsigned short sndlength, unsigned char *apdu_buffer); - -#endif // HAVE_USB_APDU - -#endif +/* Exported functions prototypes--------------------------------------------- */ diff --git a/include/os_screen.h b/include/os_screen.h index 1e57e3dc5..a6e9ceb53 100644 --- a/include/os_screen.h +++ b/include/os_screen.h @@ -4,7 +4,6 @@ #include "decorators.h" #include "os_types.h" -#ifdef HAVE_SE_SCREEN // SYSCALL void screen_write_frame(unsigned char* framebuffer PLENGTH(BAGL_WIDTH*BAGL_HEIGHT/8)); /** * Initialize the screen driver and blank the screen. @@ -52,4 +51,3 @@ SYSCALL void bagl_hal_draw_rect(unsigned int color, int y, unsigned int width, unsigned int height); -#endif // HAVE_SE_SCREEN diff --git a/include/os_seed.h b/include/os_seed.h index 4941b71e3..74e656fac 100644 --- a/include/os_seed.h +++ b/include/os_seed.h @@ -57,7 +57,7 @@ unsigned char os_perso_get_seed_algorithm(void); SYSCALL PERMISSION(APPLICATION_FLAG_BOLOS_UX) void os_perso_set_words(const unsigned char *words PLENGTH(length), unsigned int length); -SYSCALL PERMISSION(APPLICATION_FLAG_BOLOS_UX) void os_perso_finalize(void); +SYSCALL PERMISSION(APPLICATION_FLAG_BOLOS_UX) void os_perso_finalize(uint8_t disable_io); #if defined(HAVE_RECOVER) SYSCALL PERMISSION(APPLICATION_FLAG_BOLOS_UX) void os_perso_master_seed(uint8_t *master_seed PLENGTH(length), diff --git a/include/os_task.h b/include/os_task.h index 002c5cd9e..a482a158b 100644 --- a/include/os_task.h +++ b/include/os_task.h @@ -85,9 +85,3 @@ SYSCALL unsigned int os_sched_create(void *main PLENGTH(4), // kill a task SYSCALL void os_sched_kill(unsigned int taskidx); - -typedef struct { - void (*asynchmodal_end_callback)(unsigned int ux_status); -} bolos_ux_asynch_callback_t; - -extern bolos_ux_asynch_callback_t G_io_asynch_ux_callback; diff --git a/include/os_ux.h b/include/os_ux.h index d4517ecc9..b6c0a80a1 100644 --- a/include/os_ux.h +++ b/include/os_ux.h @@ -5,6 +5,10 @@ #include "os_types.h" #include "os_utils.h" +#if defined(HAVE_BOLOS) +#include "bolos_privileged_ux.h" +#endif // HAVE_BOLOS + /* ----------------------------------------------------------------------- */ /* - UX DEFINITIONS - */ /* ----------------------------------------------------------------------- */ @@ -23,7 +27,7 @@ typedef enum bolos_ux_e { BOLOS_UX_VALIDATE_PIN, BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST, // ask the ux to display a modal to accept/reject the // current pairing request - BOLOS_UX_ASYNCHMODAL_PAIRING_CANCEL, + BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS, BOLOS_UX_IO_RESET, BOLOS_UX_LAST_ID, } bolos_ux_t; @@ -73,7 +77,7 @@ typedef struct bolos_ux_params_s { BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED, BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CANCELLED_FROM_REMOTE, } pairing_ok; - } pairing_status; // sent in BOLOS_UX_ASYNCHMODAL_PAIRING_CANCEL message + } pairing_status; // sent in BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS message #endif // HAVE_BLE } u; #endif // defined(HAVE_BLE) || defined(HAVE_KEYBOARD_UX) diff --git a/include/seproxyhal_protocol.h b/include/seproxyhal_protocol.h index 4795b87be..1b0fdd584 100644 --- a/include/seproxyhal_protocol.h +++ b/include/seproxyhal_protocol.h @@ -1,261 +1,267 @@ +/* @BANNER@ */ -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#ifndef SEPROXYHAL_PROTOCOL_H -#define SEPROXYHAL_PROTOCOL_H - -#define BLE_CMD_APDU 0x05 -#define BLE_CHUNK_LENGTH 20 -#define M24SR_CHUNK_LENGTH 0xF6 - -// EVENTS -#define SEPROXYHAL_TAG_SESSION_START_EVENT \ - 0x01 // - // - // - // - // - // -#define SEPROXYHAL_TAG_SESSION_START_EVENT_REQBLE 0x01 -#define SEPROXYHAL_TAG_SESSION_START_EVENT_RECOVERY 0x02 -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FLASHBACK 0x04 -#define SEPROXYHAL_TAG_SESSION_START_EVENT_BOOTMENU 0x08 - -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_USB 0x00000001UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_BLE 0x00000002UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_TOUCH 0x00000004UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_BUTTON_COUNT 0x000000F0UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_BUTTON_COUNT_POS 4 -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_SCREEN_MASK 0x00000F00UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_NO_SCREEN 0x00000000UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_SCREEN_BIG 0x00000100UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_SCREEN_SML 0x00000200UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_SCREEN_SSD1312 0x00000300UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_HW_VERSION_MASK 0x0000F000UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_HW_VERSION_POS 12 -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_BATTERY 0x00000008UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_ISET_MASK 0xF0000000UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_ISET_BASIC 0x00000000UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_ISET_MCUSEC 0x10000000UL -#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_ISET_MCUBL 0x20000000UL - -#define SEPROXYHAL_TAG_BLE_SECURITY_DB_EVENT 0x02 -#define SEPROXYHAL_TAG_BLE_SECURITY_DB_LOADED_EVENT \ - 0x00 // the security db chunk has ben loaded into MCU's RAM, the SE can proceed with the next - // one -#define SEPROXYHAL_TAG_BLE_SECURITY_DB_DUMP_EVENT \ - 0x01 // content of the security db at given offset -#define SEPROXYHAL_TAG_BLE_WRITE_REQUEST_EVENT 0x03 -#define SEPROXYHAL_TAG_BLE_READ_REQUEST_EVENT 0x04 -#define SEPROXYHAL_TAG_BUTTON_PUSH_EVENT 0x05 -#define SEPROXYHAL_TAG_BUTTON_PUSH_ID_MASK \ - 0xFE // up to 7 physical buttons (bit is 1 when pressed, and 0 when released) -#define SEPROXYHAL_TAG_BUTTON_PUSH_INTERVAL_MS 100 // an event generated every x ms -#define SEPROXYHAL_TAG_NFC_FIELD_DETECTION_EVENT 0x06 -#define SEPROXYHAL_TAG_NFC_APDU_RECEIVED_EVENT 0x07 -#define SEPROXYHAL_TAG_BATTERY_NOTIFICATION_EVENT 0x08 -#define SEPROXYHAL_TAG_M24SR_GPO_CHANGE_EVENT 0x09 -#define SEPROXYHAL_TAG_M24SR_RESPONSE_APDU_EVENT 0x0A -#define SEPROXYHAL_TAG_BLE_NOTIFY_INDICATE_EVENT 0x0B -#define SEPROXYHAL_TAG_FINGER_EVENT 0x0C -#define SEPROXYHAL_TAG_FINGER_EVENT_TOUCH 0x01 -#define SEPROXYHAL_TAG_FINGER_EVENT_RELEASE 0x02 -#define SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT 0x0D -#define SEPROXYHAL_TAG_TICKER_EVENT 0x0E // -#define SEPROXYHAL_TAG_USB_EVENT 0x0F // -#define SEPROXYHAL_TAG_USB_EVENT_RESET 0x01 -#define SEPROXYHAL_TAG_USB_EVENT_SOF 0x02 -#define SEPROXYHAL_TAG_USB_EVENT_SUSPENDED 0x04 -#define SEPROXYHAL_TAG_USB_EVENT_RESUMED 0x08 -#define SEPROXYHAL_TAG_USB_EP_XFER_EVENT \ - 0x10 // -#define SEPROXYHAL_TAG_USB_EP_XFER_SETUP 0x01 -#define SEPROXYHAL_TAG_USB_EP_XFER_IN 0x02 -#define SEPROXYHAL_TAG_USB_EP_XFER_OUT 0x04 -#define SEPROXYHAL_TAG_BLE_CONNECTION_EVENT 0x11 // -#define SEPROXYHAL_TAG_UNSEC_CHUNK_EVENT 0x12 -#define SEPROXYHAL_TAG_ACK_LINK_SPEED 0x13 // -#define SEPROXYHAL_TAG_BLUENRG_RECV_EVENT 0x14 // - -#define SEPROXYHAL_TAG_STATUS_EVENT \ - 0x15 // - // -#define SEPROXYHAL_TAG_STATUS_EVENT_FLAG_CHARGING 0x00000001 -#define SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_ON 0x00000002 -#define SEPROXYHAL_TAG_STATUS_EVENT_FLAG_BLE_ON 0x00000004 -#define SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED 0x00000008 -#define SEPROXYHAL_TAG_STATUS_EVENT_FLAG_CHARGING_ISSUE 0x00000010 -#define SEPROXYHAL_TAG_STATUS_EVENT_FLAG_TEMPERATURE_ISSUE 0x00000020 -#define SEPROXYHAL_TAG_STATUS_EVENT_FLAG_BATTERY_ISSUE 0x00000040 - -#define SEPROXYHAL_TAG_CAPDU_EVENT 0x16 // raw command apdu transport - -#define SEPROXYHAL_TAG_I2C_EVENT 0x17 // -#define SEPROXYHAL_TAG_I2C_EVENT_KIND_READ 0x01 -#define SEPROXYHAL_TAG_I2C_EVENT_KIND_WRITE 0x02 -#define SEPROXYHAL_TAG_BLE_RECV_EVENT 0x18 // -#define SEPROXYHAL_TAG_BOOTLOADER_RAPDU_EVENT 0x19 // -#define SEPROXYHAL_TAG_UX_EVENT 0x1A // -#ifdef HAVE_NFC -#define SEPROXYHAL_TAG_NFC_APDU_EVENT 0x1C -#define SEPROXYHAL_TAG_NFC_EVENT 0x1E -#define SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED 0x01 // card_detected + type a/b + nfcid[max 7] -#define SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED_A 0x01 -#define SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED_B 0x02 -#define SEPROXYHAL_TAG_NFC_EVENT_CARD_LOST 0x02 // card lost -#endif - -#define SEPH_PROTOCOL_EVT_POWER_BUTTON_EVENT 0x1B - -#ifdef HAVE_QI_FLASH -#define SEPROXYHAL_TAG_STATUS_EVENT_QI_FLASH_CHECKSUM 0x1D -#endif - -// COMMANDS -#ifdef HAVE_SEPROXYHAL_MCU -#define SEPROXYHAL_TAG_MCU 0x31 // -#define SEPROXYHAL_TAG_MCU_TYPE_BOOTLOADER 0x00 -#define SEPROXYHAL_TAG_MCU_TYPE_LOCK 0x01 -#ifdef HAVE_MCU_PROTECT -#define SEPROXYHAL_TAG_MCU_TYPE_PROTECT 0x02 // for instance ask RDP2 to be engaged -#endif // HAVE_MCU_PROTECT -#define SEPROXYHAL_TAG_MCU_TYPE_BD_ADDR 0x03 -#define SEPROXYHAL_TAG_MCU_BOOTLOADER SEPROXYHAL_TAG_MCU -#endif // HAVE_SEPROXYHAL_MCU -#define SEPROXYHAL_TAG_UNSEC_CHUNK_READ 0x32 // -// available if SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_ISET_MCUSEC -#define SEPROXYHAL_TAG_UNSEC_CHUNK_READ_EXT \ - 0x33 // -#define SEPROXYHAL_TAG_BLE_SEND 0x38 // -#define SEPROXYHAL_TAG_SET_SCREEN_CONFIG \ - 0x3E // -#define SEPROXYHAL_TAG_SET_LINK_PROP 0x3F // -#define SEPROXYHAL_TAG_BLUENRG_SEND 0x40 // -#define SEPROXYHAL_TAG_BLE_DEFINE_GENERIC_SETTING 0x41 -#define SEPROXYHAL_TAG_BLE_DEFINE_SERVICE_SETTING 0x42 -#define SEPROXYHAL_TAG_NFC_DEFINE_SERVICE_SETTING 0x43 -#define SEPROXYHAL_TAG_BLE_RADIO_POWER 0x44 // -#define SEPROXYHAL_TAG_BLE_RADIO_POWER_ACTION_ON 0x02 -#define SEPROXYHAL_TAG_BLE_RADIO_POWER_ACTION_DBWIPE 0x04 -#define SEPROXYHAL_TAG_BLE_RADIO_POWER_FACTORY_TEST 0x40 -#define SEPROXYHAL_TAG_NFC_RADIO_POWER 0x45 -#define SEPROXYHAL_TAG_SE_POWER_OFF 0x46 -#ifdef HAVE_NOR_FLASH -#define SEPROXYHAL_TAG_SPI_CS 0x47 -#endif -// #define SEPROXYHAL_TAG_SCREEN_POWER 0x47 -#define SEPROXYHAL_TAG_BLE_SECURITY_DB 0x48 // -// TODO use a pairing key between the SE and MCU to decrypt/encrypt the content of the pairing DB. -#define SEPROXYHAL_TAG_BLE_SECURITY_DB_CMD_READ \ - 0x01 // -noarg- request the content of the security db to be transmitted through - // SEPROXYHAL_TAG_BLE_SECURITY_DB_EVENT -#define SEPROXYHAL_TAG_BLE_SECURITY_DB_CMD_WRITE \ - 0x02 // request to write a chunk of the security db at the given offset -#define SEPROXYHAL_TAG_BATTERY_CHARGE 0x49 // <> -// #define SEPROXYHAL_TAG_SCREEN_DISPLAY 0x4A // wait for display_event after sent - -#ifdef HAVE_NFC -#define SEPROXYHAL_TAG_NFC_RAPDU 0x4A -#define SEPROXYHAL_TAG_NFC_POWER 0x34 -#define SEPROXYHAL_TAG_NFC_POWER_OFF 0x00 -#define SEPROXYHAL_TAG_NFC_POWER_ON_CE 0x01 -#define SEPROXYHAL_TAG_NFC_POWER_ON_READER 0x02 -#endif - -#define SEPROXYHAL_TAG_DEVICE_OFF 0x4B -#define SEPROXYHAL_TAG_MORE_TIME 0x4C -#define SEPROXYHAL_TAG_M24SR_C_APDU 0x4D -#define SEPROXYHAL_TAG_SET_TICKER_INTERVAL 0x4E -#define SEPROXYHAL_TAG_USB_CONFIG 0x4F // -#define SEPROXYHAL_TAG_USB_CONFIG_CONNECT 0x01 // <> -#define SEPROXYHAL_TAG_USB_CONFIG_DISCONNECT 0x02 // <> -#define SEPROXYHAL_TAG_USB_CONFIG_ADDR 0x03 // -#define SEPROXYHAL_TAG_USB_CONFIG_ENDPOINTS \ - 0x04 // [ - // ] -#define SEPROXYHAL_TAG_USB_CONFIG_TYPE_DISABLED 0x00 -#define SEPROXYHAL_TAG_USB_CONFIG_TYPE_CONTROL 0x01 -#define SEPROXYHAL_TAG_USB_CONFIG_TYPE_INTERRUPT 0x02 -#define SEPROXYHAL_TAG_USB_CONFIG_TYPE_BULK 0x03 -#define SEPROXYHAL_TAG_USB_CONFIG_TYPE_ISOCHRONOUS 0x04 -#define SEPROXYHAL_TAG_USB_EP_PREPARE \ - 0x50 // -#define SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_SETUP 0x10 -#define SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN 0x20 -#define SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_OUT 0x30 -#define SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_STALL 0x40 -#define SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_UNSTALL 0x80 -#define SEPROXYHAL_TAG_SET_LED 0x51 // -#define SEPROXYHAL_TAG_REQUEST_STATUS \ - 0x52 // no args, request power levels of all peripherals and current charging state or not if a - // battery is present. -#define SEPROXYHAL_TAG_RAPDU 0x53 // raw response apdu transport -#define SEPROXYHAL_TAG_I2C_XFER \ - 0x54 // -#define SEPROXYHAL_TAG_UX_CMD 0x5D -#define SEPROXYHAL_TAG_UX_CMD_BLE_DISABLE_ADV 0x00 -#define SEPROXYHAL_TAG_UX_CMD_BLE_ENABLE_ADV 0x01 -#define SEPROXYHAL_TAG_UX_CMD_BLE_RESET_PAIRINGS 0x02 -#define SEPROXYHAL_TAG_UX_CMD_REDISPLAY 0x03 -#define SEPROXYHAL_TAG_UX_CMD_BLE_NAME_CHANGED 0x04 -#define SEPROXYHAL_TAG_UX_CMD_ACCEPT_PAIRING 0x05 - -#ifdef HAVE_SERIALIZED_NBGL -#define SEPROXYHAL_TAG_NBGL_SERIALIZED 0x5C -#endif - -#define SEPROXYHAL_TAG_SET_TOUCH_STATE 0x5B - -#define SEPROXYHAL_TAG_PRINTF 0x5F // -#define SEPROXYHAL_TAG_DBG_SCREEN_DISPLAY_STATUS 0x5E // - -#ifdef HAVE_PIEZO_SOUND -#define SEPROXYHAL_TAG_PLAY_TUNE 0x56 -#endif // HAVE_PIEZO_SOUND - -#ifdef HAVE_QI_FLASH -#define SEPROXYHAL_TAG_QI_FLASH 0x58 -#endif - -#ifdef HAVE_SHIP_MODE -#define SEPH_PROTOCOL_CMD_SET_SHIP_MODE 0x57 -#endif // HAVE_SHIP_MODE - -// STATUS -#define SEPROXYHAL_TAG_STATUS_MASK 0x60 -#define SEPROXYHAL_TAG_GENERAL_STATUS 0x60 -#define SEPROXYHAL_TAG_GENERAL_STATUS_LAST_COMMAND 0x0000 -// #define SEPROXYHAL_TAG_GENERAL_STATUS_MORE_COMMAND 0x0001 // it's a status, but it shall be a -// command instead to avoid perturbating the simple seproxyhal bus logic #define -// SEPROXYHAL_TAG_GENERAL_STATUS_ERROR 0x0002 // shall be a command instead -#define SEPROXYHAL_TAG_PAIRING_STATUS 0x61 -#define SEPROXYHAL_TAG_BLE_READ_RESPONSE_STATUS 0x62 -#define SEPROXYHAL_TAG_NFC_READ_RESPONSE_STATUS 0x63 -#define SEPROXYHAL_TAG_BLE_NOTIFY_INDICATE_STATUS 0x64 -#define SEPROXYHAL_TAG_SCREEN_DISPLAY_STATUS 0x65 // -#define SEPROXYHAL_TAG_PRINTF_STATUS 0x66 -#define SEPROXYHAL_TAG_SET_LINK_SPEED 0x67 // -#define SEPROXYHAL_TAG_SCREEN_ANIMATION_STATUS \ - 0x68 // // replied with a display processed event when - // done -#define SEPROXYHAL_TAG_SCREEN_ANIMATION_STATUS_VERTICAL_SPLIT_SLIDE \ - 0x00 // param[0:1](BE) = split Y coordinate, param[2:3](BE) = animation duration in ms -#define SEPROXYHAL_TAG_BOOTLOADER_CAPDU_STATUS 0x6A // - -#endif +#pragma once + +/* Includes ------------------------------------------------------------------*/ + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +//////////// +// EVENTS // +//////////// + +// EVT : SESSION START +#define SEPROXYHAL_TAG_SESSION_START_EVENT (0x01) +enum seph_protocol_evt_session_start_type { + SEPROXYHAL_TAG_SESSION_START_EVENT_RECOVERY = 0x02, + SEPROXYHAL_TAG_SESSION_START_EVENT_FLASHBACK = 0x04, + SEPROXYHAL_TAG_SESSION_START_EVENT_BOOTMENU = 0x08, +}; + +#define SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_HW_VERSION_POS 12 +enum seph_protocol_evt_session_start_feature_mask { + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_USB = 0x00000001, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_BLE = 0x00000002, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_TOUCH = 0x00000004, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_BATTERY = 0x00000008, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_BUTTON = 0x00000010, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_NO_SCREEN = 0x00000000, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_SCREEN_BIG = 0x00000100, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_SCREEN_SSD1312 = 0x00000300, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_SCREEN_MASK = 0x00000F00, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_HW_VERSION_MASK = 0x0000F000, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_ISET_MCUSEC = 0x10000000, + SEPROXYHAL_TAG_SESSION_START_EVENT_FEATURE_ISET_MCUBL = 0x20000000, +}; + +// EVT : BUTTON +#define SEPROXYHAL_TAG_BUTTON_PUSH_EVENT (0x05) +enum seph_protocol_evt_button_mask { + SEPROXYHAL_TAG_BUTTON_PUSH_EVENT_LEFT = 0x01, + SEPROXYHAL_TAG_BUTTON_PUSH_EVENT_RIGHT = 0x02, +}; + +// EVT : TOUCH +#define SEPROXYHAL_TAG_FINGER_EVENT (0x0C) +enum seph_protocol_evt_finger_mask { + SEPROXYHAL_TAG_FINGER_EVENT_TOUCH = 0x01, + SEPROXYHAL_TAG_FINGER_EVENT_RELEASE = 0x02, +}; + +// EVT : DISPLAY PROCESSED +#define SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT (0x0D) + +// EVT : TICKER +#define SEPROXYHAL_TAG_TICKER_EVENT (0x0E) + +// EVT : USB +#define SEPROXYHAL_TAG_USB_EVENT (0x0F) +enum seph_protocol_evt_usb_type { + SEPROXYHAL_TAG_USB_EVENT_RESET = 0x01, + SEPROXYHAL_TAG_USB_EVENT_SOF = 0x02, + SEPROXYHAL_TAG_USB_EVENT_SUSPENDED = 0x04, + SEPROXYHAL_TAG_USB_EVENT_RESUMED = 0x08, +}; + +// EVT : USB ENDPOINT XFER +#define SEPROXYHAL_TAG_USB_EP_XFER_EVENT (0x10) +enum seph_protocol_evt_usb_mask { + SEPROXYHAL_TAG_USB_EP_XFER_SETUP = 0x01, + SEPROXYHAL_TAG_USB_EP_XFER_IN = 0x02, + SEPROXYHAL_TAG_USB_EP_XFER_OUT = 0x04, +}; + +// EVT : MCU CHUNK READ RSP +#define SEPROXYHAL_TAG_UNSEC_CHUNK_EVENT (0x12) + +// EVT : STATUS +#define SEPROXYHAL_TAG_STATUS_EVENT (0x15) +enum seph_protocol_evt_status_flag_mask { + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_CHARGING = 0x00000001, + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_ON = 0x00000002, + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_BLE_ON = 0x00000004, + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED = 0x00000008, + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_CHARGING_ISSUE = 0x00000010, + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_TEMPERATURE_ISSUE = 0x00000020, + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_BATTERY_ISSUE = 0x00000040, + SEPROXYHAL_TAG_STATUS_EVENT_FLAG_GAS_GAUGE_ISSUE = 0x00000080, +}; + +// EVT : CAPDU +#define SEPROXYHAL_TAG_CAPDU_EVENT (0x16) + +// EVT : BLE RX +#define SEPROXYHAL_TAG_BLE_RECV_EVENT (0x18) + +// EVT : BOOTLOADER RAPDU +#define SEPROXYHAL_TAG_BOOTLOADER_RAPDU_EVENT (0x19) + +// EVT : ITC +#define SEPROXYHAL_TAG_ITC_EVENT (0x1A) +// EVT : UX +#define SEPROXYHAL_TAG_UX_EVENT (0x1A) + +// EVT : POWER BUTTON +#define SEPROXYHAL_TAG_POWER_BUTTON_EVENT (0x1B) + +// EVT : NFC APDU EVENT +#define SEPROXYHAL_TAG_NFC_APDU_EVENT (0x1C) + +// EVT : NFC EVENT +#define SEPROXYHAL_TAG_NFC_EVENT (0x1E) +enum seph_protocol_evt_nfc_type { + SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED = 0x01, // card_detected + type a/b + nfcid[max 7] + SEPROXYHAL_TAG_NFC_EVENT_CARD_LOST = 0x02 // card lost +}; + +enum seph_protocol_evt_nfc_card_detected_type { + SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED_A = 0x01, + SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED_B = 0x02 +}; + +// EVT : QI FLASH CHECKSUM +#define SEPROXYHAL_TAG_QI_FLASH_CHECKSUM_EVENT (0x1D) + +////////////// +// COMMANDS // +////////////// + +// CMD : MCU +#define SEPROXYHAL_TAG_MCU (0x31) +enum seph_protocol_cmd_mcu_type { + SEPROXYHAL_TAG_MCU_TYPE_BOOTLOADER = 0x00, + SEPROXYHAL_TAG_MCU_TYPE_LOCK = 0x01, + SEPROXYHAL_TAG_MCU_TYPE_PROTECT = 0x02, + SEPROXYHAL_TAG_MCU_TYPE_BD_ADDR = 0x03, +}; + +// CMD : MCU CHUNK READ +#define SEPROXYHAL_TAG_UNSEC_CHUNK_READ_EXT (0x33) +enum seph_protocol_cmd_mcu_chunk_read_type { + SEPROXYHAL_TAG_UNSEC_CHUNK_READ_EXT_TYPE_IDLE = 0x00, + SEPROXYHAL_TAG_UNSEC_CHUNK_READ_EXT_TYPE_FROM_OFFSET = 0x02, + SEPROXYHAL_TAG_UNSEC_CHUNK_READ_EXT_TYPE_TOTAL_LENGTH = 0x04, +}; + +// CMD : NFC POWER +#define SEPROXYHAL_TAG_NFC_POWER (0x34) +enum seph_protocol_cmd_nfc_power_type { + SEPROXYHAL_TAG_NFC_POWER_OFF = 0x00, + SEPROXYHAL_TAG_NFC_POWER_ON_CE = 0x01, + SEPROXYHAL_TAG_NFC_POWER_ON_READER = 0x02 +}; + +// CMD : BLE SEND +#define SEPROXYHAL_TAG_BLE_SEND (0x38) + +// CMD : SET SCREEN CONFIG +#define SEPROXYHAL_TAG_SET_SCREEN_CONFIG (0x3E) + +// CMD : BLE RADIO POWER +#define SEPROXYHAL_TAG_BLE_RADIO_POWER (0x44) +enum seph_protocol_cmd_ble_radio_power_type { + SEPROXYHAL_TAG_BLE_RADIO_POWER_ACTION_ON = 0x02, + SEPROXYHAL_TAG_BLE_RADIO_POWER_ACTION_DBWIPE = 0x04, + SEPROXYHAL_TAG_BLE_RADIO_POWER_FACTORY_TEST = 0x40, +}; + +// CMD : SE POWER OFF +#define SEPROXYHAL_TAG_SE_POWER_OFF (0x46) + +// CMD : SPI CS CTRL +#define SEPROXYHAL_TAG_SPI_CS (0x47) + +// CMD : NFC_RAPDU +#define SEPROXYHAL_TAG_NFC_RAPDU (0x4A) + +// CMD : DEVICE SHUT DOWN +#define SEPROXYHAL_TAG_DEVICE_OFF (0x4B) + +// CMD : MORE TIME +#define SEPROXYHAL_TAG_MORE_TIME (0x4C) + +// CMD : SET TICKER INTERVAL +#define SEPROXYHAL_TAG_SET_TICKER_INTERVAL (0x4E) + +// CMD : USB CONFIG +#define SEPROXYHAL_TAG_USB_CONFIG (0x4F) +enum seph_protocol_cmd_usb_config_type { + SEPROXYHAL_TAG_USB_CONFIG_CONNECT = 0x01, + SEPROXYHAL_TAG_USB_CONFIG_DISCONNECT = 0x02, + SEPROXYHAL_TAG_USB_CONFIG_ADDR = 0x03, + SEPROXYHAL_TAG_USB_CONFIG_ENDPOINTS = 0x04, +}; +enum seph_protocol_cmd_usb_config_end_point_type { + SEPROXYHAL_TAG_USB_CONFIG_TYPE_DISABLED = 0x00, + SEPROXYHAL_TAG_USB_CONFIG_TYPE_CONTROL = 0x01, + SEPROXYHAL_TAG_USB_CONFIG_TYPE_INTERRUPT = 0x02, + SEPROXYHAL_TAG_USB_CONFIG_TYPE_BULK = 0x03, + SEPROXYHAL_TAG_USB_CONFIG_TYPE_ISOCHRONOUS = 0x04, +}; + +// CMD : USB PREPARE +#define SEPROXYHAL_TAG_USB_EP_PREPARE (0x50) +enum seph_protocol_cmd_usb_prepare_type { + SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_SETUP = 0x10, + SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN = 0x20, + SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_OUT = 0x30, + SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_STALL = 0x40, + SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_UNSTALL = 0x80, +}; + +// CMD : REQUEST STATUS +#define SEPROXYHAL_TAG_REQUEST_STATUS (0x52) + +// CMD : RAPDU +#define SEPROXYHAL_TAG_RAPDU (0x53) + +// CMD : PIEZO SOUND +#define SEPROXYHAL_TAG_PLAY_TUNE (0x56) + +// CMD : SET SHIP MODE +#define SEPROXYHAL_TAG_SET_SHIP_MODE (0x57) + +// CMD : QI FLASH +#define SEPROXYHAL_TAG_QI_FLASH (0x58) + +// CMD : SET TOUCH_STATE +#define SEPROXYHAL_TAG_SET_TOUCH_STATE (0x5B) + +// CMD: NBGL SERIALIZED +#define SEPROXYHAL_TAG_NBGL_SERIALIZED (0x5C) + +// CMD : ITC +#define SEPROXYHAL_TAG_ITC_CMD (0x5D) + +// CMD : PRINTF +#define SEPROXYHAL_TAG_PRINTF (0x5F) + +// DBG : SCREEN DISPLAY +#define SEPROXYHAL_TAG_DBG_SCREEN_DISPLAY_STATUS (0x5E) + +//////////// +// STATUS // +//////////// +#define SEPROXYHAL_TAG_STATUS_MASK 0x60 + +// STATUS : GENERAL +#define SEPROXYHAL_TAG_GENERAL_STATUS (0x60) +enum seph_protocol_cmd_general_status_type { + SEPROXYHAL_TAG_GENERAL_STATUS_LAST_COMMAND = 0x0000, +}; + +// STATUS : SCREEN DISPLAY +#define SEPROXYHAL_TAG_SCREEN_DISPLAY_STATUS (0x65) + +// STATUS : BOOTLOADER CAPDU +#define SEPROXYHAL_TAG_BOOTLOADER_CAPDU_STATUS (0x6A) + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ diff --git a/include/shared_trampoline.h b/include/shared_trampoline.h index 7f3446fe5..f645b6097 100644 --- a/include/shared_trampoline.h +++ b/include/shared_trampoline.h @@ -9,7 +9,7 @@ #elif defined(TARGET_NANOS2) #define SHARED_TRAMPOLINE_ADDR 0x00808001 #elif defined(TARGET_STAX) -#define SHARED_TRAMPOLINE_ADDR 0x00810001 +#define SHARED_TRAMPOLINE_ADDR 0x00808001 #elif defined(TARGET_FLEX) -#define SHARED_TRAMPOLINE_ADDR 0x00810001 +#define SHARED_TRAMPOLINE_ADDR 0x00808001 #endif diff --git a/include/syscalls.h b/include/syscalls.h index 2c0979f71..336185867 100644 --- a/include/syscalls.h +++ b/include/syscalls.h @@ -122,7 +122,7 @@ #define SYSCALL_os_perso_set_seed_ID 0x0400004e #define SYSCALL_os_perso_derive_and_set_seed_ID 0x0700004f #define SYSCALL_os_perso_set_words_ID 0x02000050 -#define SYSCALL_os_perso_finalize_ID 0x00000051 +#define SYSCALL_os_perso_finalize_ID 0x01000051 #define SYSCALL_os_perso_is_pin_set_ID 0x0000009e #define SYSCALL_os_perso_isonboarded_ID 0x0000009f #define SYSCALL_os_perso_setonboardingstatus_ID 0x03000094 @@ -176,9 +176,13 @@ #define SYSCALL_os_sched_is_running_ID 0x0100009b #define SYSCALL_os_sched_create_ID 0x0700011b #define SYSCALL_os_sched_kill_ID 0x01000078 -#define SYSCALL_io_seph_send_ID 0x02000083 -#define SYSCALL_io_seph_is_status_sent_ID 0x00000084 -#define SYSCALL_io_seph_recv_ID 0x03000085 +#define SYSCALL_os_io_seph_tx_ID 0x03000082 +#define SYSCALL_os_io_seph_se_rx_event_ID 0x05000083 +#define SYSCALL_os_io_init_ID 0x01000084 +#define SYSCALL_os_io_start_ID 0x01000085 +#define SYSCALL_os_io_stop_ID 0x01000086 +#define SYSCALL_os_io_tx_cmd_ID 0x04000088 +#define SYSCALL_os_io_rx_evt_ID 0x03000089 #define SYSCALL_nvm_write_page_ID 0x0100010a #define SYSCALL_nvm_erase_page_ID 0x01000136 #define SYSCALL_try_context_get_ID 0x00000087 @@ -224,7 +228,7 @@ #endif // HAVE_BRIGHTNESS_SYSCALL #define SYSCALL_bagl_hal_draw_bitmap_within_rect_ID 0x0900007c #define SYSCALL_bagl_hal_draw_rect_ID 0x0500007d -#endif +#endif // HAVE_SE_SCREEN #ifdef HAVE_BLE #define SYSCALL_os_ux_set_status_ID_IN 0x02000134 @@ -246,18 +250,6 @@ #define SYSCALL_get_language_pack_ID 0x01000154 #endif // defined(HAVE_LANGUAGE_PACK) -#ifdef HAVE_IO_I2C -#define SYSCALL_io_i2c_setmode_ID 0x02000095 -#define SYSCALL_io_i2c_prepare_ID 0x01000096 -#define SYSCALL_io_i2c_xfer_ID 0x03000097 -#ifndef BOLOS_RELEASE -#ifdef BOLOS_DEBUG -#define SYSCALL_io_i2c_dumpstate_ID 0x00000098 -#define SYSCALL_io_debug_ID 0x020000a9 -#endif // BOLOS_DEBUG -#endif // BOLOS_RELEASE -#endif // HAVE_IO_I2C - #ifdef DEBUG_OS_STACK_CONSUMPTION #define SYSCALL_os_stack_operations_ID 0x01000199 #endif // DEBUG_OS_STACK_CONSUMPTION diff --git a/io/include/os_io.h b/io/include/os_io.h new file mode 100644 index 000000000..09a0671dd --- /dev/null +++ b/io/include/os_io.h @@ -0,0 +1,136 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "os_math.h" +#include "decorators.h" +#ifdef HAVE_IO_U2F +#include "u2f_transport.h" +#endif // HAVE_IO_U2F + +#ifndef HAVE_BOLOS +#include "os_io_legacy.h" +#endif // HAVE_BOLOS + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + OS_IO_PACKET_TYPE_NONE = 0x00, + OS_IO_PACKET_TYPE_SEPH = 0x01, + OS_IO_PACKET_TYPE_SE_EVT = 0x02, + OS_IO_PACKET_TYPE_RAW_APDU = 0x10, + OS_IO_PACKET_TYPE_USB_HID_APDU = 0x20, + OS_IO_PACKET_TYPE_USB_WEBUSB_APDU = 0x21, + OS_IO_PACKET_TYPE_USB_CCID_APDU = 0x22, + OS_IO_PACKET_TYPE_USB_U2F_HID_APDU = 0x23, + OS_IO_PACKET_TYPE_USB_U2F_HID_CBOR = 0x24, + OS_IO_PACKET_TYPE_USB_U2F_HID_RAW = 0x25, + OS_IO_PACKET_TYPE_USB_CDC_RAW = 0x29, + OS_IO_PACKET_TYPE_BLE_APDU = 0x30, + OS_IO_PACKET_TYPE_BLE_U2F_APDU = 0x31, + OS_IO_PACKET_TYPE_NFC_APDU = 0x40, + OS_IO_PACKET_TYPE_NFC_APDU_RSP = 0x41, +} os_io_packet_type_t; + +typedef enum { + APDU_TYPE_NONE = OS_IO_PACKET_TYPE_NONE, + APDU_TYPE_RAW = OS_IO_PACKET_TYPE_RAW_APDU, + APDU_TYPE_USB_HID = OS_IO_PACKET_TYPE_USB_HID_APDU, + APDU_TYPE_USB_WEBUSB = OS_IO_PACKET_TYPE_USB_WEBUSB_APDU, + APDU_TYPE_USB_CCID = OS_IO_PACKET_TYPE_USB_CCID_APDU, + APDU_TYPE_USB_U2F = OS_IO_PACKET_TYPE_USB_U2F_HID_APDU, + APDU_TYPE_BLE = OS_IO_PACKET_TYPE_BLE_APDU, + APDU_TYPE_NFC = OS_IO_PACKET_TYPE_NFC_APDU, +} apdu_type_t; + +typedef enum { + // IO + ITC_IO_BLE_STOP = 0x00, + ITC_IO_BLE_START = 0x01, + ITC_IO_BLE_RESET_PAIRINGS = 0x02, + ITC_IO_BLE_BLE_NAME_CHANGED = 0x03, + ITC_IO_NFC_STOP = 0x10, + ITC_IO_NFC_START_CE = 0x11, + ITC_IO_NFC_START_READER = 0x12, + // UX + ITC_UX_REDISPLAY = 0x20, + ITC_UX_ACCEPT_BLE_PAIRING = 0x21, + ITC_UX_ASK_BLE_PAIRING = 0x22, + ITC_UX_BLE_PAIRING_STATUS = 0x23, + // MISC + ITC_BUTTON_STATE = 0x30, + ITC_FINGER_STATE = 0x31, +} itc_type_t; + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + uint8_t protocol_version; + uint8_t major_device_version_number; + uint8_t minor_device_version_number; + uint8_t build_device_version_number; + uint8_t capabilities_flag; // u2f_hid_capability_t Mask +} usdb_ledger_hid_u2f_settings_t; + +typedef struct { + uint16_t pid; + uint16_t vid; + char name[20]; + uint16_t class_mask; // usbd_ledger_product_e +#ifdef HAVE_IO_U2F + usdb_ledger_hid_u2f_settings_t hid_u2f_settings; +#endif // HAVE_IO_U2F +} os_io_init_usb_t; + +typedef struct { + uint16_t profile_mask; // ble_ledger_profile_mask_e +} os_io_init_ble_t; + +typedef struct { + uint8_t syscall; + os_io_init_usb_t usb; + os_io_init_ble_t ble; +} os_io_init_t; + +/* Exported defines --------------------------------------------------------*/ +#define OS_IO_FLAG_CACHE 1 +#define OS_IO_FLAG_NO_ITC 2 + +#ifdef CUSTOM_IO_APDU_BUFFER_SIZE +#define OS_IO_BUFFER_SIZE CUSTOM_IO_APDU_BUFFER_SIZE +#else // !CUSTOM_IO_APDU_BUFFER_SIZE +#define OS_IO_BUFFER_SIZE OS_IO_SEPH_BUFFER_SIZE +#endif // !CUSTOM_IO_APDU_BUFFER_SIZE + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +extern unsigned char G_io_rx_buffer[OS_IO_BUFFER_SIZE + 1]; +extern unsigned char G_io_tx_buffer[OS_IO_BUFFER_SIZE + 1]; + +extern uint8_t G_io_syscall_flag; + +/* Exported functions prototypes--------------------------------------------- */ +SYSCALL int os_io_init(os_io_init_t *init); +SYSCALL int os_io_start(void); +SYSCALL int os_io_stop(void); +SYSCALL int os_io_rx_evt(unsigned char *buffer, + unsigned short buffer_max_length, + unsigned int *timeout_ms); +SYSCALL int os_io_tx_cmd(unsigned char type, // os_io_packet_type_t + const unsigned char *buffer PLENGTH(length), + unsigned short length, + unsigned int *timeout_ms); + +SYSCALL int os_io_seph_tx(const unsigned char *buffer PLENGTH(length), + unsigned short length, + unsigned int *timeout_ms); +SYSCALL int os_io_seph_se_rx_event(unsigned char *buffer PLENGTH(length), + unsigned short max_length, + unsigned int *timeout_ms, + bool check_se_event, + unsigned int flags); + +unsigned int os_io_handle_ux_event_reject_apdu(void); diff --git a/io/include/os_io_default_apdu.h b/io/include/os_io_default_apdu.h new file mode 100644 index 000000000..89c3623ec --- /dev/null +++ b/io/include/os_io_default_apdu.h @@ -0,0 +1,33 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include "os_types.h" +#include "os_io.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + OS_IO_APDU_POST_ACTION_NONE, + OS_IO_APDU_POST_ACTION_EXIT, +} os_io_apdu_post_action_t; + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ +#define DEFAULT_APDU_CLA (0xB0) +#define DEFAULT_APDU_INS_GET_VERSION (0x01) +#define DEFAULT_APDU_INS_GET_SEED_COOKIE (0x02) +#define DEFAULT_APDU_INS_STACK_CONSUMPTION (0x57) +#define DEFAULT_APDU_INS_APP_EXIT (0xA7) + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ +bolos_err_t os_io_handle_default_apdu(uint8_t *buffer_in, + size_t buffer_in_length, + uint8_t *buffer_out, + size_t *buffer_out_length, + os_io_apdu_post_action_t *post_action); diff --git a/io/include/os_io_seph_cmd.h b/io/include/os_io_seph_cmd.h new file mode 100644 index 000000000..52f8bace9 --- /dev/null +++ b/io/include/os_io_seph_cmd.h @@ -0,0 +1,91 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include "stdint.h" +#include "seproxyhal_protocol.h" +#include "ux.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + TUNE_RESERVED, + TUNE_BOOT, + TUNE_CHARGING, + TUNE_LEDGER_MOMENT, + TUNE_ERROR, + TUNE_NEUTRAL, + TUNE_LOCK, + TUNE_SUCCESS, + TUNE_LOOK_AT_ME, + TUNE_TAP_CASUAL, + TUNE_TAP_NEXT, + NB_TUNES // Keep at last position +} tune_index_e; + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ + +int os_io_seph_cmd_general_status(void); +int os_io_seph_cmd_more_time(void); +int os_io_seph_cmd_setup_ticker(unsigned int interval_ms); +int os_io_seph_cmd_device_shutdown(uint8_t critical_battery); +int os_io_seph_cmd_se_reset(void); +int os_io_seph_cmd_usb_disconnect(void); +int os_io_seph_cmd_mcu_status(void); +int os_io_seph_cmd_mcu_go_to_bootloader(void); +int os_io_seph_cmd_mcu_lock(void); +int os_io_seph_cmd_mcu_protect(void); +void os_io_seph_cmd_raw_apdu(const uint8_t *buffer, uint16_t length); + +#ifdef HAVE_SHIP_MODE +int os_io_seph_cmd_set_ship_mode(void); +#endif // HAVE_SHIP_MODE + +#ifdef HAVE_PRINTF +void os_io_seph_cmd_printf(const char *str, uint16_t charcount); +#endif // HAVE_PRINTF + +#ifdef HAVE_SE_TOUCH +int os_io_seph_cmd_set_touch_state(uint8_t enable); +#endif // HAVE_SE_TOUCH + +#ifdef HAVE_PIEZO_SOUND +int os_io_seph_cmd_piezo_play_tune(tune_index_e tune_index); +#endif // HAVE_PIEZO_SOUND + +#ifdef HAVE_SERIALIZED_NBGL +void os_io_seph_cmd_serialized_nbgl(const uint8_t *buffer, uint16_t length); +#endif // HAVE_SERIALIZED_NBGL + +#ifdef HAVE_NOR_FLASH +void os_io_seph_cmd_spi_cs(uint8_t select); +#endif // HAVE_NOR_FLASH + +#ifdef HAVE_BLE +int os_io_seph_cmd_ble_start_factory_test(void); +int os_io_ble_cmd_enable(uint8_t enable); +int os_io_ble_cmd_clear_bond_db(void); +int os_io_ble_cmd_name_changed(void); +int os_io_ux_cmd_ble_accept_pairing(uint8_t status); +int os_io_ux_cmd_redisplay(void); +void os_io_ux_cmd_ble_pairing_request(bolos_ux_params_t *ux_params); +void os_io_ux_cmd_ble_pairing_status(bolos_ux_params_t *ux_params); +#endif // HAVE_BLE + +#ifdef HAVE_NFC +int os_io_nfc_cmd_power(uint8_t power_type); +int os_io_nfc_cmd_stop(void); +int os_io_nfc_cmd_start_ce(void); +int os_io_nfc_cmd_start_reader(void); +#endif // HAVE_NFC + +void os_io_ux_cmd_button_state(uint8_t state); +void os_io_ux_cmd_touch_state(uint8_t state, uint16_t x, uint16_t y, uint8_t w, uint8_t h); diff --git a/io/include/os_io_seph_ux.h b/io/include/os_io_seph_ux.h new file mode 100644 index 000000000..e58e280ca --- /dev/null +++ b/io/include/os_io_seph_ux.h @@ -0,0 +1,70 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include "decorators.h" + +#ifdef HAVE_BAGL +#include "ux_bagl.h" +#endif // HAVE_BAGL + +#ifdef HAVE_SERIALIZED_NBGL +#include "nbgl_serialize.h" +#endif // HAVE_SERIALIZED_NBGL + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + OS_IO_TOUCH_AREA_NONE = 0, + OS_IO_TOUCH_AREA_LEFT_BORDER = 1, + OS_IO_TOUCH_AREA_RIGHT_BORDER = 2, + OS_IO_TOUCH_AREA_TOP_BORDER = 4, + OS_IO_TOUCH_AREA_BOTTOM_BORDER = 8, +} os_io_touch_area; + +typedef enum { + OS_IO_TOUCH_DEBUG_END = 0, + OS_IO_TOUCH_DEBUG_READ_RAW_DATA = 1, + OS_IO_TOUCH_DEBUG_READ_DIFF_DATA = 2, + OS_IO_TOUCH_DEBUG_READ_SENSOR_BUFFER = 3, +} os_io_touch_debug_mode_t; + +/* Exported types, structures, unions ----------------------------------------*/ + +typedef struct io_touch_info_s { + uint16_t x; + uint16_t y; + uint8_t state; + uint8_t w; + uint8_t h; + uint8_t swipe; +} io_touch_info_t; + +/* Exported defines --------------------------------------------------------*/ +#define SERIALIZED_NBGL_MAX_LEN (100) + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ +void io_seph_ux_init_button(void); +int io_process_itc_ux_event(uint8_t *buffer_in, size_t buffer_in_length); +void io_process_ux_event(uint8_t *buffer_in, size_t buffer_in_length); + +#ifdef HAVE_BAGL +void io_seph_ux_display_bagl_element(const bagl_element_t *element); +#endif // HAVE_BAGL + +#ifdef HAVE_SERIALIZED_NBGL +void io_seph_ux_send_nbgl_serialized(nbgl_serialized_event_type_e event, nbgl_obj_t *obj); +#endif // HAVE_SERIALIZED_NBGL + +#ifdef HAVE_SE_TOUCH +SYSCALL void touch_get_last_info(io_touch_info_t *info); +SYSCALL void touch_set_state(bool enable); +SYSCALL uint8_t touch_exclude_borders(uint8_t excluded_borders); +#ifdef HAVE_TOUCH_READ_SENSI_SYSCALL +SYSCALL void touch_read_sensitivity(uint8_t *sensi_data); +#endif // HAVE_TOUCH_READ_SENSI_SYSCALL +#endif // HAVE_SE_TOUCH diff --git a/io/src/os_io.c b/io/src/os_io.c new file mode 100644 index 000000000..5b919a0da --- /dev/null +++ b/io/src/os_io.c @@ -0,0 +1,409 @@ + +/* Includes ------------------------------------------------------------------*/ +#include +#include "os_io.h" +#include "os_io_seph_cmd.h" +#include "os_io_seph_ux.h" +#include "seproxyhal_protocol.h" +#include "checks.h" + +#ifdef HAVE_IO_USB +#include "usbd_ledger.h" +#include "usbd_ledger_hid_u2f.h" +#endif // HAVE_IO_USB + +#ifdef HAVE_BLE +#include "ble_ledger.h" +#endif // HAVE_BLE + +#ifdef HAVE_NFC +#include "nfc_ledger.h" +#endif // HAVE_NFC + +#ifdef HAVE_PRINTF +#define DEBUG PRINTF +// #define DEBUG(...) +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +#ifndef USE_OS_IO_STACK +static int process_itc_event(uint8_t *buffer_in, size_t buffer_in_length); +#endif // !USE_OS_IO_STACK + +/* Exported variables --------------------------------------------------------*/ +#ifndef HAVE_LOCAL_APDU_BUFFER +// apdu buffer must hold a complete apdu to avoid troubles +unsigned char G_io_rx_buffer[OS_IO_BUFFER_SIZE + 1]; +unsigned char G_io_tx_buffer[OS_IO_BUFFER_SIZE + 1]; +#endif + +#ifndef USE_OS_IO_STACK +unsigned char G_io_seph_buffer[OS_IO_SEPH_BUFFER_SIZE + 1]; +size_t G_io_seph_buffer_size; +#endif // !USE_OS_IO_STACK + +uint8_t G_io_syscall_flag; + +/* Private variables ---------------------------------------------------------*/ + +/* Private functions ---------------------------------------------------------*/ +#ifndef USE_OS_IO_STACK +static int process_itc_event(uint8_t *buffer_in, size_t buffer_in_length) +{ + int status = buffer_in_length; + + switch (buffer_in[3]) { +#ifdef HAVE_BLE + case ITC_IO_BLE_STOP: + BLE_LEDGER_stop(); + status = 0; + break; + + case ITC_IO_BLE_START: + BLE_LEDGER_start(); + status = 0; + break; + + case ITC_IO_BLE_RESET_PAIRINGS: + BLE_LEDGER_reset_pairings(); + status = 0; + break; + + case ITC_IO_BLE_BLE_NAME_CHANGED: + // Restart advertising + BLE_LEDGER_name_changed(); + status = 0; + break; + + case ITC_UX_ACCEPT_BLE_PAIRING: + BLE_LEDGER_accept_pairing(buffer_in[4]); + status = 0; + break; +#endif // HAVE_BLE + +#ifdef HAVE_NFC + case ITC_IO_NFC_STOP: + NFC_LEDGER_stop(); + break; + + case ITC_IO_NFC_START_CE: + NFC_LEDGER_start(NFC_LEDGER_MODE_CARD_EMULATION); + break; + + case ITC_IO_NFC_START_READER: + NFC_LEDGER_start(NFC_LEDGER_MODE_READER); + break; +#endif // HAVE_NFC + +#ifdef HAVE_SE_BUTTON + case ITC_BUTTON_STATE: { + uint8_t tx_buff[4]; + tx_buff[0] = SEPROXYHAL_TAG_BUTTON_PUSH_EVENT; + tx_buff[1] = 0; + tx_buff[2] = 1; + tx_buff[3] = buffer_in[4]; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, tx_buff, 4, NULL); + status = 0; + break; + } +#endif // HAVE_SE_BUTTON + case ITC_FINGER_STATE: { + uint8_t tx_buff[10]; + tx_buff[0] = SEPROXYHAL_TAG_FINGER_EVENT; + tx_buff[1] = 0; + tx_buff[2] = 7; + memcpy(&tx_buff[3], &buffer_in[4], 7); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, tx_buff, 10, NULL); + status = 0; + break; + } + +#ifdef HAVE_SE_TOUCH +#endif // HAVE_SE_TOUCH + + default: + break; + } + + if (!G_io_syscall_flag) { + if (status) { + status = io_process_itc_ux_event(buffer_in, buffer_in_length); + } + } + + return status; +} +#endif // !USE_OS_IO_STACK + +/* Exported functions --------------------------------------------------------*/ + +#ifndef USE_OS_IO_STACK +int os_io_init(os_io_init_t *init) +{ + if (!init) { + return -1; + } + + uint8_t force_restart = 0; + if (G_io_syscall_flag == init->syscall) { + force_restart = 1; + } + G_io_syscall_flag = init->syscall; + +#ifdef HAVE_BAGL + io_seph_ux_init_button(); +#endif + +#if (!defined(HAVE_BOLOS) && defined(HAVE_MCU_PROTECT)) + os_io_seph_cmd_mcu_protect(); +#endif // (!HAVE_BOLOS && HAVE_MCU_PROTECT) + +#if !defined(HAVE_BOLOS) && defined(HAVE_PENDING_REVIEW_SCREEN) + check_audited_app(); +#endif // !HAVE_BOLOS && HAVE_PENDING_REVIEW_SCREEN + +#ifdef HAVE_IO_USB + USBD_LEDGER_init(&init->usb, force_restart); +#endif // HAVE_IO_USB + +#ifdef HAVE_BLE + BLE_LEDGER_init(&init->ble, force_restart); +#endif // HAVE_BLE + +#ifdef HAVE_NFC + NFC_LEDGER_init(force_restart); +#endif // HAVE_NFC + +#ifndef USE_OS_IO_STACK + G_io_seph_buffer_size = 0; +#endif // USE_OS_IO_STACK + + return 0; +} + +int os_io_start(void) +{ +#ifdef HAVE_IO_USB + USBD_LEDGER_start(); +#endif // HAVE_IO_USB + +#ifdef HAVE_BLE + BLE_LEDGER_start(); +#endif // HAVE_BLE + +#ifdef HAVE_NFC + NFC_LEDGER_start(NFC_LEDGER_MODE_CARD_EMULATION); +#endif // HAVE_NFC + + return 0; +} + +int os_io_stop(void) +{ +#ifdef HAVE_IO_USB + USB_LEDGER_stop(); +#endif // HAVE_IO_USB + +#ifdef HAVE_BLE + BLE_LEDGER_stop(); +#endif // HAVE_BLE + +#ifdef HAVE_NFC + NFC_LEDGER_stop(); +#endif // HAVE_NFC + + return 0; +} + +int os_io_rx_evt(unsigned char *buffer, unsigned short buffer_max_length, unsigned int *timeout_ms) +{ + int status = 0; + uint16_t length = 0; + + if (!G_io_seph_buffer_size) { + status = os_io_seph_se_rx_event( + G_io_seph_buffer, sizeof(G_io_seph_buffer), (unsigned int *) timeout_ms, true, 0); + } + else { + // Cached rx event + status = G_io_seph_buffer_size; + G_io_seph_buffer_size = 0; + } + if (status == -1) { + // Wrong state, send cmd to MCU + status = os_io_seph_cmd_general_status(); + if (status < 0) { + return status; + } + status = os_io_seph_se_rx_event( + G_io_seph_buffer, sizeof(G_io_seph_buffer), (unsigned int *) timeout_ms, true, 0); + } + if (status < 0) { + return status; + } + if (status > 0) { + length = (uint16_t) status; + } + + switch (G_io_seph_buffer[1]) { +#ifdef HAVE_IO_USB + case SEPROXYHAL_TAG_USB_EVENT: + case SEPROXYHAL_TAG_USB_EP_XFER_EVENT: + status = USBD_LEDGER_rx_seph_evt(G_io_seph_buffer, length, buffer, buffer_max_length); + break; +#endif // HAVE_IO_USB + +#ifdef HAVE_BLE + case SEPROXYHAL_TAG_BLE_RECV_EVENT: + status = BLE_LEDGER_rx_seph_evt(G_io_seph_buffer, length, buffer, buffer_max_length); + break; +#endif // HAVE_BLE + +#ifdef HAVE_NFC + case SEPROXYHAL_TAG_NFC_APDU_EVENT: + status + = NFC_LEDGER_rx_seph_apdu_evt(G_io_seph_buffer, length, buffer, buffer_max_length); + break; +#ifdef HAVE_NFC_READER + +#endif // HAVE_NFC_READER +#endif // HAVE_NFC + + case SEPROXYHAL_TAG_CAPDU_EVENT: + if (length >= buffer_max_length - 1) { + length = buffer_max_length - 1; + } + buffer[0] = OS_IO_PACKET_TYPE_RAW_APDU; + memmove(&buffer[1], &G_io_seph_buffer[4], length); + status = length - 3; + break; + + case SEPROXYHAL_TAG_ITC_EVENT: + if (length >= buffer_max_length - 1) { + length = buffer_max_length - 1; + } + memmove(buffer, G_io_seph_buffer, length); + status = process_itc_event(&G_io_seph_buffer[1], status - 1); + if (status > 0) { + status = length; + } + break; + + default: + if (length >= buffer_max_length - 1) { + length = buffer_max_length - 1; + } + memmove(buffer, G_io_seph_buffer, length); + break; + } + + return status; +} + +int os_io_tx_cmd(uint8_t type, + const unsigned char *buffer PLENGTH(length), + unsigned short length, + unsigned int *timeout_ms) +{ + int status = 0; + switch (type) { +#ifdef HAVE_IO_USB + case OS_IO_PACKET_TYPE_USB_HID_APDU: + // TODO_IO test error code + USBD_LEDGER_send(USBD_LEDGER_CLASS_HID, type, buffer, length, 0); + break; +#ifdef HAVE_WEBUSB + case OS_IO_PACKET_TYPE_USB_WEBUSB_APDU: + USBD_LEDGER_send(USBD_LEDGER_CLASS_WEBUSB, type, buffer, length, 0); + break; +#endif // HAVE_WEBUSB +#ifdef HAVE_IO_U2F + case OS_IO_PACKET_TYPE_USB_U2F_HID_APDU: + case OS_IO_PACKET_TYPE_USB_U2F_HID_CBOR: + USBD_LEDGER_send(USBD_LEDGER_CLASS_HID_U2F, type, buffer, length, 0); + break; +#endif // HAVE_IO_U2F +#endif // HAVE_IO_USB + +#ifdef HAVE_BLE + case OS_IO_PACKET_TYPE_BLE_APDU: + BLE_LEDGER_send(buffer, length, 0); + break; +#endif // HAVE_BLE + +#ifdef HAVE_NFC + case OS_IO_PACKET_TYPE_NFC_APDU: + NFC_LEDGER_send(buffer, length, 0); + break; +#endif // HAVE_NFC + + case OS_IO_PACKET_TYPE_RAW_APDU: + os_io_seph_cmd_raw_apdu((const uint8_t *) buffer, length); + break; + + case OS_IO_PACKET_TYPE_SEPH: + status = os_io_seph_tx(buffer, length, (unsigned int *) timeout_ms); + if (status == -1) { + // Wrong state, wait for an event from the MCU + status = os_io_seph_se_rx_event(G_io_seph_buffer, + sizeof(G_io_seph_buffer), + (unsigned int *) timeout_ms, + false, + OS_IO_FLAG_NO_ITC); + if (status >= 0) { + G_io_seph_buffer_size = status; + status = os_io_seph_tx(buffer, length, NULL); + } + } + break; + + default: + break; + } + + return status; +} +#endif // !USE_OS_IO_STACK + +unsigned int os_io_handle_ux_event_reject_apdu(void) +{ + uint16_t err = 0x6601; + unsigned char err_buffer[2]; + int status = os_io_rx_evt(G_io_tx_buffer, sizeof(G_io_tx_buffer), NULL); + + err_buffer[0] = err >> 8; + err_buffer[1] = err; + + if (status > 0) { + switch (G_io_tx_buffer[0]) { + case OS_IO_PACKET_TYPE_SE_EVT: + case OS_IO_PACKET_TYPE_SEPH: + io_process_ux_event(&G_io_tx_buffer[1], status - 1); + break; + + case OS_IO_PACKET_TYPE_RAW_APDU: + case OS_IO_PACKET_TYPE_USB_HID_APDU: + case OS_IO_PACKET_TYPE_USB_WEBUSB_APDU: + case OS_IO_PACKET_TYPE_USB_U2F_HID_APDU: + case OS_IO_PACKET_TYPE_BLE_APDU: + case OS_IO_PACKET_TYPE_NFC_APDU: + os_io_tx_cmd(G_io_tx_buffer[0], err_buffer, sizeof(err_buffer), 0); + break; + + default: + break; + } + } + + return status; +} diff --git a/io/src/os_io_default_apdu.c b/io/src/os_io_default_apdu.c new file mode 100644 index 000000000..e4850d2ae --- /dev/null +++ b/io/src/os_io_default_apdu.c @@ -0,0 +1,204 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include "exceptions.h" +#include "lcx_hash.h" +#include "lcx_sha512.h" +// #include "os_errors.h" +#include "os_utils.h" +#include "os_apdu.h" +#include "os_debug.h" +#include "os_pin.h" +#include "os_seed.h" +#include "os_app.h" +#include "os_registry.h" +#include "os_io_default_apdu.h" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +static void get_version(uint8_t *buffer_out, size_t *buffer_out_length); + +#if defined(HAVE_SEED_COOKIE) +static void get_seed_cookie(uint8_t *buffer_out, size_t *buffer_out_length); +#endif // HAVE_SEED_COOKIE +#if defined(DEBUG_OS_STACK_CONSUMPTION) +static void get_stack_consumption(uint8_t mode, uint8_t *buffer_out, size_t *buffer_out_length); +#endif // DEBUG_OS_STACK_CONSUMPTION + +/* Exported variables --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ + +/* Private functions ---------------------------------------------------------*/ +static void get_version(uint8_t *buffer_out, size_t *buffer_out_length) +{ + size_t max_buffer_out_length = *buffer_out_length; + int str_length = 0; + + *buffer_out_length = 0; + buffer_out[(*buffer_out_length)++] = 1; // format ID + +#if defined(HAVE_BOLOS) + if (max_buffer_out_length >= (strlen("BOLOS") + strlen(VERSION) + 3 + 2)) { + buffer_out[(*buffer_out_length)++] = 1; // format ID + str_length = strlen("BOLOS"); + buffer_out[(*buffer_out_length)++] = str_length; + strcpy((char *) (&buffer_out[*buffer_out_length]), "BOLOS"); + *buffer_out_length += str_length; + str_length = strlen(VERSION); + buffer_out[(*buffer_out_length)++] = str_length; + strcpy((char *) (&buffer_out[*buffer_out_length]), VERSION); + *buffer_out_length += str_length; + U2BE_ENCODE(buffer_out, *buffer_out_length, SWO_SUCCESS); + *buffer_out_length += 2; + } +#else // !HAVE_BOLOS + if (max_buffer_out_length >= 3) { + buffer_out[(*buffer_out_length)++] = 1; // format ID + str_length + = os_registry_get_current_app_tag(BOLOS_TAG_APPNAME, + &buffer_out[(*buffer_out_length) + 1], + max_buffer_out_length - *buffer_out_length - 3); + buffer_out[(*buffer_out_length)++] = str_length; + *buffer_out_length += str_length; + str_length + = os_registry_get_current_app_tag(BOLOS_TAG_APPVERSION, + &buffer_out[(*buffer_out_length) + 1], + max_buffer_out_length - *buffer_out_length - 3); + buffer_out[(*buffer_out_length)++] = str_length; + *buffer_out_length += str_length; + U2BE_ENCODE(buffer_out, *buffer_out_length, SWO_SUCCESS); + *buffer_out_length += 2; + } +#endif // !HAVE_BOLOS +} + +#if defined(HAVE_SEED_COOKIE) +static void get_seed_cookie(uint8_t *buffer_out, size_t *buffer_out_length) +{ + size_t max_buffer_out_length = *buffer_out_length; + + *buffer_out_length = 0; + if (os_global_pin_is_validated() == BOLOS_UX_OK) { + if (max_buffer_out_length >= CX_SHA512_SIZE + 4) { + buffer_out[(*buffer_out_length)++] = 0x01; + bolos_bool_t seed_generated = os_perso_seed_cookie(&buffer_out[2]); + if (seed_generated == BOLOS_TRUE) { + buffer_out[(*buffer_out_length)++] = CX_SHA512_SIZE; + *buffer_out_length += CX_SHA512_SIZE; + } + else { + buffer_out[(*buffer_out_length)++] = 0; + } + U2BE_ENCODE(buffer_out, *buffer_out_length, SWO_SUCCESS); + *buffer_out_length += 2; + } + } + else { + U2BE_ENCODE(buffer_out, *buffer_out_length, 0x6985); + *buffer_out_length += 2; + } +} +#endif // HAVE_SEED_COOKIE + +#if defined(DEBUG_OS_STACK_CONSUMPTION) +static void get_stack_consumption(uint8_t mode, uint8_t *buffer_out, size_t *buffer_out_length) +{ + int status = os_stack_operations(mode); + + *buffer_out_length = 0; + if (status != -1) { + U4BE_ENCODE(buffer_out, 0x00, status); + *buffer_out_length += 4; + U2BE_ENCODE(buffer_out, *buffer_out_length, SWO_SUCCESS); + *buffer_out_length += 2; + } +} +#endif // DEBUG_OS_STACK_CONSUMPTION + +/* Exported functions --------------------------------------------------------*/ +bolos_err_t os_io_handle_default_apdu(uint8_t *buffer_in, + size_t buffer_in_length, + uint8_t *buffer_out, + size_t *buffer_out_length, + os_io_apdu_post_action_t *post_action) +{ + bolos_err_t err = SWO_SUCCESS; + + if (!buffer_in || !buffer_in_length || !buffer_out || !buffer_out_length) { + return *post_action; + } + if (post_action) { + *post_action = OS_IO_APDU_POST_ACTION_NONE; + } + + if (DEFAULT_APDU_CLA == buffer_in[APDU_OFF_CLA]) { + switch (buffer_in[APDU_OFF_INS]) { + case DEFAULT_APDU_INS_GET_VERSION: + if (!buffer_in[APDU_OFF_P1] && !buffer_in[APDU_OFF_P2]) { + get_version(buffer_out, buffer_out_length); + } + else { + err = 0x6e00; + goto end; + } + break; + +#if defined(HAVE_SEED_COOKIE) + case DEFAULT_APDU_INS_GET_SEED_COOKIE: + if (!buffer_in[APDU_OFF_P1] && !buffer_in[APDU_OFF_P2]) { + get_seed_cookie(buffer_out, buffer_out_length); + } + else { + err = 0x6e00; + goto end; + } + break; +#endif // HAVE_SEED_COOKIE + +#if defined(DEBUG_OS_STACK_CONSUMPTION) + case DEFAULT_APDU_INS_STACK_CONSUMPTION: + if (!buffer_in[APDU_OFF_P2] && !buffer_in[APDU_OFF_LC]) { + get_stack_consumption(buffer_in[APDU_OFF_P1], buffer_out, buffer_out_length); + } + else { + err = 0x6e00; + goto end; + } + break; +#endif // DEBUG_OS_STACK_CONSUMPTION + + case DEFAULT_APDU_INS_APP_EXIT: + if (!buffer_in[APDU_OFF_P1] && !buffer_in[APDU_OFF_P2]) { + U2BE_ENCODE(buffer_out, 0, SWO_SUCCESS); + *buffer_out_length = 2; +#if !defined(HAVE_BOLOS) + if (post_action) { + *post_action = OS_IO_APDU_POST_ACTION_EXIT; + } +#endif // !HAVE_BOLOS + } + else { + err = 0x6e00; + goto end; + } + break; + + default: + err = 0x6e01; + goto end; + break; + } + } + +end: + return err; +} diff --git a/io/src/os_io_seph_cmd.c b/io/src/os_io_seph_cmd.c new file mode 100644 index 000000000..958bbae45 --- /dev/null +++ b/io/src/os_io_seph_cmd.c @@ -0,0 +1,428 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "os.h" +#include "os_io.h" +#include "os_io_seph_cmd.h" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ +#ifdef HAVE_PRINTF +#define DEBUG PRINTF +// #define DEBUG(...) +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static const unsigned char seph_io_general_status[] = { + SEPROXYHAL_TAG_GENERAL_STATUS, + 0, + 2, + SEPROXYHAL_TAG_GENERAL_STATUS_LAST_COMMAND >> 8, + SEPROXYHAL_TAG_GENERAL_STATUS_LAST_COMMAND, +}; + +static const unsigned char seph_io_request_status[] = { + SEPROXYHAL_TAG_REQUEST_STATUS, + 0, + 0, +}; + +static const unsigned char seph_io_se_power_off[] = { + SEPROXYHAL_TAG_SE_POWER_OFF, + 0, + 0, +}; + +static const unsigned char seph_io_usb_disconnect[] = { + SEPROXYHAL_TAG_USB_CONFIG, + 0, + 1, + SEPROXYHAL_TAG_USB_CONFIG_DISCONNECT, +}; + +static const unsigned char seph_io_cmd_mcu_bootloader[] = { + SEPROXYHAL_TAG_MCU, + 0, + 1, + SEPROXYHAL_TAG_MCU_TYPE_BOOTLOADER, +}; + +static const unsigned char seph_io_cmd_mcu_lock[] = { + SEPROXYHAL_TAG_MCU, + 0, + 1, + SEPROXYHAL_TAG_MCU_TYPE_LOCK, +}; + +static const unsigned char seph_io_mcu_protect[] = { + SEPROXYHAL_TAG_MCU, + 0, + 1, + SEPROXYHAL_TAG_MCU_TYPE_PROTECT, +}; + +#ifdef HAVE_SHIP_MODE +static const unsigned char seph_io_cmd_set_ship_mode[] = { + SEPROXYHAL_TAG_SET_SHIP_MODE, + 0, + 0, +}; +#endif // HAVE_SHIP_MODE + +static const unsigned char seph_io_cmd_more_time[] = { + SEPROXYHAL_TAG_MORE_TIME, + 0, + 0, +}; + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +int os_io_seph_cmd_general_status(void) +{ + return os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, seph_io_general_status, sizeof(seph_io_general_status), NULL); +} + +int os_io_seph_cmd_more_time(void) +{ + return os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, seph_io_cmd_more_time, sizeof(seph_io_cmd_more_time), NULL); +} + +int os_io_seph_cmd_setup_ticker(unsigned int interval_ms) +{ + uint8_t buffer[5]; + buffer[0] = SEPROXYHAL_TAG_SET_TICKER_INTERVAL; + buffer[1] = 0; + buffer[2] = 2; + buffer[3] = (interval_ms >> 8) & 0xff; + buffer[4] = (interval_ms) &0xff; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 5, NULL); +} + +int os_io_seph_cmd_device_shutdown(uint8_t critical_battery) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_DEVICE_OFF; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = critical_battery; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} + +int os_io_seph_cmd_se_reset(void) +{ + return os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, seph_io_se_power_off, sizeof(seph_io_se_power_off), NULL); +} + +int os_io_seph_cmd_usb_disconnect(void) +{ + return os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, seph_io_usb_disconnect, sizeof(seph_io_usb_disconnect), NULL); +} + +int os_io_seph_cmd_mcu_status(void) +{ + return os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, seph_io_request_status, sizeof(seph_io_request_status), NULL); +} + +int os_io_seph_cmd_mcu_go_to_bootloader(void) +{ + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, + seph_io_cmd_mcu_bootloader, + sizeof(seph_io_cmd_mcu_bootloader), + NULL); +} + +int os_io_seph_cmd_mcu_lock(void) +{ + return os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, seph_io_cmd_mcu_lock, sizeof(seph_io_cmd_mcu_lock), NULL); +} + +int os_io_seph_cmd_mcu_protect(void) +{ + return os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, seph_io_mcu_protect, sizeof(seph_io_mcu_protect), NULL); +} + +void os_io_seph_cmd_raw_apdu(const uint8_t *buffer, uint16_t length) +{ + if (length) { + unsigned char hdr[3]; + hdr[0] = SEPROXYHAL_TAG_RAPDU; + hdr[1] = length >> 8; + hdr[2] = length; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, hdr, 3, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, length, NULL); + } +} + +#ifdef HAVE_SHIP_MODE +int os_io_seph_cmd_set_ship_mode(void) +{ + return os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, seph_io_cmd_set_ship_mode, sizeof(seph_io_cmd_set_ship_mode), NULL); +} +#endif // HAVE_SHIP_MODE + +#ifdef HAVE_PRINTF +void os_io_seph_cmd_printf(const char *str, uint16_t charcount) +{ + if (charcount) { + unsigned char hdr[3]; + hdr[0] = SEPROXYHAL_TAG_PRINTF; + hdr[1] = charcount >> 8; + hdr[2] = charcount; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, hdr, 3, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, (const uint8_t *) str, charcount, NULL); + } +} +#endif // HAVE_PRINTF + +#ifdef HAVE_SE_TOUCH +int os_io_seph_cmd_set_touch_state(uint8_t enable) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_SET_TOUCH_STATE; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = (enable ? 0x01 : 0x00); + + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} +#endif // HAVE_SE_TOUCH + +#ifdef HAVE_PIEZO_SOUND +int os_io_seph_cmd_piezo_play_tune(tune_index_e tune_index) +{ + int status = 0; + + uint8_t buffer[4]; + if (tune_index >= NB_TUNES) { + status = -22; // EINVAL + goto end; + } + + uint32_t sound_setting = os_setting_get(OS_SETTING_PIEZO_SOUND, NULL, 0); + + if ((!IS_NOTIF_ENABLED(sound_setting)) && (tune_index < TUNE_TAP_CASUAL)) { + goto end; + } + if ((!IS_TAP_ENABLED(sound_setting)) && (tune_index >= TUNE_TAP_CASUAL)) { + goto end; + } + + buffer[0] = SEPROXYHAL_TAG_PLAY_TUNE; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = (uint8_t) tune_index; + status = os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); + +end: + return status; +} + +void io_seproxyhal_play_tune(tune_index_e tune_index) +{ + (void) os_io_seph_cmd_piezo_play_tune(tune_index); +} +#endif // HAVE_PIEZO_SOUND + +#ifdef HAVE_SERIALIZED_NBGL +void os_io_seph_cmd_serialized_nbgl(const uint8_t *buffer, uint16_t length) +{ + if (length) { + unsigned char hdr[3]; + hdr[0] = SEPROXYHAL_TAG_NBGL_SERIALIZED; + hdr[1] = length >> 8; + hdr[2] = length; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, hdr, 3, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, length, NULL); + } +} +#endif // HAVE_SERIALIZED_NBGL + +#ifdef HAVE_NOR_FLASH +void os_io_seph_cmd_spi_cs(uint8_t select) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_SPI_CS; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = select; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} +#endif // HAVE_NOR_FLASH + +#ifdef HAVE_BLE +int os_io_seph_cmd_ble_start_factory_test(void) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_BLE_RADIO_POWER; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = SEPROXYHAL_TAG_BLE_RADIO_POWER_FACTORY_TEST; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} +int os_io_ble_cmd_enable(uint8_t enable) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = (enable ? ITC_IO_BLE_START : ITC_IO_BLE_STOP); + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} + +int os_io_ble_cmd_clear_bond_db(void) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = ITC_IO_BLE_RESET_PAIRINGS; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} + +int os_io_ble_cmd_name_changed(void) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = ITC_IO_BLE_BLE_NAME_CHANGED; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} + +int os_io_ux_cmd_ble_accept_pairing(unsigned char status) +{ + uint8_t buffer[5]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 2; + buffer[3] = ITC_UX_ACCEPT_BLE_PAIRING; + buffer[4] = status; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 5, NULL); +} + +int os_io_ux_cmd_redisplay(void) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = ITC_UX_REDISPLAY; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} + +void os_io_ux_cmd_ble_pairing_request(bolos_ux_params_t *ux_params) +{ + uint8_t hdr[5]; + hdr[0] = SEPROXYHAL_TAG_ITC_CMD; + hdr[1] = 0; + hdr[2] = ux_params->u.pairing_request.pairing_info_len + 2; + hdr[3] = ITC_UX_ASK_BLE_PAIRING; + hdr[4] = ux_params->u.pairing_request.type; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, hdr, 5, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, + (uint8_t *) ux_params->u.pairing_request.pairing_info, + ux_params->u.pairing_request.pairing_info_len, + NULL); +} + +void os_io_ux_cmd_ble_pairing_status(bolos_ux_params_t *ux_params) +{ + uint8_t buffer[5]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 2; + buffer[3] = ITC_UX_BLE_PAIRING_STATUS; + buffer[4] = ux_params->u.pairing_status.pairing_ok; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 5, NULL); +} +#endif // HAVE_BLE + +#ifdef HAVE_NFC +int os_io_nfc_cmd_power(uint8_t power_type) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_NFC_POWER; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = power_type; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} + +int os_io_nfc_cmd_stop(void) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = ITC_IO_NFC_STOP; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} + +int os_io_nfc_cmd_start_ce(void) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = ITC_IO_NFC_START_CE; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} + +int os_io_nfc_cmd_start_reader(void) +{ + uint8_t buffer[4]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = ITC_IO_NFC_START_READER; + return os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); +} +#endif // HAVE_NFC + +void os_io_ux_cmd_button_state(uint8_t state) +{ + uint8_t buffer[5]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 2; + buffer[3] = ITC_BUTTON_STATE; + buffer[4] = state; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 5, NULL); +} + +void os_io_ux_cmd_touch_state(uint8_t state, uint16_t x, uint16_t y, uint8_t w, uint8_t h) +{ + uint8_t buffer[11]; + buffer[0] = SEPROXYHAL_TAG_ITC_CMD; + buffer[1] = 0; + buffer[2] = 8; + buffer[3] = ITC_FINGER_STATE; + buffer[4] = state; + buffer[5] = (uint8_t) (x >> 8); + buffer[6] = (uint8_t) (x & 0x00FF); + buffer[7] = (uint8_t) (y >> 8); + buffer[8] = (uint8_t) (y & 0x00FF); + buffer[9] = w; + buffer[10] = h; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 11, NULL); +} diff --git a/io/src/os_io_seph_ux.c b/io/src/os_io_seph_ux.c new file mode 100644 index 000000000..13ec3fbf8 --- /dev/null +++ b/io/src/os_io_seph_ux.c @@ -0,0 +1,347 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "os.h" +#include "os_io.h" +#include "ux.h" +#include "os_io_seph_cmd.h" +#include "os_io_seph_ux.h" +#include "seproxyhal_protocol.h" + +#ifdef HAVE_IO_USB +#include "usbd_ledger.h" +#endif // HAVE_IO_USB + +#ifdef HAVE_PRINTF +#define DEBUG PRINTF +// #define DEBUG(...) +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +#ifdef HAVE_BAGL +static void os_io_seph_ux_display_bagl_icon(const bagl_component_t *icon_component, + const bagl_icon_details_t *icon_det); +#endif // HAVE_BAGL + +/* Exported variables --------------------------------------------------------*/ +#if defined(HAVE_BAGL) || defined(HAVE_NBGL) +ux_seph_os_and_app_t G_ux_os; +#endif + +/* Private variables ---------------------------------------------------------*/ +#ifdef HAVE_SERIALIZED_NBGL +static uint8_t nbgl_serialize_buffer[SERIALIZED_NBGL_MAX_LEN]; +#endif // HAVE_SERIALIZED_NBGL + +/* Private functions ---------------------------------------------------------*/ +#ifdef HAVE_BAGL +static void os_io_seph_ux_display_bagl_icon(const bagl_component_t *icon_component, + const bagl_icon_details_t *icon_det) +{ + bagl_component_t icon_component_mod; + const bagl_icon_details_t *icon_details = (const bagl_icon_details_t *) PIC(icon_det); + + if (icon_details && icon_details->bitmap) { + // ensure not being out of bounds in the icon component against the declared icon real size + memcpy(&icon_component_mod, PIC(icon_component), sizeof(bagl_component_t)); + icon_component_mod.width = icon_details->width; + icon_component_mod.height = icon_details->height; + icon_component = &icon_component_mod; + + bagl_draw_glyph(&icon_component_mod, icon_details); + +#if defined(HAVE_PRINTF) + // testing color index size + unsigned int h = (1 << (icon_details->bpp)) * sizeof(unsigned int); + // bitmap size + unsigned int w + = ((icon_component->width * icon_component->height * icon_details->bpp) / 8) + + ((icon_component->width * icon_component->height * icon_details->bpp) % 8 ? 1 : 0); + unsigned short length = sizeof(bagl_component_t) + 1 // bpp + + h // color index + + w; // image bitmap size + if (length > (OS_IO_SEPH_BUFFER_SIZE - 4)) { + PRINTF( + "ERROR: Inside os_io_seph_ux_display_bagl_icon, icon size (%d) is too big for the " + "buffer (%d-4)! (bitmap=0x%x, width=%d, height=%d, bpp=%d)\n", + length, + OS_IO_SEPH_BUFFER_SIZE, + icon_details->bitmap, + icon_details->width, + icon_details->height, + icon_details->bpp); + return; + } + + uint8_t seph_buffer[3]; + seph_buffer[0] = SEPROXYHAL_TAG_DBG_SCREEN_DISPLAY_STATUS; + seph_buffer[1] = length >> 8; + seph_buffer[2] = length; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, seph_buffer, 3, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, + (const uint8_t *) icon_component, + sizeof(bagl_component_t), + NULL); + seph_buffer[0] = icon_details->bpp; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, seph_buffer, 1, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, (const uint8_t *) PIC(icon_details->colors), h, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, (const uint8_t *) PIC(icon_details->bitmap), w, NULL); +#else // !HAVE_PRINTF + (void) icon_component; +#endif // !HAVE_PRINTF + } +} +#endif // HAVE_BAGL + +/* Exported functions --------------------------------------------------------*/ +void io_seph_ux_init_button(void) +{ + G_ux_os.button_mask = 0; + G_ux_os.button_same_mask_counter = 0; +} + +int io_process_itc_ux_event(uint8_t *buffer_in, size_t buffer_in_length) +{ + int status = buffer_in_length; + + switch (buffer_in[3]) { +#ifdef HAVE_BLE + case ITC_UX_ASK_BLE_PAIRING: + G_ux_params.ux_id = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST; + G_ux_params.len = sizeof(G_ux_params.u.pairing_request); + memset(&G_ux_params.u.pairing_request, 0, sizeof(G_ux_params.u.pairing_request)); + G_ux_params.u.pairing_request.type = buffer_in[4]; + G_ux_params.u.pairing_request.pairing_info_len = U2BE(buffer_in, 1) - 2; + memcpy(G_ux_params.u.pairing_request.pairing_info, + &buffer_in[5], + G_ux_params.u.pairing_request.pairing_info_len); + os_ux(&G_ux_params); + status = 0; + break; + + case ITC_UX_BLE_PAIRING_STATUS: + G_ux_params.ux_id = BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS; + G_ux_params.len = sizeof(G_ux_params.u.pairing_status); + G_ux_params.u.pairing_status.pairing_ok = buffer_in[4]; + os_ux(&G_ux_params); + status = 0; + break; +#endif // HAVE_BLE + +#if !defined(HAVE_BOLOS) && defined(HAVE_BAGL) + case ITC_UX_REDISPLAY: + ux_stack_redisplay(); + break; +#endif // HAVE_BOLOS && HAVE_BAGL +#if !defined(HAVE_BOLOS) && defined(HAVE_NBGL) + case ITC_UX_REDISPLAY: + nbgl_objAllowDrawing(true); + nbgl_screenRedraw(); + nbgl_refresh(); + break; +#endif // HAVE_BOLOS && HAVE_NBGL + + default: + break; + } + + return status; +} + +void io_process_ux_event(uint8_t *buffer_in, size_t buffer_in_length) +{ + UNUSED(buffer_in_length); + + if ((buffer_in[0] == SEPROXYHAL_TAG_TICKER_EVENT) + || (buffer_in[0] == SEPROXYHAL_TAG_BUTTON_PUSH_EVENT) + || (buffer_in[0] == SEPROXYHAL_TAG_STATUS_EVENT) + || (buffer_in[0] == SEPROXYHAL_TAG_FINGER_EVENT) + || (buffer_in[0] == SEPROXYHAL_TAG_POWER_BUTTON_EVENT)) { + G_ux_params.ux_id = BOLOS_UX_EVENT; + G_ux_params.len = 0; + os_ux(&G_ux_params); + } + else if (buffer_in[0] == SEPROXYHAL_TAG_ITC_EVENT) { + io_process_itc_ux_event(buffer_in, buffer_in_length); + } +} + +#if !defined(APP_UX) +unsigned int os_ux_blocking(bolos_ux_params_t *params) +{ + unsigned int ret; + + os_ux(params); + ret = os_sched_last_status(TASK_BOLOS_UX); + while (ret == BOLOS_UX_IGNORE || ret == BOLOS_UX_CONTINUE) { + os_io_handle_ux_event_reject_apdu(); + // only retrieve the current UX state + ret = os_sched_last_status(TASK_BOLOS_UX); + } + + return ret; +} +#endif // !APP_UX + +#ifdef HAVE_BAGL +void io_seph_ux_display_bagl_element(const bagl_element_t *element) +{ + const bagl_element_t *el = (const bagl_element_t *) PIC(element); + const char *txt; + // process automagically address from rom and from ram + unsigned int type = (el->component.type & ~(BAGL_FLAG_TOUCHABLE)); + +#if defined(HAVE_INDEXED_STRINGS) + if (type == BAGL_LABELINE_LOC) { + txt = (const char *) PIC(get_ux_loc_string(el->index)); + } + else +#endif // defined(HAVE_INDEXED_STRINGS) + { + txt = (const char *) PIC(el->text); + } + + if (type != BAGL_NONE) { + if (txt != NULL) { + // consider an icon details descriptor is pointed by the context + if (type == BAGL_ICON && el->component.icon_id == 0) { + // SECURITY: due to this wild cast, the code MUST be executed on the application + // side instead of in + // the syscall sides to avoid buffer overflows and a real hard way of + // checking buffer belonging in the syscall dispatch + os_io_seph_ux_display_bagl_icon(&el->component, (const bagl_icon_details_t *) txt); + } + else { + bagl_draw_with_context(&el->component, txt, strlen(txt), BAGL_ENCODING_DEFAULT); +#if defined(HAVE_PRINTF) + // LNS case (MCU screen) or SE screen device willing to send bagl packet for + // automated testing io_seph_send crash when using txt from language packs... + // ...let's use an intermediate buffer to store txt +#ifdef HAVE_LANGUAGE_PACK + char txt_buffer[128]; + strlcpy(txt_buffer, txt, sizeof(txt_buffer)); +#else // HAVE_LANGUAGE_PACK + const char *txt_buffer = txt; +#endif // HAVE_LANGUAGE_PACK + unsigned short length = sizeof(bagl_component_t) + strlen(txt_buffer); + if (length > (OS_IO_SEPH_BUFFER_SIZE - 3)) { + PRINTF( + "ERROR: Inside io_seph_ux_display_bagl_element, length (%d) is too big " + "for seph buffer(%d)!\n", + length + 3, + OS_IO_SEPH_BUFFER_SIZE); + return; + } + uint8_t seph_buffer[3]; + seph_buffer[0] = SEPROXYHAL_TAG_DBG_SCREEN_DISPLAY_STATUS; + seph_buffer[1] = length >> 8; + seph_buffer[2] = length; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, seph_buffer, 3, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, + (const uint8_t *) &el->component, + sizeof(bagl_component_t), + NULL); + os_io_tx_cmd( + OS_IO_PACKET_TYPE_SEPH, (const uint8_t *) txt_buffer, strlen(txt_buffer), NULL); +#endif // HAVE_PRINTF + } + } + else { + bagl_draw_with_context(&el->component, NULL, 0, 0); +#if defined(HAVE_PRINTF) + // LNS case (MCU screen) or SE screen device willing to send bagl packet for + // automated testing + unsigned short length = sizeof(bagl_component_t); + uint8_t seph_buffer[3]; + seph_buffer[0] = SEPROXYHAL_TAG_DBG_SCREEN_DISPLAY_STATUS; + seph_buffer[1] = length >> 8; + seph_buffer[2] = length; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, seph_buffer, 3, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, + (const uint8_t *) &el->component, + sizeof(bagl_component_t), + NULL); +#endif // HAVE_PRINTF + } + } +} + +void io_seproxyhal_button_push(button_push_callback_t button_callback, unsigned int new_button_mask) +{ + if (button_callback) { + unsigned int button_mask; + unsigned int button_same_mask_counter; + // enable speeded up long push + if (new_button_mask == G_ux_os.button_mask) { + // each 100ms ~ + G_ux_os.button_same_mask_counter++; + } + + // when new_button_mask is 0 and + + // append the button mask + button_mask = G_ux_os.button_mask | new_button_mask; + + // pre reset variable due to os_sched_exit + button_same_mask_counter = G_ux_os.button_same_mask_counter; + + // reset button mask + if (new_button_mask == 0) { + // reset next state when button are released + G_ux_os.button_mask = 0; + G_ux_os.button_same_mask_counter = 0; + + // notify button released event + button_mask |= BUTTON_EVT_RELEASED; + } + else { + G_ux_os.button_mask = button_mask; + } + + // reset counter when button mask changes + if (new_button_mask != G_ux_os.button_mask) { + G_ux_os.button_same_mask_counter = 0; + } + + if (button_same_mask_counter >= BUTTON_FAST_THRESHOLD_CS) { + // fast bit when pressing and timing is right + if ((button_same_mask_counter % BUTTON_FAST_ACTION_CS) == 0) { + button_mask |= BUTTON_EVT_FAST; + } + + // discard the release event after a fastskip has been detected, to avoid strange at + // release behavior and also to enable user to cancel an operation by starting + // triggering the fast skip + button_mask &= ~BUTTON_EVT_RELEASED; + } + + // indicate if button have been released + button_callback(button_mask, button_same_mask_counter); + } +} +#endif // HAVE_BAGL + +#ifdef HAVE_SERIALIZED_NBGL +void io_seph_ux_send_nbgl_serialized(nbgl_serialized_event_type_e event, nbgl_obj_t *obj) +{ + // Serialize object + size_t len = 0; + uint8_t status = nbgl_serializeNbglEvent( + event, obj, nbgl_serialize_buffer, &len, sizeof(nbgl_serialize_buffer)); + + // Encode and send + if (status == NBGL_SERIALIZE_OK) { + os_io_seph_cmd_serialized_nbgl(nbgl_serialize_buffer, len); + } +} +#endif // HAVE_SERIALIZED_NBGL diff --git a/io_legacy/include/os_io_legacy.h b/io_legacy/include/os_io_legacy.h new file mode 100644 index 000000000..7545e6596 --- /dev/null +++ b/io_legacy/include/os_io_legacy.h @@ -0,0 +1,100 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "os_math.h" +#include "decorators.h" +#include "os_io_legacy_types.h" +#include "os_io_seph_cmd.h" +#include "os_io_seph_ux.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ +#define CHANNEL_APDU 0 +#define CHANNEL_KEYBOARD 1 +#define CHANNEL_SPI 2 +#define IO_RESET_AFTER_REPLIED 0x80 +#define IO_RECEIVE_DATA 0x40 +#define IO_RETURN_AFTER_TX 0x20 +#define IO_ASYNCH_REPLY 0x10 // avoid apdu state reset if tx_len == 0 when we're expected to reply +#define IO_FLAGS 0xF8 + +#define IO_CACHE 1 + +#define IO_APDU_BUFFER_SIZE OS_IO_BUFFER_SIZE + 1 + +#define G_io_apdu_buffer G_io_rx_buffer + +// deprecated +#define G_io_apdu_media G_io_app.apdu_media +// deprecated +#define G_io_apdu_state G_io_app.apdu_state + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern unsigned char G_io_seproxyhal_spi_buffer[OS_IO_SEPH_BUFFER_SIZE]; +#ifdef HAVE_NFC_READER +extern struct nfc_reader_context G_io_reader_ctx; +#endif // HAVE_NFC_READER + +/* Exported functions prototypes--------------------------------------------- */ +SYSCALL void io_seph_send(const unsigned char *buffer PLENGTH(length), unsigned short length); +SYSCALL unsigned int io_seph_is_status_sent(void); +SYSCALL unsigned short io_seph_recv(unsigned char *buffer PLENGTH(maxlength), + unsigned short maxlength, + unsigned int flags); + +#define io_seproxyhal_spi_send io_seph_send +#define io_seproxyhal_spi_is_status_sent io_seph_is_status_sent +#define io_seproxyhal_spi_recv io_seph_recv + +void io_seproxyhal_general_status(void); +void io_seproxyhal_se_reset(void); +void io_seproxyhal_disable_io(void); +void io_seproxyhal_io_heartbeat(void); +void io_seproxyhal_request_mcu_status(void); + +#ifdef HAVE_BAGL +void io_seproxyhal_display_default(const bagl_element_t *element); +#endif // HAVE_BAGL + +#ifdef HAVE_PIEZO_SOUND +void io_seproxyhal_play_tune(tune_index_e tune_index); +#endif // HAVE_PIEZO_SOUND + +unsigned int io_seph_is_status_sent(void); + +unsigned short io_exchange(unsigned char channel_and_flags, unsigned short tx_len); +void io_seproxyhal_init(void); +void USB_power(unsigned char enabled); +#ifdef HAVE_BLE +void BLE_power(unsigned char powered, const char *discovered_name); +#endif // HAVE_BLE + +unsigned char io_event(unsigned char channel); + +int io_legacy_apdu_rx(void); +int io_legacy_apdu_tx(const unsigned char *buffer, unsigned short length); + +#ifdef HAVE_NFC_READER +void io_nfc_event(void); +void io_nfc_ticker(void); +void io_nfc_process_events(void); + +bool io_nfc_reader_send(const uint8_t *cmd_data, + size_t cmd_len, + nfc_resp_callback_t callback, + int timeout_ms); + +/* Return false if nfc reader can not be started in current conditions */ +bool io_nfc_reader_start(nfc_evt_callback_t callback); +void io_nfc_reader_stop(void); +bool io_nfc_is_reader(void); +#endif // HAVE_NFC_READER diff --git a/io_legacy/include/os_io_legacy_types.h b/io_legacy/include/os_io_legacy_types.h new file mode 100644 index 000000000..0c0ac7217 --- /dev/null +++ b/io_legacy/include/os_io_legacy_types.h @@ -0,0 +1,103 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include "os_math.h" +#include "decorators.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + IO_APDU_MEDIA_NONE = 0, // not correctly in an apdu exchange + IO_APDU_MEDIA_USB_HID = 1, + IO_APDU_MEDIA_BLE, + IO_APDU_MEDIA_NFC, + IO_APDU_MEDIA_USB_CCID, + IO_APDU_MEDIA_USB_WEBUSB, + IO_APDU_MEDIA_RAW, + IO_APDU_MEDIA_U2F, +} io_apdu_media_t; + +typedef enum { + APDU_IDLE, + APDU_BLE, + APDU_BLE_WAIT_NOTIFY, + APDU_NFC, + APDU_NFC_M24SR, + APDU_NFC_M24SR_SELECT, + APDU_NFC_M24SR_FIRST, + APDU_NFC_M24SR_RAPDU, + APDU_USB_HID, + APDU_USB_CCID, + APDU_U2F, + APDU_RAW, + APDU_USB_WEBUSB, +} io_apdu_state_e; + +#ifdef HAVE_NFC_READER +enum card_tech { + NFC_A, + NFC_B +}; + +enum nfc_event { + CARD_DETECTED, + CARD_REMOVED, +}; +#endif // HAVE_NFC_READER + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + io_apdu_state_e apdu_state; // by default + unsigned short apdu_length; // total length to be received + unsigned short io_flags; // flags to be set when calling io_exchange + io_apdu_media_t apdu_media; +#ifdef HAVE_BLE + unsigned int plane_mode; +#endif // HAVE_BLE +} io_seph_app_t; + +#ifdef HAVE_NFC_READER +struct card_info { + enum card_tech tech; + uint8_t nfcid[7]; + size_t nfcid_len; +}; + +typedef void (*nfc_evt_callback_t)(enum nfc_event event, struct card_info *info); +typedef void (*nfc_resp_callback_t)(bool error, bool timeout, uint8_t *resp_data, size_t resp_len); + +struct nfc_reader_context { + nfc_resp_callback_t resp_callback; + nfc_evt_callback_t evt_callback; + bool reader_mode; + bool event_happened; + bool response_received; + unsigned int remaining_ms; + enum nfc_event last_event; + struct card_info card; + uint8_t *apdu_rx; + size_t apdu_rx_len; // Used length + size_t apdu_rx_max_size; // Max size of buffer +}; +#endif // HAVE_NFC_READER + +/* Exported defines --------------------------------------------------------*/ +#ifdef IO_SEPROXYHAL_BUFFER_SIZE_B +#undef IO_SEPROXYHAL_BUFFER_SIZE_B +#endif // IO_SEPROXYHAL_BUFFER_SIZE_B +#define IO_SEPROXYHAL_BUFFER_SIZE_B OS_IO_SEPH_BUFFER_SIZE + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern io_seph_app_t G_io_app; +#ifdef HAVE_IO_U2F +#include "u2f_service.h" +extern u2f_service_t G_io_u2f; +#endif // HAVE_IO_U2F + +/* Exported functions prototypes--------------------------------------------- */ diff --git a/io_legacy/src/os_io_legacy.c b/io_legacy/src/os_io_legacy.c new file mode 100644 index 000000000..dc490d042 --- /dev/null +++ b/io_legacy/src/os_io_legacy.c @@ -0,0 +1,481 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include "errors.h" +#include "os_helpers.h" +#include "os_io.h" +#include "os_apdu.h" +#include "os_io_default_apdu.h" +#include "os_io_legacy.h" + +#ifdef HAVE_IO_USB +#include "usbd_ledger.h" +#endif // HAVE_IO_USB + +#ifdef HAVE_BLE +#include "ble_ledger.h" +#endif // HAVE_BLE + +#ifdef HAVE_NFC_READER +#include "nfc_ledger.h" +#endif // HAVE_NFC_READER + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +io_seph_app_t G_io_app; + +/* Private variables ---------------------------------------------------------*/ + +// Variable containing the type of the APDU response to send back. +static apdu_type_t io_os_legacy_apdu_type; +static uint8_t need_to_start_io; + +/* Private functions ---------------------------------------------------------*/ +static io_apdu_media_t get_media_from_apdu_type(apdu_type_t apdu_type) +{ + if (apdu_type == APDU_TYPE_RAW) { + return IO_APDU_MEDIA_RAW; + } + if (apdu_type == APDU_TYPE_USB_HID) { + return IO_APDU_MEDIA_USB_HID; + } + if (apdu_type == APDU_TYPE_USB_WEBUSB) { + return IO_APDU_MEDIA_USB_WEBUSB; + } + if (apdu_type == APDU_TYPE_USB_CCID) { + return IO_APDU_MEDIA_USB_CCID; + } + if (apdu_type == APDU_TYPE_USB_U2F) { + return IO_APDU_MEDIA_U2F; + } + if (apdu_type == APDU_TYPE_BLE) { + return IO_APDU_MEDIA_BLE; + } + if (apdu_type == APDU_TYPE_NFC) { + return IO_APDU_MEDIA_NFC; + } + return IO_APDU_MEDIA_NONE; +} + +/* Exported functions --------------------------------------------------------*/ + +void io_seproxyhal_general_status(void) +{ + (void) os_io_seph_cmd_general_status(); +} + +void io_seproxyhal_se_reset(void) +{ + os_io_seph_cmd_se_reset(); + for (;;) + ; +} + +void io_seproxyhal_disable_io(void) +{ + os_io_stop(); +} + +void io_seproxyhal_io_heartbeat(void) +{ + uint16_t err = 0x6601; + unsigned char err_buffer[2]; + int status = os_io_rx_evt(G_io_rx_buffer, sizeof(G_io_rx_buffer), NULL); + + err_buffer[0] = err >> 8; + err_buffer[1] = err; + + if (status > 0) { + switch (G_io_rx_buffer[0]) { + case OS_IO_PACKET_TYPE_SE_EVT: + case OS_IO_PACKET_TYPE_SEPH: + memcpy(G_io_seproxyhal_spi_buffer, &G_io_rx_buffer[1], status - 1); + io_event(CHANNEL_APDU); + break; + + case OS_IO_PACKET_TYPE_RAW_APDU: + case OS_IO_PACKET_TYPE_USB_HID_APDU: + case OS_IO_PACKET_TYPE_USB_WEBUSB_APDU: + case OS_IO_PACKET_TYPE_USB_U2F_HID_APDU: + case OS_IO_PACKET_TYPE_BLE_APDU: + case OS_IO_PACKET_TYPE_NFC_APDU: + os_io_tx_cmd(G_io_rx_buffer[0], err_buffer, sizeof(err_buffer), 0); + break; + + default: + break; + } + } +} + +void io_seproxyhal_request_mcu_status(void) {} + +#ifdef HAVE_BAGL +void io_seproxyhal_display_default(const bagl_element_t *element) +{ + io_seph_ux_display_bagl_element(element); +} +#endif // HAVE_BAGL + +void io_seph_send(const unsigned char *buffer, unsigned short length) +{ + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, length+1, 0); +} + +unsigned int io_seph_is_status_sent(void) +{ + return 1; +} + +unsigned short io_seph_recv(unsigned char *buffer, unsigned short maxlength, unsigned int flags) +{ + UNUSED(maxlength); + UNUSED(flags); + int status = os_io_rx_evt(G_io_rx_buffer, sizeof(G_io_rx_buffer), NULL); + + if (status > 0) { + switch (G_io_rx_buffer[0]) { + case OS_IO_PACKET_TYPE_SE_EVT: + case OS_IO_PACKET_TYPE_SEPH: + status -= 1; + memcpy(buffer, &G_io_rx_buffer[1], status); + if (G_io_rx_buffer[1] == SEPROXYHAL_TAG_ITC_EVENT) { + status = io_process_itc_ux_event(buffer, status); + } + else { + io_event(CHANNEL_APDU); + status = 0; + } + break; + default: + break; + } + } + + return status; +} + +unsigned short io_exchange(unsigned char channel_and_flags, unsigned short tx_len) +{ + int status = 0; + + if (need_to_start_io) { + os_io_start(); + need_to_start_io = 0; + } + + if ((channel_and_flags & ~(IO_FLAGS)) != CHANNEL_APDU) { + return 0; + } + + if (tx_len && !(channel_and_flags & IO_ASYNCH_REPLY)) { + memmove(G_io_tx_buffer, G_io_apdu_buffer, tx_len); + io_legacy_apdu_tx(G_io_tx_buffer, tx_len); + G_io_app.apdu_media = IO_APDU_MEDIA_NONE; + io_os_legacy_apdu_type = APDU_TYPE_NONE; + if (channel_and_flags & IO_RETURN_AFTER_TX) { + return 0; + } + } + + if (!(channel_and_flags & IO_ASYNCH_REPLY)) { + G_io_app.apdu_media = IO_APDU_MEDIA_NONE; + io_os_legacy_apdu_type = APDU_TYPE_NONE; + } + + G_io_app.apdu_length = 0; + + status = 0; + while (status <= 0) { + status = io_legacy_apdu_rx(); + } + G_io_app.apdu_length = status; + + return status; +} + +void io_seproxyhal_init(void) +{ + os_io_init_t init_io; + + io_os_legacy_apdu_type = APDU_TYPE_NONE; + init_io.syscall = G_io_syscall_flag; + init_io.usb.pid = 0; + init_io.usb.vid = 0; + init_io.usb.class_mask = 0; + memset(init_io.usb.name, 0, sizeof(init_io.usb.name)); +#ifdef HAVE_IO_USB + init_io.usb.class_mask = USBD_LEDGER_CLASS_HID | USBD_LEDGER_CLASS_WEBUSB; +#ifdef HAVE_IO_U2F + init_io.usb.class_mask |= USBD_LEDGER_CLASS_HID_U2F; + + init_io.usb.hid_u2f_settings.protocol_version = 2; + init_io.usb.hid_u2f_settings.major_device_version_number = 0; + init_io.usb.hid_u2f_settings.minor_device_version_number = 1; + init_io.usb.hid_u2f_settings.build_device_version_number = 0; + init_io.usb.hid_u2f_settings.capabilities_flag = 0; +#endif // HAVE_IO_U2F +#endif // !HAVE_IO_USB + + init_io.ble.profile_mask = 0; +#ifdef HAVE_BLE + init_io.ble.profile_mask = BLE_LEDGER_PROFILE_APDU; +#endif // !HAVE_BLE + +#ifdef HAVE_NFC_READER + memset((void *) &G_io_reader_ctx, 0, sizeof(G_io_reader_ctx)); + G_io_reader_ctx.apdu_rx = G_io_seproxyhal_spi_buffer; + G_io_reader_ctx.apdu_rx_max_size = sizeof(G_io_seproxyhal_spi_buffer); +#endif // HAVE_NFC_READER + + os_io_init(&init_io); + need_to_start_io = 1; +} + +void USB_power(unsigned char enabled) +{ + UNUSED(enabled); +} + +#ifdef HAVE_BLE +void BLE_power(unsigned char powered, const char *discovered_name) +{ + UNUSED(powered); + UNUSED(discovered_name); +} +#endif // HAVE_BLE + +int io_legacy_apdu_rx(void) +{ + int status = 0; + os_io_apdu_post_action_t post_action = OS_IO_APDU_POST_ACTION_NONE; + + status = os_io_rx_evt(G_io_rx_buffer, sizeof(G_io_rx_buffer), NULL); + + if (status > 0) { + switch (G_io_rx_buffer[0]) { + case OS_IO_PACKET_TYPE_SE_EVT: + case OS_IO_PACKET_TYPE_SEPH: + memcpy(G_io_seproxyhal_spi_buffer, &G_io_rx_buffer[1], status - 1); + if (G_io_rx_buffer[1] == SEPROXYHAL_TAG_ITC_EVENT) { + status = io_process_itc_ux_event(G_io_seproxyhal_spi_buffer, status - 1); + } + else { + io_event(CHANNEL_APDU); + status = 0; + } + break; + + case OS_IO_PACKET_TYPE_RAW_APDU: + case OS_IO_PACKET_TYPE_USB_HID_APDU: + case OS_IO_PACKET_TYPE_USB_WEBUSB_APDU: + case OS_IO_PACKET_TYPE_USB_U2F_HID_APDU: + case OS_IO_PACKET_TYPE_USB_U2F_HID_CBOR: + case OS_IO_PACKET_TYPE_BLE_APDU: + case OS_IO_PACKET_TYPE_NFC_APDU: + io_os_legacy_apdu_type = G_io_rx_buffer[0]; + if (G_io_rx_buffer[APDU_OFF_CLA + 1] == DEFAULT_APDU_CLA) { + size_t buffer_out_length = sizeof(G_io_rx_buffer); + bolos_err_t err = os_io_handle_default_apdu(&G_io_rx_buffer[1], + status - 1, + G_io_tx_buffer, + &buffer_out_length, + &post_action); + if (err != SWO_SUCCESS) { + buffer_out_length = 0; + } + G_io_tx_buffer[buffer_out_length++] = err >> 8; + G_io_tx_buffer[buffer_out_length++] = err; + status = os_io_tx_cmd( + io_os_legacy_apdu_type, G_io_tx_buffer, buffer_out_length, 0); + io_os_legacy_apdu_type = APDU_TYPE_NONE; + if (post_action == OS_IO_APDU_POST_ACTION_EXIT) { + os_sched_exit(-1); + } + if (status > 0) { + status = 0; + } + } + else { + G_io_app.apdu_media = get_media_from_apdu_type(io_os_legacy_apdu_type); + status -= 1; + memmove(G_io_apdu_buffer, &G_io_rx_buffer[1], status); +#ifdef HAVE_IO_U2F + if (io_os_legacy_apdu_type == OS_IO_PACKET_TYPE_USB_U2F_HID_APDU) { + G_io_u2f.media = U2F_MEDIA_USB; + G_io_app.apdu_state = APDU_U2F; + } + else if (io_os_legacy_apdu_type == OS_IO_PACKET_TYPE_USB_U2F_HID_CBOR) { + G_io_u2f.media = U2F_MEDIA_USB; + G_io_app.apdu_state = APDU_IDLE; + } + else if (io_os_legacy_apdu_type == OS_IO_PACKET_TYPE_NFC_APDU) { + G_io_u2f.media = U2F_MEDIA_NFC; + G_io_app.apdu_state = APDU_U2F; + } +#endif // HAVE_IO_U2F + } + break; + +#ifdef HAVE_NFC_READER + case OS_IO_PACKET_TYPE_NFC_APDU_RSP: + G_io_app.apdu_media = IO_APDU_MEDIA_NFC; + status -= 1; + memcpy(G_io_seproxyhal_spi_buffer, &G_io_rx_buffer[1], status); + G_io_reader_ctx.response_received = true; + G_io_reader_ctx.apdu_rx_len = status; + break; +#endif // HAVE_NFC_READER + + default: + status = 0; + break; + } + } + + return status; +} + +int io_legacy_apdu_tx(const unsigned char *buffer, unsigned short length) +{ + int status = os_io_tx_cmd(io_os_legacy_apdu_type, buffer, length, 0); + G_io_app.apdu_media = IO_APDU_MEDIA_NONE; + io_os_legacy_apdu_type = APDU_TYPE_NONE; +#ifdef HAVE_IO_U2F + G_io_u2f.media = U2F_MEDIA_NONE; +#endif // HAVE_IO_U2F + + return status; +} + +#ifdef HAVE_NFC_READER + +void io_nfc_event(void) +{ + size_t size = U2BE(G_io_seproxyhal_spi_buffer, 1); + + if (size >= 1) { + switch (G_io_seproxyhal_spi_buffer[3]) { + case SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED: { + G_io_reader_ctx.event_happened = true; + G_io_reader_ctx.last_event = CARD_DETECTED; + G_io_reader_ctx.card.tech + = (G_io_seproxyhal_spi_buffer[4] == SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED_A) + ? NFC_A + : NFC_B; + G_io_reader_ctx.card.nfcid_len = MIN(size - 2, sizeof(G_io_reader_ctx.card.nfcid)); + memcpy((void *) G_io_reader_ctx.card.nfcid, + G_io_seproxyhal_spi_buffer + 5, + G_io_reader_ctx.card.nfcid_len); + } break; + + case SEPROXYHAL_TAG_NFC_EVENT_CARD_LOST: + if (G_io_reader_ctx.evt_callback != NULL) { + G_io_reader_ctx.event_happened = true; + G_io_reader_ctx.last_event = CARD_REMOVED; + } + break; + } + } +} + +void io_nfc_process_events(void) +{ + if (G_io_reader_ctx.response_received) { + G_io_reader_ctx.response_received = false; + if (G_io_reader_ctx.resp_callback != NULL) { + nfc_resp_callback_t resp_cb = G_io_reader_ctx.resp_callback; + G_io_reader_ctx.resp_callback = NULL; + resp_cb(false, false, G_io_reader_ctx.apdu_rx, G_io_reader_ctx.apdu_rx_len); + } + } + + if (G_io_reader_ctx.resp_callback != NULL && G_io_reader_ctx.remaining_ms == 0) { + nfc_resp_callback_t resp_cb = G_io_reader_ctx.resp_callback; + G_io_reader_ctx.resp_callback = NULL; + resp_cb(false, true, NULL, 0); + } + + if (G_io_reader_ctx.event_happened) { + G_io_reader_ctx.event_happened = 0; + + // If card is removed during an APDU processing, call the resp_callback with an error + if (G_io_reader_ctx.resp_callback != NULL && G_io_reader_ctx.last_event == CARD_REMOVED) { + nfc_resp_callback_t resp_cb = G_io_reader_ctx.resp_callback; + G_io_reader_ctx.resp_callback = NULL; + resp_cb(true, false, NULL, 0); + } + + if (G_io_reader_ctx.evt_callback != NULL) { + G_io_reader_ctx.evt_callback(G_io_reader_ctx.last_event, + (struct card_info *) &G_io_reader_ctx.card); + } + if (G_io_reader_ctx.last_event == CARD_REMOVED) { + memset((void *) &G_io_reader_ctx.card, 0, sizeof(G_io_reader_ctx.card)); + } + } +} + +void io_nfc_ticker(void) +{ + if (G_io_reader_ctx.resp_callback != NULL) { + if (G_io_reader_ctx.remaining_ms <= 100) { + G_io_reader_ctx.remaining_ms = 0; + } + else { + G_io_reader_ctx.remaining_ms -= 100; + } + } +} + +bool io_nfc_reader_send(const uint8_t *cmd_data, + size_t cmd_len, + nfc_resp_callback_t callback, + int timeout_ms) +{ + G_io_reader_ctx.resp_callback = PIC(callback); + io_os_legacy_apdu_type = APDU_TYPE_NFC; + io_legacy_apdu_tx(PIC(cmd_data), cmd_len); + + G_io_reader_ctx.response_received = false; + G_io_reader_ctx.remaining_ms = timeout_ms; + + return true; +} + +bool io_nfc_reader_start(nfc_evt_callback_t callback) +{ + G_io_reader_ctx.evt_callback = PIC(callback); + G_io_reader_ctx.reader_mode = true; + G_io_reader_ctx.event_happened = false; + G_io_reader_ctx.resp_callback = NULL; + G_io_reader_ctx.response_received = false; + os_io_nfc_cmd_start_reader(); + return true; +} + +void io_nfc_reader_stop(void) +{ + G_io_reader_ctx.evt_callback = NULL; + G_io_reader_ctx.reader_mode = false; + G_io_reader_ctx.event_happened = false; + G_io_reader_ctx.resp_callback = NULL; + G_io_reader_ctx.response_received = false; + os_io_nfc_cmd_stop(); +} + +bool io_nfc_is_reader(void) +{ + return G_io_reader_ctx.reader_mode; +} +#endif // HAVE_NFC_READER diff --git a/lib_bagl/include/bagl_animate.h b/lib_bagl/include/bagl_animate.h index 8926bf557..3ae8f62b3 100644 --- a/lib_bagl/include/bagl_animate.h +++ b/lib_bagl/include/bagl_animate.h @@ -99,8 +99,6 @@ typedef struct bagl_anim_s { }; } bagl_anim_t; -#ifdef HAVE_SE_SCREEN - /** * Initialize a label animation. */ @@ -114,6 +112,4 @@ void bagl_animation_init(bagl_anim_t *anim, */ void bagl_animation_step(bagl_anim_t *anim); -#endif /* HAVE_SE_SCREEN */ - #endif /* !BAGL_ANIMATE_H_ */ diff --git a/lib_bagl/src/bagl_animate.c b/lib_bagl/src/bagl_animate.c index 5f6cde6e5..9b40af8a5 100644 --- a/lib_bagl/src/bagl_animate.c +++ b/lib_bagl/src/bagl_animate.c @@ -1,4 +1,3 @@ -#ifdef HAVE_SE_SCREEN #include #include @@ -347,5 +346,3 @@ void bagl_animation_step(bagl_anim_t *anim) break; }; } - -#endif /* HAVE_SE_SCREEN */ diff --git a/lib_blewbxx/ble.h b/lib_blewbxx/ble.h deleted file mode 100644 index 25b01f0ca..000000000 --- a/lib_blewbxx/ble.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - ****************************************************************************** - * @file ble.h - * @author MCD Application Team - * @brief BLE interface - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __BLE_H -#define __BLE_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Includes ------------------------------------------------------------------*/ -//#include "ble_conf.h" -//#include "ble_dbg_conf.h" - -/**< core */ -#include "core/ble_core.h" -#include "core/ble_bufsize.h" -#include "core/ble_defs.h" -#include "core/ble_legacy.h" -#include "core/ble_std.h" - -/**< blesvc */ -#include "svc/Inc/bas.h" -#include "svc/Inc/bls.h" -#include "svc/Inc/crs_stm.h" -#include "svc/Inc/dis.h" -#include "svc/Inc/eds_stm.h" -#include "svc/Inc/hids.h" -#include "svc/Inc/hrs.h" -#include "svc/Inc/hts.h" -#include "svc/Inc/ias.h" -#include "svc/Inc/lls.h" -#include "svc/Inc/tps.h" -#include "svc/Inc/motenv_stm.h" -#include "svc/Inc/p2p_stm.h" -#include "svc/Inc/otas_stm.h" -#include "svc/Inc/mesh.h" -#include "svc/Inc/template_stm.h" - -#include "svc/Inc/svc_ctl.h" - -#include "svc/Inc/uuid.h" - - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#ifdef __cplusplus -} -#endif - -#endif /*__BLE_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_blewbxx/ble_common.h b/lib_blewbxx/ble_common.h deleted file mode 100644 index e6ce37221..000000000 --- a/lib_blewbxx/ble_common.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - ****************************************************************************** - * @file ble_common.h - * @author MCD Application Team - * @brief Common file to BLE Middleware - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2018 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __BLE_COMMON_H -#define __BLE_COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include - -//#include "ble_conf.h" -//#include "ble_dbg_conf.h" - -/* -------------------------------- * - * Basic definitions * - * -------------------------------- */ - -#undef NULL -#define NULL 0 - -#undef FALSE -#define FALSE 0 - -#undef TRUE -#define TRUE (!0) - - -/* -------------------------------- * - * Macro delimiters * - * -------------------------------- */ - -#define M_BEGIN do { - -#define M_END } while(0) - - -/* -------------------------------- * - * Some useful macro definitions * - * -------------------------------- */ - -#ifndef MAX -#define MAX( a, b ) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN( a, b ) (((a) < (b)) ? (a) : (b)) -#endif - -#define MODINC( a, m ) M_BEGIN (a)++; if ((a)>=(m)) (a)=0; M_END - -#define MODDEC( a, m ) M_BEGIN if ((a)==0) (a)=(m); (a)--; M_END - -#define MODADD( a, b, m ) M_BEGIN (a)+=(b); if ((a)>=(m)) (a)-=(m); M_END - -#define MODSUB( a, b, m ) MODADD( a, (m)-(b), m ) - -#ifdef WIN32 -#define ALIGN(n) -#else -#define ALIGN(n) __attribute__((aligned(n))) -#endif - -#define PAUSE( t ) M_BEGIN \ - volatile int _i; \ - for ( _i = t; _i > 0; _i -- ); \ - M_END - -#define DIVF( x, y ) ((x)/(y)) - -#define DIVC( x, y ) (((x)+(y)-1)/(y)) - -#define DIVR( x, y ) (((x)+((y)/2))/(y)) - -#define SHRR( x, n ) ((((x)>>((n)-1))+1)>>1) - -#define BITN( w, n ) (((w)[(n)/32] >> ((n)%32)) & 1) - -#define BITNSET( w, n, b ) M_BEGIN (w)[(n)/32] |= ((U32)(b))<<((n)%32); M_END - - /* -------------------------------- * - * Compiler * - * -------------------------------- */ -#define PLACE_IN_SECTION( __x__ ) __attribute__((section (__x__))) - - - -#ifdef __cplusplus -} -#endif - -#endif /*__BLE_COMMON_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_blewbxx/core/auto/ble_gap_aci.c b/lib_blewbxx/core/auto/ble_gap_aci.c deleted file mode 100644 index 01e6d46af..000000000 --- a/lib_blewbxx/core/auto/ble_gap_aci.c +++ /dev/null @@ -1,1326 +0,0 @@ -/****************************************************************************** - * @file ble_gap_aci.c - * @author MCD - * @brief STM32WB BLE API (gap_aci) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#include "ble_gap_aci.h" - -tBleStatus aci_gap_set_non_discoverable( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x081; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_set_limited_discoverable( uint8_t Advertising_Type, - uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Own_Address_Type, - uint8_t Advertising_Filter_Policy, - uint8_t Local_Name_Length, - const uint8_t* Local_Name, - uint8_t Service_Uuid_length, - const uint8_t* Service_Uuid_List, - uint16_t Slave_Conn_Interval_Min, - uint16_t Slave_Conn_Interval_Max ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_limited_discoverable_cp0 *cp0 = (aci_gap_set_limited_discoverable_cp0*)(cmd_buffer); - aci_gap_set_limited_discoverable_cp1 *cp1 = (aci_gap_set_limited_discoverable_cp1*)(cmd_buffer + 1 + 2 + 2 + 1 + 1 + 1 + Local_Name_Length * (sizeof(uint8_t))); - aci_gap_set_limited_discoverable_cp2 *cp2 = (aci_gap_set_limited_discoverable_cp2*)(cmd_buffer + 1 + 2 + 2 + 1 + 1 + 1 + Local_Name_Length * (sizeof(uint8_t)) + 1 + Service_Uuid_length * (sizeof(uint8_t))); - tBleStatus status = 0; - int index_input = 0; - cp0->Advertising_Type = Advertising_Type; - index_input += 1; - cp0->Advertising_Interval_Min = Advertising_Interval_Min; - index_input += 2; - cp0->Advertising_Interval_Max = Advertising_Interval_Max; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Advertising_Filter_Policy = Advertising_Filter_Policy; - index_input += 1; - cp0->Local_Name_Length = Local_Name_Length; - index_input += 1; - /* var_len_data input */ - { - Osal_MemCpy( (void*)&cp0->Local_Name, (const void*)Local_Name, Local_Name_Length ); - index_input += Local_Name_Length; - { - cp1->Service_Uuid_length = Service_Uuid_length; - } - index_input += 1; - Osal_MemCpy( (void*)&cp1->Service_Uuid_List, (const void*)Service_Uuid_List, Service_Uuid_length ); - index_input += Service_Uuid_length; - { - cp2->Slave_Conn_Interval_Min = Slave_Conn_Interval_Min; - } - index_input += 2; - { - cp2->Slave_Conn_Interval_Max = Slave_Conn_Interval_Max; - } - index_input += 2; - } - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x082; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_set_discoverable( uint8_t Advertising_Type, - uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Own_Address_Type, - uint8_t Advertising_Filter_Policy, - uint8_t Local_Name_Length, - const uint8_t* Local_Name, - uint8_t Service_Uuid_length, - const uint8_t* Service_Uuid_List, - uint16_t Slave_Conn_Interval_Min, - uint16_t Slave_Conn_Interval_Max ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_discoverable_cp0 *cp0 = (aci_gap_set_discoverable_cp0*)(cmd_buffer); - aci_gap_set_discoverable_cp1 *cp1 = (aci_gap_set_discoverable_cp1*)(cmd_buffer + 1 + 2 + 2 + 1 + 1 + 1 + Local_Name_Length * (sizeof(uint8_t))); - aci_gap_set_discoverable_cp2 *cp2 = (aci_gap_set_discoverable_cp2*)(cmd_buffer + 1 + 2 + 2 + 1 + 1 + 1 + Local_Name_Length * (sizeof(uint8_t)) + 1 + Service_Uuid_length * (sizeof(uint8_t))); - tBleStatus status = 0; - int index_input = 0; - cp0->Advertising_Type = Advertising_Type; - index_input += 1; - cp0->Advertising_Interval_Min = Advertising_Interval_Min; - index_input += 2; - cp0->Advertising_Interval_Max = Advertising_Interval_Max; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Advertising_Filter_Policy = Advertising_Filter_Policy; - index_input += 1; - cp0->Local_Name_Length = Local_Name_Length; - index_input += 1; - /* var_len_data input */ - { - Osal_MemCpy( (void*)&cp0->Local_Name, (const void*)Local_Name, Local_Name_Length ); - index_input += Local_Name_Length; - { - cp1->Service_Uuid_length = Service_Uuid_length; - } - index_input += 1; - Osal_MemCpy( (void*)&cp1->Service_Uuid_List, (const void*)Service_Uuid_List, Service_Uuid_length ); - index_input += Service_Uuid_length; - { - cp2->Slave_Conn_Interval_Min = Slave_Conn_Interval_Min; - } - index_input += 2; - { - cp2->Slave_Conn_Interval_Max = Slave_Conn_Interval_Max; - } - index_input += 2; - } - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x083; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_set_direct_connectable( uint8_t Own_Address_Type, - uint8_t Directed_Advertising_Type, - uint8_t Direct_Address_Type, - const uint8_t* Direct_Address, - uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_direct_connectable_cp0 *cp0 = (aci_gap_set_direct_connectable_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Directed_Advertising_Type = Directed_Advertising_Type; - index_input += 1; - cp0->Direct_Address_Type = Direct_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Direct_Address, (const void*)Direct_Address, 6 ); - index_input += 6; - cp0->Advertising_Interval_Min = Advertising_Interval_Min; - index_input += 2; - cp0->Advertising_Interval_Max = Advertising_Interval_Max; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x084; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_set_io_capability( uint8_t IO_Capability ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_io_capability_cp0 *cp0 = (aci_gap_set_io_capability_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->IO_Capability = IO_Capability; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x085; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_set_authentication_requirement( uint8_t Bonding_Mode, - uint8_t MITM_Mode, - uint8_t SC_Support, - uint8_t KeyPress_Notification_Support, - uint8_t Min_Encryption_Key_Size, - uint8_t Max_Encryption_Key_Size, - uint8_t Use_Fixed_Pin, - uint32_t Fixed_Pin, - uint8_t Identity_Address_Type ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_authentication_requirement_cp0 *cp0 = (aci_gap_set_authentication_requirement_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Bonding_Mode = Bonding_Mode; - index_input += 1; - cp0->MITM_Mode = MITM_Mode; - index_input += 1; - cp0->SC_Support = SC_Support; - index_input += 1; - cp0->KeyPress_Notification_Support = KeyPress_Notification_Support; - index_input += 1; - cp0->Min_Encryption_Key_Size = Min_Encryption_Key_Size; - index_input += 1; - cp0->Max_Encryption_Key_Size = Max_Encryption_Key_Size; - index_input += 1; - cp0->Use_Fixed_Pin = Use_Fixed_Pin; - index_input += 1; - cp0->Fixed_Pin = Fixed_Pin; - index_input += 4; - cp0->Identity_Address_Type = Identity_Address_Type; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x086; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_set_authorization_requirement( uint16_t Connection_Handle, - uint8_t Authorization_Enable ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_authorization_requirement_cp0 *cp0 = (aci_gap_set_authorization_requirement_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Authorization_Enable = Authorization_Enable; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x087; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_pass_key_resp( uint16_t Connection_Handle, - uint32_t Pass_Key ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_pass_key_resp_cp0 *cp0 = (aci_gap_pass_key_resp_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Pass_Key = Pass_Key; - index_input += 4; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x088; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_authorization_resp( uint16_t Connection_Handle, - uint8_t Authorize ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_authorization_resp_cp0 *cp0 = (aci_gap_authorization_resp_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Authorize = Authorize; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x089; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_init( uint8_t Role, - uint8_t privacy_enabled, - uint8_t device_name_char_len, - uint16_t* Service_Handle, - uint16_t* Dev_Name_Char_Handle, - uint16_t* Appearance_Char_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_init_cp0 *cp0 = (aci_gap_init_cp0*)(cmd_buffer); - aci_gap_init_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Role = Role; - index_input += 1; - cp0->privacy_enabled = privacy_enabled; - index_input += 1; - cp0->device_name_char_len = device_name_char_len; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x08a; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Service_Handle = resp.Service_Handle; - *Dev_Name_Char_Handle = resp.Dev_Name_Char_Handle; - *Appearance_Char_Handle = resp.Appearance_Char_Handle; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gap_set_non_connectable( uint8_t Advertising_Event_Type, - uint8_t Own_Address_Type ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_non_connectable_cp0 *cp0 = (aci_gap_set_non_connectable_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Advertising_Event_Type = Advertising_Event_Type; - index_input += 1; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x08b; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_set_undirected_connectable( uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Own_Address_Type, - uint8_t Adv_Filter_Policy ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_undirected_connectable_cp0 *cp0 = (aci_gap_set_undirected_connectable_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Advertising_Interval_Min = Advertising_Interval_Min; - index_input += 2; - cp0->Advertising_Interval_Max = Advertising_Interval_Max; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Adv_Filter_Policy = Adv_Filter_Policy; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x08c; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_slave_security_req( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_slave_security_req_cp0 *cp0 = (aci_gap_slave_security_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x08d; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_update_adv_data( uint8_t AdvDataLen, - const uint8_t* AdvData ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_update_adv_data_cp0 *cp0 = (aci_gap_update_adv_data_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->AdvDataLen = AdvDataLen; - index_input += 1; - Osal_MemCpy( (void*)&cp0->AdvData, (const void*)AdvData, AdvDataLen ); - index_input += AdvDataLen; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x08e; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_delete_ad_type( uint8_t ADType ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_delete_ad_type_cp0 *cp0 = (aci_gap_delete_ad_type_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->ADType = ADType; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x08f; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_get_security_level( uint16_t Connection_Handle, - uint8_t* Security_Mode, - uint8_t* Security_Level ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_get_security_level_cp0 *cp0 = (aci_gap_get_security_level_cp0*)(cmd_buffer); - aci_gap_get_security_level_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x090; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Security_Mode = resp.Security_Mode; - *Security_Level = resp.Security_Level; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gap_set_event_mask( uint16_t GAP_Evt_Mask ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_event_mask_cp0 *cp0 = (aci_gap_set_event_mask_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->GAP_Evt_Mask = GAP_Evt_Mask; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x091; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_configure_whitelist( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x092; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_terminate( uint16_t Connection_Handle, - uint8_t Reason ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_terminate_cp0 *cp0 = (aci_gap_terminate_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Reason = Reason; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x093; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_clear_security_db( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x094; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_allow_rebond( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_allow_rebond_cp0 *cp0 = (aci_gap_allow_rebond_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x095; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_start_limited_discovery_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Filter_Duplicates ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_start_limited_discovery_proc_cp0 *cp0 = (aci_gap_start_limited_discovery_proc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Filter_Duplicates = Filter_Duplicates; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x096; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_start_general_discovery_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Filter_Duplicates ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_start_general_discovery_proc_cp0 *cp0 = (aci_gap_start_general_discovery_proc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Filter_Duplicates = Filter_Duplicates; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x097; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_start_name_discovery_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Peer_Address_Type, - const uint8_t* Peer_Address, - uint8_t Own_Address_Type, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_start_name_discovery_proc_cp0 *cp0 = (aci_gap_start_name_discovery_proc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Peer_Address_Type = Peer_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Address, (const void*)Peer_Address, 6 ); - index_input += 6; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Conn_Interval_Min = Conn_Interval_Min; - index_input += 2; - cp0->Conn_Interval_Max = Conn_Interval_Max; - index_input += 2; - cp0->Conn_Latency = Conn_Latency; - index_input += 2; - cp0->Supervision_Timeout = Supervision_Timeout; - index_input += 2; - cp0->Minimum_CE_Length = Minimum_CE_Length; - index_input += 2; - cp0->Maximum_CE_Length = Maximum_CE_Length; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x098; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_start_auto_connection_establish_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length, - uint8_t Num_of_Whitelist_Entries, - const Whitelist_Entry_t* Whitelist_Entry ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_start_auto_connection_establish_proc_cp0 *cp0 = (aci_gap_start_auto_connection_establish_proc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Conn_Interval_Min = Conn_Interval_Min; - index_input += 2; - cp0->Conn_Interval_Max = Conn_Interval_Max; - index_input += 2; - cp0->Conn_Latency = Conn_Latency; - index_input += 2; - cp0->Supervision_Timeout = Supervision_Timeout; - index_input += 2; - cp0->Minimum_CE_Length = Minimum_CE_Length; - index_input += 2; - cp0->Maximum_CE_Length = Maximum_CE_Length; - index_input += 2; - cp0->Num_of_Whitelist_Entries = Num_of_Whitelist_Entries; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Whitelist_Entry, (const void*)Whitelist_Entry, Num_of_Whitelist_Entries * (sizeof(Whitelist_Entry_t)) ); - index_input += Num_of_Whitelist_Entries * (sizeof(Whitelist_Entry_t)); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x099; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_start_general_connection_establish_proc( uint8_t LE_Scan_Type, - uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Scanning_Filter_Policy, - uint8_t Filter_Duplicates ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_start_general_connection_establish_proc_cp0 *cp0 = (aci_gap_start_general_connection_establish_proc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Type = LE_Scan_Type; - index_input += 1; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Scanning_Filter_Policy = Scanning_Filter_Policy; - index_input += 1; - cp0->Filter_Duplicates = Filter_Duplicates; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x09a; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_start_selective_connection_establish_proc( uint8_t LE_Scan_Type, - uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Scanning_Filter_Policy, - uint8_t Filter_Duplicates, - uint8_t Num_of_Whitelist_Entries, - const Whitelist_Entry_t* Whitelist_Entry ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_start_selective_connection_establish_proc_cp0 *cp0 = (aci_gap_start_selective_connection_establish_proc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Type = LE_Scan_Type; - index_input += 1; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Scanning_Filter_Policy = Scanning_Filter_Policy; - index_input += 1; - cp0->Filter_Duplicates = Filter_Duplicates; - index_input += 1; - cp0->Num_of_Whitelist_Entries = Num_of_Whitelist_Entries; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Whitelist_Entry, (const void*)Whitelist_Entry, Num_of_Whitelist_Entries * (sizeof(Whitelist_Entry_t)) ); - index_input += Num_of_Whitelist_Entries * (sizeof(Whitelist_Entry_t)); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x09b; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_create_connection( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Peer_Address_Type, - const uint8_t* Peer_Address, - uint8_t Own_Address_Type, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_create_connection_cp0 *cp0 = (aci_gap_create_connection_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Peer_Address_Type = Peer_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Address, (const void*)Peer_Address, 6 ); - index_input += 6; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Conn_Interval_Min = Conn_Interval_Min; - index_input += 2; - cp0->Conn_Interval_Max = Conn_Interval_Max; - index_input += 2; - cp0->Conn_Latency = Conn_Latency; - index_input += 2; - cp0->Supervision_Timeout = Supervision_Timeout; - index_input += 2; - cp0->Minimum_CE_Length = Minimum_CE_Length; - index_input += 2; - cp0->Maximum_CE_Length = Maximum_CE_Length; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x09c; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_terminate_gap_proc( uint8_t Procedure_Code ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_terminate_gap_proc_cp0 *cp0 = (aci_gap_terminate_gap_proc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Procedure_Code = Procedure_Code; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x09d; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_start_connection_update( uint16_t Connection_Handle, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_start_connection_update_cp0 *cp0 = (aci_gap_start_connection_update_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Conn_Interval_Min = Conn_Interval_Min; - index_input += 2; - cp0->Conn_Interval_Max = Conn_Interval_Max; - index_input += 2; - cp0->Conn_Latency = Conn_Latency; - index_input += 2; - cp0->Supervision_Timeout = Supervision_Timeout; - index_input += 2; - cp0->Minimum_CE_Length = Minimum_CE_Length; - index_input += 2; - cp0->Maximum_CE_Length = Maximum_CE_Length; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x09e; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_send_pairing_req( uint16_t Connection_Handle, - uint8_t Force_Rebond ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_send_pairing_req_cp0 *cp0 = (aci_gap_send_pairing_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Force_Rebond = Force_Rebond; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x09f; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_resolve_private_addr( const uint8_t* Address, - uint8_t* Actual_Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_resolve_private_addr_cp0 *cp0 = (aci_gap_resolve_private_addr_cp0*)(cmd_buffer); - aci_gap_resolve_private_addr_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - Osal_MemCpy( (void*)&cp0->Address, (const void*)Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a0; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)Actual_Address, (const void*)resp.Actual_Address, 6 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gap_set_broadcast_mode( uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Advertising_Type, - uint8_t Own_Address_Type, - uint8_t Adv_Data_Length, - const uint8_t* Adv_Data, - uint8_t Num_of_Whitelist_Entries, - const Whitelist_Entry_t* Whitelist_Entry ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_broadcast_mode_cp0 *cp0 = (aci_gap_set_broadcast_mode_cp0*)(cmd_buffer); - aci_gap_set_broadcast_mode_cp1 *cp1 = (aci_gap_set_broadcast_mode_cp1*)(cmd_buffer + 2 + 2 + 1 + 1 + 1 + Adv_Data_Length * (sizeof(uint8_t))); - tBleStatus status = 0; - int index_input = 0; - cp0->Advertising_Interval_Min = Advertising_Interval_Min; - index_input += 2; - cp0->Advertising_Interval_Max = Advertising_Interval_Max; - index_input += 2; - cp0->Advertising_Type = Advertising_Type; - index_input += 1; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Adv_Data_Length = Adv_Data_Length; - index_input += 1; - /* var_len_data input */ - { - Osal_MemCpy( (void*)&cp0->Adv_Data, (const void*)Adv_Data, Adv_Data_Length ); - index_input += Adv_Data_Length; - { - cp1->Num_of_Whitelist_Entries = Num_of_Whitelist_Entries; - } - index_input += 1; - Osal_MemCpy( (void*)&cp1->Whitelist_Entry, (const void*)Whitelist_Entry, Num_of_Whitelist_Entries * (sizeof(Whitelist_Entry_t)) ); - index_input += Num_of_Whitelist_Entries * (sizeof(Whitelist_Entry_t)); - } - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a1; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_start_observation_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t LE_Scan_Type, - uint8_t Own_Address_Type, - uint8_t Filter_Duplicates, - uint8_t Scanning_Filter_Policy ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_start_observation_proc_cp0 *cp0 = (aci_gap_start_observation_proc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->LE_Scan_Type = LE_Scan_Type; - index_input += 1; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Filter_Duplicates = Filter_Duplicates; - index_input += 1; - cp0->Scanning_Filter_Policy = Scanning_Filter_Policy; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a2; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_get_bonded_devices( uint8_t* Num_of_Addresses, - Bonded_Device_Entry_t* Bonded_Device_Entry ) -{ - struct hci_request rq; - aci_gap_get_bonded_devices_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a3; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Num_of_Addresses = resp.Num_of_Addresses; - Osal_MemCpy( (void*)Bonded_Device_Entry, (const void*)resp.Bonded_Device_Entry, *Num_of_Addresses * (sizeof(Bonded_Device_Entry_t)) ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gap_is_device_bonded( uint8_t Peer_Address_Type, - const uint8_t* Peer_Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_is_device_bonded_cp0 *cp0 = (aci_gap_is_device_bonded_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Peer_Address_Type = Peer_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Address, (const void*)Peer_Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a4; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_numeric_comparison_value_confirm_yesno( uint16_t Connection_Handle, - uint8_t Confirm_Yes_No ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_numeric_comparison_value_confirm_yesno_cp0 *cp0 = (aci_gap_numeric_comparison_value_confirm_yesno_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Confirm_Yes_No = Confirm_Yes_No; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a5; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_passkey_input( uint16_t Connection_Handle, - uint8_t Input_Type ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_passkey_input_cp0 *cp0 = (aci_gap_passkey_input_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Input_Type = Input_Type; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a6; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_get_oob_data( uint8_t OOB_Data_Type, - uint8_t* Address_Type, - uint8_t* Address, - uint8_t* OOB_Data_Len, - uint8_t* OOB_Data ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_get_oob_data_cp0 *cp0 = (aci_gap_get_oob_data_cp0*)(cmd_buffer); - aci_gap_get_oob_data_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->OOB_Data_Type = OOB_Data_Type; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a7; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Address_Type = resp.Address_Type; - Osal_MemCpy( (void*)Address, (const void*)resp.Address, 6 ); - *OOB_Data_Len = resp.OOB_Data_Len; - Osal_MemCpy( (void*)OOB_Data, (const void*)resp.OOB_Data, 16 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gap_set_oob_data( uint8_t Device_Type, - uint8_t Address_Type, - const uint8_t* Address, - uint8_t OOB_Data_Type, - uint8_t OOB_Data_Len, - const uint8_t* OOB_Data ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_set_oob_data_cp0 *cp0 = (aci_gap_set_oob_data_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Device_Type = Device_Type; - index_input += 1; - cp0->Address_Type = Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Address, (const void*)Address, 6 ); - index_input += 6; - cp0->OOB_Data_Type = OOB_Data_Type; - index_input += 1; - cp0->OOB_Data_Len = OOB_Data_Len; - index_input += 1; - Osal_MemCpy( (void*)&cp0->OOB_Data, (const void*)OOB_Data, 16 ); - index_input += 16; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a8; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_add_devices_to_resolving_list( uint8_t Num_of_Resolving_list_Entries, - const Whitelist_Identity_Entry_t* Whitelist_Identity_Entry, - uint8_t Clear_Resolving_List ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_add_devices_to_resolving_list_cp0 *cp0 = (aci_gap_add_devices_to_resolving_list_cp0*)(cmd_buffer); - aci_gap_add_devices_to_resolving_list_cp1 *cp1 = (aci_gap_add_devices_to_resolving_list_cp1*)(cmd_buffer + 1 + Num_of_Resolving_list_Entries * (sizeof(Whitelist_Identity_Entry_t))); - tBleStatus status = 0; - int index_input = 0; - cp0->Num_of_Resolving_list_Entries = Num_of_Resolving_list_Entries; - index_input += 1; - /* var_len_data input */ - { - Osal_MemCpy( (void*)&cp0->Whitelist_Identity_Entry, (const void*)Whitelist_Identity_Entry, Num_of_Resolving_list_Entries * (sizeof(Whitelist_Identity_Entry_t)) ); - index_input += Num_of_Resolving_list_Entries * (sizeof(Whitelist_Identity_Entry_t)); - { - cp1->Clear_Resolving_List = Clear_Resolving_List; - } - index_input += 1; - } - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0a9; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gap_remove_bonded_device( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gap_remove_bonded_device_cp0 *cp0 = (aci_gap_remove_bonded_device_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Peer_Identity_Address_Type = Peer_Identity_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Identity_Address, (const void*)Peer_Identity_Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x0aa; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - diff --git a/lib_blewbxx/core/auto/ble_gap_aci.h b/lib_blewbxx/core/auto/ble_gap_aci.h deleted file mode 100644 index 0e663dd29..000000000 --- a/lib_blewbxx/core/auto/ble_gap_aci.h +++ /dev/null @@ -1,1551 +0,0 @@ -/****************************************************************************** - * @file ble_gap_aci.h - * @author MCD - * @brief STM32WB BLE API (gap_aci) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_GAP_ACI_H__ -#define BLE_GAP_ACI_H__ - - -#include "ble_types.h" - -/** - * @brief ACI_GAP_SET_NON_DISCOVERABLE - * Put the device in non-discoverable mode. This command disables the LL - * advertising. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_non_discoverable( void ); - -/** - * @brief ACI_GAP_SET_LIMITED_DISCOVERABLE - * Put the device in limited discoverable mode (as defined in Bluetooth - * Specification v.5.0, Vol. 3, Part C, section 9.2.3). The device will be - * discoverable for maximum period of TGAP (lim_adv_timeout) = 180 seconds - * (from errata). The advertising can be disabled at any time by issuing - * ACI_GAP_SET_NON_DISCOVERABLE command. - * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both - * are set to 0, the GAP will use default values for adv intervals for limited - * discoverable mode (250 ms and 500 ms respectively). - * To allow a fast connection, the host can set Local_Name, Service_Uuid_List, - * Slave_Conn_Interval_Min and Slave_Conn_Interval_Max. If provided, these data - * will be inserted into the advertising packet payload as AD data. These - * parameters are optional in this command. These values can be set in - * advertised data using ACI_GAP_UPDATE_ADV_DATA command separately. - * The total size of data in advertising packet cannot exceed 31 bytes. - * With this command, the BLE Stack will also add automatically the following - * standard AD types: - * - AD Flags - * - Power Level - * When advertising timeout happens (i.e. limited discovery period has - * elapsed), controller generates ACI_GAP_LIMITED_DISCOVERABLE_EVENT event. - * - * @param Advertising_Type Advertising type - * Values: - * - 0x00: ADV_IND (Connectable undirected advertising) - * - 0x02: ADV_SCAN_IND (Scannable undirected advertising) - * - 0x03: ADV_NONCONN_IND (Non connectable undirected advertising) - * @param Advertising_Interval_Min Minimum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Advertising_Interval_Max Maximum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Advertising_Filter_Policy Advertising filter policy: not applicable - * (the value of Advertising_Filter_Policy parameter is not used inside - * the Stack) - * @param Local_Name_Length Length of the local_name field in octets. - * If length is set to 0x00, Local_Name parameter is not used. - * @param Local_Name Local name of the device. First byte must be 0x08 for - * Shortened Local Name or 0x09 for Complete Local Name. No NULL - * character at the end. - * @param Service_Uuid_length Length of the Service Uuid List in octets. - * If there is no service to be advertised, set this field to 0x00. - * @param Service_Uuid_List This is the list of the UUIDs as defined in Volume - * 3, Section 11 of GAP Specification. First byte is the AD Type. - * See also Supplement to the Bluetooth Core 5.0 specification. - * @param Slave_Conn_Interval_Min Slave connection interval minimum value - * suggested by Peripheral. - * If Slave_Conn_Interval_Min and Slave_Conn_Interval_Max are not - * 0x0000, Slave Connection Interval Range AD structure will be added in - * advertising data. - * Connection interval is defined in the following manner: - * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms. - * Values: - * - 0x0000 (NaN) - * - 0xFFFF (NaN) : No specific minimum - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Slave_Conn_Interval_Max Slave connection interval maximum value - * suggested by Peripheral. - * If Slave_Conn_Interval_Min and Slave_Conn_Interval_Max are not - * 0x0000, Slave Connection Interval Range AD structure will be added in - * advertising data. - * Connection interval is defined in the following manner: - * connIntervalmax = Slave_Conn_Interval_Max x 1.25ms - * Values: - * - 0x0000 (NaN) - * - 0xFFFF (NaN) : No specific maximum - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_limited_discoverable( uint8_t Advertising_Type, - uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Own_Address_Type, - uint8_t Advertising_Filter_Policy, - uint8_t Local_Name_Length, - const uint8_t* Local_Name, - uint8_t Service_Uuid_length, - const uint8_t* Service_Uuid_List, - uint16_t Slave_Conn_Interval_Min, - uint16_t Slave_Conn_Interval_Max ); - -/** - * @brief ACI_GAP_SET_DISCOVERABLE - * Put the device in general discoverable mode (as defined in Bluetooth - * Specification v.5.0, Vol. 3, Part C, section 9.2.4). The device will be - * discoverable until the host issues the ACI_GAP_SET_NON_DISCOVERABLE command. - * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both - * are set to 0, the GAP uses the default values for adv intervals for general - * discoverable mode. - * When using connectable undirected advertising events: - * - Adv_Interval_Min = 30 ms - * - Adv_Interval_Max = 60 ms - * When using non-connectable advertising events or scannable undirected - * advertising events: - * - Adv_Interval_Min = 100 ms - * - Adv_Interval_Max = 150 ms - * Host can set the Local Name, a Service UUID list and the Slave Connection - * Interval Range. - * If provided, these data will be inserted into the advertising packet payload - * as AD data. - * These parameters are optional in this command. These values can be also set - * using ACI_GAP_UPDATE_ADV_DATA command separately. - * The total size of data in advertising packet cannot exceed 31 bytes. - * With this command, the BLE Stack will also add automatically the following - * standard AD types: - * - AD Flags - * - TX Power Level - * - * @param Advertising_Type Advertising type - * Values: - * - 0x00: ADV_IND (Connectable undirected advertising) - * - 0x02: ADV_SCAN_IND (Scannable undirected advertising) - * - 0x03: ADV_NONCONN_IND (Non connectable undirected advertising) - * @param Advertising_Interval_Min Minimum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Advertising_Interval_Max Maximum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Advertising_Filter_Policy Advertising filter policy: not applicable - * (the value of Advertising_Filter_Policy parameter is not used inside - * the Stack) - * @param Local_Name_Length Length of the local_name field in octets. - * If length is set to 0x00, Local_Name parameter is not used. - * @param Local_Name Local name of the device. First byte must be 0x08 for - * Shortened Local Name or 0x09 for Complete Local Name. No NULL - * character at the end. - * @param Service_Uuid_length Length of the Service Uuid List in octets. - * If there is no service to be advertised, set this field to 0x00. - * @param Service_Uuid_List This is the list of the UUIDs as defined in Volume - * 3, Section 11 of GAP Specification. First byte is the AD Type. - * See also Supplement to the Bluetooth Core 5.0 specification. - * @param Slave_Conn_Interval_Min Slave connection interval minimum value - * suggested by Peripheral. - * If Slave_Conn_Interval_Min and Slave_Conn_Interval_Max are not - * 0x0000, Slave Connection Interval Range AD structure will be added in - * advertising data. - * Connection interval is defined in the following manner: - * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms. - * Values: - * - 0x0000 (NaN) - * - 0xFFFF (NaN) : No specific minimum - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Slave_Conn_Interval_Max Slave connection interval maximum value - * suggested by Peripheral. - * If Slave_Conn_Interval_Min and Slave_Conn_Interval_Max are not - * 0x0000, Slave Connection Interval Range AD structure will be added in - * advertising data. - * Connection interval is defined in the following manner: - * connIntervalmax = Slave_Conn_Interval_Max x 1.25ms - * Values: - * - 0x0000 (NaN) - * - 0xFFFF (NaN) : No specific maximum - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_discoverable( uint8_t Advertising_Type, - uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Own_Address_Type, - uint8_t Advertising_Filter_Policy, - uint8_t Local_Name_Length, - const uint8_t* Local_Name, - uint8_t Service_Uuid_length, - const uint8_t* Service_Uuid_List, - uint16_t Slave_Conn_Interval_Min, - uint16_t Slave_Conn_Interval_Max ); - -/** - * @brief ACI_GAP_SET_DIRECT_CONNECTABLE - * Set the device in direct connectable mode (as defined in Bluetooth - * Specification v.5.0, Vol. 3, Part C, section 9.3.3). Device uses direct - * connectable mode to advertise using High Duty cycle advertisement events or - * Low Duty cycle advertisement events and the address as either what is - * specified in the Own Address Type parameter. The command specifies the type - * of the advertising used. - * If the privacy is enabled, the Type parameter in reconnection address is - * used for advertising, otherwise the address of the type specified in - * OwnAddrType is used. - * The device stays in directed connectable mode only for 1.28 seconds. If no - * connection is established within this duration, the device enters non - * discoverable mode and advertising has to be again enabled explicitly. - * The controller generates a HCI_LE_CONNECTION_COMPLETE_EVENT event with the - * status set to HCI_ADVERTISING_TIMEOUT_ERR_CODE if the connection was not - * established and BLE_STATUS_SUCCESS (0x00) if the connection was successfully - * established. - * If Host privacy is enabled this command returns BLE_STATUS_INVALID_PARAMS. - * - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * @param Directed_Advertising_Type Advertising type - * Values: - * - 0x01: High Duty Cycle Directed Advertising - * - 0x04: Low Duty Cycle Directed Advertising - * @param Direct_Address_Type The address type of the peer device. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * @param Direct_Address Initiator Bluetooth address - * @param Advertising_Interval_Min Minimum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0006 (3.750 ms) : for High Duty Cycle Directed Advertising - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) : for Low Duty Cycle - * Directed Advertising - * @param Advertising_Interval_Max Maximum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0006 (3.750 ms) : for High Duty Cycle Directed Advertising - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) : for Low Duty Cycle - * Directed Advertising - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_direct_connectable( uint8_t Own_Address_Type, - uint8_t Directed_Advertising_Type, - uint8_t Direct_Address_Type, - const uint8_t* Direct_Address, - uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max ); - -/** - * @brief ACI_GAP_SET_IO_CAPABILITY - * Set the IO capabilities of the device. This command has to be given only - * when the device is not in a connected state. - * - * @param IO_Capability IO capability of the device. - * Values: - * - 0x00: IO_CAP_DISPLAY_ONLY - * - 0x01: IO_CAP_DISPLAY_YES_NO - * - 0x02: IO_CAP_KEYBOARD_ONLY - * - 0x03: IO_CAP_NO_INPUT_NO_OUTPUT - * - 0x04: IO_CAP_KEYBOARD_DISPLAY - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_io_capability( uint8_t IO_Capability ); - -/** - * @brief ACI_GAP_SET_AUTHENTICATION_REQUIREMENT - * Set the authentication requirements for the device. If the OOB_Enable is set - * to 0, the following 16 octets of OOB_Data will be ignored on reception. This - * command has to be given only when the device is not in a connected state. - * - * @param Bonding_Mode Bonding mode. - * Only if bonding is enabled (0x01), the bonding information is stored - * in flash - * Values: - * - 0x00: No-bonding mode - * - 0x01: Bonding mode - * @param MITM_Mode MITM mode. - * Values: - * - 0x00: MITM protection not required - * - 0x01: MITM protection required - * @param SC_Support LE Secure connections support - * Values: - * - 0x00: Secure Connections Pairing not supported - * - 0x01: Secure Connections Pairing supported but optional - * - 0x02: Secure Connections Pairing supported and mandatory (SC Only - * Mode) - * @param KeyPress_Notification_Support Keypress notification support - * Values: - * - 0x00: Keypress notification not supported - * - 0x01: Keypress notification supported - * @param Min_Encryption_Key_Size Minimum encryption key size to be used during - * pairing - * @param Max_Encryption_Key_Size Maximum encryption key size to be used during - * pairing - * @param Use_Fixed_Pin Use or not fixed pin. If set to 0x00, then during the - * pairing process the application will not be requested for a pin - * (Fixed_Pin will be used). - * If set to 0x01, then during pairing process if a passkey is required - * the application will be notified - * Values: - * - 0x00: use a fixed pin - * - 0x01: do not use a fixed pin - * @param Fixed_Pin Fixed pin to be used during pairing if MIMT protection is - * enabled. - * Any random value between 0 to 999999 - * Values: - * - 0 ... 999999 - * @param Identity_Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_authentication_requirement( uint8_t Bonding_Mode, - uint8_t MITM_Mode, - uint8_t SC_Support, - uint8_t KeyPress_Notification_Support, - uint8_t Min_Encryption_Key_Size, - uint8_t Max_Encryption_Key_Size, - uint8_t Use_Fixed_Pin, - uint32_t Fixed_Pin, - uint8_t Identity_Address_Type ); - -/** - * @brief ACI_GAP_SET_AUTHORIZATION_REQUIREMENT - * Set the authorization requirements of the device. This command has to be - * given when connected to a device if authorization is required to access - * services which require authorization. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Authorization_Enable Enable the authorization in the device and when - * a remote device tries to read/write a characteristic with - * authorization requirements, the stack will send back an error - * response with "Insufficient authorization" error code. After pairing - * is complete an ACI_GAP_AUTHORIZATION_REQ_EVENT will be sent to the - * Host. - * Values: - * - 0x00: Authorization not required - * - 0x01: Authorization required - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_authorization_requirement( uint16_t Connection_Handle, - uint8_t Authorization_Enable ); - -/** - * @brief ACI_GAP_PASS_KEY_RESP - * This command should be send by the host in response to - * ACI_GAP_PASS_KEY_REQ_EVENT event. The command parameter contains the pass - * key which will be used during the pairing process. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Pass_Key Pass key that will be used during the pairing process. - * Must be a six-digit decimal number. - * Values: - * - 0 ... 999999 - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_pass_key_resp( uint16_t Connection_Handle, - uint32_t Pass_Key ); - -/** - * @brief ACI_GAP_AUTHORIZATION_RESP - * Authorize a device to access attributes. This command should be send by the - * host in response to ACI_GAP_AUTHORIZATION_REQ_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Authorize Authorization response. - * Values: - * - 0x01: Authorize - * - 0x02: Reject - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_authorization_resp( uint16_t Connection_Handle, - uint8_t Authorize ); - -/** - * @brief ACI_GAP_INIT - * Initialize the GAP layer. Register the GAP service with the GATT. - * All the standard GAP characteristics will also be added: - * - Device Name - * - Appearance - * - Peripheral Preferred Connection Parameters (peripheral role only). - * Note that if the Peripheral Preferred Connection Parameters characteristic - * is added, its handle is equal to the Appearance characteristic handle plus - * 2. - * - * @param Role Bitmap of allowed roles. - * Flags: - * - 0x01: Peripheral - * - 0x02: Broadcaster - * - 0x04: Central - * - 0x08: Observer - * @param privacy_enabled Specify if privacy is enabled or not and which one . - * Values: - * - 0x00: Privacy disabled - * - 0x01: Privacy host enabled - * - 0x02: Privacy controller enabled - * @param device_name_char_len Length of the device name characteristic - * @param[out] Service_Handle Handle of the GAP service - * @param[out] Dev_Name_Char_Handle Device Name Characteristic handle - * @param[out] Appearance_Char_Handle Appearance Characteristic handle - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_init( uint8_t Role, - uint8_t privacy_enabled, - uint8_t device_name_char_len, - uint16_t* Service_Handle, - uint16_t* Dev_Name_Char_Handle, - uint16_t* Appearance_Char_Handle ); - -/** - * @brief ACI_GAP_SET_NON_CONNECTABLE - * Put the device into non connectable mode. This mode does not support - * connection. The privacy setting done in the ACI_GAP_INIT command plays a - * role in deciding the valid parameters for this command. - * Advertiser filter policy is internally set to 0. - * - * @param Advertising_Event_Type Advertising type - * Values: - * - 0x02: ADV_SCAN_IND (Scannable undirected advertising) - * - 0x03: ADV_NONCONN_IND (Non connectable undirected advertising) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_non_connectable( uint8_t Advertising_Event_Type, - uint8_t Own_Address_Type ); - -/** - * @brief ACI_GAP_SET_UNDIRECTED_CONNECTABLE - * Put the device into undirected connectable mode. - * If privacy is enabled in the device, a resolvable private address is - * generated and used as the advertiser's address. If not, the address of the - * type specified in own_addr_type is used for advertising. - * - * @param Advertising_Interval_Min Minimum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Advertising_Interval_Max Maximum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if Host privacy (i.e. privacy 1.1) is enabled) - * @param Adv_Filter_Policy Advertising filter policy. - * Values: - * - 0x00: Allow Scan Request from Any, Allow Connect Request from Any - * - 0x03: Allow Scan Request from White List Only, Allow Connect - * Request from White List Only - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_undirected_connectable( uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Own_Address_Type, - uint8_t Adv_Filter_Policy ); - -/** - * @brief ACI_GAP_SLAVE_SECURITY_REQ - * Send a slave security request to the master. - * This command has to be issued to notify the master of the security - * requirements of the slave. The master may encrypt the link, initiate the - * pairing procedure, or reject the request. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_slave_security_req( uint16_t Connection_Handle ); - -/** - * @brief ACI_GAP_UPDATE_ADV_DATA - * This command can be used to update the advertising data for a particular AD - * type. If the AD type specified does not exist, then it is added to the - * advertising data. If the overall advertising data length is more than 31 - * octets after the update, then the command is rejected and the old data is - * retained. - * - * @param AdvDataLen Length of AdvData in octets - * @param AdvData Advertising data used by the device while advertising. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_update_adv_data( uint8_t AdvDataLen, - const uint8_t* AdvData ); - -/** - * @brief ACI_GAP_DELETE_AD_TYPE - * This command can be used to delete the specified AD type from the - * advertisement data if present. - * - * @param ADType One of the AD types like in Bluetooth specification (see - * volume 3, Part C, 11.1) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_delete_ad_type( uint8_t ADType ); - -/** - * @brief ACI_GAP_GET_SECURITY_LEVEL - * This command can be used to get the current security settings of the device. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param[out] Security_Mode Security mode. - * Values: - * - 0x01: Security Mode 1 - * - 0x02: Security Mode 2 - * @param[out] Security_Level Security Level. - * Values: - * - 0x01: Security Level 1 - * - 0x02: Security Level 2 - * - 0x03: Security Level 3 - * - 0x04: Security Level 4 - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_get_security_level( uint16_t Connection_Handle, - uint8_t* Security_Mode, - uint8_t* Security_Level ); - -/** - * @brief ACI_GAP_SET_EVENT_MASK - * It allows masking events from the GAP. The default configuration is all the - * events masked. - * - * @param GAP_Evt_Mask GAP event mask. Default: 0xFFFF. - * Flags: - * - 0x0000: No events - * - 0x0001: ACI_GAP_LIMITED_DISCOVERABLE_EVENT - * - 0x0002: ACI_GAP_PAIRING_COMPLETE_EVENT - * - 0x0004: ACI_GAP_PASS_KEY_REQ_EVENT - * - 0x0008: ACI_GAP_AUTHORIZATION_REQ_EVENT - * - 0x0010: ACI_GAP_SLAVE_SECURITY_INITIATED_EVENT - * - 0x0020: ACI_GAP_BOND_LOST_EVENT - * - 0x0080: ACI_GAP_PROC_COMPLETE_EVENT - * - 0x0100: ACI_L2CAP_CONNECTION_UPDATE_REQ_EVENT - * - 0x0200: ACI_L2CAP_CONNECTION_UPDATE_RESP_EVENT - * - 0x0400: ACI_L2CAP_PROC_TIMEOUT_EVENT - * - 0x0800: ACI_GAP_ADDR_NOT_RESOLVED_EVENT - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_event_mask( uint16_t GAP_Evt_Mask ); - -/** - * @brief ACI_GAP_CONFIGURE_WHITELIST - * Add addresses of bonded devices into the controller's whitelist. - * The command returns an error if it was unable to add the bonded devices into - * the whitelist. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_configure_whitelist( void ); - -/** - * @brief ACI_GAP_TERMINATE - * Command the controller to terminate the connection. A - * HCI_DISCONNECTION_COMPLETE_EVENT event is generated when the link is - * disconnected. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Reason The reason for ending the connection. - * Values: - * - 0x05: Authentication Failure - * - 0x13: Remote User Terminated Connection - * - 0x14: Remote Device Terminated Connection due to Low Resources - * - 0x15: Remote Device Terminated Connection due to Power Off - * - 0x1A: Unsupported Remote Feature - * - 0x3B: Unacceptable Connection Parameters - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_terminate( uint16_t Connection_Handle, - uint8_t Reason ); - -/** - * @brief ACI_GAP_CLEAR_SECURITY_DB - * Clear the security database. All the devices in the security database are - * removed. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_clear_security_db( void ); - -/** - * @brief ACI_GAP_ALLOW_REBOND - * Allows the security manager to complete the pairing procedure and re-bond - * with the master. This command should be given by the application when it - * receives the ACI_GAP_BOND_LOST_EVENT if it wants the re-bonding to happen - * successfully. If this command is not given on receiving the event, the - * bonding procedure will timeout. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_allow_rebond( uint16_t Connection_Handle ); - -/** - * @brief ACI_GAP_START_LIMITED_DISCOVERY_PROC - * Start the limited discovery procedure. The controller is commanded to start - * active scanning. - * When this procedure is started, only the devices in limited discoverable - * mode are returned to the upper layers. - * The procedure is terminated when either the upper layers issue a command to - * terminate the procedure by issuing the command ACI_GAP_TERMINATE_GAP_PROC - * with the procedure code set to 0x01 or a timeout happens (the timeout value - * is fixed at 10.24 s.). When the procedure is terminated due to any of the - * above reasons, ACI_GAP_PROC_COMPLETE_EVENT event is returned with the - * procedure code set to 0x01. - * The device found when the procedure is ongoing is returned to the upper - * layers through the event HCI_LE_ADVERTISING_REPORT_EVENT. - * - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Filter_Duplicates Enable/disable duplicate filtering. - * Values: - * - 0x00: Duplicate filtering disabled - * - 0x01: Duplicate filtering enabled - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_limited_discovery_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Filter_Duplicates ); - -/** - * @brief ACI_GAP_START_GENERAL_DISCOVERY_PROC - * Start the general discovery procedure. The controller is commanded to start - * active scanning. The procedure is terminated when either the upper layers - * issue a command to terminate the procedure by issuing the command - * ACI_GAP_TERMINATE_GAP_PROC with the procedure code set to 0x02 or a timeout - * happens (the timeout value is fixed at 10.24 s.). When the procedure is - * terminated due to any of the above reasons, ACI_GAP_PROC_COMPLETE_EVENT - * event is returned with the procedure code set to 0x02. The device found when - * the procedure is ongoing is returned to HCI_LE_ADVERTISING_REPORT_EVENT. - * - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Filter_Duplicates Enable/disable duplicate filtering. - * Values: - * - 0x00: Duplicate filtering disabled - * - 0x01: Duplicate filtering enabled - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_general_discovery_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Filter_Duplicates ); - -/** - * @brief ACI_GAP_START_NAME_DISCOVERY_PROC - * Start the name discovery procedure. A LE_Create_Connection call will be made - * to the controller by GAP with the initiator filter policy set to "ignore - * whitelist and process connectable advertising packets only for the specified - * device". Once a connection is established, GATT procedure is started to read - * the device name characteristic. When the read is completed (successfully or - * unsuccessfully), a ACI_GAP_PROC_COMPLETE_EVENT event is given to the upper - * layer. The event also contains the name of the device if the device name was - * read successfully. - * - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Peer_Address_Type Address type. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * @param Peer_Address Public Device Address or Random Device Address of the - * device to be connected. - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Conn_Interval_Min Minimum value for the connection event interval. - * This shall be less than or equal to Conn_Interval_Max. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Interval_Max Maximum value for the connection event interval. - * This shall be greater than or equal to Conn_Interval_Min. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Latency Slave latency for the connection in number of connection - * events. - * Values: - * - 0x0000 ... 0x01F3 - * @param Supervision_Timeout Supervision timeout for the LE Link. - * It shall be a multiple of 10 ms and larger than (1 + - * connSlaveLatency) * connInterval * 2. - * Time = N * 10 msec. - * Values: - * - 0x000A (100 ms) ... 0x0C80 (32000 ms) - * @param Minimum_CE_Length Information parameter about the minimum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Maximum_CE_Length Information parameter about the maximum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_name_discovery_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Peer_Address_Type, - const uint8_t* Peer_Address, - uint8_t Own_Address_Type, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ); - -/** - * @brief ACI_GAP_START_AUTO_CONNECTION_ESTABLISH_PROC - * Start the auto connection establishment procedure. The devices specified are - * added to the white list of the controller and a LE_Create_Connection call - * will be made to the controller by GAP with the initiator filter policy set - * to "use whitelist to determine which advertiser to connect to". When a - * command is issued to terminate the procedure by upper layer, a - * LE_Create_Connection_Cancel call will be made to the controller by GAP. - * The procedure is terminated when either a connection is successfully - * established with one of the specified devices in the white list or the - * procedure is explicitly terminated by issuing the command - * ACI_GAP_TERMINATE_GAP_PROC with the procedure code set to 0x08. A - * ACI_GAP_PROC_COMPLETE_EVENT event is returned with the procedure code set to - * 0x08. - * If controller privacy is enabled and the peer device (advertiser) is in the - * resolving list then the link layer will generate a RPA, if it is not then - * the RPA/NRPA generated by the Host will be used. - * - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Conn_Interval_Min Minimum value for the connection event interval. - * This shall be less than or equal to Conn_Interval_Max. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Interval_Max Maximum value for the connection event interval. - * This shall be greater than or equal to Conn_Interval_Min. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Latency Slave latency for the connection in number of connection - * events. - * Values: - * - 0x0000 ... 0x01F3 - * @param Supervision_Timeout Supervision timeout for the LE Link. - * It shall be a multiple of 10 ms and larger than (1 + - * connSlaveLatency) * connInterval * 2. - * Time = N * 10 msec. - * Values: - * - 0x000A (100 ms) ... 0x0C80 (32000 ms) - * @param Minimum_CE_Length Information parameter about the minimum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Maximum_CE_Length Information parameter about the maximum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Num_of_Whitelist_Entries Number of devices that have to be added to - * the whitelist. - * @param Whitelist_Entry See @ref Whitelist_Entry_t - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_auto_connection_establish_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length, - uint8_t Num_of_Whitelist_Entries, - const Whitelist_Entry_t* Whitelist_Entry ); - -/** - * @brief ACI_GAP_START_GENERAL_CONNECTION_ESTABLISH_PROC - * Start a general connection establishment procedure. The host enables - * scanning in the controller with the scanner filter policy set to "accept all - * advertising packets" and from the scanning results, all the devices are sent - * to the upper layer using the event LE_Advertising_Report. The upper layer - * then has to select one of the devices to which it wants to connect by - * issuing the command ACI_GAP_CREATE_CONNECTION. If privacy is enabled, then - * either a private resolvable address or a non resolvable address, based on - * the address type specified in the command is set as the scanner address but - * the gap create connection always uses a private resolvable address if the - * general connection establishment procedure is active. - * The procedure is terminated when a connection is established or the upper - * layer terminates the procedure by issuing the command - * ACI_GAP_TERMINATE_GAP_PROC with the procedure code set to 0x10. On - * completion of the procedure a ACI_GAP_PROC_COMPLETE_EVENT event is generated - * with the procedure code set to 0x10. - * If controller privacy is enabled and the peer device (advertiser) is in the - * resolving list then the link layer will generate a RPA, if it is not then - * the RPA/NRPA generated by the Host will be used. - * - * @param LE_Scan_Type Passive or active scanning. With active scanning - * SCAN_REQ packets are sent. - * Values: - * - 0x00: Passive Scanning - * - 0x01: Active scanning - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Scanning_Filter_Policy Scanning filter policy: - * - 0x00 Accept all advertisement packets.Directed advertising packets - * which are not addressed for this device shall be ignored. - * - 0x01 Ignore advertisement packets from devices not in the White - * List Only.Directed advertising packets which are not addressed for - * this device shall be ignored. - * - 0x02 Accept all undirected advertisement packets (it is allowed - * only if controller privacy or host privacy is enabled).Directed - * advertisement packets where initiator address is a RPA and Directed - * advertisement packets addressed to this device shall be accepted. - * - 0x03 Accept all undirected advertisement packets from devices that - * are in the White List.Directed advertisement packets where initiator - * address is RPA and Directed advertisement packets addressed to this - * device shall be accepted. - * - NOTE: if controller privacy is enabled Scanning_Filter_Policy can - * only assume values 0x00 or 0x02; if Host privacy is enabled - * Scanning_Filter_Policy can only assume value 0x00. - * Values: - * - 0x00: Accept all - * - 0x01: Ignore devices not in the White List - * - 0x02: Accept all (use resolving list) - * - 0x03: Ignore devices not in the White List (use resolving list) - * @param Filter_Duplicates Enable/disable duplicate filtering. - * Values: - * - 0x00: Duplicate filtering disabled - * - 0x01: Duplicate filtering enabled - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_general_connection_establish_proc( uint8_t LE_Scan_Type, - uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Scanning_Filter_Policy, - uint8_t Filter_Duplicates ); - -/** - * @brief ACI_GAP_START_SELECTIVE_CONNECTION_ESTABLISH_PROC - * Start a selective connection establishment procedure. The GAP adds the - * specified device addresses into white list and enables scanning in the - * controller with the scanner filter policy set to "accept packets only from - * devices in whitelist". All the devices found are sent to the upper layer by - * the event HCI_LE_ADVERTISING_REPORT_EVENT. The upper layer then has to - * select one of the devices to which it wants to connect by issuing the - * command ACI_GAP_CREATE_CONNECTION. - * On completion of the procedure a ACI_GAP_PROC_COMPLETE_EVENT event is - * generated with the procedure code set to 0x20. The procedure is terminated - * when a connection is established or the upper layer terminates the procedure - * by issuing the command ACI_GAP_TERMINATE_GAP_PROC with the procedure code - * set to 0x20. - * If controller privacy is enabled and the peer device (advertiser) is in the - * resolving list then the link layer will generate a RPA, if it is not then - * the RPA/NRPA generated by the Host will be used. - * - * @param LE_Scan_Type Passive or active scanning. With active scanning - * SCAN_REQ packets are sent. - * Values: - * - 0x00: Passive Scanning - * - 0x01: Active scanning - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Scanning_Filter_Policy Scanning filter policy: - * - 0x00 Accept all advertisement packets.Directed advertising packets - * which are not addressed for this device shall be ignored. - * - 0x01 Ignore advertisement packets from devices not in the White - * List Only.Directed advertising packets which are not addressed for - * this device shall be ignored. - * - 0x02 Accept all undirected advertisement packets (it is allowed - * only if controller privacy or host privacy is enabled).Directed - * advertisement packets where initiator address is a RPA and Directed - * advertisement packets addressed to this device shall be accepted. - * - 0x03 Accept all undirected advertisement packets from devices that - * are in the White List.Directed advertisement packets where initiator - * address is RPA and Directed advertisement packets addressed to this - * device shall be accepted. - * - NOTE: if controller privacy is enabled Scanning_Filter_Policy can - * only assume values 0x01 or 0x03; if Host privacy is enabled - * Scanning_Filter_Policy can only assume value 0x01. - * Values: - * - 0x00: Accept all - * - 0x01: Ignore devices not in the White List - * - 0x02: Accept all (use resolving list) - * - 0x03: Ignore devices not in the White List (use resolving list) - * @param Filter_Duplicates Enable/disable duplicate filtering. - * Values: - * - 0x00: Duplicate filtering disabled - * - 0x01: Duplicate filtering enabled - * @param Num_of_Whitelist_Entries Number of devices that have to be added to - * the whitelist. - * @param Whitelist_Entry See @ref Whitelist_Entry_t - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_selective_connection_establish_proc( uint8_t LE_Scan_Type, - uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Scanning_Filter_Policy, - uint8_t Filter_Duplicates, - uint8_t Num_of_Whitelist_Entries, - const Whitelist_Entry_t* Whitelist_Entry ); - -/** - * @brief ACI_GAP_CREATE_CONNECTION - * Start the direct connection establishment procedure. A LE_Create_Connection - * call will be made to the controller by GAP with the initiator filter policy - * set to "ignore whitelist and process connectable advertising packets only - * for the specified device". The procedure can be terminated explicitly by the - * upper layer by issuing the command ACI_GAP_TERMINATE_GAP_PROC. When a - * command is issued to terminate the procedure by upper layer, a - * HCI_LE_CREATE_CONNECTION_CANCEL call will be made to the controller by GAP. - * On termination of the procedure, a HCI_LE_CONNECTION_COMPLETE_EVENT event is - * returned. The procedure can be explicitly terminated by the upper layer by - * issuing the command ACI_GAP_TERMINATE_GAP_PROC with the procedure_code set - * to 0x40. - * If controller privacy is enabled and the peer device (advertiser) is in the - * resolving list then the link layer will generate a RPA, if it is not then - * the RPA/NRPA generated by the Host will be used. - * - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Peer_Address_Type The address type of the peer device. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * @param Peer_Address Public Device Address or Random Device Address of the - * device to be connected. - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Conn_Interval_Min Minimum value for the connection event interval. - * This shall be less than or equal to Conn_Interval_Max. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Interval_Max Maximum value for the connection event interval. - * This shall be greater than or equal to Conn_Interval_Min. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Latency Slave latency for the connection in number of connection - * events. - * Values: - * - 0x0000 ... 0x01F3 - * @param Supervision_Timeout Supervision timeout for the LE Link. - * It shall be a multiple of 10 ms and larger than (1 + - * connSlaveLatency) * connInterval * 2. - * Time = N * 10 msec. - * Values: - * - 0x000A (100 ms) ... 0x0C80 (32000 ms) - * @param Minimum_CE_Length Information parameter about the minimum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Maximum_CE_Length Information parameter about the maximum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_create_connection( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Peer_Address_Type, - const uint8_t* Peer_Address, - uint8_t Own_Address_Type, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ); - -/** - * @brief ACI_GAP_TERMINATE_GAP_PROC - * Terminate the specified GAP procedure. An ACI_GAP_PROC_COMPLETE_EVENT event - * is returned with the procedure code set to the corresponding procedure. - * - * @param Procedure_Code GAP procedure bitmap. - * Values: - * - 0x00: No events - * - 0x01: GAP_LIMITED_DISCOVERY_PROC - * - 0x02: GAP_GENERAL_DISCOVERY_PROC - * - 0x04: GAP_NAME_DISCOVERY_PROC - * - 0x08: GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC - * - 0x10: GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC - * - 0x20: GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC - * - 0x40: GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC - * - 0x80: GAP_OBSERVATION_PROC - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_terminate_gap_proc( uint8_t Procedure_Code ); - -/** - * @brief ACI_GAP_START_CONNECTION_UPDATE - * Start the connection update procedure (only when role is Master). A - * HCI_LE_CONNECTION_UPDATE is called. - * On completion of the procedure, an HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT - * event is returned to the upper layer. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Conn_Interval_Min Minimum value for the connection event interval. - * This shall be less than or equal to Conn_Interval_Max. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Interval_Max Maximum value for the connection event interval. - * This shall be greater than or equal to Conn_Interval_Min. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Latency Slave latency for the connection in number of connection - * events. - * Values: - * - 0x0000 ... 0x01F3 - * @param Supervision_Timeout Supervision timeout for the LE Link. - * It shall be a multiple of 10 ms and larger than (1 + - * connSlaveLatency) * connInterval * 2. - * Time = N * 10 msec. - * Values: - * - 0x000A (100 ms) ... 0x0C80 (32000 ms) - * @param Minimum_CE_Length Information parameter about the minimum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Maximum_CE_Length Information parameter about the maximum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_connection_update( uint16_t Connection_Handle, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ); - -/** - * @brief ACI_GAP_SEND_PAIRING_REQ - * Send the SM pairing request to start a pairing process. The authentication - * requirements and IO capabilities should be set before issuing this command - * using the ACI_GAP_SET_IO_CAPABILITY and - * ACI_GAP_SET_AUTHENTICATION_REQUIREMENT commands. - * A ACI_GAP_PAIRING_COMPLETE_EVENT event is returned after the pairing process - * is completed. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Force_Rebond If 1, Pairing request will be sent even if the device - * was previously bonded, - * otherwise pairing request is not sent. - * Values: - * - 0x00: NO - * - 0x01: YES - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_send_pairing_req( uint16_t Connection_Handle, - uint8_t Force_Rebond ); - -/** - * @brief ACI_GAP_RESOLVE_PRIVATE_ADDR - * This command tries to resolve the address provided with the IRKs present in - * its database. If the address is resolved successfully with any one of the - * IRKs present in the database, it returns success and also the corresponding - * public/static random address stored with the IRK in the database. - * - * @param Address Address to be resolved - * @param[out] Actual_Address The public or static random address of the peer - * device, distributed during pairing phase. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_resolve_private_addr( const uint8_t* Address, - uint8_t* Actual_Address ); - -/** - * @brief ACI_GAP_SET_BROADCAST_MODE - * This command puts the device into broadcast mode. A privacy enabled device - * uses either a resolvable private address or a non-resolvable private address - * as specified in the Own_Addr_Type parameter of the command. - * - * @param Advertising_Interval_Min Minimum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Advertising_Interval_Max Maximum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Advertising_Type Advertising type - * Values: - * - 0x02: ADV_SCAN_IND (Scannable undirected advertising) - * - 0x03: ADV_NONCONN_IND (Non connectable undirected advertising) - * @param Own_Address_Type If Privacy is disabled, then the address can be - * public or static random. - * If Privacy is enabled, then the address can be a resolvable private - * address or a non-resolvable private address. - * Values: - * - 0x00: Public address - * - 0x01: Static random address - * - 0x02: Resolvable private address - * - 0x03: Non-resolvable private address - * @param Adv_Data_Length Length of the advertising data in the advertising - * packet. - * @param Adv_Data Advertising data used by the device while advertising. - * @param Num_of_Whitelist_Entries Number of devices that have to be added to - * the whitelist. - * @param Whitelist_Entry See @ref Whitelist_Entry_t - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_broadcast_mode( uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Advertising_Type, - uint8_t Own_Address_Type, - uint8_t Adv_Data_Length, - const uint8_t* Adv_Data, - uint8_t Num_of_Whitelist_Entries, - const Whitelist_Entry_t* Whitelist_Entry ); - -/** - * @brief ACI_GAP_START_OBSERVATION_PROC - * Starts an Observation procedure, when the device is in Observer Role. The - * host enables scanning in the controller. The advertising reports are sent to - * the upper layer using standard LE Advertising Report Event. (See Bluetooth - * Core v5.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event). - * If controller privacy is enabled and the peer device (advertiser) is in the - * resolving list then the link layer will generate a RPA, if it is not then - * the RPA/NRPA generated by the Host will be used. - * - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Type Passive or active scanning. With active scanning - * SCAN_REQ packets are sent. - * Values: - * - 0x00: Passive Scanning - * - 0x01: Active scanning - * @param Own_Address_Type Own address type - * Values: - * - 0x00: Public Device Address - * (only if privacy is disabled) - * - 0x01: Random Device Address - * (only if privacy is disabled) - * - 0x02: Resolvable Private Address - * (only if privacy is enabled) - * - 0x03: Non Resolvable Private Address - * (only if privacy is enabled) - * @param Filter_Duplicates Enable/disable duplicate filtering. - * Values: - * - 0x00: Duplicate filtering disabled - * - 0x01: Duplicate filtering enabled - * @param Scanning_Filter_Policy Scanning filter policy: - * - 0x00 Accept all advertisement packets (it is allowed only if - * controller privacy is enabled).Directed advertising packets which are - * not addressed for this device shall be ignored. - * - 0x01 Ignore advertisement packets from devices not in the White - * List Only.Directed advertising packets which are not addressed for - * this device shall be ignored. - * - 0x02 Accept all undirected advertisement packets (it is allowed - * only if controller privacy or host privacy is enabled).Directed - * advertisement packets where initiator address is a RPA and Directed - * advertisement packets addressed to this device shall be accepted. - * - 0x03 Accept all undirected advertisement packets from devices that - * are in the White List.Directed advertisement packets where initiator - * address is RPA and Directed advertisement packets addressed to this - * device shall be accepted. - * - NOTE: If Host privacy is enabled Scanning_Filter_Policy can only - * take values 0x00 or 0x01; - * Values: - * - 0x00: Accept all - * - 0x01: Ignore devices not in the White List - * - 0x02: Accept all (use resolving list) - * - 0x03: Ignore devices not in the White List (use resolving list) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_observation_proc( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t LE_Scan_Type, - uint8_t Own_Address_Type, - uint8_t Filter_Duplicates, - uint8_t Scanning_Filter_Policy ); - -/** - * @brief ACI_GAP_GET_BONDED_DEVICES - * This command gets the list of the devices which are bonded. It returns the - * number of addresses and the corresponding address types and values. - * - * @param[out] Num_of_Addresses The number of bonded devices - * @param[out] Bonded_Device_Entry See @ref Bonded_Device_Entry_t - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_get_bonded_devices( uint8_t* Num_of_Addresses, - Bonded_Device_Entry_t* Bonded_Device_Entry ); - -/** - * @brief ACI_GAP_IS_DEVICE_BONDED - * The command finds whether the device, whose address is specified in the - * command, is bonded. If the device is using a resolvable private address and - * it has been bonded, then the command will return BLE_STATUS_SUCCESS. - * - * @param Peer_Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param Peer_Address Public or Random (static) Identity address of the peer - * device - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_is_device_bonded( uint8_t Peer_Address_Type, - const uint8_t* Peer_Address ); - -/** - * @brief ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO - * This command allows the User to validate/confirm or not the Numeric - * Comparison value showed through the ACI_GAP_Numeric_Comparison_Value_Event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Confirm_Yes_No 0 : The Numeric Values showed on both local and peer - * device are different! - * 1 : The Numeric Values showed on both local and peer device are - * equal! - * Values: - * - 0x00: No - * - 0x01: YES - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_numeric_comparison_value_confirm_yesno( uint16_t Connection_Handle, - uint8_t Confirm_Yes_No ); - -/** - * @brief ACI_GAP_PASSKEY_INPUT - * This command permits to signal to the Stack the input type detected during - * Passkey input. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Input_Type Passkey input type detected - * Values: - * - 0x00: Passkey entry started - * - 0x01: Passkey digit entered - * - 0x02: Passkey digit erased - * - 0x03: Passkey cleared - * - 0x04: Passkey entry completed - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_passkey_input( uint16_t Connection_Handle, - uint8_t Input_Type ); - -/** - * @brief ACI_GAP_GET_OOB_DATA - * This command is sent by the User to get (i.e. to extract from the Stack) the - * OOB data generated by the Stack itself. - * - * @param OOB_Data_Type OOB Data type - * Values: - * - 0x00: TK (LP v.4.1) - * - 0x01: Random (SC v.4.2) - * - 0x02: Confirm (SC v.4.2) - * @param[out] Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param[out] Address Public or Random (static) address of this device - * @param[out] OOB_Data_Len Length of OOB Data - * @param[out] OOB_Data Local Pairing Data intended to the remote device to be - * sent via OOB. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_get_oob_data( uint8_t OOB_Data_Type, - uint8_t* Address_Type, - uint8_t* Address, - uint8_t* OOB_Data_Len, - uint8_t* OOB_Data ); - -/** - * @brief ACI_GAP_SET_OOB_DATA - * This command is sent (by the User) to input the OOB data arrived via OOB - * communication. - * - * @param Device_Type OOB Device type - * Values: - * - 0x00: Local device - * - 0x01: Remote device - * @param Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param Address Public or Random (static) address of the peer device - * @param OOB_Data_Type OOB Data type - * Values: - * - 0x00: TK (LP v.4.1) - * - 0x01: Random (SC v.4.2) - * - 0x02: Confirm (SC v.4.2) - * @param OOB_Data_Len Length of OOB Data - * @param OOB_Data Pairing Data received through OOB from remote device - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_oob_data( uint8_t Device_Type, - uint8_t Address_Type, - const uint8_t* Address, - uint8_t OOB_Data_Type, - uint8_t OOB_Data_Len, - const uint8_t* OOB_Data ); - -/** - * @brief ACI_GAP_ADD_DEVICES_TO_RESOLVING_LIST - * This command is used to add one device to the list of address translations - * used to resolve Resolvable Private Addresses in the Controller. - * - * @param Num_of_Resolving_list_Entries Number of devices that have to be added - * to the resolving list. - * @param Whitelist_Identity_Entry See @ref Whitelist_Identity_Entry_t - * @param Clear_Resolving_List Clear the resolving list - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_add_devices_to_resolving_list( uint8_t Num_of_Resolving_list_Entries, - const Whitelist_Identity_Entry_t* Whitelist_Identity_Entry, - uint8_t Clear_Resolving_List ); - -/** - * @brief ACI_GAP_REMOVE_BONDED_DEVICE - * This command is used to remove a specified device from bonding table - * - * @param Peer_Identity_Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param Peer_Identity_Address Public or Random (static) Identity address of - * the peer device - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_remove_bonded_device( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address ); - - -#endif /* BLE_GAP_ACI_H__ */ diff --git a/lib_blewbxx/core/auto/ble_gatt_aci.c b/lib_blewbxx/core/auto/ble_gatt_aci.c deleted file mode 100644 index b552cf22b..000000000 --- a/lib_blewbxx/core/auto/ble_gatt_aci.c +++ /dev/null @@ -1,1454 +0,0 @@ -/****************************************************************************** - * @file ble_gatt_aci.c - * @author MCD - * @brief STM32WB BLE API (gatt_aci) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#include "ble_gatt_aci.h" - -tBleStatus aci_gatt_init( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x101; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_add_service( uint8_t Service_UUID_Type, - const Service_UUID_t* Service_UUID, - uint8_t Service_Type, - uint8_t Max_Attribute_Records, - uint16_t* Service_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_add_service_cp0 *cp0 = (aci_gatt_add_service_cp0*)(cmd_buffer); - aci_gatt_add_service_cp1 *cp1 = (aci_gatt_add_service_cp1*)(cmd_buffer + 1 + (Service_UUID_Type == 1 ? 2 : (Service_UUID_Type == 2 ? 16 : 0))); - aci_gatt_add_service_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Service_UUID_Type = Service_UUID_Type; - index_input += 1; - /* var_len_data input */ - { - uint8_t size; - switch ( Service_UUID_Type ) - { - case 1: size = 2; break; - case 2: size = 16; break; - default: return BLE_STATUS_ERROR; - } - Osal_MemCpy( (void*)&cp0->Service_UUID, (const void*)Service_UUID, size ); - index_input += size; - { - cp1->Service_Type = Service_Type; - } - index_input += 1; - { - cp1->Max_Attribute_Records = Max_Attribute_Records; - } - index_input += 1; - } - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x102; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Service_Handle = resp.Service_Handle; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gatt_include_service( uint16_t Service_Handle, - uint16_t Include_Start_Handle, - uint16_t Include_End_Handle, - uint8_t Include_UUID_Type, - const Include_UUID_t* Include_UUID, - uint16_t* Include_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_include_service_cp0 *cp0 = (aci_gatt_include_service_cp0*)(cmd_buffer); - aci_gatt_include_service_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - int uuid_size = (Include_UUID_Type == 2) ? 16 : 2; - cp0->Service_Handle = Service_Handle; - index_input += 2; - cp0->Include_Start_Handle = Include_Start_Handle; - index_input += 2; - cp0->Include_End_Handle = Include_End_Handle; - index_input += 2; - cp0->Include_UUID_Type = Include_UUID_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Include_UUID, (const void*)Include_UUID, uuid_size ); - index_input += uuid_size; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x103; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Include_Handle = resp.Include_Handle; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gatt_add_char( uint16_t Service_Handle, - uint8_t Char_UUID_Type, - const Char_UUID_t* Char_UUID, - uint16_t Char_Value_Length, - uint8_t Char_Properties, - uint8_t Security_Permissions, - uint8_t GATT_Evt_Mask, - uint8_t Enc_Key_Size, - uint8_t Is_Variable, - uint16_t* Char_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_add_char_cp0 *cp0 = (aci_gatt_add_char_cp0*)(cmd_buffer); - aci_gatt_add_char_cp1 *cp1 = (aci_gatt_add_char_cp1*)(cmd_buffer + 2 + 1 + (Char_UUID_Type == 1 ? 2 : (Char_UUID_Type == 2 ? 16 : 0))); - aci_gatt_add_char_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Service_Handle = Service_Handle; - index_input += 2; - cp0->Char_UUID_Type = Char_UUID_Type; - index_input += 1; - /* var_len_data input */ - { - uint8_t size; - switch ( Char_UUID_Type ) - { - case 1: size = 2; break; - case 2: size = 16; break; - default: return BLE_STATUS_ERROR; - } - Osal_MemCpy( (void*)&cp0->Char_UUID, (const void*)Char_UUID, size ); - index_input += size; - { - cp1->Char_Value_Length = Char_Value_Length; - } - index_input += 2; - { - cp1->Char_Properties = Char_Properties; - } - index_input += 1; - { - cp1->Security_Permissions = Security_Permissions; - } - index_input += 1; - { - cp1->GATT_Evt_Mask = GATT_Evt_Mask; - } - index_input += 1; - { - cp1->Enc_Key_Size = Enc_Key_Size; - } - index_input += 1; - { - cp1->Is_Variable = Is_Variable; - } - index_input += 1; - } - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x104; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Char_Handle = resp.Char_Handle; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gatt_add_char_desc( uint16_t Service_Handle, - uint16_t Char_Handle, - uint8_t Char_Desc_Uuid_Type, - const Char_Desc_Uuid_t* Char_Desc_Uuid, - uint8_t Char_Desc_Value_Max_Len, - uint8_t Char_Desc_Value_Length, - const uint8_t* Char_Desc_Value, - uint8_t Security_Permissions, - uint8_t Access_Permissions, - uint8_t GATT_Evt_Mask, - uint8_t Enc_Key_Size, - uint8_t Is_Variable, - uint16_t* Char_Desc_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_add_char_desc_cp0 *cp0 = (aci_gatt_add_char_desc_cp0*)(cmd_buffer); - aci_gatt_add_char_desc_cp1 *cp1 = (aci_gatt_add_char_desc_cp1*)(cmd_buffer + 2 + 2 + 1 + (Char_Desc_Uuid_Type == 1 ? 2 : (Char_Desc_Uuid_Type == 2 ? 16 : 0))); - aci_gatt_add_char_desc_cp2 *cp2 = (aci_gatt_add_char_desc_cp2*)(cmd_buffer + 2 + 2 + 1 + (Char_Desc_Uuid_Type == 1 ? 2 : (Char_Desc_Uuid_Type == 2 ? 16 : 0)) + 1 + 1 + Char_Desc_Value_Length * (sizeof(uint8_t))); - aci_gatt_add_char_desc_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Service_Handle = Service_Handle; - index_input += 2; - cp0->Char_Handle = Char_Handle; - index_input += 2; - cp0->Char_Desc_Uuid_Type = Char_Desc_Uuid_Type; - index_input += 1; - /* var_len_data input */ - { - uint8_t size; - switch ( Char_Desc_Uuid_Type ) - { - case 1: size = 2; break; - case 2: size = 16; break; - default: return BLE_STATUS_ERROR; - } - Osal_MemCpy( (void*)&cp0->Char_Desc_Uuid, (const void*)Char_Desc_Uuid, size ); - index_input += size; - { - cp1->Char_Desc_Value_Max_Len = Char_Desc_Value_Max_Len; - } - index_input += 1; - { - cp1->Char_Desc_Value_Length = Char_Desc_Value_Length; - } - index_input += 1; - Osal_MemCpy( (void*)&cp1->Char_Desc_Value, (const void*)Char_Desc_Value, Char_Desc_Value_Length ); - index_input += Char_Desc_Value_Length; - { - cp2->Security_Permissions = Security_Permissions; - } - index_input += 1; - { - cp2->Access_Permissions = Access_Permissions; - } - index_input += 1; - { - cp2->GATT_Evt_Mask = GATT_Evt_Mask; - } - index_input += 1; - { - cp2->Enc_Key_Size = Enc_Key_Size; - } - index_input += 1; - { - cp2->Is_Variable = Is_Variable; - } - index_input += 1; - } - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x105; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Char_Desc_Handle = resp.Char_Desc_Handle; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gatt_update_char_value( uint16_t Service_Handle, - uint16_t Char_Handle, - uint8_t Val_Offset, - uint8_t Char_Value_Length, - const uint8_t* Char_Value ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_update_char_value_cp0 *cp0 = (aci_gatt_update_char_value_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Service_Handle = Service_Handle; - index_input += 2; - cp0->Char_Handle = Char_Handle; - index_input += 2; - cp0->Val_Offset = Val_Offset; - index_input += 1; - cp0->Char_Value_Length = Char_Value_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Char_Value, (const void*)Char_Value, Char_Value_Length ); - index_input += Char_Value_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x106; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_del_char( uint16_t Serv_Handle, - uint16_t Char_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_del_char_cp0 *cp0 = (aci_gatt_del_char_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Serv_Handle = Serv_Handle; - index_input += 2; - cp0->Char_Handle = Char_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x107; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_del_service( uint16_t Serv_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_del_service_cp0 *cp0 = (aci_gatt_del_service_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Serv_Handle = Serv_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x108; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_del_include_service( uint16_t Serv_Handle, - uint16_t Include_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_del_include_service_cp0 *cp0 = (aci_gatt_del_include_service_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Serv_Handle = Serv_Handle; - index_input += 2; - cp0->Include_Handle = Include_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x109; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_set_event_mask( uint32_t GATT_Evt_Mask ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_set_event_mask_cp0 *cp0 = (aci_gatt_set_event_mask_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->GATT_Evt_Mask = GATT_Evt_Mask; - index_input += 4; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x10a; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_exchange_config( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_exchange_config_cp0 *cp0 = (aci_gatt_exchange_config_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x10b; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_att_find_info_req( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_att_find_info_req_cp0 *cp0 = (aci_att_find_info_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Start_Handle = Start_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x10c; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_att_find_by_type_value_req( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint16_t UUID, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_att_find_by_type_value_req_cp0 *cp0 = (aci_att_find_by_type_value_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Start_Handle = Start_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - cp0->UUID = UUID; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x10d; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_att_read_by_type_req( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_att_read_by_type_req_cp0 *cp0 = (aci_att_read_by_type_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - int uuid_size = (UUID_Type == 2) ? 16 : 2; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Start_Handle = Start_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - cp0->UUID_Type = UUID_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->UUID, (const void*)UUID, uuid_size ); - index_input += uuid_size; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x10e; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_att_read_by_group_type_req( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_att_read_by_group_type_req_cp0 *cp0 = (aci_att_read_by_group_type_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - int uuid_size = (UUID_Type == 2) ? 16 : 2; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Start_Handle = Start_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - cp0->UUID_Type = UUID_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->UUID, (const void*)UUID, uuid_size ); - index_input += uuid_size; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x10f; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_att_prepare_write_req( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_att_prepare_write_req_cp0 *cp0 = (aci_att_prepare_write_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Val_Offset = Val_Offset; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x110; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_att_execute_write_req( uint16_t Connection_Handle, - uint8_t Execute ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_att_execute_write_req_cp0 *cp0 = (aci_att_execute_write_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Execute = Execute; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x111; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_disc_all_primary_services( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_disc_all_primary_services_cp0 *cp0 = (aci_gatt_disc_all_primary_services_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x112; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_disc_primary_service_by_uuid( uint16_t Connection_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_disc_primary_service_by_uuid_cp0 *cp0 = (aci_gatt_disc_primary_service_by_uuid_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - int uuid_size = (UUID_Type == 2) ? 16 : 2; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->UUID_Type = UUID_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->UUID, (const void*)UUID, uuid_size ); - index_input += uuid_size; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x113; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_find_included_services( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_find_included_services_cp0 *cp0 = (aci_gatt_find_included_services_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Start_Handle = Start_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x114; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_disc_all_char_of_service( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_disc_all_char_of_service_cp0 *cp0 = (aci_gatt_disc_all_char_of_service_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Start_Handle = Start_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x115; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_disc_char_by_uuid( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_disc_char_by_uuid_cp0 *cp0 = (aci_gatt_disc_char_by_uuid_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - int uuid_size = (UUID_Type == 2) ? 16 : 2; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Start_Handle = Start_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - cp0->UUID_Type = UUID_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->UUID, (const void*)UUID, uuid_size ); - index_input += uuid_size; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x116; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_disc_all_char_desc( uint16_t Connection_Handle, - uint16_t Char_Handle, - uint16_t End_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_disc_all_char_desc_cp0 *cp0 = (aci_gatt_disc_all_char_desc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Char_Handle = Char_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x117; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_read_char_value( uint16_t Connection_Handle, - uint16_t Attr_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_read_char_value_cp0 *cp0 = (aci_gatt_read_char_value_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x118; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_read_using_char_uuid( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_read_using_char_uuid_cp0 *cp0 = (aci_gatt_read_using_char_uuid_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - int uuid_size = (UUID_Type == 2) ? 16 : 2; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Start_Handle = Start_Handle; - index_input += 2; - cp0->End_Handle = End_Handle; - index_input += 2; - cp0->UUID_Type = UUID_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->UUID, (const void*)UUID, uuid_size ); - index_input += uuid_size; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x119; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_read_long_char_value( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_read_long_char_value_cp0 *cp0 = (aci_gatt_read_long_char_value_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Val_Offset = Val_Offset; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x11a; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_read_multiple_char_value( uint16_t Connection_Handle, - uint8_t Number_of_Handles, - const Handle_Entry_t* Handle_Entry ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_read_multiple_char_value_cp0 *cp0 = (aci_gatt_read_multiple_char_value_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Number_of_Handles = Number_of_Handles; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Handle_Entry, (const void*)Handle_Entry, Number_of_Handles * (sizeof(Handle_Entry_t)) ); - index_input += Number_of_Handles * (sizeof(Handle_Entry_t)); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x11b; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_write_char_value( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_write_char_value_cp0 *cp0 = (aci_gatt_write_char_value_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x11c; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_write_long_char_value( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_write_long_char_value_cp0 *cp0 = (aci_gatt_write_long_char_value_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Val_Offset = Val_Offset; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x11d; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_write_char_reliable( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_write_char_reliable_cp0 *cp0 = (aci_gatt_write_char_reliable_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Val_Offset = Val_Offset; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x11e; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_write_long_char_desc( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_write_long_char_desc_cp0 *cp0 = (aci_gatt_write_long_char_desc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Val_Offset = Val_Offset; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x11f; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_read_long_char_desc( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_read_long_char_desc_cp0 *cp0 = (aci_gatt_read_long_char_desc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Val_Offset = Val_Offset; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x120; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_write_char_desc( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_write_char_desc_cp0 *cp0 = (aci_gatt_write_char_desc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x121; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_read_char_desc( uint16_t Connection_Handle, - uint16_t Attr_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_read_char_desc_cp0 *cp0 = (aci_gatt_read_char_desc_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x122; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_write_without_resp( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_write_without_resp_cp0 *cp0 = (aci_gatt_write_without_resp_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x123; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_signed_write_without_resp( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_signed_write_without_resp_cp0 *cp0 = (aci_gatt_signed_write_without_resp_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x124; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_confirm_indication( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_confirm_indication_cp0 *cp0 = (aci_gatt_confirm_indication_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x125; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_write_resp( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Write_status, - uint8_t Error_Code, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_write_resp_cp0 *cp0 = (aci_gatt_write_resp_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Write_status = Write_status; - index_input += 1; - cp0->Error_Code = Error_Code; - index_input += 1; - cp0->Attribute_Val_Length = Attribute_Val_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Attribute_Val, (const void*)Attribute_Val, Attribute_Val_Length ); - index_input += Attribute_Val_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x126; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_allow_read( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_allow_read_cp0 *cp0 = (aci_gatt_allow_read_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x127; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_set_security_permission( uint16_t Serv_Handle, - uint16_t Attr_Handle, - uint8_t Security_Permissions ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_set_security_permission_cp0 *cp0 = (aci_gatt_set_security_permission_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Serv_Handle = Serv_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Security_Permissions = Security_Permissions; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x128; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_set_desc_value( uint16_t Serv_Handle, - uint16_t Char_Handle, - uint16_t Char_Desc_Handle, - uint16_t Val_Offset, - uint8_t Char_Desc_Value_Length, - const uint8_t* Char_Desc_Value ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_set_desc_value_cp0 *cp0 = (aci_gatt_set_desc_value_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Serv_Handle = Serv_Handle; - index_input += 2; - cp0->Char_Handle = Char_Handle; - index_input += 2; - cp0->Char_Desc_Handle = Char_Desc_Handle; - index_input += 2; - cp0->Val_Offset = Val_Offset; - index_input += 2; - cp0->Char_Desc_Value_Length = Char_Desc_Value_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Char_Desc_Value, (const void*)Char_Desc_Value, Char_Desc_Value_Length ); - index_input += Char_Desc_Value_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x129; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_read_handle_value( uint16_t Attr_Handle, - uint16_t Offset, - uint16_t Value_Length_Requested, - uint16_t* Length, - uint16_t* Value_Length, - uint8_t* Value ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_read_handle_value_cp0 *cp0 = (aci_gatt_read_handle_value_cp0*)(cmd_buffer); - aci_gatt_read_handle_value_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Offset = Offset; - index_input += 2; - cp0->Value_Length_Requested = Value_Length_Requested; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x12a; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Length = resp.Length; - *Value_Length = resp.Value_Length; - Osal_MemCpy( (void*)Value, (const void*)resp.Value, *Value_Length); - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_gatt_update_char_value_ext( uint16_t Conn_Handle_To_Notify, - uint16_t Service_Handle, - uint16_t Char_Handle, - uint8_t Update_Type, - uint16_t Char_Length, - uint16_t Value_Offset, - uint8_t Value_Length, - const uint8_t* Value ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_update_char_value_ext_cp0 *cp0 = (aci_gatt_update_char_value_ext_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Conn_Handle_To_Notify = Conn_Handle_To_Notify; - index_input += 2; - cp0->Service_Handle = Service_Handle; - index_input += 2; - cp0->Char_Handle = Char_Handle; - index_input += 2; - cp0->Update_Type = Update_Type; - index_input += 1; - cp0->Char_Length = Char_Length; - index_input += 2; - cp0->Value_Offset = Value_Offset; - index_input += 2; - cp0->Value_Length = Value_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Value, (const void*)Value, Value_Length ); - index_input += Value_Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x12c; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_deny_read( uint16_t Connection_Handle, - uint8_t Error_Code ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_deny_read_cp0 *cp0 = (aci_gatt_deny_read_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Error_Code = Error_Code; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x12d; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_gatt_set_access_permission( uint16_t Serv_Handle, - uint16_t Attr_Handle, - uint8_t Access_Permissions ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_gatt_set_access_permission_cp0 *cp0 = (aci_gatt_set_access_permission_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Serv_Handle = Serv_Handle; - index_input += 2; - cp0->Attr_Handle = Attr_Handle; - index_input += 2; - cp0->Access_Permissions = Access_Permissions; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x12e; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - diff --git a/lib_blewbxx/core/auto/ble_gatt_aci.h b/lib_blewbxx/core/auto/ble_gatt_aci.h deleted file mode 100644 index 04ad116b3..000000000 --- a/lib_blewbxx/core/auto/ble_gatt_aci.h +++ /dev/null @@ -1,1079 +0,0 @@ -/****************************************************************************** - * @file ble_gatt_aci.h - * @author MCD - * @brief STM32WB BLE API (gatt_aci) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_GATT_ACI_H__ -#define BLE_GATT_ACI_H__ - - -#include "ble_types.h" - -/** - * @brief ACI_GATT_INIT - * Initialize the GATT layer for server and client roles. It adds also the GATT - * service with Service Changed Characteristic. - * Until this command is issued the GATT channel does not process any commands - * even if the connection is opened. This command has to be given before using - * any of the GAP features. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_init( void ); - -/** - * @brief ACI_GATT_ADD_SERVICE - * Add a service to GATT Server. When a service is created in the server, the - * host needs to reserve the handle ranges for this service using - * Max_Attribute_Records parameter. This parameter specifies the maximum number - * of attribute records that can be added to this service (including the - * service attribute, include attribute, characteristic attribute, - * characteristic value attribute and characteristic descriptor attribute). - * Handle of the created service is returned in command complete event. Service - * declaration is taken from the service pool. - * The attributes for characteristics and descriptors are allocated from the - * attribute pool. - * - * @param Service_UUID_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 - * bits UUID - * @param Service_UUID See @ref Service_UUID_t - * @param Service_Type Service type. - * Values: - * - 0x01: Primary Service - * - 0x02: Secondary Service - * @param Max_Attribute_Records Maximum number of attribute records that can be - * added to this service - * @param[out] Service_Handle Handle of the Service. - * When this service is added, a handle is allocated by the server for - * this service. - * Server also allocates a range of handles for this service from - * serviceHandle to - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_add_service( uint8_t Service_UUID_Type, - const Service_UUID_t* Service_UUID, - uint8_t Service_Type, - uint8_t Max_Attribute_Records, - uint16_t* Service_Handle ); - -/** - * @brief ACI_GATT_INCLUDE_SERVICE - * Include a service given by Include_Start_Handle and Include_End_Handle to - * another service given by Service_Handle. Attribute server creates an INCLUDE - * definition attribute and return the handle of this attribute in - * Included_handle. - * - * @param Service_Handle Handle of the Service to which another service has to - * be included. - * @param Include_Start_Handle Start Handle of the Service which has to be - * included in service - * @param Include_End_Handle End Handle of the Service which has to be included - * in service - * @param Include_UUID_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 - * bits UUID - * @param Include_UUID See @ref Include_UUID_t - * @param[out] Include_Handle Handle of the include declaration - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_include_service( uint16_t Service_Handle, - uint16_t Include_Start_Handle, - uint16_t Include_End_Handle, - uint8_t Include_UUID_Type, - const Include_UUID_t* Include_UUID, - uint16_t* Include_Handle ); - -/** - * @brief ACI_GATT_ADD_CHAR - * Add a characteristic to a service. - * - * @param Service_Handle Handle of the Service to which the characteristic will - * be added - * @param Char_UUID_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits - * UUID - * @param Char_UUID See @ref Char_UUID_t - * @param Char_Value_Length Maximum length of the characteristic value. - * @param Char_Properties Characteristic Properties (Volume 3, Part G, section - * 3.3.1.1 of Bluetooth Specification 5.0) - * Flags: - * - 0x00: CHAR_PROP_NONE - * - 0x01: CHAR_PROP_BROADCAST (Broadcast) - * - 0x02: CHAR_PROP_READ (Read) - * - 0x04: CHAR_PROP_WRITE_WITHOUT_RESP (Write w/o resp) - * - 0x08: CHAR_PROP_WRITE (Write) - * - 0x10: CHAR_PROP_NOTIFY (Notify) - * - 0x20: CHAR_PROP_INDICATE (Indicate) - * - 0x40: CHAR_PROP_SIGNED_WRITE (Authenticated Signed Writes) - * - 0x80: CHAR_PROP_EXT (Extended Properties) - * @param Security_Permissions Security permission flags. - * Flags: - * - 0x00: None - * - 0x01: AUTHEN_READ (Need authentication to read) - * - 0x02: AUTHOR_READ (Need authorization to read) - * - 0x04: ENCRY_READ (Need encryption to read) - * - 0x08: AUTHEN_WRITE (need authentication to write) - * - 0x10: AUTHOR_WRITE (need authorization to write) - * - 0x20: ENCRY_WRITE (need encryption to write) - * @param GATT_Evt_Mask GATT event mask. - * Flags: - * - 0x00: GATT_DONT_NOTIFY_EVENTS - * - 0x01: GATT_NOTIFY_ATTRIBUTE_WRITE - * - 0x02: GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP - * - 0x04: GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP - * @param Enc_Key_Size Minimum encryption key size required to read the - * characteristic. - * Values: - * - 0x07 ... 0x10 - * @param Is_Variable Specify if the characteristic value has a fixed length or - * a variable length. - * Values: - * - 0x00: Fixed length - * - 0x01: Variable length - * @param[out] Char_Handle Handle of the characteristic that has been added (it - * is the handle of the characteristic declaration). - * The attribute that holds the characteristic value is allocated at the - * next handle, followed by the Client Characteristic Configuration - * descriptor if the characteristic has CHAR_PROP_NOTIFY or - * CHAR_PROP_INDICATE properties. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_add_char( uint16_t Service_Handle, - uint8_t Char_UUID_Type, - const Char_UUID_t* Char_UUID, - uint16_t Char_Value_Length, - uint8_t Char_Properties, - uint8_t Security_Permissions, - uint8_t GATT_Evt_Mask, - uint8_t Enc_Key_Size, - uint8_t Is_Variable, - uint16_t* Char_Handle ); - -/** - * @brief ACI_GATT_ADD_CHAR_DESC - * Add a characteristic descriptor to a service. - * - * @param Service_Handle Handle of service to which the characteristic belongs - * @param Char_Handle Handle of the characteristic to which description has to - * be added - * @param Char_Desc_Uuid_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 - * bits UUID - * @param Char_Desc_Uuid See @ref Char_Desc_Uuid_t - * @param Char_Desc_Value_Max_Len The maximum length of the descriptor value - * @param Char_Desc_Value_Length Current Length of the characteristic - * descriptor value - * @param Char_Desc_Value Value of the characteristic description - * @param Security_Permissions Security permission flags. - * Flags: - * - 0x00: None - * - 0x01: AUTHEN_READ (Need authentication to read) - * - 0x02: AUTHOR_READ (Need authorization to read) - * - 0x04: ENCRY_READ (Need encryption to read) - * - 0x08: AUTHEN_WRITE (need authentication to write) - * - 0x10: AUTHOR_WRITE (need authorization to write) - * - 0x20: ENCRY_WRITE (need encryption to write) - * @param Access_Permissions Access permission - * Flags: - * - 0x00: None - * - 0x01: READ - * - 0x02: WRITE - * - 0x04: WRITE_WO_RESP - * - 0x08: SIGNED_WRITE - * @param GATT_Evt_Mask GATT event mask. - * Flags: - * - 0x00: GATT_DONT_NOTIFY_EVENTS - * - 0x01: GATT_NOTIFY_ATTRIBUTE_WRITE - * - 0x02: GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP - * - 0x04: GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP - * @param Enc_Key_Size Minimum encryption key size required to read the - * characteristic. - * Values: - * - 0x07 ... 0x10 - * @param Is_Variable Specify if the characteristic value has a fixed length or - * a variable length. - * Values: - * - 0x00: Fixed length - * - 0x01: Variable length - * @param[out] Char_Desc_Handle Handle of the characteristic descriptor - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_add_char_desc( uint16_t Service_Handle, - uint16_t Char_Handle, - uint8_t Char_Desc_Uuid_Type, - const Char_Desc_Uuid_t* Char_Desc_Uuid, - uint8_t Char_Desc_Value_Max_Len, - uint8_t Char_Desc_Value_Length, - const uint8_t* Char_Desc_Value, - uint8_t Security_Permissions, - uint8_t Access_Permissions, - uint8_t GATT_Evt_Mask, - uint8_t Enc_Key_Size, - uint8_t Is_Variable, - uint16_t* Char_Desc_Handle ); - -/** - * @brief ACI_GATT_UPDATE_CHAR_VALUE - * Update a characteristic value in a service. If notifications (or - * indications) are enabled on that characteristic, a notification (or - * indication) is sent to the client after sending this command. The command is - * queued into the STM32WB command queue. - * If the buffer is full, because previous commands could not be still - * processed, the function will return BLE_STATUS_INSUFFICIENT_RESOURCES. This - * will happen if notifications (or indications) are enabled and the - * application calls ACI_GATT_UPDATE_CHAR_VALUE at an higher rate than what is - * allowed by the link. - * Throughput on BLE link depends on connection interval and connection length - * parameters (decided by the master, see - * aci_l2cap_connection_parameter_update_request() for more info on how to - * suggest new connection parameters from a slave). If the application does not - * want to lose notifications because STM32WB buffer becomes full, it has to - * retry again till the function returns BLE_STATUS_SUCCESS or any other error - * code. - * - * @param Service_Handle Handle of service to which the characteristic belongs - * @param Char_Handle Handle of the characteristic declaration - * @param Val_Offset The offset from which the attribute value has to be - * updated. - * If this is set to 0 and the attribute value is of variable length, - * then the length of the attribute will be set to the - * Char_Value_Length. - * If the Val_Offset is set to a value greater than 0, then the length - * of the attribute will be set to the maximum length as specified for - * the attribute while adding the characteristic. - * @param Char_Value_Length Length of the characteristic value in octets - * @param Char_Value Characteristic value - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_update_char_value( uint16_t Service_Handle, - uint16_t Char_Handle, - uint8_t Val_Offset, - uint8_t Char_Value_Length, - const uint8_t* Char_Value ); - -/** - * @brief ACI_GATT_DEL_CHAR - * Delete the specified characteristic from the service. - * - * @param Serv_Handle Handle of service to which the characteristic belongs - * @param Char_Handle Handle of the characteristic which has to be deleted - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_del_char( uint16_t Serv_Handle, - uint16_t Char_Handle ); - -/** - * @brief ACI_GATT_DEL_SERVICE - * Delete the specified service from the GATT server database. - * - * @param Serv_Handle Handle of the service to be deleted - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_del_service( uint16_t Serv_Handle ); - -/** - * @brief ACI_GATT_DEL_INCLUDE_SERVICE - * Delete the Include definition from the service. - * - * @param Serv_Handle Handle of the service to which the include service - * belongs - * @param Include_Handle Handle of the included service which has to be deleted - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_del_include_service( uint16_t Serv_Handle, - uint16_t Include_Handle ); - -/** - * @brief ACI_GATT_SET_EVENT_MASK - * Mask events from the GATT. The default configuration is all the events - * masked. - * - * @param GATT_Evt_Mask GATT/ATT event mask. - * Values: - * - 0x00000001: ACI_GATT_ATTRIBUTE_MODIFIED_EVENT - * - 0x00000002: ACI_GATT_PROC_TIMEOUT_EVENT - * - 0x00000004: ACI_ATT_EXCHANGE_MTU_RESP_EVENT - * - 0x00000008: ACI_ATT_FIND_INFO_RESP_EVENT - * - 0x00000010: ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT - * - 0x00000020: ACI_ATT_READ_BY_TYPE_RESP_EVENT - * - 0x00000040: ACI_ATT_READ_RESP_EVENT - * - 0x00000080: ACI_ATT_READ_BLOB_RESP_EVENT - * - 0x00000100: ACI_ATT_READ_MULTIPLE_RESP_EVENT - * - 0x00000200: ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT - * - 0x00000800: ACI_ATT_PREPARE_WRITE_RESP_EVENT - * - 0x00001000: ACI_ATT_EXEC_WRITE_RESP_EVENT - * - 0x00002000: ACI_GATT_INDICATION_EVENT - * - 0x00004000: ACI_GATT_NOTIFICATION_EVENT - * - 0x00008000: ACI_GATT_ERROR_RESP_EVENT - * - 0x00010000: ACI_GATT_PROC_COMPLETE_EVENT - * - 0x00020000: ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT - * - 0x00040000: ACI_GATT_TX_POOL_AVAILABLE_EVENT - * - 0x00100000: ACI_GATT_READ_EXT_EVENT - * - 0x00200000: ACI_GATT_INDICATION_EXT_EVENT - * - 0x00400000: ACI_GATT_NOTIFICATION_EXT_EVENT - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_set_event_mask( uint32_t GATT_Evt_Mask ); - -/** - * @brief ACI_GATT_EXCHANGE_CONFIG - * Perform an ATT MTU exchange procedure. - * When the ATT MTU exchange procedure is completed, a - * ACI_ATT_EXCHANGE_MTU_RESP_EVENT event is generated. A - * ACI_GATT_PROC_COMPLETE_EVENT event is also generated to indicate the end of - * the procedure. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_exchange_config( uint16_t Connection_Handle ); - -/** - * @brief ACI_ATT_FIND_INFO_REQ - * Send a Find Information Request. - * This command is used to obtain the mapping of attribute handles with their - * associated types. The responses of the procedure are given through the - * ACI_ATT_FIND_INFO_RESP_EVENT event. The end of the procedure is indicated by - * a ACI_GATT_PROC_COMPLETE_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Start_Handle First requested handle number - * @param End_Handle Last requested handle number - * @return Value indicating success or error code. - */ -tBleStatus aci_att_find_info_req( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle ); - -/** - * @brief ACI_ATT_FIND_BY_TYPE_VALUE_REQ - * Send a Find By Type Value Request - * The Find By Type Value Request is used to obtain the handles of attributes - * that have a given 16-bit UUID attribute type and a given attribute value. - * The responses of the procedure are given through the - * ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT event. - * The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT - * event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Start_Handle First requested handle number - * @param End_Handle Last requested handle number - * @param UUID 2 octet UUID to find (little-endian) - * @param Attribute_Val_Length Length of attribute value (maximum value is - * ATT_MTU - 7). - * @param Attribute_Val Attribute value to find - * @return Value indicating success or error code. - */ -tBleStatus aci_att_find_by_type_value_req( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint16_t UUID, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_ATT_READ_BY_TYPE_REQ - * Send a Read By Type Request. - * The Read By Type Request is used to obtain the values of attributes where - * the attribute type is known but the handle is not known. - * The responses are given through the ACI_ATT_READ_BY_TYPE_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Start_Handle First requested handle number - * @param End_Handle Last requested handle number - * @param UUID_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID - * @param UUID See @ref UUID_t - * @return Value indicating success or error code. - */ -tBleStatus aci_att_read_by_type_req( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ); - -/** - * @brief ACI_ATT_READ_BY_GROUP_TYPE_REQ - * Send a Read By Group Type Request. - * The Read By Group Type Request is used to obtain the values of grouping - * attributes where the attribute type is known but the handle is not known. - * Grouping attributes are defined at GATT layer. The grouping attribute types - * are: "Primary Service", "Secondary Service" and "Characteristic". - * The responses of the procedure are given through the - * ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT event. - * The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Start_Handle First requested handle number - * @param End_Handle Last requested handle number - * @param UUID_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID - * @param UUID See @ref UUID_t - * @return Value indicating success or error code. - */ -tBleStatus aci_att_read_by_group_type_req( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ); - -/** - * @brief ACI_ATT_PREPARE_WRITE_REQ - * Send a Prepare Write Request. - * The Prepare Write Request is used to request the server to prepare to write - * the value of an attribute. - * The responses of the procedure are given through the - * ACI_ATT_PREPARE_WRITE_RESP_EVENT event. - * The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the attribute to be written - * @param Val_Offset The offset of the first octet to be written - * @param Attribute_Val_Length Length of attribute value (maximum value is - * ATT_MTU - 5). - * @param Attribute_Val The value of the attribute to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_att_prepare_write_req( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_ATT_EXECUTE_WRITE_REQ - * Send an Execute Write Request. - * The Execute Write Request is used to request the server to write or cancel - * the write of all the prepared values currently held in the prepare queue - * from this client. - * The result of the procedure is given through the - * ACI_ATT_EXEC_WRITE_RESP_EVENT event. - * The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT - * event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Execute Execute or cancel writes. - * Values: - * - 0x00: Cancel all prepared writes - * - 0x01: Immediately write all pending prepared values - * @return Value indicating success or error code. - */ -tBleStatus aci_att_execute_write_req( uint16_t Connection_Handle, - uint8_t Execute ); - -/** - * @brief ACI_GATT_DISC_ALL_PRIMARY_SERVICES - * Start the GATT client procedure to discover all primary services on the - * server. - * The responses of the procedure are given through the - * ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_all_primary_services( uint16_t Connection_Handle ); - -/** - * @brief ACI_GATT_DISC_PRIMARY_SERVICE_BY_UUID - * Start the procedure to discover the primary services of the specified UUID - * on the server. - * The responses of the procedure are given through the - * ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT event. - * The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT - * event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param UUID_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID - * @param UUID See @ref UUID_t - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_primary_service_by_uuid( uint16_t Connection_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ); - -/** - * @brief ACI_GATT_FIND_INCLUDED_SERVICES - * Start the procedure to find all included services. - * The responses of the procedure are given through the - * ACI_ATT_READ_BY_TYPE_RESP_EVENT event. - * The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT - * event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Start_Handle Start attribute handle of the service - * @param End_Handle End attribute handle of the service - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_find_included_services( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle ); - -/** - * @brief ACI_GATT_DISC_ALL_CHAR_OF_SERVICE - * Start the procedure to discover all the characteristics of a given service. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. Before procedure completion the response packets are given - * through ACI_ATT_READ_BY_TYPE_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Start_Handle Start attribute handle of the service - * @param End_Handle End attribute handle of the service - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_all_char_of_service( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle ); - -/** - * @brief ACI_GATT_DISC_CHAR_BY_UUID - * Start the procedure to discover all the characteristics specified by a UUID. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. Before procedure completion the response packets are given - * through ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Start_Handle Start attribute handle of the service - * @param End_Handle End attribute handle of the service - * @param UUID_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID - * @param UUID See @ref UUID_t - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_char_by_uuid( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ); - -/** - * @brief ACI_GATT_DISC_ALL_CHAR_DESC - * Start the procedure to discover all characteristic descriptors on the - * server. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. Before procedure completion the response packets are given - * through ACI_ATT_FIND_INFO_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Char_Handle Handle of the characteristic value - * @param End_Handle End handle of the characteristic - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_all_char_desc( uint16_t Connection_Handle, - uint16_t Char_Handle, - uint16_t End_Handle ); - -/** - * @brief ACI_GATT_READ_CHAR_VALUE - * Start the procedure to read the attribute value. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. Before procedure completion the response packet is given through - * ACI_ATT_READ_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the characteristic value to be read - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_char_value( uint16_t Connection_Handle, - uint16_t Attr_Handle ); - -/** - * @brief ACI_GATT_READ_USING_CHAR_UUID - * This command sends a Read By Type Request packet to the server in order to - * read the value attribute of the characteristics specified by the UUID. - * When the procedure is completed, an ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. Before procedure completion, the response packet is given through - * one ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT event per reported attribute. - * Note: the number of bytes of a value reported by - * ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT event can not exceed - * BLE_EVT_MAX_PARAM_LEN - 7 i.e. 248 bytes for default value of - * BLE_EVT_MAX_PARAM_LEN. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Start_Handle Starting handle of the range to be searched - * @param End_Handle End handle of the range to be searched - * @param UUID_Type UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID - * @param UUID See @ref UUID_t - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_using_char_uuid( uint16_t Connection_Handle, - uint16_t Start_Handle, - uint16_t End_Handle, - uint8_t UUID_Type, - const UUID_t* UUID ); - -/** - * @brief ACI_GATT_READ_LONG_CHAR_VALUE - * Start the procedure to read a long characteristic value. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. Before procedure completion the response packets are given - * through ACI_ATT_READ_BLOB_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the characteristic value to be read - * @param Val_Offset Offset from which the value needs to be read - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_long_char_value( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset ); - -/** - * @brief ACI_GATT_READ_MULTIPLE_CHAR_VALUE - * Start a procedure to read multiple characteristic values from a server. - * This sub-procedure is used to read multiple Characteristic Values from a - * server when the client knows the Characteristic Value Handles. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. Before procedure completion the response packets are given - * through ACI_ATT_READ_MULTIPLE_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Number_of_Handles The number of handles for which the value has to be - * read - * @param Handle_Entry See @ref Handle_Entry_t - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_multiple_char_value( uint16_t Connection_Handle, - uint8_t Number_of_Handles, - const Handle_Entry_t* Handle_Entry ); - -/** - * @brief ACI_GATT_WRITE_CHAR_VALUE - * Start the procedure to write a characteristic value. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the characteristic value to be written - * @param Attribute_Val_Length Length of the value to be written - * @param Attribute_Val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_char_value( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_GATT_WRITE_LONG_CHAR_VALUE - * Start the procedure to write a long characteristic value. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. During the procedure, ACI_ATT_PREPARE_WRITE_RESP_EVENT and - * ACI_ATT_EXEC_WRITE_RESP_EVENT events are raised. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the characteristic value to be written - * @param Val_Offset Offset at which the attribute has to be written - * @param Attribute_Val_Length Length of the value to be written - * @param Attribute_Val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_long_char_value( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_GATT_WRITE_CHAR_RELIABLE - * Start the procedure to write a characteristic reliably. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. During the procedure, ACI_ATT_PREPARE_WRITE_RESP_EVENT and - * ACI_ATT_EXEC_WRITE_RESP_EVENT events are raised. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the attribute to be written - * @param Val_Offset Offset at which the attribute has to be written - * @param Attribute_Val_Length Length of the value to be written - * @param Attribute_Val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_char_reliable( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_GATT_WRITE_LONG_CHAR_DESC - * Start the procedure to write a long characteristic descriptor. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. During the procedure, ACI_ATT_PREPARE_WRITE_RESP_EVENT and - * ACI_ATT_EXEC_WRITE_RESP_EVENT events are raised. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the attribute to be written - * @param Val_Offset Offset at which the attribute has to be written - * @param Attribute_Val_Length Length of the value to be written - * @param Attribute_Val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_long_char_desc( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_GATT_READ_LONG_CHAR_DESC - * Start the procedure to read a long characteristic value. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. Before procedure completion the response packets are given - * through ACI_ATT_READ_BLOB_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the characteristic descriptor - * @param Val_Offset Offset from which the value needs to be read - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_long_char_desc( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint16_t Val_Offset ); - -/** - * @brief ACI_GATT_WRITE_CHAR_DESC - * Start the procedure to write a characteristic descriptor. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the attribute to be written - * @param Attribute_Val_Length Length of the value to be written - * @param Attribute_Val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_char_desc( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_GATT_READ_CHAR_DESC - * Start the procedure to read the descriptor specified. - * When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is - * generated. - * Before procedure completion the response packet is given through - * ACI_ATT_READ_RESP_EVENT event. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the descriptor to be read - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_char_desc( uint16_t Connection_Handle, - uint16_t Attr_Handle ); - -/** - * @brief ACI_GATT_WRITE_WITHOUT_RESP - * Start the procedure to write a characteristic value without waiting for any - * response from the server. No events are generated after this command is - * executed. The length of the value to be written must not exceed (ATT_MTU - - * 3); it must also not exceed (BLE_EVT_MAX_PARAM_LEN - 5) i.e. 250 for - * BLE_EVT_MAX_PARAM_LEN default value. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the characteristic value to be written - * @param Attribute_Val_Length Length of the value to be written - * @param Attribute_Val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_without_resp( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_GATT_SIGNED_WRITE_WITHOUT_RESP - * Start a signed write without response from the server. - * The procedure is used to write a characteristic value with an authentication - * signature without waiting for any response from the server. It cannot be - * used when the link is encrypted. The length of the value to be written must - * not exceed (ATT_MTU - 15); it must also not exceed (BLE_EVT_MAX_PARAM_LEN - - * 5) i.e. 250 for BLE_EVT_MAX_PARAM_LEN default value. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the characteristic value to be written - * @param Attribute_Val_Length Length of the value to be written - * @param Attribute_Val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_signed_write_without_resp( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_GATT_CONFIRM_INDICATION - * Allow application to confirm indication. This command has to be sent when - * the application receives the event ACI_GATT_INDICATION_EVENT. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_confirm_indication( uint16_t Connection_Handle ); - -/** - * @brief ACI_GATT_WRITE_RESP - * Allow or reject a write request from a client. - * This command has to be sent by the application when it receives the - * ACI_GATT_WRITE_PERMIT_REQ_EVENT. If the write can be allowed, then the - * status and error code has to be set to 0. If the write cannot be allowed, - * then the status has to be set to 1 and the error code has to be set to the - * error code that has to be passed to the client. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Attr_Handle Handle of the attribute that was passed in the event - * ACI_GATT_WRITE_PERMIT_REQ_EVENT - * @param Write_status If the value can be written or not. - * Values: - * - 0x00: The value can be written to the attribute specified by - * attr_handle - * - 0x01: The value cannot be written to the attribute specified by the - * attr_handle - * @param Error_Code The error code that has to be passed to the client in case - * the write has to be rejected - * @param Attribute_Val_Length Length of the value to be written as passed in - * the event ACI_GATT_WRITE_PERMIT_REQ_EVENT - * @param Attribute_Val Value as passed in the event - * ACI_GATT_WRITE_PERMIT_REQ_EVENT - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_resp( uint16_t Connection_Handle, - uint16_t Attr_Handle, - uint8_t Write_status, - uint8_t Error_Code, - uint8_t Attribute_Val_Length, - const uint8_t* Attribute_Val ); - -/** - * @brief ACI_GATT_ALLOW_READ - * Allow the GATT server to send a response to a read request from a client. - * The application has to send this command when it receives the - * ACI_GATT_READ_PERMIT_REQ_EVENT or ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT. This - * command indicates to the stack that the response can be sent to the client. - * So if the application wishes to update any of the attributes before they are - * read by the client, it has to update the characteristic values using the - * ACI_GATT_UPDATE_CHAR_VALUE and then give this command. The application - * should perform the required operations within 30 seconds. Otherwise the GATT - * procedure will be timeout. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_allow_read( uint16_t Connection_Handle ); - -/** - * @brief ACI_GATT_SET_SECURITY_PERMISSION - * This command sets the security permission for the attribute handle - * specified. Currently the setting of security permission is allowed only for - * client configuration descriptor. - * - * @param Serv_Handle Handle of the service which contains the attribute whose - * security permission has to be modified - * @param Attr_Handle Handle of the attribute whose security permission has to - * be modified - * @param Security_Permissions Security permission flags. - * Flags: - * - 0x00: None - * - 0x01: AUTHEN_READ (Need authentication to read) - * - 0x02: AUTHOR_READ (Need authorization to read) - * - 0x04: ENCRY_READ (Need encryption to read) - * - 0x08: AUTHEN_WRITE (need authentication to write) - * - 0x10: AUTHOR_WRITE (need authorization to write) - * - 0x20: ENCRY_WRITE (need encryption to write) - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_set_security_permission( uint16_t Serv_Handle, - uint16_t Attr_Handle, - uint8_t Security_Permissions ); - -/** - * @brief ACI_GATT_SET_DESC_VALUE - * This command sets the value of the descriptor specified by charDescHandle. - * - * @param Serv_Handle Handle of the service which contains the characteristic - * descriptor - * @param Char_Handle Handle of the characteristic which contains the - * descriptor - * @param Char_Desc_Handle Handle of the descriptor whose value has to be set - * @param Val_Offset Offset from which the descriptor value has to be updated - * @param Char_Desc_Value_Length Length of the descriptor value - * @param Char_Desc_Value Descriptor value - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_set_desc_value( uint16_t Serv_Handle, - uint16_t Char_Handle, - uint16_t Char_Desc_Handle, - uint16_t Val_Offset, - uint8_t Char_Desc_Value_Length, - const uint8_t* Char_Desc_Value ); - -/** - * @brief ACI_GATT_READ_HANDLE_VALUE - * Reads the value of the attribute handle specified from the local GATT - * database. - * - * @param Attr_Handle Handle of the attribute to read - * @param Offset Offset from which the value needs to be read - * @param Value_Length_Requested Maximum number of octets to be returned as - * attribute value - * @param[out] Length Length of the attribute value - * @param[out] Value_Length Length in octets of the Value parameter - * @param[out] Value Attribute value - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_handle_value( uint16_t Attr_Handle, - uint16_t Offset, - uint16_t Value_Length_Requested, - uint16_t* Length, - uint16_t* Value_Length, - uint8_t* Value ); - -/** - * @brief ACI_GATT_UPDATE_CHAR_VALUE_EXT - * This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to - * support update of long attribute up to 512 bytes and indicate selectively - * the generation of Indication/Notification. - * - * @param Conn_Handle_To_Notify Connection handle to notify. Notify all - * subscribed clients if equal to 0x0000 - * @param Service_Handle Handle of service to which the characteristic belongs - * @param Char_Handle Handle of the characteristic declaration - * @param Update_Type Allow Notification or Indication generation, - * if enabled in the client characteristic configuration descriptor - * Flags: - * - 0x00: Do not notify - * - 0x01: Notification - * - 0x02: Indication - * @param Char_Length Total length of the characteristic value. - * In case of a variable size characteristic, this field specifies the - * new length of the characteristic value after the update; in case of - * fixed length characteristic this field is ignored. - * @param Value_Offset The offset from which the attribute value has to be - * updated. - * @param Value_Length Length of the Value parameter in octets - * @param Value Updated characteristic value - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_update_char_value_ext( uint16_t Conn_Handle_To_Notify, - uint16_t Service_Handle, - uint16_t Char_Handle, - uint8_t Update_Type, - uint16_t Char_Length, - uint16_t Value_Offset, - uint8_t Value_Length, - const uint8_t* Value ); - -/** - * @brief ACI_GATT_DENY_READ - * Deny the GATT server to send a response to a read request from a client. - * The application may send this command when it receives the - * ACI_GATT_READ_PERMIT_REQ_EVENT or ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT. - * This command indicates to the stack that the client is not allowed to read - * the requested characteristic due to e.g. application restrictions. - * The Error code shall be either 0x08 (Insufficient Authorization) or a value - * in the range 0x80-0x9F (Application Error). - * The application should issue the ACI_GATT_DENY_READ or ACI_GATT_ALLOW_READ - * command within 30 seconds from the reception of the - * ACI_GATT_READ_PERMIT_REQ_EVENT or ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT - * events; otherwise the GATT procedure issues a timeout. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Error_Code Error code for the command - * Values: - * - 0x08: Insufficient Authorization - * - 0x80 ... 0x9F: Application Error - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_deny_read( uint16_t Connection_Handle, - uint8_t Error_Code ); - -/** - * @brief ACI_GATT_SET_ACCESS_PERMISSION - * This command sets the access permission for the attribute handle specified. - * - * @param Serv_Handle Handle of the service which contains the attribute whose - * access permission has to be modified - * @param Attr_Handle Handle of the attribute whose security permission has to - * be modified - * @param Access_Permissions Access permission - * Flags: - * - 0x00: None - * - 0x01: READ - * - 0x02: WRITE - * - 0x04: WRITE_WO_RESP - * - 0x08: SIGNED_WRITE - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_set_access_permission( uint16_t Serv_Handle, - uint16_t Attr_Handle, - uint8_t Access_Permissions ); - - -#endif /* BLE_GATT_ACI_H__ */ diff --git a/lib_blewbxx/core/auto/ble_hal_aci.c b/lib_blewbxx/core/auto/ble_hal_aci.c deleted file mode 100644 index 147839ad5..000000000 --- a/lib_blewbxx/core/auto/ble_hal_aci.c +++ /dev/null @@ -1,416 +0,0 @@ -/****************************************************************************** - * @file ble_hal_aci.c - * @author MCD - * @brief STM32WB BLE API (hal_aci) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#include "ble_hal_aci.h" - -tBleStatus aci_hal_get_fw_build_number( uint16_t* Build_Number ) -{ - struct hci_request rq; - aci_hal_get_fw_build_number_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x000; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Build_Number = resp.Build_Number; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_hal_write_config_data( uint8_t Offset, - uint8_t Length, - const uint8_t* Value ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_write_config_data_cp0 *cp0 = (aci_hal_write_config_data_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Offset = Offset; - index_input += 1; - cp0->Length = Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Value, (const void*)Value, Length ); - index_input += Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x00c; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_read_config_data( uint8_t Offset, - uint8_t* Data_Length, - uint8_t* Data ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_read_config_data_cp0 *cp0 = (aci_hal_read_config_data_cp0*)(cmd_buffer); - aci_hal_read_config_data_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Offset = Offset; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x00d; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Data_Length = resp.Data_Length; - Osal_MemCpy( (void*)Data, (const void*)resp.Data, *Data_Length); - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_hal_set_tx_power_level( uint8_t En_High_Power, - uint8_t PA_Level ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_set_tx_power_level_cp0 *cp0 = (aci_hal_set_tx_power_level_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->En_High_Power = En_High_Power; - index_input += 1; - cp0->PA_Level = PA_Level; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x00f; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_le_tx_test_packet_number( uint32_t* Number_Of_Packets ) -{ - struct hci_request rq; - aci_hal_le_tx_test_packet_number_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x014; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Number_Of_Packets = resp.Number_Of_Packets; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_hal_tone_start( uint8_t RF_Channel, - uint8_t Freq_offset ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_tone_start_cp0 *cp0 = (aci_hal_tone_start_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->RF_Channel = RF_Channel; - index_input += 1; - cp0->Freq_offset = Freq_offset; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x015; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_tone_stop( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x016; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_get_link_status( uint8_t* Link_Status, - uint16_t* Link_Connection_Handle ) -{ - struct hci_request rq; - aci_hal_get_link_status_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x017; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)Link_Status, (const void*)resp.Link_Status, 8 ); - Osal_MemCpy( (void*)Link_Connection_Handle, (const void*)resp.Link_Connection_Handle, 16 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_hal_set_radio_activity_mask( uint16_t Radio_Activity_Mask ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_set_radio_activity_mask_cp0 *cp0 = (aci_hal_set_radio_activity_mask_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Radio_Activity_Mask = Radio_Activity_Mask; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x018; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_get_anchor_period( uint32_t* Anchor_Period, - uint32_t* Max_Free_Slot ) -{ - struct hci_request rq; - aci_hal_get_anchor_period_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x019; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Anchor_Period = resp.Anchor_Period; - *Max_Free_Slot = resp.Max_Free_Slot; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_hal_set_event_mask( uint32_t Event_Mask ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_set_event_mask_cp0 *cp0 = (aci_hal_set_event_mask_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Event_Mask = Event_Mask; - index_input += 4; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x01a; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_set_smp_eng_config( uint32_t SMP_Config ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_set_smp_eng_config_cp0 *cp0 = (aci_hal_set_smp_eng_config_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->SMP_Config = SMP_Config; - index_input += 4; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x01b; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_get_pm_debug_info( uint8_t* Allocated_For_TX, - uint8_t* Allocated_For_RX, - uint8_t* Allocated_MBlocks ) -{ - struct hci_request rq; - aci_hal_get_pm_debug_info_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x01c; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Allocated_For_TX = resp.Allocated_For_TX; - *Allocated_For_RX = resp.Allocated_For_RX; - *Allocated_MBlocks = resp.Allocated_MBlocks; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_hal_read_radio_reg( uint8_t Register_Address, - uint8_t* reg_val ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_read_radio_reg_cp0 *cp0 = (aci_hal_read_radio_reg_cp0*)(cmd_buffer); - aci_hal_read_radio_reg_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Register_Address = Register_Address; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x030; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *reg_val = resp.reg_val; - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_hal_write_radio_reg( uint8_t Register_Address, - uint8_t Register_Value ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_write_radio_reg_cp0 *cp0 = (aci_hal_write_radio_reg_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Register_Address = Register_Address; - index_input += 1; - cp0->Register_Value = Register_Value; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x031; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_read_raw_rssi( uint8_t* Value ) -{ - struct hci_request rq; - aci_hal_read_raw_rssi_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x032; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)Value, (const void*)resp.Value, 3 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_hal_rx_start( uint8_t RF_Channel ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_hal_rx_start_cp0 *cp0 = (aci_hal_rx_start_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->RF_Channel = RF_Channel; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x033; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_rx_stop( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x034; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_hal_stack_reset( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x03b; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - diff --git a/lib_blewbxx/core/auto/ble_hal_aci.h b/lib_blewbxx/core/auto/ble_hal_aci.h deleted file mode 100644 index 9a04aa497..000000000 --- a/lib_blewbxx/core/auto/ble_hal_aci.h +++ /dev/null @@ -1,368 +0,0 @@ -/****************************************************************************** - * @file ble_hal_aci.h - * @author MCD - * @brief STM32WB BLE API (hal_aci) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_HAL_ACI_H__ -#define BLE_HAL_ACI_H__ - - -#include "ble_types.h" - -/** - * @brief ACI_HAL_GET_FW_BUILD_NUMBER - * This command returns the build number associated with the firmware version - * currently running - * - * @param[out] Build_Number Build number of the firmware. - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_get_fw_build_number( uint16_t* Build_Number ); - -/** - * @brief ACI_HAL_WRITE_CONFIG_DATA - * This command writes a value to a low level configure data structure. It is - * useful to setup directly some low level parameters for the system in the - * runtime. - * - * @param Offset Offset of the element in the configuration data structure - * which has to be written. - * Values: - * - 0x00: CONFIG_DATA_PUBADDR_OFFSET; - * Bluetooth public address; 6 bytes - * - 0x08: CONFIG_DATA_ER_OFFSET; - * Encryption root key used to derive LTK and CSRK; 16 bytes - * - 0x18: CONFIG_DATA_IR_OFFSET; - * Identity root key used to derive LTK and CSRK; 16 bytes - * - 0x2E: CONFIG_DATA_RANDOM_ADDRESS_WR; - * Static Random Address; 6 bytes - * @param Length Length of data to be written - * @param Value Data to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_write_config_data( uint8_t Offset, - uint8_t Length, - const uint8_t* Value ); - -/** - * @brief ACI_HAL_READ_CONFIG_DATA - * This command requests the value in the low level configure data structure. - * The number of read bytes changes for different Offset. - * - * @param Offset Offset of the element in the configuration data structure - * which has to be read. - * Values: - * - 0x00: CONFIG_DATA_PUBADDR_OFFSET; - * Bluetooth public address; 6 bytes - * - 0x08: CONFIG_DATA_ER_OFFSET; - * Encryption root key used to derive LTK and CSRK; 16 bytes - * - 0x18: CONFIG_DATA_IR_OFFSET - * Identity root key used to derive LTK and CSRK; 16 bytes - * - 0x80: CONFIG_DATA_RANDOM_ADDRESS - * Static random address; 6 bytes (read-only) - * @param[out] Data_Length Length of Data in octets - * @param[out] Data Data field associated with Offset parameter - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_read_config_data( uint8_t Offset, - uint8_t* Data_Length, - uint8_t* Data ); - -/** - * @brief ACI_HAL_SET_TX_POWER_LEVEL - * This command sets the TX power level of the device. By controlling the - * PA_LEVEL, that determines the output power level (dBm) at the IC pin. - * When the system starts up or reboots, the default TX power level will be - * used, which is the maximum value of 6 dBm. Once this command is given, the - * output power will be changed instantly, regardless if there is Bluetooth - * communication going on or not. For example, for debugging purpose, the - * device can be set to advertise all the time. And use this command to observe - * the signal strength changing. - * The system will keep the last received TX power level from the command, i.e. - * the 2nd command overwrites the previous TX power level. The new TX power - * level remains until another Set TX Power command, or the system reboots. - * - * @param En_High_Power Enable High Power mode - Deprecated and ignored on - * STM32WB - * Values: - * - 0x00: Standard Power - * - 0x01: High Power - * @param PA_Level Power amplifier output level. Output power is indicative and - * it depends on the PCB layout and associated - * components.Here the values are given at the IC pin - * Values: - * - 0x00: -40 dBm - * - 0x01: -20.85 dBm - * - 0x02: -19.75 dBm - * - 0x03: -18.85 dBm - * - 0x04: -17.6 dBm - * - 0x05: -16.5 dBm - * - 0x06: -15.25 dBm - * - 0x07: -14.1 dBm - * - 0x08: -13.15 dBm - * - 0x09: -12.05 dBm - * - 0x0A: -10.9 dBm - * - 0x0B: -9.9 dBm - * - 0x0C: -8.85 dBm - * - 0x0D: -7.8 dBm - * - 0x0E: -6.9 dBm - * - 0x0F: -5.9 dBm - * - 0x10: -4.95 dBm - * - 0x11: -4 dBm - * - 0x12: -3.15 dBm - * - 0x13: -2.45 dBm - * - 0x14: -1.8 dBm - * - 0x15: -1.3 dBm - * - 0x16: -0.85 dBm - * - 0x17: -0.5 dBm - * - 0x18: -0.15 dBm - * - 0x19: 0 dBm - * - 0x1A: +1 dBm - * - 0x1B: +2 dBm - * - 0x1C: +3 dBm - * - 0x1D: +4 dBm - * - 0x1E: +5 dBm - * - 0x1F: +6 dBm - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_set_tx_power_level( uint8_t En_High_Power, - uint8_t PA_Level ); - -/** - * @brief ACI_HAL_LE_TX_TEST_PACKET_NUMBER - * This command returns the number of packets sent in Direct Test Mode. - * When the Direct TX test is started, a 32-bit counter is used to count how - * many packets have been transmitted. - * This command can be used to check how many packets have been sent during the - * Direct TX test. - * The counter starts from 0 and counts upwards. The counter can wrap and start - * from 0 again. The counter is not cleared until the next Direct TX test - * starts. - * - * @param[out] Number_Of_Packets Number of packets sent during the last Direct - * TX test. - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_le_tx_test_packet_number( uint32_t* Number_Of_Packets ); - -/** - * @brief ACI_HAL_TONE_START - * This command starts a carrier frequency, i.e. a tone, on a specific channel. - * The frequency sine wave at the specific channel may be used for debugging - * purpose only. The channel ID is a parameter from 0x00 to 0x27 for the 40 BLE - * channels, e.g. 0x00 for 2.402 GHz, 0x01 for 2.404 GHz etc. - * This command should not be used when normal Bluetooth activities are - * ongoing. - * The tone should be stopped by ACI_HAL_TONE_STOP command. - * - * @param RF_Channel BLE Channel ID, from 0x00 to 0x27 meaning (2.402 + 2*0xXX) - * GHz - * Device will continuously emit 0s, that means that the tone - * will be at the channel center frequency less the maximum - * frequency deviation (250kHz). - * Values: - * - 0x00 ... 0x27 - * @param Freq_offset Frequency Offset for tone channel - * Values: - * - 0x00 ... 0xFF - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_tone_start( uint8_t RF_Channel, - uint8_t Freq_offset ); - -/** - * @brief ACI_HAL_TONE_STOP - * This command is used to stop the previously started ACI_HAL_TONE_START - * command. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_tone_stop( void ); - -/** - * @brief ACI_HAL_GET_LINK_STATUS - * This command returns the status of the 8 Bluetooth low energy links managed - * by the device - * - * @param[out] Link_Status Array of link status (8 links). Each link status is - * 1 byte. - * Values: - * - 0x00: Idle - * - 0x01: Advertising - * - 0x02: Connected in slave role - * - 0x03: Scanning - * - 0x04: Reserved - * - 0x05: Connected in master role - * - 0x06: TX test mode - * - 0x07: RX test mode - * @param[out] Link_Connection_Handle Array of connection handles (2 bytes) for - * 8 links. - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_get_link_status( uint8_t* Link_Status, - uint16_t* Link_Connection_Handle ); - -/** - * @brief ACI_HAL_SET_RADIO_ACTIVITY_MASK - * This command set the bitmask associated to - * ACI_HAL_END_OF_RADIO_ACTIVITY_EVENT. - * Only the radio activities enabled in the mask will be reported to - * application by ACI_HAL_END_OF_RADIO_ACTIVITY_EVENT - * - * @param Radio_Activity_Mask Bitmask of radio events - * Flags: - * - 0x0001: Idle - * - 0x0002: Advertising - * - 0x0004: Connection event slave - * - 0x0008: Scanning - * - 0x0010: Connection request - * - 0x0020: Connection event master - * - 0x0040: TX test mode - * - 0x0080: RX test mode - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_set_radio_activity_mask( uint16_t Radio_Activity_Mask ); - -/** - * @brief ACI_HAL_GET_ANCHOR_PERIOD - * This command returns information about the Anchor Period to help application - * in selecting slot timings when operating in multi-link scenarios. - * - * @param[out] Anchor_Period Current anchor period. - * T = N * 0.625 ms. - * @param[out] Max_Free_Slot Maximum available time that can be allocated for a - * new slot. - * T = N * 0.625 ms. - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_get_anchor_period( uint32_t* Anchor_Period, - uint32_t* Max_Free_Slot ); - -/** - * @brief ACI_HAL_SET_EVENT_MASK - * This command is used to enable/disable the generation of HAL events - * - * @param Event_Mask Mask to enable/disable generation of HAL events - * Flags: - * - 0x00000000: No events specified (Default) - * - 0x00000001: ACI_HAL_SCAN_REQ_REPORT_EVENT - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_set_event_mask( uint32_t Event_Mask ); - -/** - * @brief ACI_HAL_SET_SMP_ENG_CONFIG - * This command is used to provide a specific engineering setup to the Security - * Manager Protocol Layer. It may be used during development/debug only! - * - * @param SMP_Config Mask to configure SMP engineering knobs - * Flags: - * - 0x00000000: Default config (all reset) - * - 0x00000001: Cheat Level 1 ON - * - 0x00000002: RFU - * - 0x00000003: Cheat Level 3 ON - * - 0x00000004: RFU - * - 0x00000005: Cheat Level 5 ON - * - 0x00000006: Cheat Level 6 ON - * - 0x00000007: Cheat Level 7 ON - * - 0x00000010: DBG messages ON - * - 0x00000100: Debug Public Key ON - * - 0x00000107: Debug KEY On + DBG msg Off + CL=7 - * - 0x00000117: Debug KEY On + DBG msg On + CL=7 - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_set_smp_eng_config( uint32_t SMP_Config ); - -/** - * @brief ACI_HAL_GET_PM_DEBUG_INFO - * This command is used to retrieve TX, RX and total buffer count allocated for - * ACL packets. - * - * @param[out] Allocated_For_TX MBlocks allocated for TXing - * @param[out] Allocated_For_RX MBlocks allocated for RXing - * @param[out] Allocated_MBlocks Overall allocated MBlocks - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_get_pm_debug_info( uint8_t* Allocated_For_TX, - uint8_t* Allocated_For_RX, - uint8_t* Allocated_MBlocks ); - -/** - * @brief ACI_HAL_READ_RADIO_REG - * This command Reads Register value from the RF module. - * - * @param Register_Address Address of the register to be read - * @param[out] reg_val Register value - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_read_radio_reg( uint8_t Register_Address, - uint8_t* reg_val ); - -/** - * @brief ACI_HAL_WRITE_RADIO_REG - * This command writes Register value to the RF module. - * - * @param Register_Address Address of the register to be written - * @param Register_Value Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_write_radio_reg( uint8_t Register_Address, - uint8_t Register_Value ); - -/** - * @brief ACI_HAL_READ_RAW_RSSI - * This command returns the raw value of the RSSI. - * - * @param[out] Value RAW RSSI value - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_read_raw_rssi( uint8_t* Value ); - -/** - * @brief ACI_HAL_RX_START - * This command does set up the RF to listen to a specific RF channel. - * - * @param RF_Channel BLE Channel ID, from 0x00 to 0x27 meaning (2.402 + 2*0xXX) - * GHz - * Device will continuously emit 0s, that means that the tone - * will be at the channel center frequency less the maximum - * frequency deviation (250kHz). - * Values: - * - 0x00 ... 0x27 - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_rx_start( uint8_t RF_Channel ); - -/** - * @brief ACI_HAL_RX_STOP - * This command stop a previous ACI_HAL_RX_START command. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_rx_stop( void ); - -/** - * @brief ACI_HAL_STACK_RESET - * This command is equivalent to HCI_RESET but ensures the sleep mode is - * entered immediately after its completion. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_stack_reset( void ); - - -#endif /* BLE_HAL_ACI_H__ */ diff --git a/lib_blewbxx/core/auto/ble_hci_le.c b/lib_blewbxx/core/auto/ble_hci_le.c deleted file mode 100644 index 127892e07..000000000 --- a/lib_blewbxx/core/auto/ble_hci_le.c +++ /dev/null @@ -1,1567 +0,0 @@ -/****************************************************************************** - * @file ble_hci_le.c - * @author MCD - * @brief STM32WB BLE API (hci_le) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#include "ble_hci_le.h" - -tBleStatus hci_disconnect( uint16_t Connection_Handle, - uint8_t Reason ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_disconnect_cp0 *cp0 = (hci_disconnect_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Reason = Reason; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x01; - rq.ocf = 0x006; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_read_remote_version_information( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_read_remote_version_information_cp0 *cp0 = (hci_read_remote_version_information_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x01; - rq.ocf = 0x01d; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_set_event_mask( const uint8_t* Event_Mask ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_set_event_mask_cp0 *cp0 = (hci_set_event_mask_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - Osal_MemCpy( (void*)&cp0->Event_Mask, (const void*)Event_Mask, 8 ); - index_input += 8; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x03; - rq.ocf = 0x001; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_reset( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x03; - rq.ocf = 0x003; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_read_transmit_power_level( uint16_t Connection_Handle, - uint8_t Type, - uint8_t* Transmit_Power_Level ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_read_transmit_power_level_cp0 *cp0 = (hci_read_transmit_power_level_cp0*)(cmd_buffer); - hci_read_transmit_power_level_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Type = Type; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x03; - rq.ocf = 0x02d; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Transmit_Power_Level = resp.Transmit_Power_Level; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_set_controller_to_host_flow_control( uint8_t Flow_Control_Enable ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_set_controller_to_host_flow_control_cp0 *cp0 = (hci_set_controller_to_host_flow_control_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Flow_Control_Enable = Flow_Control_Enable; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x03; - rq.ocf = 0x031; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_host_buffer_size( uint16_t Host_ACL_Data_Packet_Length, - uint8_t Host_Synchronous_Data_Packet_Length, - uint16_t Host_Total_Num_ACL_Data_Packets, - uint16_t Host_Total_Num_Synchronous_Data_Packets ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_host_buffer_size_cp0 *cp0 = (hci_host_buffer_size_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Host_ACL_Data_Packet_Length = Host_ACL_Data_Packet_Length; - index_input += 2; - cp0->Host_Synchronous_Data_Packet_Length = Host_Synchronous_Data_Packet_Length; - index_input += 1; - cp0->Host_Total_Num_ACL_Data_Packets = Host_Total_Num_ACL_Data_Packets; - index_input += 2; - cp0->Host_Total_Num_Synchronous_Data_Packets = Host_Total_Num_Synchronous_Data_Packets; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x03; - rq.ocf = 0x033; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_host_number_of_completed_packets( uint8_t Number_Of_Handles, - const Host_Nb_Of_Completed_Pkt_Pair_t* Host_Nb_Of_Completed_Pkt_Pair ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_host_number_of_completed_packets_cp0 *cp0 = (hci_host_number_of_completed_packets_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Number_Of_Handles = Number_Of_Handles; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Host_Nb_Of_Completed_Pkt_Pair, (const void*)Host_Nb_Of_Completed_Pkt_Pair, Number_Of_Handles * (sizeof(Host_Nb_Of_Completed_Pkt_Pair_t)) ); - index_input += Number_Of_Handles * (sizeof(Host_Nb_Of_Completed_Pkt_Pair_t)); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x03; - rq.ocf = 0x035; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_read_local_version_information( uint8_t* HCI_Version, - uint16_t* HCI_Revision, - uint8_t* LMP_PAL_Version, - uint16_t* Manufacturer_Name, - uint16_t* LMP_PAL_Subversion ) -{ - struct hci_request rq; - hci_read_local_version_information_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x04; - rq.ocf = 0x001; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *HCI_Version = resp.HCI_Version; - *HCI_Revision = resp.HCI_Revision; - *LMP_PAL_Version = resp.LMP_PAL_Version; - *Manufacturer_Name = resp.Manufacturer_Name; - *LMP_PAL_Subversion = resp.LMP_PAL_Subversion; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_read_local_supported_commands( uint8_t* Supported_Commands ) -{ - struct hci_request rq; - hci_read_local_supported_commands_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x04; - rq.ocf = 0x002; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)Supported_Commands, (const void*)resp.Supported_Commands, 64 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_read_local_supported_features( uint8_t* LMP_Features ) -{ - struct hci_request rq; - hci_read_local_supported_features_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x04; - rq.ocf = 0x003; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)LMP_Features, (const void*)resp.LMP_Features, 8 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_read_bd_addr( uint8_t* BD_ADDR ) -{ - struct hci_request rq; - hci_read_bd_addr_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x04; - rq.ocf = 0x009; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)BD_ADDR, (const void*)resp.BD_ADDR, 6 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_read_rssi( uint16_t Connection_Handle, - uint8_t* RSSI ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_read_rssi_cp0 *cp0 = (hci_read_rssi_cp0*)(cmd_buffer); - hci_read_rssi_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x05; - rq.ocf = 0x005; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *RSSI = resp.RSSI; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_set_event_mask( const uint8_t* LE_Event_Mask ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_event_mask_cp0 *cp0 = (hci_le_set_event_mask_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - Osal_MemCpy( (void*)&cp0->LE_Event_Mask, (const void*)LE_Event_Mask, 8 ); - index_input += 8; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x001; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_read_buffer_size( uint16_t* HC_LE_ACL_Data_Packet_Length, - uint8_t* HC_Total_Num_LE_ACL_Data_Packets ) -{ - struct hci_request rq; - hci_le_read_buffer_size_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x002; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *HC_LE_ACL_Data_Packet_Length = resp.HC_LE_ACL_Data_Packet_Length; - *HC_Total_Num_LE_ACL_Data_Packets = resp.HC_Total_Num_LE_ACL_Data_Packets; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_read_local_supported_features( uint8_t* LE_Features ) -{ - struct hci_request rq; - hci_le_read_local_supported_features_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x003; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)LE_Features, (const void*)resp.LE_Features, 8 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_set_random_address( const uint8_t* Random_Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_random_address_cp0 *cp0 = (hci_le_set_random_address_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - Osal_MemCpy( (void*)&cp0->Random_Address, (const void*)Random_Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x005; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_set_advertising_parameters( uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Advertising_Type, - uint8_t Own_Address_Type, - uint8_t Peer_Address_Type, - const uint8_t* Peer_Address, - uint8_t Advertising_Channel_Map, - uint8_t Advertising_Filter_Policy ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_advertising_parameters_cp0 *cp0 = (hci_le_set_advertising_parameters_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Advertising_Interval_Min = Advertising_Interval_Min; - index_input += 2; - cp0->Advertising_Interval_Max = Advertising_Interval_Max; - index_input += 2; - cp0->Advertising_Type = Advertising_Type; - index_input += 1; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Peer_Address_Type = Peer_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Address, (const void*)Peer_Address, 6 ); - index_input += 6; - cp0->Advertising_Channel_Map = Advertising_Channel_Map; - index_input += 1; - cp0->Advertising_Filter_Policy = Advertising_Filter_Policy; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x006; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_read_advertising_channel_tx_power( uint8_t* Transmit_Power_Level ) -{ - struct hci_request rq; - hci_le_read_advertising_channel_tx_power_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x007; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Transmit_Power_Level = resp.Transmit_Power_Level; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_set_advertising_data( uint8_t Advertising_Data_Length, - const uint8_t* Advertising_Data ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_advertising_data_cp0 *cp0 = (hci_le_set_advertising_data_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Advertising_Data_Length = Advertising_Data_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Advertising_Data, (const void*)Advertising_Data, 31 ); - index_input += 31; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x008; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_set_scan_response_data( uint8_t Scan_Response_Data_Length, - const uint8_t* Scan_Response_Data ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_scan_response_data_cp0 *cp0 = (hci_le_set_scan_response_data_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Scan_Response_Data_Length = Scan_Response_Data_Length; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Scan_Response_Data, (const void*)Scan_Response_Data, 31 ); - index_input += 31; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x009; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_set_advertise_enable( uint8_t Advertising_Enable ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_advertise_enable_cp0 *cp0 = (hci_le_set_advertise_enable_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Advertising_Enable = Advertising_Enable; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x00a; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_set_scan_parameters( uint8_t LE_Scan_Type, - uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Scanning_Filter_Policy ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_scan_parameters_cp0 *cp0 = (hci_le_set_scan_parameters_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Type = LE_Scan_Type; - index_input += 1; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Scanning_Filter_Policy = Scanning_Filter_Policy; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x00b; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_set_scan_enable( uint8_t LE_Scan_Enable, - uint8_t Filter_Duplicates ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_scan_enable_cp0 *cp0 = (hci_le_set_scan_enable_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Enable = LE_Scan_Enable; - index_input += 1; - cp0->Filter_Duplicates = Filter_Duplicates; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x00c; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_create_connection( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Initiator_Filter_Policy, - uint8_t Peer_Address_Type, - const uint8_t* Peer_Address, - uint8_t Own_Address_Type, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_create_connection_cp0 *cp0 = (hci_le_create_connection_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->LE_Scan_Interval = LE_Scan_Interval; - index_input += 2; - cp0->LE_Scan_Window = LE_Scan_Window; - index_input += 2; - cp0->Initiator_Filter_Policy = Initiator_Filter_Policy; - index_input += 1; - cp0->Peer_Address_Type = Peer_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Address, (const void*)Peer_Address, 6 ); - index_input += 6; - cp0->Own_Address_Type = Own_Address_Type; - index_input += 1; - cp0->Conn_Interval_Min = Conn_Interval_Min; - index_input += 2; - cp0->Conn_Interval_Max = Conn_Interval_Max; - index_input += 2; - cp0->Conn_Latency = Conn_Latency; - index_input += 2; - cp0->Supervision_Timeout = Supervision_Timeout; - index_input += 2; - cp0->Minimum_CE_Length = Minimum_CE_Length; - index_input += 2; - cp0->Maximum_CE_Length = Maximum_CE_Length; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x00d; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_create_connection_cancel( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x00e; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_read_white_list_size( uint8_t* White_List_Size ) -{ - struct hci_request rq; - hci_le_read_white_list_size_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x00f; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *White_List_Size = resp.White_List_Size; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_clear_white_list( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x010; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_add_device_to_white_list( uint8_t Address_Type, - const uint8_t* Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_add_device_to_white_list_cp0 *cp0 = (hci_le_add_device_to_white_list_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Address_Type = Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Address, (const void*)Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x011; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_remove_device_from_white_list( uint8_t Address_Type, - const uint8_t* Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_remove_device_from_white_list_cp0 *cp0 = (hci_le_remove_device_from_white_list_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Address_Type = Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Address, (const void*)Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x012; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_connection_update( uint16_t Connection_Handle, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_connection_update_cp0 *cp0 = (hci_le_connection_update_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Conn_Interval_Min = Conn_Interval_Min; - index_input += 2; - cp0->Conn_Interval_Max = Conn_Interval_Max; - index_input += 2; - cp0->Conn_Latency = Conn_Latency; - index_input += 2; - cp0->Supervision_Timeout = Supervision_Timeout; - index_input += 2; - cp0->Minimum_CE_Length = Minimum_CE_Length; - index_input += 2; - cp0->Maximum_CE_Length = Maximum_CE_Length; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x013; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_set_host_channel_classification( const uint8_t* LE_Channel_Map ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_host_channel_classification_cp0 *cp0 = (hci_le_set_host_channel_classification_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - Osal_MemCpy( (void*)&cp0->LE_Channel_Map, (const void*)LE_Channel_Map, 5 ); - index_input += 5; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x014; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_read_channel_map( uint16_t Connection_Handle, - uint8_t* LE_Channel_Map ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_read_channel_map_cp0 *cp0 = (hci_le_read_channel_map_cp0*)(cmd_buffer); - hci_le_read_channel_map_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x015; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)LE_Channel_Map, (const void*)resp.LE_Channel_Map, 5 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_read_remote_features( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_read_remote_features_cp0 *cp0 = (hci_le_read_remote_features_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x016; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_encrypt( const uint8_t* Key, - const uint8_t* Plaintext_Data, - uint8_t* Encrypted_Data ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_encrypt_cp0 *cp0 = (hci_le_encrypt_cp0*)(cmd_buffer); - hci_le_encrypt_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - Osal_MemCpy( (void*)&cp0->Key, (const void*)Key, 16 ); - index_input += 16; - Osal_MemCpy( (void*)&cp0->Plaintext_Data, (const void*)Plaintext_Data, 16 ); - index_input += 16; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x017; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)Encrypted_Data, (const void*)resp.Encrypted_Data, 16 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_rand( uint8_t* Random_Number ) -{ - struct hci_request rq; - hci_le_rand_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x018; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)Random_Number, (const void*)resp.Random_Number, 8 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_start_encryption( uint16_t Connection_Handle, - const uint8_t* Random_Number, - uint16_t Encrypted_Diversifier, - const uint8_t* Long_Term_Key ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_start_encryption_cp0 *cp0 = (hci_le_start_encryption_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemCpy( (void*)&cp0->Random_Number, (const void*)Random_Number, 8 ); - index_input += 8; - cp0->Encrypted_Diversifier = Encrypted_Diversifier; - index_input += 2; - Osal_MemCpy( (void*)&cp0->Long_Term_Key, (const void*)Long_Term_Key, 16 ); - index_input += 16; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x019; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_long_term_key_request_reply( uint16_t Connection_Handle, - const uint8_t* Long_Term_Key ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_long_term_key_request_reply_cp0 *cp0 = (hci_le_long_term_key_request_reply_cp0*)(cmd_buffer); - hci_le_long_term_key_request_reply_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemCpy( (void*)&cp0->Long_Term_Key, (const void*)Long_Term_Key, 16 ); - index_input += 16; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x01a; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_long_term_key_requested_negative_reply( uint16_t Connection_Handle ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_long_term_key_requested_negative_reply_cp0 *cp0 = (hci_le_long_term_key_requested_negative_reply_cp0*)(cmd_buffer); - hci_le_long_term_key_requested_negative_reply_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x01b; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_read_supported_states( uint8_t* LE_States ) -{ - struct hci_request rq; - hci_le_read_supported_states_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x01c; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)LE_States, (const void*)resp.LE_States, 8 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_receiver_test( uint8_t RX_Frequency ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_receiver_test_cp0 *cp0 = (hci_le_receiver_test_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->RX_Frequency = RX_Frequency; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x01d; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_transmitter_test( uint8_t TX_Frequency, - uint8_t Length_Of_Test_Data, - uint8_t Packet_Payload ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_transmitter_test_cp0 *cp0 = (hci_le_transmitter_test_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->TX_Frequency = TX_Frequency; - index_input += 1; - cp0->Length_Of_Test_Data = Length_Of_Test_Data; - index_input += 1; - cp0->Packet_Payload = Packet_Payload; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x01e; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_test_end( uint16_t* Number_Of_Packets ) -{ - struct hci_request rq; - hci_le_test_end_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x01f; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Number_Of_Packets = resp.Number_Of_Packets; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_set_data_length( uint16_t Connection_Handle, - uint16_t TxOctets, - uint16_t TxTime ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_data_length_cp0 *cp0 = (hci_le_set_data_length_cp0*)(cmd_buffer); - hci_le_set_data_length_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->TxOctets = TxOctets; - index_input += 2; - cp0->TxTime = TxTime; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x022; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_read_suggested_default_data_length( uint16_t* SuggestedMaxTxOctets, - uint16_t* SuggestedMaxTxTime ) -{ - struct hci_request rq; - hci_le_read_suggested_default_data_length_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x023; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *SuggestedMaxTxOctets = resp.SuggestedMaxTxOctets; - *SuggestedMaxTxTime = resp.SuggestedMaxTxTime; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_write_suggested_default_data_length( uint16_t SuggestedMaxTxOctets, - uint16_t SuggestedMaxTxTime ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_write_suggested_default_data_length_cp0 *cp0 = (hci_le_write_suggested_default_data_length_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->SuggestedMaxTxOctets = SuggestedMaxTxOctets; - index_input += 2; - cp0->SuggestedMaxTxTime = SuggestedMaxTxTime; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x024; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_read_local_p256_public_key( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x025; - rq.event = 0x0F; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_generate_dhkey( const uint8_t* Remote_P256_Public_Key ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_generate_dhkey_cp0 *cp0 = (hci_le_generate_dhkey_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - Osal_MemCpy( (void*)&cp0->Remote_P256_Public_Key, (const void*)Remote_P256_Public_Key, 64 ); - index_input += 64; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x026; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_add_device_to_resolving_list( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address, - const uint8_t* Peer_IRK, - const uint8_t* Local_IRK ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_add_device_to_resolving_list_cp0 *cp0 = (hci_le_add_device_to_resolving_list_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Peer_Identity_Address_Type = Peer_Identity_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Identity_Address, (const void*)Peer_Identity_Address, 6 ); - index_input += 6; - Osal_MemCpy( (void*)&cp0->Peer_IRK, (const void*)Peer_IRK, 16 ); - index_input += 16; - Osal_MemCpy( (void*)&cp0->Local_IRK, (const void*)Local_IRK, 16 ); - index_input += 16; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x027; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_remove_device_from_resolving_list( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_remove_device_from_resolving_list_cp0 *cp0 = (hci_le_remove_device_from_resolving_list_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Peer_Identity_Address_Type = Peer_Identity_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Identity_Address, (const void*)Peer_Identity_Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x028; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_clear_resolving_list( void ) -{ - struct hci_request rq; - tBleStatus status = 0; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x029; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_read_resolving_list_size( uint8_t* Resolving_List_Size ) -{ - struct hci_request rq; - hci_le_read_resolving_list_size_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x02a; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Resolving_List_Size = resp.Resolving_List_Size; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_read_peer_resolvable_address( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address, - uint8_t* Peer_Resolvable_Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_read_peer_resolvable_address_cp0 *cp0 = (hci_le_read_peer_resolvable_address_cp0*)(cmd_buffer); - hci_le_read_peer_resolvable_address_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Peer_Identity_Address_Type = Peer_Identity_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Identity_Address, (const void*)Peer_Identity_Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x02b; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)Peer_Resolvable_Address, (const void*)resp.Peer_Resolvable_Address, 6 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_read_local_resolvable_address( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address, - uint8_t* Local_Resolvable_Address ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_read_local_resolvable_address_cp0 *cp0 = (hci_le_read_local_resolvable_address_cp0*)(cmd_buffer); - hci_le_read_local_resolvable_address_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Peer_Identity_Address_Type = Peer_Identity_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Identity_Address, (const void*)Peer_Identity_Address, 6 ); - index_input += 6; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x02c; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - Osal_MemCpy( (void*)Local_Resolvable_Address, (const void*)resp.Local_Resolvable_Address, 6 ); - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_set_address_resolution_enable( uint8_t Address_Resolution_Enable ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_address_resolution_enable_cp0 *cp0 = (hci_le_set_address_resolution_enable_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Address_Resolution_Enable = Address_Resolution_Enable; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x02d; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_set_resolvable_private_address_timeout( uint16_t RPA_Timeout ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_resolvable_private_address_timeout_cp0 *cp0 = (hci_le_set_resolvable_private_address_timeout_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->RPA_Timeout = RPA_Timeout; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x02e; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_read_maximum_data_length( uint16_t* supportedMaxTxOctets, - uint16_t* supportedMaxTxTime, - uint16_t* supportedMaxRxOctets, - uint16_t* supportedMaxRxTime ) -{ - struct hci_request rq; - hci_le_read_maximum_data_length_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x02f; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *supportedMaxTxOctets = resp.supportedMaxTxOctets; - *supportedMaxTxTime = resp.supportedMaxTxTime; - *supportedMaxRxOctets = resp.supportedMaxRxOctets; - *supportedMaxRxTime = resp.supportedMaxRxTime; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_read_phy( uint16_t Connection_Handle, - uint8_t* TX_PHY, - uint8_t* RX_PHY ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_read_phy_cp0 *cp0 = (hci_le_read_phy_cp0*)(cmd_buffer); - hci_le_read_phy_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x030; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *TX_PHY = resp.TX_PHY; - *RX_PHY = resp.RX_PHY; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_set_default_phy( uint8_t ALL_PHYS, - uint8_t TX_PHYS, - uint8_t RX_PHYS ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_default_phy_cp0 *cp0 = (hci_le_set_default_phy_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->ALL_PHYS = ALL_PHYS; - index_input += 1; - cp0->TX_PHYS = TX_PHYS; - index_input += 1; - cp0->RX_PHYS = RX_PHYS; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x031; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_set_phy( uint16_t Connection_Handle, - uint8_t ALL_PHYS, - uint8_t TX_PHYS, - uint8_t RX_PHYS, - uint16_t PHY_options ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_phy_cp0 *cp0 = (hci_le_set_phy_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->ALL_PHYS = ALL_PHYS; - index_input += 1; - cp0->TX_PHYS = TX_PHYS; - index_input += 1; - cp0->RX_PHYS = RX_PHYS; - index_input += 1; - cp0->PHY_options = PHY_options; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x032; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_enhanced_receiver_test( uint8_t RX_Frequency, - uint8_t PHY, - uint8_t Modulation_Index ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_enhanced_receiver_test_cp0 *cp0 = (hci_le_enhanced_receiver_test_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->RX_Frequency = RX_Frequency; - index_input += 1; - cp0->PHY = PHY; - index_input += 1; - cp0->Modulation_Index = Modulation_Index; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x033; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_enhanced_transmitter_test( uint8_t TX_Frequency, - uint8_t Length_Of_Test_Data, - uint8_t Packet_Payload, - uint8_t PHY ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_enhanced_transmitter_test_cp0 *cp0 = (hci_le_enhanced_transmitter_test_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->TX_Frequency = TX_Frequency; - index_input += 1; - cp0->Length_Of_Test_Data = Length_Of_Test_Data; - index_input += 1; - cp0->Packet_Payload = Packet_Payload; - index_input += 1; - cp0->PHY = PHY; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x034; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus hci_le_read_transmit_power( uint8_t* Min_TX_Power, - uint8_t* Max_TX_Power ) -{ - struct hci_request rq; - hci_le_read_transmit_power_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x04b; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Min_TX_Power = resp.Min_TX_Power; - *Max_TX_Power = resp.Max_TX_Power; - return BLE_STATUS_SUCCESS; -} - -tBleStatus hci_le_set_privacy_mode( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address, - uint8_t Privacy_Mode ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - hci_le_set_privacy_mode_cp0 *cp0 = (hci_le_set_privacy_mode_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Peer_Identity_Address_Type = Peer_Identity_Address_Type; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Peer_Identity_Address, (const void*)Peer_Identity_Address, 6 ); - index_input += 6; - cp0->Privacy_Mode = Privacy_Mode; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x08; - rq.ocf = 0x04e; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - diff --git a/lib_blewbxx/core/auto/ble_hci_le.h b/lib_blewbxx/core/auto/ble_hci_le.h deleted file mode 100644 index 8f9c5faf8..000000000 --- a/lib_blewbxx/core/auto/ble_hci_le.h +++ /dev/null @@ -1,1780 +0,0 @@ -/****************************************************************************** - * @file ble_hci_le.h - * @author MCD - * @brief STM32WB BLE API (hci_le) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_HCI_LE_H__ -#define BLE_HCI_LE_H__ - - -#include "ble_types.h" - -/** - * @brief HCI_DISCONNECT - * The HCI_DISCONNECT is used to terminate an existing connection. The - * Connection_Handle command parameter indicates which connection is to be - * disconnected. The Reason command parameter indicates the reason for ending - * the connection. The remote Controller will receive the Reason command - * parameter in the HCI_DISCONNECTION_COMPLETE_EVENT event. All synchronous - * connections on a physical link should be disconnected before the ACL - * connection on the same physical connection is disconnected. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.1.6) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Reason The reason for ending the connection. - * Values: - * - 0x05: Authentication Failure - * - 0x13: Remote User Terminated Connection - * - 0x14: Remote Device Terminated Connection due to Low Resources - * - 0x15: Remote Device Terminated Connection due to Power Off - * - 0x1A: Unsupported Remote Feature - * - 0x3B: Unacceptable Connection Parameters - * @return Value indicating success or error code. - */ -tBleStatus hci_disconnect( uint16_t Connection_Handle, - uint8_t Reason ); - -/** - * @brief HCI_READ_REMOTE_VERSION_INFORMATION - * This command will obtain the values for the version information for the - * remote device identified by the Connection_Handle parameter. The - * Connection_Handle must be a Connection_Handle for an ACL or LE connection. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.1.23) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus hci_read_remote_version_information( uint16_t Connection_Handle ); - -/** - * @brief HCI_SET_EVENT_MASK - * The Set_Event_Mask command is used to control which events are generated by - * the HCI for the Host. If the bit in the Event_Mask is set to a one, then the - * event associated with that bit will be enabled. For an LE Controller, the LE - * Meta Event bit in the Event_Mask shall enable or disable all LE events in - * the LE Meta Event (see Section 7.7.65). The Host has to deal with each event - * that occurs. The event mask allows the Host to control how much it is - * interrupted. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.3.1) - * - * @param Event_Mask Event mask. Default: 0x20001FFFFFFFFFFF - * Flags: - * - 0x0000000000000000: No events specified - * - 0x0000000000000010: Disconnection Complete Event - * - 0x0000000000000080: Encryption Change Event - * - 0x0000000000000800: Read Remote Version Information Complete Event - * - 0x0000000000008000: Hardware Error Event - * - 0x0000800000000000: Encryption Key Refresh Complete Event - * - 0x2000000000000000: LE Meta-Event - * @return Value indicating success or error code. - */ -tBleStatus hci_set_event_mask( const uint8_t* Event_Mask ); - -/** - * @brief HCI_RESET - * The Reset command resets the Link Layer on an LE Controller. The Reset - * command shall not affect the used HCI transport layer since the HCI - * transport layers may have reset mechanisms of their own. After the reset is - * completed, the current operational state is lost, the Controller enters - * standby mode and the Controller automatically reverts to the default values - * for the parameters for which default values are defined in the - * specification. - * Note: The Reset command does not necessarily perform a hardware reset. This - * is implementation defined. - * The Host shall not send additional HCI commands before the Command Complete - * event related to the Reset command has been received. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.3.2) - * - * @return Value indicating success or error code. - */ -tBleStatus hci_reset( void ); - -/** - * @brief HCI_READ_TRANSMIT_POWER_LEVEL - * This command reads the values for the Transmit_Power_Level parameter for the - * specified Connection_Handle. The Connection_Handle shall be a - * Connection_Handle for an ACL connection. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.3.35) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Type Current or maximum transmit power level. - * Values: - * - 0x00: Read Current Transmit Power Level. - * - 0x01: Read Maximum Transmit Power Level. - * @param[out] Transmit_Power_Level Size: 1 Octet (signed integer) - * Units: dBm - * Values: - * - -30 ... 20 - * @return Value indicating success or error code. - */ -tBleStatus hci_read_transmit_power_level( uint16_t Connection_Handle, - uint8_t Type, - uint8_t* Transmit_Power_Level ); - -/** - * @brief HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL - * This command is used by the Host to turn flow control on or off for data - * and/or voice sent in the direction from the Controller to the Host. If flow - * control is turned off, the Host should not send the - * Host_Number_Of_Completed_Packets command. That command will be ignored by - * the Controller if it is sent by the Host and flow control is off. If flow - * control is turned on for HCI ACL Data Packets and off for HCI synchronous - * Data Packets, Host_Number_Of_Completed_Packets commands sent by the Host - * should only contain Connection_Handles for ACL connections. If flow control - * is turned off for HCI ACL Data Packets and on for HCI synchronous Data - * Packets, Host_Number_Of_Completed_Packets commands sent by the Host should - * only contain Connection_Handles for synchronous connections. If flow control - * is turned on for HCI ACL Data Packets and HCI synchronous Data Packets, the - * Host will send Host_Number_Of_Completed_Packets commands both for ACL - * connections and synchronous connections. - * The Flow_Control_Enable parameter shall only be changed if no connections - * exist. - * (See Bluetooth Spec v.5.0, Vol. 2, Part E, 7.3.38) - * - * @param Flow_Control_Enable Enable/Disable the Flow Control - * Values: - * - 0x00: Flow control off in direction from Controller to Host. - * Default. - * - 0x01: Flow control on for HCI ACL Data Packets and off for HCI - * synchronous.Data Packets in direction from Controller to Host. - * - 0x02: Flow control off for HCI ACL Data Packets and on for HCI - * synchronous.Data Packets in direction from Controller to Host. - * - 0x03: Flow control on both for HCI ACL Data Packets and HCI - * synchronous.Data Packets in direction from Controller to Host. - * @return Value indicating success or error code. - */ -tBleStatus hci_set_controller_to_host_flow_control( uint8_t Flow_Control_Enable ); - -/** - * @brief HCI_HOST_BUFFER_SIZE - * The Host_Buffer_Size command is used by the Host to notify the Controller - * about the maximum size of the data portion of HCI ACL and synchronous Data - * Packets sent from the Controller to the Host. The Controller shall segment - * the data to be transmitted from the Controller to the Host according to - * these sizes, so that the HCI Data Packets will contain data with up to these - * sizes. The Host_Buffer_Size command also notifies the Controller about the - * total number of HCI ACL and synchronous Data Packets that can be stored in - * the data buffers of the Host. If flow control from the Controller to the - * Host is turned off, and the Host_Buffer_Size command has not been issued by - * the Host, this means that the Controller will send HCI Data Packets to the - * Host with any lengths the Controller wants to use, and it is assumed that - * the data buffer sizes of the Host are unlimited. If flow control from the - * Controller to the Host is turned on, the Host_Buffer_Size command shall - * after a power-on or a reset always be sent by the Host before the first - * Host_Number_Of_Completed_Packets command is sent. - * The Set Controller To Host Flow Control Command is used to turn flow control - * on or off. - * The Host_ACL_Data_Packet_Length command parameter will be used to determine - * the size of the L2CAP segments contained in ACL Data Packets, which are - * transferred from the Controller to the Host. - * The Host_Synchronous_Data_Packet_Length command parameter is used to - * determine the maximum size of HCI synchronous Data Packets. Both the Host - * and the Controller shall support command and event packets, where the data - * portion (excluding header) contained in the packets is 255 octets in size. - * The Host_Total_Num_ACL_Data_Packets command parameter contains the total - * number of HCI ACL Data Packets that can be stored in the data buffers of the - * Host. The Controller will determine how the buffers are to be divided - * between different Connection_Handles. - * The Host_Total_Num_Synchronous_Data_Packets command parameter gives the same - * information for HCI synchronous Data Packets. - * Note: The Host_ACL_Data_Packet_Length and - * Host_Synchronous_Data_Packet_Length command parameters do not include the - * length of the HCI Data Packet header. - * (See Bluetooth Spec v.5.0, Vol. 2, Part E, 7.3.39) - * - * @param Host_ACL_Data_Packet_Length Maximum length (in octets) of the data - * portion of each HCI ACL Data Packet that the Host is able to accept. - * Must be greater or equal to 251 bytes - * @param Host_Synchronous_Data_Packet_Length Maximum length (in octets) of the - * data portion of each HCI synchronous Data Packet that the Host is - * able to accept. - * @param Host_Total_Num_ACL_Data_Packets Total number of HCI ACL Data Packets - * that can be stored in the data buffers of the Host. - * @param Host_Total_Num_Synchronous_Data_Packets Total number of HCI - * synchronous Data Packets that can be stored in the data buffers of - * the Host. - * @return Value indicating success or error code. - */ -tBleStatus hci_host_buffer_size( uint16_t Host_ACL_Data_Packet_Length, - uint8_t Host_Synchronous_Data_Packet_Length, - uint16_t Host_Total_Num_ACL_Data_Packets, - uint16_t Host_Total_Num_Synchronous_Data_Packets ); - -/** - * @brief HCI_HOST_NUMBER_OF_COMPLETED_PACKETS - * The Host_Number_Of_Completed_Packets command is used by the Host to indicate - * to the Controller the number of HCI Data Packets that have been completed - * for each Connection_Handle since the previous - * Host_Number_Of_Completed_Packets command was sent to the Controller. This - * means that the corresponding buffer space has been freed in the Host. Based - * on this information, and the Host_Total_Num_ACL_Data_Packets and - * Host_Total_Num_Synchronous_Data_Packets command parameters of the - * Host_Buffer_Size command, the Controller can determine for which - * Connection_Handles the following HCI Data Packets should be sent to the - * Host. The command should only be issued by the Host if flow control in the - * direction from the Controller to the Host is on and there is at least one - * connection, or if the Controller is in local loopback mode. Otherwise, the - * command will be ignored by the Controller. When the Host has completed one - * or more HCI Data Packet(s) it shall send a Host_Number_Of_Completed_Packets - * command to the Controller, until it finally reports that all pending HCI - * Data Packets have been completed. The frequency at which this command is - * sent is manufacturer specific. - * The Set Controller To Host Flow Control Command is used to turn flow control - * on or off. If flow control from the Controller to the Host is turned on, the - * Host_Buffer_Size command shall always be sent by the Host after a power-on - * or a reset before the first Host_Number_Of_Completed_Packets command is - * sent. - * Note: The Host_Number_Of_Completed_Packets command is a special command in - * the sense that no event is normally generated after the command has - * completed. The command may be sent at any time by the Host when there is at - * least one connection, or if the Controller is in local loopback mode - * independent of other commands. The normal flow control for commands is not - * used for the Host_Number_Of_Completed_Packets command. - * (See Bluetooth Spec v.5.0, Vol. 2, Part E, 7.3.40) - * - * @param Number_Of_Handles The number of Connection_Handles and - * Host_Num_Of_Completed_Packets parameters pairs contained in this - * command. - * Values: - * - 0 ... 255 - * @param Host_Nb_Of_Completed_Pkt_Pair See @ref - * Host_Nb_Of_Completed_Pkt_Pair_t - * @return Value indicating success or error code. - */ -tBleStatus hci_host_number_of_completed_packets( uint8_t Number_Of_Handles, - const Host_Nb_Of_Completed_Pkt_Pair_t* Host_Nb_Of_Completed_Pkt_Pair ); - -/** - * @brief HCI_READ_LOCAL_VERSION_INFORMATION - * This command reads the values for the version information for the local - * Controller. The HCI Version information defines the version information of - * the HCI layer. The LMP/PAL Version information defines the version of the - * LMP or PAL. The Manufacturer_Name information indicates the manufacturer of - * the local device. The HCI Revision and LMP/PAL Subversion are implementation - * dependent. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.4.1) - * - * @param[out] HCI_Version See Bluetooth Assigned Numbers - * (https://www.bluetooth.org/en-us/specification/assigned-numbers) - * @param[out] HCI_Revision Revision of the Current HCI in the BR/EDR - * Controller. - * @param[out] LMP_PAL_Version Version of the Current LMP or PAL in the - * Controller. - * See Bluetooth Assigned Numbers (https://www.bluetooth.org/en- - * us/specification/assigned-numbers) - * @param[out] Manufacturer_Name Manufacturer Name of the BR/EDR Controller. - * See Bluetooth Assigned Numbers (https://www.bluetooth.org/en- - * us/specification/assigned-numbers) - * @param[out] LMP_PAL_Subversion Subversion of the Current LMP or PAL in the - * Controller. This value is - * implementation dependent. - * @return Value indicating success or error code. - */ -tBleStatus hci_read_local_version_information( uint8_t* HCI_Version, - uint16_t* HCI_Revision, - uint8_t* LMP_PAL_Version, - uint16_t* Manufacturer_Name, - uint16_t* LMP_PAL_Subversion ); - -/** - * @brief HCI_READ_LOCAL_SUPPORTED_COMMANDS - * This command reads the list of HCI commands supported for the local - * Controller. This command shall return the Supported_Commands configuration - * parameter. It is implied that if a command is listed as supported, the - * feature underlying that command is also supported. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.4.2) - * - * @param[out] Supported_Commands Bit mask for each HCI Command. If a bit is 1, - * the Controller supports the corresponding command and the features - * required for the command. - * Unsupported or undefined commands shall be set to 0. - * @return Value indicating success or error code. - */ -tBleStatus hci_read_local_supported_commands( uint8_t* Supported_Commands ); - -/** - * @brief HCI_READ_LOCAL_SUPPORTED_FEATURES - * This command requests a list of the supported features for the local - * Controller. This command will return a list of the LMP features. For details - * see Part C, Link Manager Protocol Specification on page 227. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.4.3) - * - * @param[out] LMP_Features Bit Mask List of LMP features. - * @return Value indicating success or error code. - */ -tBleStatus hci_read_local_supported_features( uint8_t* LMP_Features ); - -/** - * @brief HCI_READ_BD_ADDR - * On an LE Controller, this command shall read the Public Device Address as - * defined in [Vol 6] Part B, Section 1.3, Device Address. If this Controller - * does not have a Public Device Address, the value 0x000000000000 shall be - * returned. - * On an LE Controller, the public address shall be the same as the BD_ADDR. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.4.6) - * - * @param[out] BD_ADDR BD_ADDR ( Bluetooth Device Address) of the Device. - * @return Value indicating success or error code. - */ -tBleStatus hci_read_bd_addr( uint8_t* BD_ADDR ); - -/** - * @brief HCI_READ_RSSI - * This command reads the Received Signal Strength Indication (RSSI) value from - * a Controller. For an LE transport, a Connection_Handle is used as the Handle - * command parameter and return parameter. The meaning of the RSSI metric is an - * absolute receiver signal strength value in dBm to +/- 6 dB accuracy. If the - * RSSI cannot be read, the RSSI metric shall be set to 127. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.5.4) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param[out] RSSI N Size: 1 Octet (signed integer) - * Units: dBm - * Values: - * - 127: RSSI not available - * - -127 ... 20 - * @return Value indicating success or error code. - */ -tBleStatus hci_read_rssi( uint16_t Connection_Handle, - uint8_t* RSSI ); - -/** - * @brief HCI_LE_SET_EVENT_MASK - * The LE_Set_Event_Mask command is used to control which LE events are - * generated by the HCI for the Host. If the bit in the LE_Event_Mask is set to - * a one, then the event associated with that bit will be enabled. The Host has - * to deal with each event that is generated by an LE Controller. The event - * mask allows the Host to control which events will interrupt it. - * For LE events to be generated, the LE Meta-Event bit in the Event_Mask shall - * also be set. If that bit is not set, then LE events shall not be generated, - * regardless of how the LE_Event_Mask is set. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.1) - * - * @param LE_Event_Mask LE event mask. Default: 0x00000000000FFFFF. - * Flags: - * - 0x0000000000000000: No LE events specified - * - 0x0000000000000001: LE Connection Complete Event - * - 0x0000000000000002: LE Advertising Report Event - * - 0x0000000000000004: LE Connection Update Complete Event - * - 0x0000000000000008: LE Read Remote Used Features Complete Event - * - 0x0000000000000010: LE Long Term Key Request Event - * - 0x0000000000000020: LE Remote Connection Parameter Request Event - * - 0x0000000000000040: LE Data Length Change Event - * - 0x0000000000000080: LE Read Local P-256 Public Key Complete Event - * - 0x0000000000000100: LE Generate DHKey Complete Event - * - 0x0000000000000200: LE Enhanced Connection Complete Event - * - 0x0000000000000400: LE Direct Advertising Report Event - * - 0x0000000000000800: LE PHY Update Complete Event - * - 0x0000000000001000: LE Extended Advertising Report Event - * - 0x0000000000002000: LE Periodic Advertising Sync Established Event - * - 0x0000000000004000: LE Periodic Advertising Report Event - * - 0x0000000000008000: LE Periodic Advertising Sync Lost Event - * - 0x0000000000010000: LE Extended Scan Timeouout Event - * - 0x0000000000020000: LE Extended Advertising Set Terminated Event - * - 0x0000000000040000: LE Scan Request Received Event - * - 0x0000000000080000: LE Channel Selection Algorithm Event - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_event_mask( const uint8_t* LE_Event_Mask ); - -/** - * @brief HCI_LE_READ_BUFFER_SIZE - * The LE_Read_Buffer_Size command is used to read the maximum size of the data - * portion of HCI LE ACL Data Packets sent from the Host to the Controller. - * The Host will segment the data transmitted to the Controller according to - * these values, so that the HCI Data Packets will contain data with up to this - * size. The LE_Read_Buffer_Size command also returns the total number of HCI - * LE ACL Data Packets that can be stored in the data buffers of the - * Controller. The LE_Read_Buffer_Size command must be issued by the Host - * before it sends any data to an LE Controller (see Section 4.1.1). - * If the Controller returns a length value of zero, the Host shall use the - * Read_Buffer_Size command to determine the size of the data buffers. - * Note: Both the Read_Buffer_Size and LE_Read_Buffer_Size commands may return - * buffer length and number of packets parameter values that are nonzero. - * The HC_LE_ACL_Data_Packet_Length return parameter shall be used to determine - * the size of the L2CAP PDU segments contained in ACL Data Packets, which are - * transferred from the Host to the Controller to be broken up into packets by - * the Link Layer. Both the Host and the Controller shall support command and - * event packets, where the data portion (excluding header) contained in the - * packets is 255 octets in size. The HC_Total_Num_LE_ACL_Data_Packets return - * parameter contains the total number of HCI ACL Data Packets that can be - * stored in the data buffers of the Controller. The Host determines how the - * buffers are to be divided between different Connection Handles. - * Note: The HC_LE_ACL_Data_Packet_Length return parameter does not include the - * length of the HCI Data Packet header. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.2) - * - * @param[out] HC_LE_ACL_Data_Packet_Length 0x0000 No dedicated LE Buffer - use - * Read_Buffer_Size command. - * 0x0001 - 0xFFFF Maximum length (in octets) of the data portion of - * each HCI ACL Data Packet that the Controller is able to accept. - * @param[out] HC_Total_Num_LE_ACL_Data_Packets 0x00 No dedicated LE Buffer - - * use Read_Buffer_Size command. - * 0x01 - 0xFF Total number of HCI ACL Data Packets that can be stored - * in the data buffers of the Controller. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_buffer_size( uint16_t* HC_LE_ACL_Data_Packet_Length, - uint8_t* HC_Total_Num_LE_ACL_Data_Packets ); - -/** - * @brief HCI_LE_READ_LOCAL_SUPPORTED_FEATURES - * This command requests the list of the supported LE features for the - * Controller. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.3) - * - * @param[out] LE_Features Bit Mask List of LE features. See Core v5.0, Vol. 6, - * Part B, Section 4.6. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_local_supported_features( uint8_t* LE_Features ); - -/** - * @brief HCI_LE_SET_RANDOM_ADDRESS - * The LE_Set_Random_Address command is used by the Host to set the LE Random - * Device Address in the Controller (see [Vol 6] Part B, Section 1.3). - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.4) - * - * @param Random_Address Random Device Address. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_random_address( const uint8_t* Random_Address ); - -/** - * @brief HCI_LE_SET_ADVERTISING_PARAMETERS - * The LE_Set_Advertising_Parameters command is used by the Host to set the - * advertising parameters. - * The Advertising_Interval_Min shall be less than or equal to the - * Advertising_Interval_Max. - * The Advertising_Interval_Min and Advertising_Interval_Max should not be the - * same value to enable the Controller to determine the best advertising - * interval given other activities. - * For high duty cycle directed advertising, i.e. when Advertising_Type is 0x01 - * (ADV_DIRECT_IND, high duty cycle), the Advertising_Interval_Min and - * Advertising_Interval_Max parameters are not used and shall be ignored. - * The Advertising_Type is used to determine the packet type that is used for - * advertising when advertising is enabled. - * The Advertising_Interval_Min and Advertising_Interval_Max shall not be set - * to less than 0x00A0 (100 ms) if the Advertising_Type is set to 0x02 - * (ADV_SCAN_IND) or 0x03 (ADV_NONCONN_IND). The Own_Address_Type determines if - * the advertising packets are identified with the Public Device Address of the - * device, or a Random Device Address as written by the LE_Set_Random_Address - * command. - * If directed advertising is performed, i.e. when Advertising_Type is set to - * 0x01 (ADV_DIRECT_IND, high duty cycle) or 0x04 (ADV_DIRECT_IND, low duty - * cycle mode), then the Direct_Address_Type and Direct_Address shall be valid, - * otherwise they shall be ignored by the Controller and not used. - * The Advertising_Channel_Map is a bit field that indicates the advertising - * channels that shall be used when transmitting advertising packets. At least - * one channel bit shall be set in the Advertising_Channel_Map parameter. - * The Advertising_Filter_Policy parameter shall be ignored when directed - * advertising is enabled. - * The Host shall not issue this command when advertising is enabled in the - * Controller; if it is the Command Disallowed error code shall be used. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.5) - * - * @param Advertising_Interval_Min Minimum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Advertising_Interval_Max Maximum advertising interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) - * @param Advertising_Type Advertising type - * Values: - * - 0x00: ADV_IND (Connectable undirected advertising) - * - 0x01: ADV_DIRECT_IND, high duty cycle (Connectable high duty cycle - * directed advertising) - * - 0x02: ADV_SCAN_IND (Scannable undirected advertising) - * - 0x03: ADV_NONCONN_IND (Non connectable undirected advertising) - * - 0x04: ADV_DIRECT_IND_LDC, low duty cycle (Connectable low duty - * cycle directed advertising) - * @param Own_Address_Type Own address type. - * - 0x00: Public Device Address - * - 0x01 Random Device Address - * - 0x02: Controller generates Resolvable Private Address based on the - * local IRK from resolving list. If resolving list contains no matching - * entry, use public address. - * - 0x03: Controller generates Resolvable Private Address based on the - * local IRK from resolving list. If resolving list contains no matching - * entry, use random address from LE_Set_Random_Address. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * - 0x02: Resolvable Private Address or Public Address - * - 0x03: Resolvable Private Address or Random Address - * @param Peer_Address_Type The address type of the peer device. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * @param Peer_Address Public Device Address, Random Device Address, Public - * Identity Address or Random (static) Identity Address of the device to - * be connected. - * @param Advertising_Channel_Map Advertising channel map. - * Default: 00000111b (all channels enabled). - * Flags: - * - 0x01: ch 37 - * - 0x02: ch 38 - * - 0x04: ch 39 - * @param Advertising_Filter_Policy Advertising filter policy. - * Values: - * - 0x00: Allow Scan Request from Any, Allow Connect Request from Any - * - 0x01: Allow Scan Request from White List Only, Allow Connect - * Request from Any - * - 0x02: Allow Scan Request from Any, Allow Connect Request from White - * List Only - * - 0x03: Allow Scan Request from White List Only, Allow Connect - * Request from White List Only - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_advertising_parameters( uint16_t Advertising_Interval_Min, - uint16_t Advertising_Interval_Max, - uint8_t Advertising_Type, - uint8_t Own_Address_Type, - uint8_t Peer_Address_Type, - const uint8_t* Peer_Address, - uint8_t Advertising_Channel_Map, - uint8_t Advertising_Filter_Policy ); - -/** - * @brief HCI_LE_READ_ADVERTISING_CHANNEL_TX_POWER - * The LE_Read_Advertising_Channel_Tx_Power command is used by the Host to read - * the transmit power level used for LE advertising channel packets. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.6) - * - * @param[out] Transmit_Power_Level Size: 1 Octet (signed integer) - * Units: dBm - * Accuracy: +/- 4 dBm - * Values: - * - -20 ... 10 - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_advertising_channel_tx_power( uint8_t* Transmit_Power_Level ); - -/** - * @brief HCI_LE_SET_ADVERTISING_DATA - * The LE_Set_Advertising_Data command is used to set the data used in - * advertising packets that have a data field. - * Only the significant part of the Advertising_Data is transmitted in the - * advertising packets, as defined in [Vol 3] Part C, Section 11., - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.7) - * - * @param Advertising_Data_Length The number of significant octets in the - * following data field - * @param Advertising_Data 31 octets of data formatted as defined in [Vol 3] - * Part C, Section 11. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_advertising_data( uint8_t Advertising_Data_Length, - const uint8_t* Advertising_Data ); - -/** - * @brief HCI_LE_SET_SCAN_RESPONSE_DATA - * This command is used to provide data used in Scanning Packets that have a - * data field. - * Only the significant part of the Scan_Response_Data is transmitted in the - * Scanning Packets, as defined in [Vol 3] Part C, Section 11. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.8) - * - * @param Scan_Response_Data_Length The number of significant octets in the - * following data field - * @param Scan_Response_Data 31 octets of data formatted as defined in [Vol 3] - * Part C, Section 11. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_scan_response_data( uint8_t Scan_Response_Data_Length, - const uint8_t* Scan_Response_Data ); - -/** - * @brief HCI_LE_SET_ADVERTISE_ENABLE - * The LE_Set_Advertise_Enable command is used to request the Controller to - * start or stop advertising. The Controller manages the timing of - * advertisements as per the advertising parameters given in the - * LE_Set_Advertising_Parameters command. - * The Controller shall continue advertising until the Host issues an - * LE_Set_Advertise_Enable command with Advertising_Enable set to 0x00 - * (Advertising is disabled) or until a connection is created or until the - * Advertising is timed out due to high duty cycle Directed Advertising. In - * these cases, advertising is then disabled. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.9) - * - * @param Advertising_Enable Enable/disable advertise. Default is 0 (disabled). - * Values: - * - 0x00: Advertising is disabled - * - 0x01: Advertising is enabled - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_advertise_enable( uint8_t Advertising_Enable ); - -/** - * @brief HCI_LE_SET_SCAN_PARAMETERS - * The LE_Set_Scan_Parameters command is used to set the scan parameters. - * The LE_Scan_Type parameter controls the type of scan to perform. - * The LE_Scan_Interval and LE_Scan_Window parameters are recommendations from - * the Host on how long (LE_Scan_Window) and how frequently (LE_Scan_Interval) - * the Controller should scan (See [Vol 6] Part B, Section 4.4.3). The - * LE_Scan_Window parameter shall always be set to a value smaller or equal to - * the value set for the LE_Scan_Interval parameter. If they are set to the - * same value scanning should be run continuously. - * The Own_Address_Type parameter determines the address used (Public or Random - * Device Address) when performing active scan. - * The Host shall not issue this command when scanning is enabled in the - * Controller; if it is the Command Disallowed error code shall be used. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.10) - * - * @param LE_Scan_Type Passive or active scanning. With active scanning - * SCAN_REQ packets are sent. - * Values: - * - 0x00: Passive Scanning - * - 0x01: Active scanning - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Own_Address_Type Own address type. - * - 0x00: Public Device Address - * - 0x01 Random Device Address - * - 0x02: Controller generates Resolvable Private Address based on the - * local IRK from resolving list. If resolving list contains no matching - * entry, use public address. - * - 0x03: Controller generates Resolvable Private Address based on the - * local IRK from resolving list. If resolving list contains no matching - * entry, use random address from LE_Set_Random_Address. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * - 0x02: Resolvable Private Address or Public Address - * - 0x03: Resolvable Private Address or Random Address - * @param Scanning_Filter_Policy 0x00 Accept all advertisement packets. - * Directed advertising packets which are not addressed for this device - * shall be ignored. - * 0x01 Ignore advertisement packets from devices not in the White List - * Only. Directed advertising packets which are not addressed for this - * device shall be ignored - * 0x02 Accept all undirected advertisement packets. Directed - * advertisement packets where initiator address is a RPA and Directed - * advertisement packets addressed to this device shall be accepted. - * 0x03 Accept all undirected advertisement packets from devices that - * are in the White List.Directed advertisement packets where initiator - * address is RPA and Directed advertisement packets addressed to this - * device shall be accepted. - * Values: - * - 0x00: Accept all - * - 0x01: Ignore devices not in the White List - * - 0x02: Accept all (use resolving list) - * - 0x03: Ignore devices not in the White List (use resolving list) - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_scan_parameters( uint8_t LE_Scan_Type, - uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Own_Address_Type, - uint8_t Scanning_Filter_Policy ); - -/** - * @brief HCI_LE_SET_SCAN_ENABLE - * The LE_Set_Scan_Enable command is used to start scanning. Scanning is used - * to discover advertising devices nearby. - * The Filter_Duplicates parameter controls whether the Link Layer shall filter - * duplicate advertising reports to the Host, or if the Link Layer should - * generate advertising reports for each packet received. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.11) - * - * @param LE_Scan_Enable Enable/disable scan. Default is 0 (disabled). - * Values: - * - 0x00: Scanning disabled - * - 0x01: Scanning enabled - * @param Filter_Duplicates Enable/disable duplicate filtering. - * Values: - * - 0x00: Duplicate filtering disabled - * - 0x01: Duplicate filtering enabled - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_scan_enable( uint8_t LE_Scan_Enable, - uint8_t Filter_Duplicates ); - -/** - * @brief HCI_LE_CREATE_CONNECTION - * The LE_Create_Connection command is used to create a Link Layer connection - * to a connectable advertiser. - * The LE_Scan_Interval and LE_Scan_Window parameters are recommendations from - * the Host on how long (LE_Scan_Window) and how frequently (LE_Scan_Interval) - * the Controller should scan. The LE_Scan_Window parameter shall be set to a - * value smaller or equal to the value set for the LE_Scan_Interval parameter. - * If both are set to the same value, scanning should run continuously. - * The Initiator_Filter_Policy is used to determine whether the White List is - * used. - * If the White List is not used, the Peer_Address_Type and the Peer_Address - * parameters specify the address type and address of the advertising device to - * connect to. - * The Link Layer shall set the address in the CONNECT_REQ packets to either - * the Public Device Address or the Random Device Addressed based on the - * Own_Address_Type parameter. - * The Conn_Interval_Min and Conn_Interval_Max parameters define the minimum - * and maximum allowed connection interval. The Conn_Interval_Min parameter - * shall not be greater than the Conn_Interval_Max parameter. - * The Conn_Latency parameter defines the maximum allowed connection latency - * (see [Vol 6] Part B, Section 4.5.1). - * The Supervision_Timeout parameter defines the link supervision timeout for - * the connection. The Supervision_Timeout in milliseconds shall be larger than - * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given - * in milliseconds. (See [Vol 6] Part B, Section 4.5.2). - * The Minimum_CE_Length and Maximum_CE_Length parameters are informative - * parameters providing the Controller with the expected minimum and maximum - * length of the connection events. The Minimum_CE_Length parameter shall be - * less than or equal to the Maximum_CE_Length parameter. - * The Host shall not issue this command when another LE_Create_Connection is - * pending in the Controller; if this does occur the Controller shall return - * the Command Disallowed error code shall be used. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.12) - * - * @param LE_Scan_Interval This is defined as the time interval from when the - * Controller started its last LE scan until it begins the subsequent LE - * scan. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param LE_Scan_Window Amount of time for the duration of the LE scan. - * LE_Scan_Window shall be less than or equal to LE_Scan_Interval. - * Time = N * 0.625 msec. - * Values: - * - 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms) - * @param Initiator_Filter_Policy 0x00 White list is not used to determine - * which advertiser to connect to. - * Peer_Address_Type and Peer_Address shall be used. - * 0x01 White list is used to determine which advertiser to connect to. - * Peer_Address_Type and Peer_Address shall be ignored. - * Values: - * - 0x00: White list not used - * - 0x01: White list used - * @param Peer_Address_Type Address type - * 0x00 Public Device Address - * 0x01 Random Device Address - * 0x02 Public Identity Address (Corresponds to Resolved Private - * Address) - * 0x03 Random (Static) Identity Address (Corresponds to Resolved - * Private Address) - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * - 0x02: Public Identity Address - * - 0x03: Random (Static) Identity Address - * @param Peer_Address Public Device Address or Random Device Address of the - * device to be connected. - * @param Own_Address_Type Own address type. - * - 0x00: Public Device Address - * - 0x01 Random Device Address - * - 0x02: Controller generates Resolvable Private Address based on the - * local IRK from resolving list. If resolving list contains no matching - * entry, use public address. - * - 0x03: Controller generates Resolvable Private Address based on the - * local IRK from resolving list. If resolving list contains no matching - * entry, use random address from LE_Set_Random_Address. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * - 0x02: Resolvable Private Address or Public Address - * - 0x03: Resolvable Private Address or Random Address - * @param Conn_Interval_Min Minimum value for the connection event interval. - * This shall be less than or equal to Conn_Interval_Max. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Interval_Max Maximum value for the connection event interval. - * This shall be greater than or equal to Conn_Interval_Min. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Latency Slave latency for the connection in number of connection - * events. - * Values: - * - 0x0000 ... 0x01F3 - * @param Supervision_Timeout Supervision timeout for the LE Link. - * It shall be a multiple of 10 ms and larger than (1 + - * connSlaveLatency) * connInterval * 2. - * Time = N * 10 msec. - * Values: - * - 0x000A (100 ms) ... 0x0C80 (32000 ms) - * @param Minimum_CE_Length Information parameter about the minimum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Maximum_CE_Length Information parameter about the maximum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @return Value indicating success or error code. - */ -tBleStatus hci_le_create_connection( uint16_t LE_Scan_Interval, - uint16_t LE_Scan_Window, - uint8_t Initiator_Filter_Policy, - uint8_t Peer_Address_Type, - const uint8_t* Peer_Address, - uint8_t Own_Address_Type, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ); - -/** - * @brief HCI_LE_CREATE_CONNECTION_CANCEL - * The LE_Create_Connection_Cancel command is used to cancel the - * LE_Create_Connection command. This command shall only be issued after the - * LE_Create_Connection command has been issued, a Command Status event has - * been received for the LE Create Connection command and before the LE - * Connection Complete event. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.13) - * - * @return Value indicating success or error code. - */ -tBleStatus hci_le_create_connection_cancel( void ); - -/** - * @brief HCI_LE_READ_WHITE_LIST_SIZE - * The LE_Read_White_List_Size command is used to read the total number of - * white list entries that can be stored in the Controller. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.14) - * - * @param[out] White_List_Size Total number of white list entries that can be - * stored in the Controller. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_white_list_size( uint8_t* White_List_Size ); - -/** - * @brief HCI_LE_CLEAR_WHITE_LIST - * The LE_Clear_White_List command is used to clear the white list stored in - * the Controller. - * This command can be used at any time except when: - * - the advertising filter policy uses the white list and advertising is - * enabled. - * - the scanning filter policy uses the white list and scanning is enabled. - * - the initiator filter policy uses the white list and an - * LE_Create_Connection command is outstanding. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.15) - * - * @return Value indicating success or error code. - */ -tBleStatus hci_le_clear_white_list( void ); - -/** - * @brief HCI_LE_ADD_DEVICE_TO_WHITE_LIST - * The LE_Add_Device_To_White_List command is used to add a single device to - * the white list stored in the Controller. - * This command can be used at any time except when: - * - the advertising filter policy uses the white list and advertising is - * enabled. - * - the scanning filter policy uses the white list and scanning is enabled. - * - the initiator filter policy uses the white list and a create connection - * command is outstanding. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.16) - * - * @param Address_Type Address type. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * @param Address Public Device Address or Random Device Address. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_add_device_to_white_list( uint8_t Address_Type, - const uint8_t* Address ); - -/** - * @brief HCI_LE_REMOVE_DEVICE_FROM_WHITE_LIST - * The LE_Remove_Device_From_White_List command is used to remove a single - * device from the white list stored in the Controller. - * This command can be used at any time except when: - * - the advertising filter policy uses the white list and advertising is - * enabled. - * - the scanning filter policy uses the white list and scanning is enabled. - * - the initiator filter policy uses the white list and a create connection - * command is outstanding. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.17) - * - * @param Address_Type Address type. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * @param Address Public Device Address or Random Device Address. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_remove_device_from_white_list( uint8_t Address_Type, - const uint8_t* Address ); - -/** - * @brief HCI_LE_CONNECTION_UPDATE - * The LE_Connection_Update command is used to change the Link Layer connection - * parameters of a connection. This command is supported only on master side. - * The Conn_Interval_Min and Conn_Interval_Max parameters are used to define - * the minimum and maximum allowed connection interval. The Conn_Interval_Min - * parameter shall not be greater than the Conn_Interval_Max parameter. - * The Conn_Latency parameter shall define the maximum allowed connection - * latency. - * The Supervision_Timeout parameter shall define the link supervision timeout - * for the LE link. The Supervision_Timeout in milliseconds shall be larger - * than (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is - * given in milliseconds. - * The Minimum_CE_Length and Maximum_CE_Length are information parameters - * providing the Controller with a hint about the expected minimum and maximum - * length of the connection events. The Minimum_CE_Length shall be less than or - * equal to the Maximum_CE_Length. - * The actual parameter values selected by the Link Layer may be different from - * the parameter values provided by the Host through this command. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.18) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Conn_Interval_Min Minimum value for the connection event interval. - * This shall be less than or equal to Conn_Interval_Max. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Interval_Max Maximum value for the connection event interval. - * This shall be greater than or equal to Conn_Interval_Min. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Latency Slave latency for the connection in number of connection - * events. - * Values: - * - 0x0000 ... 0x01F3 - * @param Supervision_Timeout Supervision timeout for the LE Link. - * It shall be a multiple of 10 ms and larger than (1 + - * connSlaveLatency) * connInterval * 2. - * Time = N * 10 msec. - * Values: - * - 0x000A (100 ms) ... 0x0C80 (32000 ms) - * @param Minimum_CE_Length Information parameter about the minimum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Maximum_CE_Length Information parameter about the maximum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @return Value indicating success or error code. - */ -tBleStatus hci_le_connection_update( uint16_t Connection_Handle, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Conn_Latency, - uint16_t Supervision_Timeout, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length ); - -/** - * @brief HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION - * The LE_Set_Host_Channel_Classification command allows the Host to specify a - * channel classification for data channels based on its "local information". - * This classification persists until overwritten with a subsequent - * LE_Set_Host_Channel_Classification command or until the Controller is reset - * using the Reset command (see [Vol 6] Part B, Section 4.5.8.1). - * If this command is used, the Host should send it within 10 seconds of - * knowing that the channel classification has changed. The interval between - * two successive commands sent shall be at least one second. - * This command shall only be used when the local device supports the Master - * role. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.19) - * - * @param LE_Channel_Map This parameter contains 37 1-bit fields. - * The nth such field (in the range 0 to 36) contains the value for the - * link layer channel index n. - * Channel n is bad = 0. - * Channel n is unknown = 1. - * The most significant bits are reserved and shall be set to 0. - * At least one channel shall be marked as unknown. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_host_channel_classification( const uint8_t* LE_Channel_Map ); - -/** - * @brief HCI_LE_READ_CHANNEL_MAP - * The LE_Read_Channel_Map command returns the current Channel_Map for the - * specified Connection_Handle. The returned value indicates the state of the - * Channel_Map specified by the last transmitted or received Channel_Map (in a - * CONNECT_REQ or LL_CHANNEL_MAP_REQ message) for the specified - * Connection_Handle, regardless of whether the Master has received an - * acknowledgement. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.20) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param[out] LE_Channel_Map This parameter contains 37 1-bit fields. - * The nth such field (in the range 0 to 36) contains the value for the - * link layer channel index n. - * Channel n is unused = 0. - * Channel n is used = 1. - * The most significant bits are reserved and shall be set to 0. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_channel_map( uint16_t Connection_Handle, - uint8_t* LE_Channel_Map ); - -/** - * @brief HCI_LE_READ_REMOTE_FEATURES - * This command requests a list of the used LE features from the remote device. - * This command shall return a list of the used LE features. For details see - * [Vol 6] Part B, Section 4.6. - * This command may be issued on both the master and slave. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.21) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_remote_features( uint16_t Connection_Handle ); - -/** - * @brief HCI_LE_ENCRYPT - * The LE_Encrypt command is used to request the Controller to encrypt the - * Plaintext_Data in the command using the Key given in the command and returns - * the Encrypted_Data to the Host. The AES-128 bit block cypher is defined in - * NIST Publication FIPS-197 - * (http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf). - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.22) - * - * @param Key 128 bit key for the encryption of the data given in the command. - * @param Plaintext_Data 128 bit data block that is requested to be encrypted. - * @param[out] Encrypted_Data 128 bit encrypted data block. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_encrypt( const uint8_t* Key, - const uint8_t* Plaintext_Data, - uint8_t* Encrypted_Data ); - -/** - * @brief HCI_LE_RAND - * The LE_Rand command is used to request the Controller to generate 8 octets - * of random data to be sent to the Host. The Random_Number shall be generated - * according to [Vol 2] Part H, Section 2 if the LE Feature (LL Encryption) is - * supported. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.23) - * - * @param[out] Random_Number Random Number - * @return Value indicating success or error code. - */ -tBleStatus hci_le_rand( uint8_t* Random_Number ); - -/** - * @brief HCI_LE_START_ENCRYPTION - * The LE_Start_Encryption command is used to authenticate the given encryption - * key associated with the remote device specified by the connection handle, - * and once authenticated will encrypt the connection. The parameters are as - * defined in [Vol 3] Part H, Section 2.4.4. - * If the connection is already encrypted then the Controller shall pause - * connection encryption before attempting to authenticate the given encryption - * key, and then re-encrypt the connection. While encryption is paused no user - * data shall be transmitted. - * On an authentication failure, the connection shall be automatically - * disconnected by the Link Layer. If this command succeeds, then the - * connection shall be encrypted. - * This command shall only be used when the local device's role is Master. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.24) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Random_Number 64 bit random number. - * @param Encrypted_Diversifier 16 bit encrypted diversifier. - * @param Long_Term_Key 128 bit long term key. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_start_encryption( uint16_t Connection_Handle, - const uint8_t* Random_Number, - uint16_t Encrypted_Diversifier, - const uint8_t* Long_Term_Key ); - -/** - * @brief HCI_LE_LONG_TERM_KEY_REQUEST_REPLY - * The LE_Long_Term_Key_Request_Reply command is used to reply to an LE Long - * Term Key Request event from the Controller, and specifies the Long_Term_Key - * parameter that shall be used for this Connection_Handle. The Long_Term_Key - * is used as defined in [Vol 6] Part B, Section 5.1.3. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.25) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Long_Term_Key 128 bit long term key. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_long_term_key_request_reply( uint16_t Connection_Handle, - const uint8_t* Long_Term_Key ); - -/** - * @brief HCI_LE_LONG_TERM_KEY_REQUESTED_NEGATIVE_REPLY - * The LE_Long_Term_Key_Request_Negative_Reply command is used to reply to an - * LE Long Term Key Request event from the Controller if the Host cannot - * provide a Long Term Key for this Connection_Handle. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.26) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @return Value indicating success or error code. - */ -tBleStatus hci_le_long_term_key_requested_negative_reply( uint16_t Connection_Handle ); - -/** - * @brief HCI_LE_READ_SUPPORTED_STATES - * The LE_Read_Supported_States command reads the states and state combinations - * that the link layer supports. See [Vol 6] Part B, Section 1.1.1. - * LE_States is an 8-octet bit field. If a bit is set to 1 then this state or - * state combination is supported by the Controller. Multiple bits in LE_States - * may be set to 1 to indicate support for multiple state and state - * combinations. - * All the Advertising type with the Initiate State combinations shall be set - * only if the corresponding Advertising types and Master Role combination are - * set. - * All the Scanning types and the Initiate State combinations shall be set only - * if the corresponding Scanning types and Master Role combination are set. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.27) - * - * @param[out] LE_States State or state combination is supported by the - * Controller. - * See Core v5.0, Vol.2, part E, Ch. 7.8.27. - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_supported_states( uint8_t* LE_States ); - -/** - * @brief HCI_LE_RECEIVER_TEST - * This command is used to start a test where the DUT receives test reference - * packets at a fixed interval. The tester generates the test reference - * packets. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.28) - * - * @param RX_Frequency N = (F - 2402) / 2 - * Frequency Range : 2402 MHz to 2480 MHz - * Values: - * - 0x00 ... 0x27 - * @return Value indicating success or error code. - */ -tBleStatus hci_le_receiver_test( uint8_t RX_Frequency ); - -/** - * @brief HCI_LE_TRANSMITTER_TEST - * This command is used to start a test where the DUT generates test reference - * packets at a fixed interval. The Controller shall transmit at maximum power. - * An LE Controller supporting the LE_Transmitter_Test command shall support - * Packet_Payload values 0x00, 0x01 and 0x02. An LE Controller may support - * other values of Packet_Payload. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.29) - * - * @param TX_Frequency N = (F - 2402) / 2 - * Frequency Range : 2402 MHz to 2480 MHz - * Values: - * - 0x00 ... 0x27 - * @param Length_Of_Test_Data Length in bytes of payload data in each packet. - * Values: - * - 0x00 ... 0x25 - * @param Packet_Payload Type of packet payload. - * Values: - * - 0x00: Pseudo-Random bit sequence 9 - * - 0x01: Pattern of alternating bits '11110000' - * - 0x02: Pattern of alternating bits '10101010' - * - 0x03: Pseudo-Random bit sequence 15 - * - 0x04: Pattern of All '1' bits - * - 0x05: Pattern of All '0' bits - * - 0x06: Pattern of alternating bits '00001111' - * - 0x07: Pattern of alternating bits '0101' - * @return Value indicating success or error code. - */ -tBleStatus hci_le_transmitter_test( uint8_t TX_Frequency, - uint8_t Length_Of_Test_Data, - uint8_t Packet_Payload ); - -/** - * @brief HCI_LE_TEST_END - * This command is used to stop any test which is in progress. The - * Number_Of_Packets for a transmitter test shall be reported as 0x0000. The - * Number_Of_Packets is an unsigned number and contains the number of received - * packets. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.30) - * - * @param[out] Number_Of_Packets Number of packets received - * @return Value indicating success or error code. - */ -tBleStatus hci_le_test_end( uint16_t* Number_Of_Packets ); - -/** - * @brief HCI_LE_SET_DATA_LENGTH - * The LE_Set_Data_Length command allows the Host to suggest maximum - * transmission packet size and maximum packet transmission time - * (connMaxTxOctets and connMaxTxTime - see Bluetooth Specification v5.0 [Vol - * 6] Part B, Section 4.5.10) to be used for a given connection. The Controller - * may use smaller or larger values based on local information. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param TxOctets Preferred maximum number of payload octets that the local - * Controller should include in a single Link Layer packet on this - * connection. - * Values: - * - 0x001B ... 0x00FB - * @param TxTime Preferred maximum number of microseconds that the local - * Controller should use to transmit a single Link Layer packet on this - * connection. - * Values: - * - 0x0148 ... 0x4290 - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_data_length( uint16_t Connection_Handle, - uint16_t TxOctets, - uint16_t TxTime ); - -/** - * @brief HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH - * The LE_Read_Suggested_Default_Data_Length command allows the Host to read - * the Host's suggested values (SuggestedMaxTxOctets and SuggestedMaxTxTime) - * for the Controller's maximum transmitted number of payload octets and - * maximum packet transmission time to be used for new connections (see - * Bluetooth Specification v5.0 [Vol 6] Part B, Section 4.5.10). - * - * @param[out] SuggestedMaxTxOctets The Host's suggested value for the - * Controller's maximum transmitted number of payload octets to be used - * for new connections. - * Values: - * - 0x001B ... 0x00FB - * @param[out] SuggestedMaxTxTime The Host's suggested value for the - * Controller's maximum packet transmission time to be used for new - * connections. - * Values: - * - 0x0148 ... 0x4290 - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_suggested_default_data_length( uint16_t* SuggestedMaxTxOctets, - uint16_t* SuggestedMaxTxTime ); - -/** - * @brief HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH - * The LE_Write_Suggested_Default_Data_Length command allows the Host to - * specify its suggested values for the Controller's maximum transmission - * number of payload octets and maximum packet transmission time to be used for - * new connections. The Controller may use smaller or larger values for - * connInitialMaxTxOctets and connInitialMaxTxTime based on local information. - * (see Bluetooth Specification [Vol 6] Part B, Section 4.5.10). - * - * @param SuggestedMaxTxOctets The Host's suggested value for the Controller's - * maximum transmitted number of payload octets to be used for new - * connections. - * Values: - * - 0x001B ... 0x00FB - * @param SuggestedMaxTxTime The Host's suggested value for the Controller's - * maximum packet transmission time to be used for new connections. - * Values: - * - 0x0148 ... 0x4290 - * @return Value indicating success or error code. - */ -tBleStatus hci_le_write_suggested_default_data_length( uint16_t SuggestedMaxTxOctets, - uint16_t SuggestedMaxTxTime ); - -/** - * @brief HCI_LE_READ_LOCAL_P256_PUBLIC_KEY - * The LE_Read_Local_P-256_Public_Key command is used to return the local P-256 - * public key from the Controller. The Controller shall generate a new P-256 - * public/private key pair upon receipt of this command. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.36) - * - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_local_p256_public_key( void ); - -/** - * @brief HCI_LE_GENERATE_DHKEY - * The LE_Generate_DHKey command is used to initiate generation of a Diffie- - * Hellman key in the Controller for use over the LE transport. This command - * takes the remote P-256 public key as input. The Diffie-Hellman key - * generation uses the private key generated by LE_Read_Local_P256_Public_Key - * command. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.37) - * - * @param Remote_P256_Public_Key The remote P-256 public key in X, Y format: - * Octets 31-0: X co-ordinate - * Octets 63-32: Y co-ordinate - * Little Endian Format - * @return Value indicating success or error code. - */ -tBleStatus hci_le_generate_dhkey( const uint8_t* Remote_P256_Public_Key ); - -/** - * @brief HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST - * The LE_Add_Device_To_Resolving_List command is used to add one device to the - * list of address translations used to resolve Resolvable Private Addresses in - * the Controller. - * This command cannot be used when address translation is enabled in the - * Controller and: - * - Advertising is enabled - * - Scanning is enabled - * - Create connection command is outstanding - * This command can be used at any time when address translation is disabled in - * the Controller. - * When a Controller cannot add a device to the resolving list because the list - * is full, it shall respond with error code 0x07 (Memory Capacity Exceeded). - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.38) - * - * @param Peer_Identity_Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param Peer_Identity_Address Public or Random (static) Identity address of - * the peer device - * @param Peer_IRK IRK of the peer device - * @param Local_IRK IRK of the local device - * @return Value indicating success or error code. - */ -tBleStatus hci_le_add_device_to_resolving_list( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address, - const uint8_t* Peer_IRK, - const uint8_t* Local_IRK ); - -/** - * @brief HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST - * The LE_Remove_Device_From_Resolving_List command is used to remove one - * device from the list of address translations used to resolve Resolvable - * Private Addresses in the controller. - * This command cannot be used when address translation is enabled in the - * Controller and: - * - Advertising is enabled - * - Scanning is enabled - * - Create connection command is outstanding - * This command can be used at any time when address translation is disabled in - * the Controller. - * When a Controller cannot remove a device from the resolving list because it - * is not found, it shall respond with error code 0x02 (Unknown Connection - * Identifier). - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.39) - * - * @param Peer_Identity_Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param Peer_Identity_Address Public or Random (static) Identity address of - * the peer device - * @return Value indicating success or error code. - */ -tBleStatus hci_le_remove_device_from_resolving_list( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address ); - -/** - * @brief HCI_LE_CLEAR_RESOLVING_LIST - * The LE_Clear_Resolving_List command is used to remove all devices from the - * list of address translations used to resolve Resolvable Private Addresses in - * the Controller. - * This command cannot be used when address translation is enabled in the - * Controller and: - * - Advertising is enabled - * - Scanning is enabled - * - Create connection command is outstanding - * This command can be used at any time when address translation is disabled in - * the Controller. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.40) - * - * @return Value indicating success or error code. - */ -tBleStatus hci_le_clear_resolving_list( void ); - -/** - * @brief HCI_LE_READ_RESOLVING_LIST_SIZE - * The LE_Read_Resolving_List_Size command is used to read the total number of - * address translation entries in the resolving list that can be stored in the - * Controller. - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.41) - * - * @param[out] Resolving_List_Size Number of address translation entries in the - * resolving list - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_resolving_list_size( uint8_t* Resolving_List_Size ); - -/** - * @brief HCI_LE_READ_PEER_RESOLVABLE_ADDRESS - * The LE_Read_Peer_Resolvable_Address command is used to get the current peer - * Resolvable Private Address being used for the corresponding peer Public and - * Random (static) Identity Address. The peer's resolvable address being used - * may change after the command is called. - * This command can be used at any time. - * When a Controller cannot find a Resolvable Private Address associated with - * the Peer Identity Address, it shall respond with error code 0x02 (Unknown - * Connection Identifier). - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.42) - * - * @param Peer_Identity_Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param Peer_Identity_Address Public or Random (static) Identity address of - * the peer device - * @param[out] Peer_Resolvable_Address Resolvable Private Address being used by - * the peer device - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_peer_resolvable_address( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address, - uint8_t* Peer_Resolvable_Address ); - -/** - * @brief HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS - * The LE_Read_Local_Resolvable_Address command is used to get the current - * local Resolvable Private Address being used for the corresponding peer - * Identity Address. The local's resolvable address being used may change after - * the command is called. - * This command can be used at any time. - * When a Controller cannot find a Resolvable Private Address associated with - * the Peer Identity Address, it shall respond with error code 0x02 (Unknown - * Connection Identifier). - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.43) - * - * @param Peer_Identity_Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param Peer_Identity_Address Public or Random (static) Identity address of - * the peer device - * @param[out] Local_Resolvable_Address Resolvable Private Address being used - * by the local device - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_local_resolvable_address( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address, - uint8_t* Local_Resolvable_Address ); - -/** - * @brief HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE - * The LE_Set_Address_Resolution_Enable command is used to enable resolution of - * Resolvable Private Addresses in the Controller. This causes the Controller - * to use the resolving list whenever the Controller receives a local or peer - * Resolvable Private Address. - * This command can be used at any time except when: - * - Advertising is enabled - * - Scanning is enabled - * - Create connection command is outstanding - * (See Bluetooth Specification v.5.0, Vol. 2, Part E, Section 7.8.44) - * - * @param Address_Resolution_Enable Enable/disable address resolution in the - * controller. - * 0x00: Address Resolution in controller disabled (default), - * 0x01: Address Resolution in controller enabled - * Values: - * - 0x00: Address Resolution in controller disabled (default) - * - 0x01: Address Resolution in controller enabled - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_address_resolution_enable( uint8_t Address_Resolution_Enable ); - -/** - * @brief HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT - * The LE_Set_Resolvable_Private_Address_Timeout command set the length of time - * the controller uses a Resolvable Private Address before a new resolvable - * private address is generated and starts being used. This timeout applies to - * all addresses generated by the controller. - * (See Bluetooth Specification v.5.0 [Vol 2] Part E, Section 7.8.45) - * - * @param RPA_Timeout RPA_Timeout measured in seconds. - * Range for N: 0x0001 - 0xA1B8 (1 sec - approximately 11.5 hours) - * Default: N= 0x0384 (900 secs or 15 minutes) - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_resolvable_private_address_timeout( uint16_t RPA_Timeout ); - -/** - * @brief HCI_LE_READ_MAXIMUM_DATA_LENGTH - * The LE_Read_Maximum_Data_Length command allows the Host to read the - * Controller's maximum supported payload octets and packet duration times for - * transmission and reception (supportedMaxTxOctets and supportedMaxTxTime, - * supportedMaxRxOctets, and supportedMaxRxTime, see Bluetooth Specification - * v5.0 [Vol 6] Part B, Section 4.5.10). - * - * @param[out] supportedMaxTxOctets Maximum number of payload octets that the - * local Controller supports for transmission of a single Link Layer - * packet on a data connection. - * Values: - * - 0x001B ... 0x00FB - * @param[out] supportedMaxTxTime Maximum time, in microseconds, that the local - * Controller supports for transmission of a single Link Layer packet on - * a data connection. - * Values: - * - 0x0148 ... 0x4290 - * @param[out] supportedMaxRxOctets Maximum number of payload octets that the - * local Controller supports for reception of a single Link Layer packet - * on a data connection. - * Values: - * - 0x001B ... 0x00FB - * @param[out] supportedMaxRxTime Maximum time, in microseconds, that the local - * Controller supports for reception of a single Link Layer packet on a - * data connection. - * Values: - * - 0x0148 ... 0x4290 - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_maximum_data_length( uint16_t* supportedMaxTxOctets, - uint16_t* supportedMaxTxTime, - uint16_t* supportedMaxRxOctets, - uint16_t* supportedMaxRxTime ); - -/** - * @brief HCI_LE_READ_PHY - * The LE_Read_PHY command is used to read the current transmitter PHY and - * receiver PHY on the connection identified by the Connection_Handle. see - * Bluetooth Specification [Vol 2] part E, Section 7.8.47 - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param[out] TX_PHY Transmitter PHY in use - * Values: - * - 0x01: The transmitter PHY for the connection is LE 1M - * - 0x02: The transmitter PHY for the connection is LE 2M - * - 0x03: The transmitter PHY for the connection is LE Coded - * (Not supported by STM32WB) - * @param[out] RX_PHY Receiver PHY in use - * Values: - * - 0x01: The receiver PHY for the connection is LE 1M - * - 0x02: The receiver PHY for the connection is LE 2M - * - 0x03: The receiver PHY for the connection is LE Coded - * (Not supported by STM32WB) - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_phy( uint16_t Connection_Handle, - uint8_t* TX_PHY, - uint8_t* RX_PHY ); - -/** - * @brief HCI_LE_SET_DEFAULT_PHY - * The LE_Set_Default_PHY command allows the Host to specify its preferred - * values for the transmitter PHY and receiver PHY to be used for all - * subsequent connections over the LE transport. - * The ALL_PHYS parameter is a bit field that allows the Host to specify, for - * each - * direction, whether it has no preference among the PHYs that the Controller - * supports in a given direction or whether it has specified particular PHYs - * that it prefers in the TX_PHYS or RX_PHYS parameter. - * The TX_PHYS parameter is a bit field that indicates the transmitter PHYs - * that the Host prefers the Controller to use. If the ALL_PHYS parameter - * specifies that the Host has no preference, the TX_PHYS parameter is ignored; - * otherwise at least one bit shall be set to 1. - * The RX_PHYS parameter is a bit field that indicates the receiver PHYs that - * the Host prefers the Controller to use. If the ALL_PHYS parameter specifies - * that the Host has no preference, the RX_PHYS parameter is ignored; otherwise - * at least one bit shall be set to 1. - * See Bluetooth Specification [Vol2] Part E Section 7.8.48 - * - * @param ALL_PHYS Host preferences for TX PHY and RX PHY - * Values: - * - 0x00 ... 0x03 - * @param TX_PHYS Host preferences for TX PHY (no LE coded support) - * Values: - * - 0x00 ... 0x03 - * @param RX_PHYS Host preferences for RX PHY (no LE coded support) - * Values: - * - 0x00 ... 0x03 - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_default_phy( uint8_t ALL_PHYS, - uint8_t TX_PHYS, - uint8_t RX_PHYS ); - -/** - * @brief HCI_LE_SET_PHY - * The LE_Set_PHY command is used to set the PHY preferences for the connection - * identified by the Connection_Handle. The Controller might not be able to - * make the change (e.g. because the peer does not support the requested PHY) - * or may decide that the current PHY is preferable. - * The ALL_PHYS parameter is a bit field that allows the Host to specify, for - * each direction, whether it has no preference among the PHYs that the - * Controller supports in a given direction or whether it has specified - * particular PHYs that it prefers in the TX_PHYS or RX_PHYS parameter. - * The TX_PHYS parameter is a bit field that indicates the transmitter PHYs - * that the Host prefers the Controller to use. If the ALL_PHYS parameter - * specifies that the Host has no preference, the TX_PHYS parameter is ignored; - * otherwise at least one bit shall be set to 1. - * The RX_PHYS parameter is a bit field that indicates the receiver PHYs that - * the Host prefers the Controller to use. If the ALL_PHYS parameter specifies - * that the Host has no preference, the RX_PHYS parameter is ignored; otherwise - * at least one bit shall be set to 1. - * If, for at least one direction, the Host has specified a preference and the - * current PHY is not one of those preferred, the Controller shall request a - * change. Otherwise the Controller may, but need not, request a change. - * The PHY preferences provided by the LE Set PHY command override those - * provided via the LE Set Default PHY command (Section 7.8.48) or any - * preferences previously set using the LE Set PHY command on the same - * connection. - * The PHY_options parameter is a bit field that allows the Host to specify - * options for PHYs. The default value for a new connection shall be all zero - * bits. The Controller may override any preferred coding for transmitting on - * the LE Coded PHY. - * The Host may specify a preferred coding even if it prefers not to use the LE - * Coded transmitter PHY since the Controller may override the PHY preference. - * (See Bluetooth Specification v5.0 [Vol 6] Part B, Section 7.8.49) - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param ALL_PHYS Host preferences for TX PHY and RX PHY - * Values: - * - 0x00 ... 0x03 - * @param TX_PHYS Host preferences for TX PHY (no LE coded support) - * Values: - * - 0x00 ... 0x03 - * @param RX_PHYS Host preferences for RX PHY (no LE coded support) - * Values: - * - 0x00 ... 0x03 - * @param PHY_options Not supported - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_phy( uint16_t Connection_Handle, - uint8_t ALL_PHYS, - uint8_t TX_PHYS, - uint8_t RX_PHYS, - uint16_t PHY_options ); - -/** - * @brief HCI_LE_ENHANCED_RECEIVER_TEST - * This command is used to start a test where the DUT receives test reference - * packets at a fixed interval. The tester generates the test reference - * packets. - * (See Bluetooth Specification v5.0 [Vol 6] Part B, Section 7.8.50) - * - * @param RX_Frequency N = (F - 2402) / 2 - * Frequency Range : 2402 MHz to 2480 MHz - * Values: - * - 0x00 ... 0x27 - * @param PHY PHY to use for test packet - * Values: - * - 0x00: Reserved for future use - * - 0x01: Transmitter set to use the LE 1M PHY - * - 0x02: Transmitter set to use the LE 2M PHY - * - 0x03: Transmitter set to use the LE Coded PHY with S=8 data coding - * - 0x04: Transmitter set to use the LE Coded PHY with S=2 data coding - * @param Modulation_Index Modulation index capability of the transmitter - * Values: - * - 0x00: Assume transmitter will have a standard modulation index - * - 0x01: Assume transmitter will have a stable modulation index - * @return Value indicating success or error code. - */ -tBleStatus hci_le_enhanced_receiver_test( uint8_t RX_Frequency, - uint8_t PHY, - uint8_t Modulation_Index ); - -/** - * @brief HCI_LE_ENHANCED_TRANSMITTER_TEST - * This command is used to start a test where the DUT generates test reference - * packets at a fixed interval. The Controller shall transmit at maximum power. - * An LE Controller supporting the LE_Enhanced Transmitter_Test command shall - * support Packet_Payload values 0x00, 0x01 and 0x02. An LE Controller - * supporting the LE Coded PHY shall also support Packet_Payload value 0x04 - * (not supported by STM32WB). An LE Controller may support other values of - * Packet_Payload. - * (See Bluetooth Specification v5.0 [Vol 6] Part B, Section 7.8.51) - * - * @param TX_Frequency N = (F - 2402) / 2 - * Frequency Range : 2402 MHz to 2480 MHz - * Values: - * - 0x00 ... 0x27 - * @param Length_Of_Test_Data Length in bytes of payload data in each packet. - * Values: - * - 0x00 ... 0x25 - * @param Packet_Payload Type of packet payload. - * Values: - * - 0x00: Pseudo-Random bit sequence 9 - * - 0x01: Pattern of alternating bits '11110000' - * - 0x02: Pattern of alternating bits '10101010' - * - 0x03: Pseudo-Random bit sequence 15 - * - 0x04: Pattern of All '1' bits - * - 0x05: Pattern of All '0' bits - * - 0x06: Pattern of alternating bits '00001111' - * - 0x07: Pattern of alternating bits '0101' - * @param PHY PHY to use for test packet - * Values: - * - 0x00: Reserved for future use - * - 0x01: Transmitter set to use the LE 1M PHY - * - 0x02: Transmitter set to use the LE 2M PHY - * - 0x03: Transmitter set to use the LE Coded PHY with S=8 data coding - * - 0x04: Transmitter set to use the LE Coded PHY with S=2 data coding - * @return Value indicating success or error code. - */ -tBleStatus hci_le_enhanced_transmitter_test( uint8_t TX_Frequency, - uint8_t Length_Of_Test_Data, - uint8_t Packet_Payload, - uint8_t PHY ); - -/** - * @brief HCI_LE_READ_TRANSMIT_POWER - * This command is used to read the minimum and maximum transmit powers - * supported by the Controller. - * - * @param[out] Min_TX_Power Signed integer. Units: dBm - * Values: - * - -127 ... 20 - * @param[out] Max_TX_Power Signed integer. Units: dBm - * Values: - * - -127 ... 20 - * @return Value indicating success or error code. - */ -tBleStatus hci_le_read_transmit_power( uint8_t* Min_TX_Power, - uint8_t* Max_TX_Power ); - -/** - * @brief HCI_LE_SET_PRIVACY_MODE - * This command is used to allow the Host to specify the privacy mode to be - * used for a given entry on the resolving list. - * (See Bluetooth Specification v.5.0 [Vol 2] Part E, Section 7.8.77) - * - * @param Peer_Identity_Address_Type Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - * @param Peer_Identity_Address Public or Random (static) Identity address of - * the peer device - * @param Privacy_Mode Privacy Mode. - * Values: - * - 0x00: Use Network Privacy Mode - * - 0x01: Use Device Privacy Mode - * @return Value indicating success or error code. - */ -tBleStatus hci_le_set_privacy_mode( uint8_t Peer_Identity_Address_Type, - const uint8_t* Peer_Identity_Address, - uint8_t Privacy_Mode ); - - -#endif /* BLE_HCI_LE_H__ */ diff --git a/lib_blewbxx/core/auto/ble_l2cap_aci.c b/lib_blewbxx/core/auto/ble_l2cap_aci.c deleted file mode 100644 index c7bf367d5..000000000 --- a/lib_blewbxx/core/auto/ble_l2cap_aci.c +++ /dev/null @@ -1,305 +0,0 @@ -/****************************************************************************** - * @file ble_l2cap_aci.c - * @author MCD - * @brief STM32WB BLE API (l2cap_aci) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#include "ble_l2cap_aci.h" - -tBleStatus aci_l2cap_connection_parameter_update_req( uint16_t Connection_Handle, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Slave_latency, - uint16_t Timeout_Multiplier ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_connection_parameter_update_req_cp0 *cp0 = (aci_l2cap_connection_parameter_update_req_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Conn_Interval_Min = Conn_Interval_Min; - index_input += 2; - cp0->Conn_Interval_Max = Conn_Interval_Max; - index_input += 2; - cp0->Slave_latency = Slave_latency; - index_input += 2; - cp0->Timeout_Multiplier = Timeout_Multiplier; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x181; - rq.event = 0x0F; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_l2cap_connection_parameter_update_resp( uint16_t Connection_Handle, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Slave_latency, - uint16_t Timeout_Multiplier, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length, - uint8_t Identifier, - uint8_t Accept ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_connection_parameter_update_resp_cp0 *cp0 = (aci_l2cap_connection_parameter_update_resp_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Conn_Interval_Min = Conn_Interval_Min; - index_input += 2; - cp0->Conn_Interval_Max = Conn_Interval_Max; - index_input += 2; - cp0->Slave_latency = Slave_latency; - index_input += 2; - cp0->Timeout_Multiplier = Timeout_Multiplier; - index_input += 2; - cp0->Minimum_CE_Length = Minimum_CE_Length; - index_input += 2; - cp0->Maximum_CE_Length = Maximum_CE_Length; - index_input += 2; - cp0->Identifier = Identifier; - index_input += 1; - cp0->Accept = Accept; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x182; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_l2cap_coc_connect( uint16_t Connection_Handle, - uint16_t SPSM, - uint16_t MTU, - uint16_t MPS, - uint16_t Initial_Credits, - uint8_t Channel_Number ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_coc_connect_cp0 *cp0 = (aci_l2cap_coc_connect_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->SPSM = SPSM; - index_input += 2; - cp0->MTU = MTU; - index_input += 2; - cp0->MPS = MPS; - index_input += 2; - cp0->Initial_Credits = Initial_Credits; - index_input += 2; - cp0->Channel_Number = Channel_Number; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x188; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_l2cap_coc_connect_confirm( uint16_t Connection_Handle, - uint16_t MTU, - uint16_t MPS, - uint16_t Initial_Credits, - uint16_t Result, - uint8_t* Channel_Number, - uint8_t* Channel_Index_List ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_coc_connect_confirm_cp0 *cp0 = (aci_l2cap_coc_connect_confirm_cp0*)(cmd_buffer); - aci_l2cap_coc_connect_confirm_rp0 resp; - Osal_MemSet( &resp, 0, sizeof(resp) ); - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->MTU = MTU; - index_input += 2; - cp0->MPS = MPS; - index_input += 2; - cp0->Initial_Credits = Initial_Credits; - index_input += 2; - cp0->Result = Result; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x189; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &resp; - rq.rlen = sizeof(resp); - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - if ( resp.Status ) - return resp.Status; - *Channel_Number = resp.Channel_Number; - Osal_MemCpy( (void*)Channel_Index_List, (const void*)resp.Channel_Index_List, *Channel_Number); - return BLE_STATUS_SUCCESS; -} - -tBleStatus aci_l2cap_coc_reconf( uint16_t Connection_Handle, - uint16_t MTU, - uint16_t MPS, - uint8_t Channel_Number, - const uint8_t* Channel_Index_List ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_coc_reconf_cp0 *cp0 = (aci_l2cap_coc_reconf_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->MTU = MTU; - index_input += 2; - cp0->MPS = MPS; - index_input += 2; - cp0->Channel_Number = Channel_Number; - index_input += 1; - Osal_MemCpy( (void*)&cp0->Channel_Index_List, (const void*)Channel_Index_List, Channel_Number ); - index_input += Channel_Number; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x18a; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_l2cap_coc_reconf_confirm( uint16_t Connection_Handle, - uint16_t Result ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_coc_reconf_confirm_cp0 *cp0 = (aci_l2cap_coc_reconf_confirm_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Connection_Handle = Connection_Handle; - index_input += 2; - cp0->Result = Result; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x18b; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_l2cap_coc_disconnect( uint8_t Channel_Index ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_coc_disconnect_cp0 *cp0 = (aci_l2cap_coc_disconnect_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Channel_Index = Channel_Index; - index_input += 1; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x18c; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_l2cap_coc_flow_control( uint8_t Channel_Index, - uint16_t Credits ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_coc_flow_control_cp0 *cp0 = (aci_l2cap_coc_flow_control_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Channel_Index = Channel_Index; - index_input += 1; - cp0->Credits = Credits; - index_input += 2; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x18d; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - -tBleStatus aci_l2cap_coc_tx_data( uint8_t Channel_Index, - uint16_t Length, - const uint8_t* Data ) -{ - struct hci_request rq; - uint8_t cmd_buffer[BLE_CMD_MAX_PARAM_LEN]; - aci_l2cap_coc_tx_data_cp0 *cp0 = (aci_l2cap_coc_tx_data_cp0*)(cmd_buffer); - tBleStatus status = 0; - int index_input = 0; - cp0->Channel_Index = Channel_Index; - index_input += 1; - cp0->Length = Length; - index_input += 2; - Osal_MemCpy( (void*)&cp0->Data, (const void*)Data, Length ); - index_input += Length; - Osal_MemSet( &rq, 0, sizeof(rq) ); - rq.ogf = 0x3f; - rq.ocf = 0x18e; - rq.cparam = cmd_buffer; - rq.clen = index_input; - rq.rparam = &status; - rq.rlen = 1; - if ( hci_send_req(&rq, FALSE) < 0 ) - return BLE_STATUS_TIMEOUT; - return status; -} - diff --git a/lib_blewbxx/core/auto/ble_l2cap_aci.h b/lib_blewbxx/core/auto/ble_l2cap_aci.h deleted file mode 100644 index d37148bad..000000000 --- a/lib_blewbxx/core/auto/ble_l2cap_aci.h +++ /dev/null @@ -1,291 +0,0 @@ -/****************************************************************************** - * @file ble_l2cap_aci.h - * @author MCD - * @brief STM32WB BLE API (l2cap_aci) - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_L2CAP_ACI_H__ -#define BLE_L2CAP_ACI_H__ - - -#include "ble_types.h" - -/** - * @brief ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_REQ - * Send an L2CAP connection parameter update request from the slave to the - * master. - * An ACI_L2CAP_CONNECTION_UPDATE_RESP_EVENT event is raised when the master - * responds to the request (accepts or rejects). - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Conn_Interval_Min Minimum value for the connection event interval. - * This shall be less than or equal to Conn_Interval_Max. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Interval_Max Maximum value for the connection event interval. - * This shall be greater than or equal to Conn_Interval_Min. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Slave_latency Slave latency for the connection in number of - * connection events. - * Values: - * - 0x0000 ... 0x01F3 - * @param Timeout_Multiplier Defines connection timeout parameter in the - * following manner: Timeout Multiplier * 10ms. - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_connection_parameter_update_req( uint16_t Connection_Handle, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Slave_latency, - uint16_t Timeout_Multiplier ); - -/** - * @brief ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_RESP - * Accept or reject a connection update. This command should be sent in - * response to an ACI_L2CAP_CONNECTION_UPDATE_REQ_EVENT event from the - * controller. The accept parameter has to be set if the connection parameters - * given in the event are acceptable. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Conn_Interval_Min Minimum value for the connection event interval. - * This shall be less than or equal to Conn_Interval_Max. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Conn_Interval_Max Maximum value for the connection event interval. - * This shall be greater than or equal to Conn_Interval_Min. - * Time = N * 1.25 msec. - * Values: - * - 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms) - * @param Slave_latency Slave latency for the connection in number of - * connection events. - * Values: - * - 0x0000 ... 0x01F3 - * @param Timeout_Multiplier Defines connection timeout parameter in the - * following manner: Timeout Multiplier * 10ms. - * @param Minimum_CE_Length Information parameter about the minimum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Maximum_CE_Length Information parameter about the maximum length of - * connection needed for this LE connection. - * Time = N * 0.625 msec. - * Values: - * - 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms) - * @param Identifier Identifier received in ACI_L2CAP_Connection_Update_Req - * event. - * @param Accept Specify if connection update parameters are acceptable or not. - * Values: - * - 0x00: Reject - * - 0x01: Accept - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_connection_parameter_update_resp( uint16_t Connection_Handle, - uint16_t Conn_Interval_Min, - uint16_t Conn_Interval_Max, - uint16_t Slave_latency, - uint16_t Timeout_Multiplier, - uint16_t Minimum_CE_Length, - uint16_t Maximum_CE_Length, - uint8_t Identifier, - uint8_t Accept ); - -/** - * @brief ACI_L2CAP_COC_CONNECT - * This command sends a Credit Based Connection Request packet on the specified - * connection. See Bluetooth Core specification Vol.3 Part A. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param SPSM Simplified Protocol/Service Multiplexer. - * Values: - * - 0x0001 ... 0x00FF - * @param MTU Maximum Transmission Unit. - * Values: - * - 23 ... 65535 - * @param MPS Maximum payload size (in octets). - * Values: - * - 23 ... 65533 - * @param Initial_Credits Number of K-frames that can be received on the - * created channel(s) by the L2CAP layer entity sending this packet. - * Values: - * - 0 ... 65535 - * @param Channel_Number Number of channels to be created. If this parameter is - * set to 0, it requests the creation of one LE credit based connection- - * oriented channel. Otherwise, it requests the creation of one or more - * enhanced credit based connection-oriented channels. - * Values: - * - 0 ... 5 - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_coc_connect( uint16_t Connection_Handle, - uint16_t SPSM, - uint16_t MTU, - uint16_t MPS, - uint16_t Initial_Credits, - uint8_t Channel_Number ); - -/** - * @brief ACI_L2CAP_COC_CONNECT_CONFIRM - * This command sends a Credit Based Connection Response packet. It must be - * used upon receipt of a connection request through an - * ACI_L2CAP_COC_CONNECT_EVENT event. See Bluetooth Core specification Vol.3 - * Part A. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param MTU Maximum Transmission Unit. - * Values: - * - 23 ... 65535 - * @param MPS Maximum payload size (in octets). - * Values: - * - 23 ... 65533 - * @param Initial_Credits Number of K-frames that can be received on the - * created channel(s) by the L2CAP layer entity sending this packet. - * Values: - * - 0 ... 65535 - * @param Result This parameter indicates the outcome of the request. A value - * of 0x0000 indicates success while a non-zero value indicates the - * request is refused. - * Values: - * - 0x0000 ... 0x000C - * @param[out] Channel_Number Number of created channels. It is the length of - * Channel_Index_List. - * Values: - * - 0 ... 5 - * @param[out] Channel_Index_List List of channel indexes for which the - * primitive applies. - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_coc_connect_confirm( uint16_t Connection_Handle, - uint16_t MTU, - uint16_t MPS, - uint16_t Initial_Credits, - uint16_t Result, - uint8_t* Channel_Number, - uint8_t* Channel_Index_List ); - -/** - * @brief ACI_L2CAP_COC_RECONF - * This command sends a Credit Based Reconfigure Request packet on the - * specified connection. See Bluetooth Core specification Vol.3 Part A. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param MTU Maximum Transmission Unit. - * Values: - * - 23 ... 65535 - * @param MPS Maximum payload size (in octets). - * Values: - * - 23 ... 65533 - * @param Channel_Number Number of created channels. It is the length of - * Channel_Index_List. - * Values: - * - 1 ... 5 - * @param Channel_Index_List List of channel indexes for which the primitive - * applies. - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_coc_reconf( uint16_t Connection_Handle, - uint16_t MTU, - uint16_t MPS, - uint8_t Channel_Number, - const uint8_t* Channel_Index_List ); - -/** - * @brief ACI_L2CAP_COC_RECONF_CONFIRM - * This command sends a Credit Based Reconfigure Response packet. It must be - * used upon receipt of a Credit Based Reconfigure Request through an - * ACI_L2CAP_COC_RECONF_EVENT event. See Bluetooth Core specification Vol.3 - * Part A. - * - * @param Connection_Handle Connection handle for which the command applies. - * Values: - * - 0x0000 ... 0x0EFF - * @param Result This parameter indicates the outcome of the request. A value - * of 0x0000 indicates success while a non-zero value indicates the - * request is refused. - * Values: - * - 0x0000 ... 0x000C - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_coc_reconf_confirm( uint16_t Connection_Handle, - uint16_t Result ); - -/** - * @brief ACI_L2CAP_COC_DISCONNECT - * This command sends a Disconnection Request signaling packet on the specified - * connection-oriented channel. See Bluetooth Core specification Vol.3 Part A. - * The ACI_L2CAP_COC_DISCONNECT_EVENT event is received when the disconnection - * of the channel is effective. - * - * @param Channel_Index Index of the connection-oriented channel for which the - * primitive applies. - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_coc_disconnect( uint8_t Channel_Index ); - -/** - * @brief ACI_L2CAP_COC_FLOW_CONTROL - * This command sends a Flow Control Credit signaling packet on the specified - * connection-oriented channel. See Bluetooth Core specification Vol.3 Part A. - * - * @param Channel_Index Index of the connection-oriented channel for which the - * primitive applies. - * @param Credits Number of credits the receiving device can increment, - * corresponding to the number of K-frames that can be sent to the peer - * device sending the Flow Control Credit packet. - * Values: - * - 1 ... 65535 - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_coc_flow_control( uint8_t Channel_Index, - uint16_t Credits ); - -/** - * @brief ACI_L2CAP_COC_TX_DATA - * This command sends a K-frame packet on the specified connection-oriented - * channel. See Bluetooth Core specification Vol.3 Part A. - * Note: for the first K-frame of the SDU, the Information data shall contain - * the L2CAP SDU Length coded on two octets followed by the K-frame information - * payload. For the next K-frames of the SDU, the Information data shall only - * contain the K-frame information payload. - * The Length value must not exceed (BLE_CMD_MAX_PARAM_LEN - 3) i.e. 252 for - * BLE_CMD_MAX_PARAM_LEN default value. - * - * @param Channel_Index Index of the connection-oriented channel for which the - * primitive applies. - * @param Length Length of Data (in octets) - * @param Data Information data - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_coc_tx_data( uint8_t Channel_Index, - uint16_t Length, - const uint8_t* Data ); - - -#endif /* BLE_L2CAP_ACI_H__ */ diff --git a/lib_blewbxx/core/auto/ble_types.h b/lib_blewbxx/core/auto/ble_types.h deleted file mode 100644 index 3ba9cbb97..000000000 --- a/lib_blewbxx/core/auto/ble_types.h +++ /dev/null @@ -1,2872 +0,0 @@ -/****************************************************************************** - * @file ble_types.h - * @author MCD - * @brief STM32WB BLE command/event types - * Auto-generated file: do not edit! - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_TYPES_H__ -#define BLE_TYPES_H__ - - -#include -#include "compiler.h" -#include "ble_const.h" - -/* Type used for function return value */ -typedef uint8_t tBleStatus; - -/* Definition of Host_Nb_Of_Completed_Pkt_Pair_t */ -typedef PACKED(struct) -{ - /** - * Connection_Handle[i] - * Values: - * - 0x0000 ... 0x0EFF - */ - uint16_t Connection_Handle; - /** - * The number of HCI Data Packets [i] that have been completed for the - * associated Connection_Handle since the previous time the event was - * returned. - * Values: - * - 0x0000 ... 0xFFFF - */ - uint16_t Host_Num_Of_Completed_Packets; -} Host_Nb_Of_Completed_Pkt_Pair_t; - -/* Definition of Whitelist_Entry_t */ -typedef PACKED(struct) -{ - /** - * Address type. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - */ - uint8_t Peer_Address_Type; - /** - * Public Device Address or Random Device Address. - */ - uint8_t Peer_Address[6]; -} Whitelist_Entry_t; - -/* Definition of Bonded_Device_Entry_t */ -typedef PACKED(struct) -{ - /** - * Address type. - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - */ - uint8_t Address_Type; - /** - * Public Device Address or Random Device Address. - */ - uint8_t Address[6]; -} Bonded_Device_Entry_t; - -/* Definition of Whitelist_Identity_Entry_t */ -typedef PACKED(struct) -{ - /** - * Identity address type. - * Values: - * - 0x00: Public Identity Address - * - 0x01: Random (static) Identity Address - */ - uint8_t Peer_Identity_Address_Type; - /** - * Public or Random (static) Identity address of the peer device - */ - uint8_t Peer_Identity_Address[6]; -} Whitelist_Identity_Entry_t; - -/* Definition of Service_UUID_t */ -typedef PACKED(union) -{ - /** - * 16-bit UUID - */ - uint16_t Service_UUID_16; - /** - * 128-bit UUID - */ - uint8_t Service_UUID_128[16]; -} Service_UUID_t; - -/* Definition of Include_UUID_t */ -typedef PACKED(union) -{ - /** - * 16-bit UUID - */ - uint16_t Include_UUID_16; - /** - * 128-bit UUID - */ - uint8_t Include_UUID_128[16]; -} Include_UUID_t; - -/* Definition of Char_UUID_t */ -typedef PACKED(union) -{ - /** - * 16-bit UUID - */ - uint16_t Char_UUID_16; - /** - * 128-bit UUID - */ - uint8_t Char_UUID_128[16]; -} Char_UUID_t; - -/* Definition of Char_Desc_Uuid_t */ -typedef PACKED(union) -{ - /** - * 16-bit UUID - */ - uint16_t Char_UUID_16; - /** - * 128-bit UUID - */ - uint8_t Char_UUID_128[16]; -} Char_Desc_Uuid_t; - -/* Definition of UUID_t */ -typedef PACKED(union) -{ - /** - * 16-bit UUID - */ - uint16_t UUID_16; - /** - * 128-bit UUID - */ - uint8_t UUID_128[16]; -} UUID_t; - -/* Definition of Handle_Entry_t */ -typedef PACKED(struct) -{ - /** - * The handles for which the attribute value has to be read - */ - uint16_t Handle; -} Handle_Entry_t; - -/* Definition of Handle_Packets_Pair_Entry_t */ -typedef PACKED(struct) -{ - /** - * Connection handle - */ - uint16_t Connection_Handle; - /** - * The number of HCI Data Packets that have been completed (transmitted or - * flushed) for the associated Connection_Handle since the previous time the - * event was returned. - */ - uint16_t HC_Num_Of_Completed_Packets; -} Handle_Packets_Pair_Entry_t; - -/* Definition of Advertising_Report_t */ -typedef PACKED(struct) -{ - /** - * Type of advertising report event: - * ADV_IND: Connectable undirected advertising', - * ADV_DIRECT_IND: Connectable directed advertising, - * ADV_SCAN_IND: Scannable undirected advertising, - * ADV_NONCONN_IND: Non connectable undirected advertising, - * SCAN_RSP: Scan response. - * Values: - * - 0x00: ADV_IND - * - 0x01: ADV_DIRECT_IND - * - 0x02: ADV_SCAN_IND - * - 0x03: ADV_NONCONN_IND - * - 0x04: SCAN_RSP - */ - uint8_t Event_Type; - /** - * Address type - * 0x00 Public Device Address - * 0x01 Random Device Address - * 0x02 Public Identity Address (Corresponds to Resolved Private Address) - * 0x03 Random (Static) Identity Address (Corresponds to Resolved Private - * Address) - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * - 0x02: Public Identity Address - * - 0x03: Random (Static) Identity Address - */ - uint8_t Address_Type; - /** - * Public Device Address or Random Device Address of the device to be - * connected. - */ - uint8_t Address[6]; - /** - * Length of the Data[i] field for each device which responded. - * Values: - * - 0 ... 31 - */ - uint8_t Length_Data; - /** - * Length_Data[i] octets of advertising or scan response data formatted - * as defined in [Vol 3] Part C, Section 8. - */ - const uint8_t* Data; - /** - * N Size: 1 Octet (signed integer) - * Units: dBm - * Values: - * - 127: RSSI not available - * - -127 ... 20 - */ - uint8_t RSSI; -} Advertising_Report_t; - -/* Definition of Direct_Advertising_Report_t */ -typedef PACKED(struct) -{ - /** - * Advertising type - * Values: - * - 0x01: Connectable directed advertising (ADV_DIRECT_IND) - */ - uint8_t Event_Type; - /** - * Address type - * 0x00 Public Device Address - * 0x01 Random Device Address - * 0x02 Public Identity Address (Corresponds to Resolved Private Address) - * 0x03 Random (Static) Identity Address (Corresponds to Resolved Private - * Address) - * Values: - * - 0x00: Public Device Address - * - 0x01: Random Device Address - * - 0x02: Public Identity Address - * - 0x03: Random (Static) Identity Address - */ - uint8_t Address_Type; - /** - * Public Device Address, Random Device Address, Public Identity Address or - * Random (static) Identity Address of the advertising device. - */ - uint8_t Address[6]; - /** - * 0x01 Random Device Address - * Values: - * - 0x01: Random Device Address - */ - uint8_t Direct_Address_Type; - /** - * Random Device Address - */ - uint8_t Direct_Address[6]; - /** - * N Size: 1 Octet (signed integer) - * Units: dBm - * Values: - * - 127: RSSI not available - * - -127 ... 20 - */ - uint8_t RSSI; -} Direct_Advertising_Report_t; - -/* Definition of Attribute_Group_Handle_Pair_t */ -typedef PACKED(struct) -{ - /** - * Found Attribute handle - */ - uint16_t Found_Attribute_Handle; - /** - * Group End handle - */ - uint16_t Group_End_Handle; -} Attribute_Group_Handle_Pair_t; - -/* Definition of Handle_Item_t */ -typedef PACKED(struct) -{ - uint16_t Handle; -} Handle_Item_t; - -/* Internal types used by process functions */ - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Reason; -} hci_disconnect_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_disconnect_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} hci_read_remote_version_information_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_read_remote_version_information_rp0; - -typedef PACKED(struct) -{ - uint8_t Event_Mask[8]; -} hci_set_event_mask_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_set_event_mask_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_reset_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Type; -} hci_read_transmit_power_level_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t Transmit_Power_Level; -} hci_read_transmit_power_level_rp0; - -typedef PACKED(struct) -{ - uint8_t Flow_Control_Enable; -} hci_set_controller_to_host_flow_control_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_set_controller_to_host_flow_control_rp0; - -typedef PACKED(struct) -{ - uint16_t Host_ACL_Data_Packet_Length; - uint8_t Host_Synchronous_Data_Packet_Length; - uint16_t Host_Total_Num_ACL_Data_Packets; - uint16_t Host_Total_Num_Synchronous_Data_Packets; -} hci_host_buffer_size_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_host_buffer_size_rp0; - -typedef PACKED(struct) -{ - uint8_t Number_Of_Handles; - Host_Nb_Of_Completed_Pkt_Pair_t Host_Nb_Of_Completed_Pkt_Pair[(BLE_CMD_MAX_PARAM_LEN - 1)/sizeof(Host_Nb_Of_Completed_Pkt_Pair_t)]; -} hci_host_number_of_completed_packets_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_host_number_of_completed_packets_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t HCI_Version; - uint16_t HCI_Revision; - uint8_t LMP_PAL_Version; - uint16_t Manufacturer_Name; - uint16_t LMP_PAL_Subversion; -} hci_read_local_version_information_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Supported_Commands[64]; -} hci_read_local_supported_commands_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t LMP_Features[8]; -} hci_read_local_supported_features_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t BD_ADDR[6]; -} hci_read_bd_addr_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} hci_read_rssi_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t RSSI; -} hci_read_rssi_rp0; - -typedef PACKED(struct) -{ - uint8_t LE_Event_Mask[8]; -} hci_le_set_event_mask_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_event_mask_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t HC_LE_ACL_Data_Packet_Length; - uint8_t HC_Total_Num_LE_ACL_Data_Packets; -} hci_le_read_buffer_size_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t LE_Features[8]; -} hci_le_read_local_supported_features_rp0; - -typedef PACKED(struct) -{ - uint8_t Random_Address[6]; -} hci_le_set_random_address_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_random_address_rp0; - -typedef PACKED(struct) -{ - uint16_t Advertising_Interval_Min; - uint16_t Advertising_Interval_Max; - uint8_t Advertising_Type; - uint8_t Own_Address_Type; - uint8_t Peer_Address_Type; - uint8_t Peer_Address[6]; - uint8_t Advertising_Channel_Map; - uint8_t Advertising_Filter_Policy; -} hci_le_set_advertising_parameters_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_advertising_parameters_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Transmit_Power_Level; -} hci_le_read_advertising_channel_tx_power_rp0; - -typedef PACKED(struct) -{ - uint8_t Advertising_Data_Length; - uint8_t Advertising_Data[31]; -} hci_le_set_advertising_data_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_advertising_data_rp0; - -typedef PACKED(struct) -{ - uint8_t Scan_Response_Data_Length; - uint8_t Scan_Response_Data[31]; -} hci_le_set_scan_response_data_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_scan_response_data_rp0; - -typedef PACKED(struct) -{ - uint8_t Advertising_Enable; -} hci_le_set_advertise_enable_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_advertise_enable_rp0; - -typedef PACKED(struct) -{ - uint8_t LE_Scan_Type; - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Own_Address_Type; - uint8_t Scanning_Filter_Policy; -} hci_le_set_scan_parameters_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_scan_parameters_rp0; - -typedef PACKED(struct) -{ - uint8_t LE_Scan_Enable; - uint8_t Filter_Duplicates; -} hci_le_set_scan_enable_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_scan_enable_rp0; - -typedef PACKED(struct) -{ - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Initiator_Filter_Policy; - uint8_t Peer_Address_Type; - uint8_t Peer_Address[6]; - uint8_t Own_Address_Type; - uint16_t Conn_Interval_Min; - uint16_t Conn_Interval_Max; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; - uint16_t Minimum_CE_Length; - uint16_t Maximum_CE_Length; -} hci_le_create_connection_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_create_connection_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_create_connection_cancel_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t White_List_Size; -} hci_le_read_white_list_size_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_clear_white_list_rp0; - -typedef PACKED(struct) -{ - uint8_t Address_Type; - uint8_t Address[6]; -} hci_le_add_device_to_white_list_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_add_device_to_white_list_rp0; - -typedef PACKED(struct) -{ - uint8_t Address_Type; - uint8_t Address[6]; -} hci_le_remove_device_from_white_list_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_remove_device_from_white_list_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Conn_Interval_Min; - uint16_t Conn_Interval_Max; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; - uint16_t Minimum_CE_Length; - uint16_t Maximum_CE_Length; -} hci_le_connection_update_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_connection_update_rp0; - -typedef PACKED(struct) -{ - uint8_t LE_Channel_Map[5]; -} hci_le_set_host_channel_classification_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_host_channel_classification_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} hci_le_read_channel_map_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t LE_Channel_Map[5]; -} hci_le_read_channel_map_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} hci_le_read_remote_features_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_read_remote_features_rp0; - -typedef PACKED(struct) -{ - uint8_t Key[16]; - uint8_t Plaintext_Data[16]; -} hci_le_encrypt_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Encrypted_Data[16]; -} hci_le_encrypt_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Random_Number[8]; -} hci_le_rand_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Random_Number[8]; - uint16_t Encrypted_Diversifier; - uint8_t Long_Term_Key[16]; -} hci_le_start_encryption_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_start_encryption_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Long_Term_Key[16]; -} hci_le_long_term_key_request_reply_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; -} hci_le_long_term_key_request_reply_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} hci_le_long_term_key_requested_negative_reply_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; -} hci_le_long_term_key_requested_negative_reply_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t LE_States[8]; -} hci_le_read_supported_states_rp0; - -typedef PACKED(struct) -{ - uint8_t RX_Frequency; -} hci_le_receiver_test_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_receiver_test_rp0; - -typedef PACKED(struct) -{ - uint8_t TX_Frequency; - uint8_t Length_Of_Test_Data; - uint8_t Packet_Payload; -} hci_le_transmitter_test_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_transmitter_test_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Number_Of_Packets; -} hci_le_test_end_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t TxOctets; - uint16_t TxTime; -} hci_le_set_data_length_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; -} hci_le_set_data_length_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t SuggestedMaxTxOctets; - uint16_t SuggestedMaxTxTime; -} hci_le_read_suggested_default_data_length_rp0; - -typedef PACKED(struct) -{ - uint16_t SuggestedMaxTxOctets; - uint16_t SuggestedMaxTxTime; -} hci_le_write_suggested_default_data_length_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_write_suggested_default_data_length_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_read_local_p256_public_key_rp0; - -typedef PACKED(struct) -{ - uint8_t Remote_P256_Public_Key[64]; -} hci_le_generate_dhkey_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_generate_dhkey_rp0; - -typedef PACKED(struct) -{ - uint8_t Peer_Identity_Address_Type; - uint8_t Peer_Identity_Address[6]; - uint8_t Peer_IRK[16]; - uint8_t Local_IRK[16]; -} hci_le_add_device_to_resolving_list_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_add_device_to_resolving_list_rp0; - -typedef PACKED(struct) -{ - uint8_t Peer_Identity_Address_Type; - uint8_t Peer_Identity_Address[6]; -} hci_le_remove_device_from_resolving_list_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_remove_device_from_resolving_list_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_clear_resolving_list_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Resolving_List_Size; -} hci_le_read_resolving_list_size_rp0; - -typedef PACKED(struct) -{ - uint8_t Peer_Identity_Address_Type; - uint8_t Peer_Identity_Address[6]; -} hci_le_read_peer_resolvable_address_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Peer_Resolvable_Address[6]; -} hci_le_read_peer_resolvable_address_rp0; - -typedef PACKED(struct) -{ - uint8_t Peer_Identity_Address_Type; - uint8_t Peer_Identity_Address[6]; -} hci_le_read_local_resolvable_address_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Local_Resolvable_Address[6]; -} hci_le_read_local_resolvable_address_rp0; - -typedef PACKED(struct) -{ - uint8_t Address_Resolution_Enable; -} hci_le_set_address_resolution_enable_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_address_resolution_enable_rp0; - -typedef PACKED(struct) -{ - uint16_t RPA_Timeout; -} hci_le_set_resolvable_private_address_timeout_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_resolvable_private_address_timeout_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t supportedMaxTxOctets; - uint16_t supportedMaxTxTime; - uint16_t supportedMaxRxOctets; - uint16_t supportedMaxRxTime; -} hci_le_read_maximum_data_length_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} hci_le_read_phy_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t TX_PHY; - uint8_t RX_PHY; -} hci_le_read_phy_rp0; - -typedef PACKED(struct) -{ - uint8_t ALL_PHYS; - uint8_t TX_PHYS; - uint8_t RX_PHYS; -} hci_le_set_default_phy_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_default_phy_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t ALL_PHYS; - uint8_t TX_PHYS; - uint8_t RX_PHYS; - uint16_t PHY_options; -} hci_le_set_phy_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_phy_rp0; - -typedef PACKED(struct) -{ - uint8_t RX_Frequency; - uint8_t PHY; - uint8_t Modulation_Index; -} hci_le_enhanced_receiver_test_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_enhanced_receiver_test_rp0; - -typedef PACKED(struct) -{ - uint8_t TX_Frequency; - uint8_t Length_Of_Test_Data; - uint8_t Packet_Payload; - uint8_t PHY; -} hci_le_enhanced_transmitter_test_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_enhanced_transmitter_test_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Min_TX_Power; - uint8_t Max_TX_Power; -} hci_le_read_transmit_power_rp0; - -typedef PACKED(struct) -{ - uint8_t Peer_Identity_Address_Type; - uint8_t Peer_Identity_Address[6]; - uint8_t Privacy_Mode; -} hci_le_set_privacy_mode_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} hci_le_set_privacy_mode_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Build_Number; -} aci_hal_get_fw_build_number_rp0; - -typedef PACKED(struct) -{ - uint8_t Offset; - uint8_t Length; - uint8_t Value[BLE_CMD_MAX_PARAM_LEN - 2]; -} aci_hal_write_config_data_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_write_config_data_rp0; - -typedef PACKED(struct) -{ - uint8_t Offset; -} aci_hal_read_config_data_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Data_Length; - uint8_t Data[(BLE_EVT_MAX_PARAM_LEN - 3) - 2]; -} aci_hal_read_config_data_rp0; - -typedef PACKED(struct) -{ - uint8_t En_High_Power; - uint8_t PA_Level; -} aci_hal_set_tx_power_level_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_set_tx_power_level_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint32_t Number_Of_Packets; -} aci_hal_le_tx_test_packet_number_rp0; - -typedef PACKED(struct) -{ - uint8_t RF_Channel; - uint8_t Freq_offset; -} aci_hal_tone_start_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_tone_start_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_tone_stop_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Link_Status[8]; - uint16_t Link_Connection_Handle[8]; -} aci_hal_get_link_status_rp0; - -typedef PACKED(struct) -{ - uint16_t Radio_Activity_Mask; -} aci_hal_set_radio_activity_mask_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_set_radio_activity_mask_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint32_t Anchor_Period; - uint32_t Max_Free_Slot; -} aci_hal_get_anchor_period_rp0; - -typedef PACKED(struct) -{ - uint32_t Event_Mask; -} aci_hal_set_event_mask_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_set_event_mask_rp0; - -typedef PACKED(struct) -{ - uint32_t SMP_Config; -} aci_hal_set_smp_eng_config_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_set_smp_eng_config_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Allocated_For_TX; - uint8_t Allocated_For_RX; - uint8_t Allocated_MBlocks; -} aci_hal_get_pm_debug_info_rp0; - -typedef PACKED(struct) -{ - uint8_t Register_Address; -} aci_hal_read_radio_reg_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t reg_val; -} aci_hal_read_radio_reg_rp0; - -typedef PACKED(struct) -{ - uint8_t Register_Address; - uint8_t Register_Value; -} aci_hal_write_radio_reg_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_write_radio_reg_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Value[3]; -} aci_hal_read_raw_rssi_rp0; - -typedef PACKED(struct) -{ - uint8_t RF_Channel; -} aci_hal_rx_start_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_rx_start_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_rx_stop_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_hal_stack_reset_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_non_discoverable_rp0; - -typedef PACKED(struct) -{ - uint8_t Advertising_Type; - uint16_t Advertising_Interval_Min; - uint16_t Advertising_Interval_Max; - uint8_t Own_Address_Type; - uint8_t Advertising_Filter_Policy; - uint8_t Local_Name_Length; - uint8_t Local_Name[BLE_CMD_MAX_PARAM_LEN - 13]; -} aci_gap_set_limited_discoverable_cp0; - -typedef PACKED(struct) -{ - uint8_t Service_Uuid_length; - uint8_t Service_Uuid_List[BLE_CMD_MAX_PARAM_LEN - 13]; -} aci_gap_set_limited_discoverable_cp1; - -typedef PACKED(struct) -{ - uint16_t Slave_Conn_Interval_Min; - uint16_t Slave_Conn_Interval_Max; -} aci_gap_set_limited_discoverable_cp2; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_limited_discoverable_rp0; - -typedef PACKED(struct) -{ - uint8_t Advertising_Type; - uint16_t Advertising_Interval_Min; - uint16_t Advertising_Interval_Max; - uint8_t Own_Address_Type; - uint8_t Advertising_Filter_Policy; - uint8_t Local_Name_Length; - uint8_t Local_Name[BLE_CMD_MAX_PARAM_LEN - 13]; -} aci_gap_set_discoverable_cp0; - -typedef PACKED(struct) -{ - uint8_t Service_Uuid_length; - uint8_t Service_Uuid_List[BLE_CMD_MAX_PARAM_LEN - 13]; -} aci_gap_set_discoverable_cp1; - -typedef PACKED(struct) -{ - uint16_t Slave_Conn_Interval_Min; - uint16_t Slave_Conn_Interval_Max; -} aci_gap_set_discoverable_cp2; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_discoverable_rp0; - -typedef PACKED(struct) -{ - uint8_t Own_Address_Type; - uint8_t Directed_Advertising_Type; - uint8_t Direct_Address_Type; - uint8_t Direct_Address[6]; - uint16_t Advertising_Interval_Min; - uint16_t Advertising_Interval_Max; -} aci_gap_set_direct_connectable_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_direct_connectable_rp0; - -typedef PACKED(struct) -{ - uint8_t IO_Capability; -} aci_gap_set_io_capability_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_io_capability_rp0; - -typedef PACKED(struct) -{ - uint8_t Bonding_Mode; - uint8_t MITM_Mode; - uint8_t SC_Support; - uint8_t KeyPress_Notification_Support; - uint8_t Min_Encryption_Key_Size; - uint8_t Max_Encryption_Key_Size; - uint8_t Use_Fixed_Pin; - uint32_t Fixed_Pin; - uint8_t Identity_Address_Type; -} aci_gap_set_authentication_requirement_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_authentication_requirement_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Authorization_Enable; -} aci_gap_set_authorization_requirement_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_authorization_requirement_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint32_t Pass_Key; -} aci_gap_pass_key_resp_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_pass_key_resp_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Authorize; -} aci_gap_authorization_resp_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_authorization_resp_rp0; - -typedef PACKED(struct) -{ - uint8_t Role; - uint8_t privacy_enabled; - uint8_t device_name_char_len; -} aci_gap_init_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Service_Handle; - uint16_t Dev_Name_Char_Handle; - uint16_t Appearance_Char_Handle; -} aci_gap_init_rp0; - -typedef PACKED(struct) -{ - uint8_t Advertising_Event_Type; - uint8_t Own_Address_Type; -} aci_gap_set_non_connectable_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_non_connectable_rp0; - -typedef PACKED(struct) -{ - uint16_t Advertising_Interval_Min; - uint16_t Advertising_Interval_Max; - uint8_t Own_Address_Type; - uint8_t Adv_Filter_Policy; -} aci_gap_set_undirected_connectable_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_undirected_connectable_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gap_slave_security_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_slave_security_req_rp0; - -typedef PACKED(struct) -{ - uint8_t AdvDataLen; - uint8_t AdvData[BLE_CMD_MAX_PARAM_LEN - 1]; -} aci_gap_update_adv_data_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_update_adv_data_rp0; - -typedef PACKED(struct) -{ - uint8_t ADType; -} aci_gap_delete_ad_type_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_delete_ad_type_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gap_get_security_level_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Security_Mode; - uint8_t Security_Level; -} aci_gap_get_security_level_rp0; - -typedef PACKED(struct) -{ - uint16_t GAP_Evt_Mask; -} aci_gap_set_event_mask_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_event_mask_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_configure_whitelist_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Reason; -} aci_gap_terminate_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_terminate_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_clear_security_db_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gap_allow_rebond_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_allow_rebond_rp0; - -typedef PACKED(struct) -{ - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Own_Address_Type; - uint8_t Filter_Duplicates; -} aci_gap_start_limited_discovery_proc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_start_limited_discovery_proc_rp0; - -typedef PACKED(struct) -{ - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Own_Address_Type; - uint8_t Filter_Duplicates; -} aci_gap_start_general_discovery_proc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_start_general_discovery_proc_rp0; - -typedef PACKED(struct) -{ - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Peer_Address_Type; - uint8_t Peer_Address[6]; - uint8_t Own_Address_Type; - uint16_t Conn_Interval_Min; - uint16_t Conn_Interval_Max; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; - uint16_t Minimum_CE_Length; - uint16_t Maximum_CE_Length; -} aci_gap_start_name_discovery_proc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_start_name_discovery_proc_rp0; - -typedef PACKED(struct) -{ - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Own_Address_Type; - uint16_t Conn_Interval_Min; - uint16_t Conn_Interval_Max; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; - uint16_t Minimum_CE_Length; - uint16_t Maximum_CE_Length; - uint8_t Num_of_Whitelist_Entries; - Whitelist_Entry_t Whitelist_Entry[(BLE_CMD_MAX_PARAM_LEN - 18)/sizeof(Whitelist_Entry_t)]; -} aci_gap_start_auto_connection_establish_proc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_start_auto_connection_establish_proc_rp0; - -typedef PACKED(struct) -{ - uint8_t LE_Scan_Type; - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Own_Address_Type; - uint8_t Scanning_Filter_Policy; - uint8_t Filter_Duplicates; -} aci_gap_start_general_connection_establish_proc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_start_general_connection_establish_proc_rp0; - -typedef PACKED(struct) -{ - uint8_t LE_Scan_Type; - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Own_Address_Type; - uint8_t Scanning_Filter_Policy; - uint8_t Filter_Duplicates; - uint8_t Num_of_Whitelist_Entries; - Whitelist_Entry_t Whitelist_Entry[(BLE_CMD_MAX_PARAM_LEN - 9)/sizeof(Whitelist_Entry_t)]; -} aci_gap_start_selective_connection_establish_proc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_start_selective_connection_establish_proc_rp0; - -typedef PACKED(struct) -{ - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t Peer_Address_Type; - uint8_t Peer_Address[6]; - uint8_t Own_Address_Type; - uint16_t Conn_Interval_Min; - uint16_t Conn_Interval_Max; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; - uint16_t Minimum_CE_Length; - uint16_t Maximum_CE_Length; -} aci_gap_create_connection_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_create_connection_rp0; - -typedef PACKED(struct) -{ - uint8_t Procedure_Code; -} aci_gap_terminate_gap_proc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_terminate_gap_proc_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Conn_Interval_Min; - uint16_t Conn_Interval_Max; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; - uint16_t Minimum_CE_Length; - uint16_t Maximum_CE_Length; -} aci_gap_start_connection_update_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_start_connection_update_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Force_Rebond; -} aci_gap_send_pairing_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_send_pairing_req_rp0; - -typedef PACKED(struct) -{ - uint8_t Address[6]; -} aci_gap_resolve_private_addr_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Actual_Address[6]; -} aci_gap_resolve_private_addr_rp0; - -typedef PACKED(struct) -{ - uint16_t Advertising_Interval_Min; - uint16_t Advertising_Interval_Max; - uint8_t Advertising_Type; - uint8_t Own_Address_Type; - uint8_t Adv_Data_Length; - uint8_t Adv_Data[BLE_CMD_MAX_PARAM_LEN - 8]; -} aci_gap_set_broadcast_mode_cp0; - -typedef PACKED(struct) -{ - uint8_t Num_of_Whitelist_Entries; - Whitelist_Entry_t Whitelist_Entry[(BLE_CMD_MAX_PARAM_LEN - 8)/sizeof(Whitelist_Entry_t)]; -} aci_gap_set_broadcast_mode_cp1; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_broadcast_mode_rp0; - -typedef PACKED(struct) -{ - uint16_t LE_Scan_Interval; - uint16_t LE_Scan_Window; - uint8_t LE_Scan_Type; - uint8_t Own_Address_Type; - uint8_t Filter_Duplicates; - uint8_t Scanning_Filter_Policy; -} aci_gap_start_observation_proc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_start_observation_proc_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Num_of_Addresses; - Bonded_Device_Entry_t Bonded_Device_Entry[((BLE_EVT_MAX_PARAM_LEN - 3) - 2)/sizeof(Bonded_Device_Entry_t)]; -} aci_gap_get_bonded_devices_rp0; - -typedef PACKED(struct) -{ - uint8_t Peer_Address_Type; - uint8_t Peer_Address[6]; -} aci_gap_is_device_bonded_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_is_device_bonded_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Confirm_Yes_No; -} aci_gap_numeric_comparison_value_confirm_yesno_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_numeric_comparison_value_confirm_yesno_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Input_Type; -} aci_gap_passkey_input_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_passkey_input_rp0; - -typedef PACKED(struct) -{ - uint8_t OOB_Data_Type; -} aci_gap_get_oob_data_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Address_Type; - uint8_t Address[6]; - uint8_t OOB_Data_Type; - uint8_t OOB_Data_Len; - uint8_t OOB_Data[16]; -} aci_gap_get_oob_data_rp0; - -typedef PACKED(struct) -{ - uint8_t Device_Type; - uint8_t Address_Type; - uint8_t Address[6]; - uint8_t OOB_Data_Type; - uint8_t OOB_Data_Len; - uint8_t OOB_Data[16]; -} aci_gap_set_oob_data_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_set_oob_data_rp0; - -typedef PACKED(struct) -{ - uint8_t Num_of_Resolving_list_Entries; - Whitelist_Identity_Entry_t Whitelist_Identity_Entry[(BLE_CMD_MAX_PARAM_LEN - 2)/sizeof(Whitelist_Identity_Entry_t)]; -} aci_gap_add_devices_to_resolving_list_cp0; - -typedef PACKED(struct) -{ - uint8_t Clear_Resolving_List; -} aci_gap_add_devices_to_resolving_list_cp1; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_add_devices_to_resolving_list_rp0; - -typedef PACKED(struct) -{ - uint8_t Peer_Identity_Address_Type; - uint8_t Peer_Identity_Address[6]; -} aci_gap_remove_bonded_device_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gap_remove_bonded_device_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_init_rp0; - -typedef PACKED(struct) -{ - uint8_t Service_UUID_Type; - Service_UUID_t Service_UUID; -} aci_gatt_add_service_cp0; - -typedef PACKED(struct) -{ - uint8_t Service_Type; - uint8_t Max_Attribute_Records; -} aci_gatt_add_service_cp1; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Service_Handle; -} aci_gatt_add_service_rp0; - -typedef PACKED(struct) -{ - uint16_t Service_Handle; - uint16_t Include_Start_Handle; - uint16_t Include_End_Handle; - uint8_t Include_UUID_Type; - Include_UUID_t Include_UUID; -} aci_gatt_include_service_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Include_Handle; -} aci_gatt_include_service_rp0; - -typedef PACKED(struct) -{ - uint16_t Service_Handle; - uint8_t Char_UUID_Type; - Char_UUID_t Char_UUID; -} aci_gatt_add_char_cp0; - -typedef PACKED(struct) -{ - uint16_t Char_Value_Length; - uint8_t Char_Properties; - uint8_t Security_Permissions; - uint8_t GATT_Evt_Mask; - uint8_t Enc_Key_Size; - uint8_t Is_Variable; -} aci_gatt_add_char_cp1; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Char_Handle; -} aci_gatt_add_char_rp0; - -typedef PACKED(struct) -{ - uint16_t Service_Handle; - uint16_t Char_Handle; - uint8_t Char_Desc_Uuid_Type; - Char_Desc_Uuid_t Char_Desc_Uuid; -} aci_gatt_add_char_desc_cp0; - -typedef PACKED(struct) -{ - uint8_t Char_Desc_Value_Max_Len; - uint8_t Char_Desc_Value_Length; - uint8_t Char_Desc_Value[BLE_CMD_MAX_PARAM_LEN - 12]; -} aci_gatt_add_char_desc_cp1; - -typedef PACKED(struct) -{ - uint8_t Security_Permissions; - uint8_t Access_Permissions; - uint8_t GATT_Evt_Mask; - uint8_t Enc_Key_Size; - uint8_t Is_Variable; -} aci_gatt_add_char_desc_cp2; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Char_Desc_Handle; -} aci_gatt_add_char_desc_rp0; - -typedef PACKED(struct) -{ - uint16_t Service_Handle; - uint16_t Char_Handle; - uint8_t Val_Offset; - uint8_t Char_Value_Length; - uint8_t Char_Value[BLE_CMD_MAX_PARAM_LEN - 6]; -} aci_gatt_update_char_value_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_update_char_value_rp0; - -typedef PACKED(struct) -{ - uint16_t Serv_Handle; - uint16_t Char_Handle; -} aci_gatt_del_char_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_del_char_rp0; - -typedef PACKED(struct) -{ - uint16_t Serv_Handle; -} aci_gatt_del_service_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_del_service_rp0; - -typedef PACKED(struct) -{ - uint16_t Serv_Handle; - uint16_t Include_Handle; -} aci_gatt_del_include_service_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_del_include_service_rp0; - -typedef PACKED(struct) -{ - uint32_t GATT_Evt_Mask; -} aci_gatt_set_event_mask_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_set_event_mask_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gatt_exchange_config_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_exchange_config_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Start_Handle; - uint16_t End_Handle; -} aci_att_find_info_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_att_find_info_req_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Start_Handle; - uint16_t End_Handle; - uint16_t UUID; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 9]; -} aci_att_find_by_type_value_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_att_find_by_type_value_req_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Start_Handle; - uint16_t End_Handle; - uint8_t UUID_Type; - UUID_t UUID; -} aci_att_read_by_type_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_att_read_by_type_req_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Start_Handle; - uint16_t End_Handle; - uint8_t UUID_Type; - UUID_t UUID; -} aci_att_read_by_group_type_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_att_read_by_group_type_req_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint16_t Val_Offset; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 7]; -} aci_att_prepare_write_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_att_prepare_write_req_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Execute; -} aci_att_execute_write_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_att_execute_write_req_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gatt_disc_all_primary_services_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_disc_all_primary_services_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t UUID_Type; - UUID_t UUID; -} aci_gatt_disc_primary_service_by_uuid_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_disc_primary_service_by_uuid_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Start_Handle; - uint16_t End_Handle; -} aci_gatt_find_included_services_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_find_included_services_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Start_Handle; - uint16_t End_Handle; -} aci_gatt_disc_all_char_of_service_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_disc_all_char_of_service_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Start_Handle; - uint16_t End_Handle; - uint8_t UUID_Type; - UUID_t UUID; -} aci_gatt_disc_char_by_uuid_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_disc_char_by_uuid_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Char_Handle; - uint16_t End_Handle; -} aci_gatt_disc_all_char_desc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_disc_all_char_desc_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; -} aci_gatt_read_char_value_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_read_char_value_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Start_Handle; - uint16_t End_Handle; - uint8_t UUID_Type; - UUID_t UUID; -} aci_gatt_read_using_char_uuid_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_read_using_char_uuid_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint16_t Val_Offset; -} aci_gatt_read_long_char_value_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_read_long_char_value_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Number_of_Handles; - Handle_Entry_t Handle_Entry[(BLE_CMD_MAX_PARAM_LEN - 3)/sizeof(Handle_Entry_t)]; -} aci_gatt_read_multiple_char_value_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_read_multiple_char_value_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 5]; -} aci_gatt_write_char_value_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_write_char_value_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint16_t Val_Offset; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 7]; -} aci_gatt_write_long_char_value_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_write_long_char_value_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint16_t Val_Offset; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 7]; -} aci_gatt_write_char_reliable_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_write_char_reliable_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint16_t Val_Offset; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 7]; -} aci_gatt_write_long_char_desc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_write_long_char_desc_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint16_t Val_Offset; -} aci_gatt_read_long_char_desc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_read_long_char_desc_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 5]; -} aci_gatt_write_char_desc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_write_char_desc_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; -} aci_gatt_read_char_desc_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_read_char_desc_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 5]; -} aci_gatt_write_without_resp_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_write_without_resp_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 5]; -} aci_gatt_signed_write_without_resp_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_signed_write_without_resp_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gatt_confirm_indication_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_confirm_indication_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint8_t Write_status; - uint8_t Error_Code; - uint8_t Attribute_Val_Length; - uint8_t Attribute_Val[BLE_CMD_MAX_PARAM_LEN - 7]; -} aci_gatt_write_resp_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_write_resp_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gatt_allow_read_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_allow_read_rp0; - -typedef PACKED(struct) -{ - uint16_t Serv_Handle; - uint16_t Attr_Handle; - uint8_t Security_Permissions; -} aci_gatt_set_security_permission_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_set_security_permission_rp0; - -typedef PACKED(struct) -{ - uint16_t Serv_Handle; - uint16_t Char_Handle; - uint16_t Char_Desc_Handle; - uint16_t Val_Offset; - uint8_t Char_Desc_Value_Length; - uint8_t Char_Desc_Value[BLE_CMD_MAX_PARAM_LEN - 9]; -} aci_gatt_set_desc_value_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_set_desc_value_rp0; - -typedef PACKED(struct) -{ - uint16_t Attr_Handle; - uint16_t Offset; - uint16_t Value_Length_Requested; -} aci_gatt_read_handle_value_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Length; - uint16_t Value_Length; - uint8_t Value[(BLE_EVT_MAX_PARAM_LEN - 3) - 5]; -} aci_gatt_read_handle_value_rp0; - -typedef PACKED(struct) -{ - uint16_t Conn_Handle_To_Notify; - uint16_t Service_Handle; - uint16_t Char_Handle; - uint8_t Update_Type; - uint16_t Char_Length; - uint16_t Value_Offset; - uint8_t Value_Length; - uint8_t Value[BLE_CMD_MAX_PARAM_LEN - 12]; -} aci_gatt_update_char_value_ext_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_update_char_value_ext_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Error_Code; -} aci_gatt_deny_read_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_deny_read_rp0; - -typedef PACKED(struct) -{ - uint16_t Serv_Handle; - uint16_t Attr_Handle; - uint8_t Access_Permissions; -} aci_gatt_set_access_permission_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_gatt_set_access_permission_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Conn_Interval_Min; - uint16_t Conn_Interval_Max; - uint16_t Slave_latency; - uint16_t Timeout_Multiplier; -} aci_l2cap_connection_parameter_update_req_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_l2cap_connection_parameter_update_req_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Conn_Interval_Min; - uint16_t Conn_Interval_Max; - uint16_t Slave_latency; - uint16_t Timeout_Multiplier; - uint16_t Minimum_CE_Length; - uint16_t Maximum_CE_Length; - uint8_t Identifier; - uint8_t Accept; -} aci_l2cap_connection_parameter_update_resp_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_l2cap_connection_parameter_update_resp_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t SPSM; - uint16_t MTU; - uint16_t MPS; - uint16_t Initial_Credits; - uint8_t Channel_Number; -} aci_l2cap_coc_connect_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_l2cap_coc_connect_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t MTU; - uint16_t MPS; - uint16_t Initial_Credits; - uint16_t Result; -} aci_l2cap_coc_connect_confirm_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Channel_Number; - uint8_t Channel_Index_List[(BLE_EVT_MAX_PARAM_LEN - 3) - 2]; -} aci_l2cap_coc_connect_confirm_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t MTU; - uint16_t MPS; - uint8_t Channel_Number; - uint8_t Channel_Index_List[BLE_CMD_MAX_PARAM_LEN - 7]; -} aci_l2cap_coc_reconf_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_l2cap_coc_reconf_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Result; -} aci_l2cap_coc_reconf_confirm_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_l2cap_coc_reconf_confirm_rp0; - -typedef PACKED(struct) -{ - uint8_t Channel_Index; -} aci_l2cap_coc_disconnect_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_l2cap_coc_disconnect_rp0; - -typedef PACKED(struct) -{ - uint8_t Channel_Index; - uint16_t Credits; -} aci_l2cap_coc_flow_control_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_l2cap_coc_flow_control_rp0; - -typedef PACKED(struct) -{ - uint8_t Channel_Index; - uint16_t Length; - uint8_t Data[BLE_CMD_MAX_PARAM_LEN - 3]; -} aci_l2cap_coc_tx_data_cp0; - -typedef PACKED(struct) -{ - uint8_t Status; -} aci_l2cap_coc_tx_data_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t Reason; -} hci_disconnection_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t Encryption_Enabled; -} hci_encryption_change_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t Version; - uint16_t Manufacturer_Name; - uint16_t Subversion; -} hci_read_remote_version_information_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Hardware_Code; -} hci_hardware_error_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Number_of_Handles; - Handle_Packets_Pair_Entry_t Handle_Packets_Pair_Entry[(BLE_EVT_MAX_PARAM_LEN - 1)/sizeof(Handle_Packets_Pair_Entry_t)]; -} hci_number_of_completed_packets_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; -} hci_encryption_key_refresh_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t Role; - uint8_t Peer_Address_Type; - uint8_t Peer_Address[6]; - uint16_t Conn_Interval; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; - uint8_t Master_Clock_Accuracy; -} hci_le_connection_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Num_Reports; - Advertising_Report_t Advertising_Report[((BLE_EVT_MAX_PARAM_LEN - 1) - 1)/sizeof(Advertising_Report_t)]; -} hci_le_advertising_report_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint16_t Conn_Interval; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; -} hci_le_connection_update_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t LE_Features[8]; -} hci_le_read_remote_features_complete_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Random_Number[8]; - uint16_t Encrypted_Diversifier; -} hci_le_long_term_key_request_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t MaxTxOctets; - uint16_t MaxTxTime; - uint16_t MaxRxOctets; - uint16_t MaxRxTime; -} hci_le_data_length_change_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t Local_P256_Public_Key[64]; -} hci_le_read_local_p256_public_key_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint8_t DHKey[32]; -} hci_le_generate_dhkey_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t Role; - uint8_t Peer_Address_Type; - uint8_t Peer_Address[6]; - uint8_t Local_Resolvable_Private_Address[6]; - uint8_t Peer_Resolvable_Private_Address[6]; - uint16_t Conn_Interval; - uint16_t Conn_Latency; - uint16_t Supervision_Timeout; - uint8_t Master_Clock_Accuracy; -} hci_le_enhanced_connection_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Num_Reports; - Direct_Advertising_Report_t Direct_Advertising_Report[((BLE_EVT_MAX_PARAM_LEN - 1) - 1)/sizeof(Direct_Advertising_Report_t)]; -} hci_le_direct_advertising_report_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Status; - uint16_t Connection_Handle; - uint8_t TX_PHY; - uint8_t RX_PHY; -} hci_le_phy_update_complete_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Last_State; - uint8_t Next_State; - uint32_t Next_State_SysTime; -} aci_hal_end_of_radio_activity_event_rp0; - -typedef PACKED(struct) -{ - uint8_t RSSI; - uint8_t Peer_Address_Type; - uint8_t Peer_Address[6]; -} aci_hal_scan_req_report_event_rp0; - -typedef PACKED(struct) -{ - uint8_t FW_Error_Type; - uint8_t Data_Length; - uint8_t Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 2]; -} aci_hal_fw_error_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Status; - uint8_t Reason; -} aci_gap_pairing_complete_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gap_pass_key_req_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gap_authorization_req_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Procedure_Code; - uint8_t Status; - uint8_t Data_Length; - uint8_t Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 3]; -} aci_gap_proc_complete_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gap_addr_not_resolved_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint32_t Numeric_Value; -} aci_gap_numeric_comparison_value_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Notification_Type; -} aci_gap_keypress_notification_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Result; -} aci_l2cap_connection_update_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Data_Length; - uint8_t Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 3]; -} aci_l2cap_proc_timeout_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Identifier; - uint16_t L2CAP_Length; - uint16_t Interval_Min; - uint16_t Interval_Max; - uint16_t Slave_Latency; - uint16_t Timeout_Multiplier; -} aci_l2cap_connection_update_req_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Identifier; - uint16_t Reason; - uint8_t Data_Length; - uint8_t Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 6]; -} aci_l2cap_command_reject_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t SPSM; - uint16_t MTU; - uint16_t MPS; - uint16_t Initial_Credits; - uint8_t Channel_Number; -} aci_l2cap_coc_connect_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t MTU; - uint16_t MPS; - uint16_t Initial_Credits; - uint16_t Result; - uint8_t Channel_Number; - uint8_t Channel_Index_List[(BLE_EVT_MAX_PARAM_LEN - 2) - 11]; -} aci_l2cap_coc_connect_confirm_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t MTU; - uint16_t MPS; - uint8_t Channel_Number; - uint8_t Channel_Index_List[(BLE_EVT_MAX_PARAM_LEN - 2) - 7]; -} aci_l2cap_coc_reconf_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Result; -} aci_l2cap_coc_reconf_confirm_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Channel_Index; -} aci_l2cap_coc_disconnect_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Channel_Index; - uint16_t Credits; -} aci_l2cap_coc_flow_control_event_rp0; - -typedef PACKED(struct) -{ - uint8_t Channel_Index; - uint16_t Length; - uint8_t Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 3]; -} aci_l2cap_coc_rx_data_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attr_Handle; - uint16_t Offset; - uint16_t Attr_Data_Length; - uint8_t Attr_Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 8]; -} aci_gatt_attribute_modified_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gatt_proc_timeout_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Server_RX_MTU; -} aci_att_exchange_mtu_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Format; - uint8_t Event_Data_Length; - uint8_t Handle_UUID_Pair[(BLE_EVT_MAX_PARAM_LEN - 2) - 4]; -} aci_att_find_info_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Num_of_Handle_Pair; - Attribute_Group_Handle_Pair_t Attribute_Group_Handle_Pair[((BLE_EVT_MAX_PARAM_LEN - 2) - 3)/sizeof(Attribute_Group_Handle_Pair_t)]; -} aci_att_find_by_type_value_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Handle_Value_Pair_Length; - uint8_t Data_Length; - uint8_t Handle_Value_Pair_Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 4]; -} aci_att_read_by_type_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Event_Data_Length; - uint8_t Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 3]; -} aci_att_read_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Event_Data_Length; - uint8_t Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 3]; -} aci_att_read_blob_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Event_Data_Length; - uint8_t Set_Of_Values[(BLE_EVT_MAX_PARAM_LEN - 2) - 3]; -} aci_att_read_multiple_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Attribute_Data_Length; - uint8_t Data_Length; - uint8_t Attribute_Data_List[(BLE_EVT_MAX_PARAM_LEN - 2) - 4]; -} aci_att_read_by_group_type_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint16_t Offset; - uint8_t Part_Attribute_Value_Length; - uint8_t Part_Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 7]; -} aci_att_prepare_write_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_att_exec_write_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint8_t Attribute_Value_Length; - uint8_t Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 5]; -} aci_gatt_indication_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint8_t Attribute_Value_Length; - uint8_t Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 5]; -} aci_gatt_notification_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Error_Code; -} aci_gatt_proc_complete_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Req_Opcode; - uint16_t Attribute_Handle; - uint8_t Error_Code; -} aci_gatt_error_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint8_t Attribute_Value_Length; - uint8_t Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 5]; -} aci_gatt_disc_read_char_by_uuid_resp_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint8_t Data_Length; - uint8_t Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 5]; -} aci_gatt_write_permit_req_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint16_t Offset; -} aci_gatt_read_permit_req_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint8_t Number_of_Handles; - Handle_Item_t Handle_Item[((BLE_EVT_MAX_PARAM_LEN - 2) - 3)/sizeof(Handle_Item_t)]; -} aci_gatt_read_multi_permit_req_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Available_Buffers; -} aci_gatt_tx_pool_available_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; -} aci_gatt_server_confirmation_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint16_t Offset; - uint8_t Data_Length; - uint8_t Data[(BLE_EVT_MAX_PARAM_LEN - 2) - 7]; -} aci_gatt_prepare_write_permit_req_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Offset; - uint16_t Event_Data_Length; - uint8_t Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 6]; -} aci_gatt_read_ext_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint16_t Offset; - uint16_t Attribute_Value_Length; - uint8_t Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 8]; -} aci_gatt_indication_ext_event_rp0; - -typedef PACKED(struct) -{ - uint16_t Connection_Handle; - uint16_t Attribute_Handle; - uint16_t Offset; - uint16_t Attribute_Value_Length; - uint8_t Attribute_Value[(BLE_EVT_MAX_PARAM_LEN - 2) - 8]; -} aci_gatt_notification_ext_event_rp0; - - -#endif /* BLE_TYPES_H__ */ diff --git a/lib_blewbxx/core/ble_const.h b/lib_blewbxx/core/ble_const.h deleted file mode 100644 index 8396b41ce..000000000 --- a/lib_blewbxx/core/ble_const.h +++ /dev/null @@ -1,125 +0,0 @@ -/***************************************************************************** - * @file ble_const.h - * @author MCD - * @brief This file contains the definitions which are compiler dependent. - ***************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_CONST_H__ -#define BLE_CONST_H__ - - -#include -#include -#include "ble_std.h" -#include "ble_defs.h" -#include "osal.h" - - -/* Default BLE variant */ -#ifndef BASIC_FEATURES -#define BASIC_FEATURES 0 -#endif -#ifndef SLAVE_ONLY -#define SLAVE_ONLY 0 -#endif -#ifndef LL_ONLY -#define LL_ONLY 0 -#endif -#ifndef BEACON_ONLY -#define BEACON_ONLY 0 -#endif - - -/* Size of command/events buffers: - * - * To change the size of commands and events parameters used in the - * auto-generated files, you need to update 2 defines: - * - * - BLE_CMD_MAX_PARAM_LEN - * - BLE_EVT_MAX_PARAM_LEN - * - * These 2 defines are set below with default values and can be changed. - * - * To compute the value to support a characteristic of 512 bytes for a specific - * command or an event, you need to look in "ble_types.h". - * - * Here are 2 examples, one with a command and one with an event: - * - * - aci_gatt_update_char_value_ext_cp0 - * ---------------------------------- - * - * we have in the structure: - * - * uint8_t Value[(BLE_CMD_MAX_PARAM_LEN- 12)/sizeof(uint8_t)]; - * - * so to support a 512 byte value, we need to have - * - * BLE_CMD_MAX_PARAM_LEN at least equal to: 512 + 12 = 524 - * - * - aci_gatt_read_handle_value_rp0 - * ------------------------------ - * - * we have in the structure: - * - * uint8_t Value[((BLE_EVT_MAX_PARAM_LEN - 3) - 5)/sizeof(uint8_t)]; - * - * so to support a 512 byte value, we need to have - * - * BLE_EVT_MAX_PARAM_LEN at least equal to: 512 + 3 + 5 = 520 - * - * If you need several events or commands with 512-size values, you need to - * take the maximum values for BLE_EVT_MAX_PARAM_LEN and BLE_CMD_MAX_PARAM_LEN. - * - */ - -/* Maximum parameter size of BLE commands. - * Change this value if needed. */ -#define BLE_CMD_MAX_PARAM_LEN HCI_COMMAND_MAX_PARAM_LEN - -/* Maximum parameter size of BLE responses/events. - * Change this value if needed. */ -#define BLE_EVT_MAX_PARAM_LEN HCI_EVENT_MAX_PARAM_LEN - - -/* Callback function to send command and receive response */ -struct hci_request -{ - uint16_t ogf; - uint16_t ocf; - int event; - void* cparam; - int clen; - void* rparam; - int rlen; -}; -extern int hci_send_req( struct hci_request* req, uint8_t async ); - - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef MIN -#define MIN( a, b ) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef MAX -#define MAX( a, b ) (((a) > (b)) ? (a) : (b)) -#endif - - -#endif /* BLE_CONST_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***/ diff --git a/lib_blewbxx/core/ble_core.h b/lib_blewbxx/core/ble_core.h deleted file mode 100644 index 432b17b07..000000000 --- a/lib_blewbxx/core/ble_core.h +++ /dev/null @@ -1,44 +0,0 @@ -/***************************************************************************** - * @file ble_core.h - * @author MCD - * @brief This file contains the definitions for BLE stack - ***************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_CORE_H__ -#define BLE_CORE_H__ - - -/* BLE standard definitions */ -#include "ble_std.h" - -/* BLE stack API definitions */ -#include "ble_defs.h" -#include "auto/ble_gap_aci.h" -#include "auto/ble_gatt_aci.h" -#include "auto/ble_hal_aci.h" -#include "auto/ble_hci_le.h" -#include "auto/ble_l2cap_aci.h" -//#include "auto/ble_events.h" - -/* BLE stack buffer size definitions */ -#include "ble_bufsize.h" - -/* BLE stack legacy definitions */ -#include "ble_legacy.h" - - -#endif /* BLE_CORE_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***/ diff --git a/lib_blewbxx/core/ble_defs.h b/lib_blewbxx/core/ble_defs.h deleted file mode 100644 index 90d8233cb..000000000 --- a/lib_blewbxx/core/ble_defs.h +++ /dev/null @@ -1,716 +0,0 @@ -/***************************************************************************** - * @file ble_defs.h - * @author MCD - * @brief This file contains definitions used for BLE Stack interface. - ***************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_DEFS_H__ -#define BLE_DEFS_H__ - - -/* ------------------------------------------------------------------------- */ - -/* ACI GAP vendor specific event codes - */ - -/* ACI_GAP_LIMITED_DISCOVERABLE_EVENT code: */ -#define ACI_GAP_LIMITED_DISCOVERABLE_VSEVT_CODE 0x0400U - -/* ACI_GAP_PAIRING_COMPLETE_EVENT code: */ -#define ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE 0x0401U - -/* ACI_GAP_PASS_KEY_REQ_EVENT code: */ -#define ACI_GAP_PASS_KEY_REQ_VSEVT_CODE 0x0402U - -/* ACI_GAP_AUTHORIZATION_REQ_EVENT code: */ -#define ACI_GAP_AUTHORIZATION_REQ_VSEVT_CODE 0x0403U - -/* ACI_GAP_SLAVE_SECURITY_INITIATED_EVENT code: */ -#define ACI_GAP_SLAVE_SECURITY_INITIATED_VSEVT_CODE 0x0404U - -/* ACI_GAP_BOND_LOST_EVENT code: */ -#define ACI_GAP_BOND_LOST_VSEVT_CODE 0x0405U - -/* ACI_GAP_PROC_COMPLETE_EVENT code: */ -#define ACI_GAP_PROC_COMPLETE_VSEVT_CODE 0x0407U - -/* ACI_GAP_ADDR_NOT_RESOLVED_EVENT code: */ -#define ACI_GAP_ADDR_NOT_RESOLVED_VSEVT_CODE 0x0408U - -/* ACI_GAP_NUMERIC_COMPARISON_VALUE_EVENT code: */ -#define ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE 0x0409U - -/* ACI_GAP_KEYPRESS_NOTIFICATION_EVENT code: */ -#define ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE 0x040AU - -/* ACI GATT/ATT vendor specific event codes - */ - -/* ACI_GATT_ATTRIBUTE_MODIFIED_EVENT code: */ -#define ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE 0x0C01U - -/* ACI_GATT_PROC_TIMEOUT_EVENT code: */ -#define ACI_GATT_PROC_TIMEOUT_VSEVT_CODE 0x0C02U - -/* ACI_ATT_EXCHANGE_MTU_RESP_EVENT code: */ -#define ACI_ATT_EXCHANGE_MTU_RESP_VSEVT_CODE 0x0C03U - -/* ACI_ATT_FIND_INFO_RESP_EVENT code: */ -#define ACI_ATT_FIND_INFO_RESP_VSEVT_CODE 0x0C04U - -/* ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT code: */ -#define ACI_ATT_FIND_BY_TYPE_VALUE_RESP_VSEVT_CODE 0x0C05U - -/* ACI_ATT_READ_BY_TYPE_RESP_EVENT code: */ -#define ACI_ATT_READ_BY_TYPE_RESP_VSEVT_CODE 0x0C06U - -/* ACI_ATT_READ_RESP_EVENT code: */ -#define ACI_ATT_READ_RESP_VSEVT_CODE 0x0C07U - -/* ACI_ATT_READ_BLOB_RESP_EVENT code: */ -#define ACI_ATT_READ_BLOB_RESP_VSEVT_CODE 0x0C08U - -/* ACI_ATT_READ_MULTIPLE_RESP_EVENT code: */ -#define ACI_ATT_READ_MULTIPLE_RESP_VSEVT_CODE 0x0C09U - -/* ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT code: */ -#define ACI_ATT_READ_BY_GROUP_TYPE_RESP_VSEVT_CODE 0x0C0AU - -/* ACI_ATT_PREPARE_WRITE_RESP_EVENT code: */ -#define ACI_ATT_PREPARE_WRITE_RESP_VSEVT_CODE 0x0C0CU - -/* ACI_ATT_EXEC_WRITE_RESP_EVENT code: */ -#define ACI_ATT_EXEC_WRITE_RESP_VSEVT_CODE 0x0C0DU - -/* ACI_GATT_INDICATION_EVENT code: */ -#define ACI_GATT_INDICATION_VSEVT_CODE 0x0C0EU - -/* ACI_GATT_NOTIFICATION_EVENT code: */ -#define ACI_GATT_NOTIFICATION_VSEVT_CODE 0x0C0FU - -/* ACI_GATT_PROC_COMPLETE_EVENT code: */ -#define ACI_GATT_PROC_COMPLETE_VSEVT_CODE 0x0C10U - -/* ACI_GATT_ERROR_RESP_EVENT code: */ -#define ACI_GATT_ERROR_RESP_VSEVT_CODE 0x0C11U - -/* ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT code: */ -#define ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_VSEVT_CODE 0x0C12U - -/* ACI_GATT_WRITE_PERMIT_REQ_EVENT code: */ -#define ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE 0x0C13U - -/* ACI_GATT_READ_PERMIT_REQ_EVENT code: */ -#define ACI_GATT_READ_PERMIT_REQ_VSEVT_CODE 0x0C14U - -/* ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT code: */ -#define ACI_GATT_READ_MULTI_PERMIT_REQ_VSEVT_CODE 0x0C15U - -/* ACI_GATT_TX_POOL_AVAILABLE_EVENT code: */ -#define ACI_GATT_TX_POOL_AVAILABLE_VSEVT_CODE 0x0C16U - -/* ACI_GATT_SERVER_CONFIRMATION_EVENT code: */ -#define ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE 0x0C17U - -/* ACI_GATT_PREPARE_WRITE_PERMIT_REQ_EVENT code: */ -#define ACI_GATT_PREPARE_WRITE_PERMIT_REQ_VSEVT_CODE 0x0C18U - -/* ACI_GATT_READ_EXT_EVENT code: */ -#define ACI_GATT_READ_EXT_VSEVT_CODE 0x0C1DU - -/* ACI_GATT_INDICATION_EXT_EVENT code: */ -#define ACI_GATT_INDICATION_EXT_VSEVT_CODE 0x0C1EU - -/* ACI_GATT_NOTIFICATION_EXT_EVENT code: */ -#define ACI_GATT_NOTIFICATION_EXT_VSEVT_CODE 0x0C1FU - -/* ACI L2CAP vendor specific event codes - */ - -/* ACI_L2CAP_CONNECTION_UPDATE_RESP_EVENT code: */ -#define ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE 0x0800U - -/* ACI_L2CAP_PROC_TIMEOUT_EVENT code: */ -#define ACI_L2CAP_PROC_TIMEOUT_VSEVT_CODE 0x0801U - -/* ACI_L2CAP_CONNECTION_UPDATE_REQ_EVENT code: */ -#define ACI_L2CAP_CONNECTION_UPDATE_REQ_VSEVT_CODE 0x0802U - -/* ACI_L2CAP_COMMAND_REJECT_EVENT code: */ -#define ACI_L2CAP_COMMAND_REJECT_VSEVT_CODE 0x080AU - -/* ACI_L2CAP_COC_CONNECT_EVENT code: */ -#define ACI_L2CAP_COC_CONNECT_VSEVT_CODE 0x0810U - -/* ACI_L2CAP_COC_CONNECT_CONFIRM_EVENT code: */ -#define ACI_L2CAP_COC_CONNECT_CONFIRM_VSEVT_CODE 0x0811U - -/* ACI_L2CAP_COC_RECONF_EVENT code: */ -#define ACI_L2CAP_COC_RECONF_VSEVT_CODE 0x0812U - -/* ACI_L2CAP_COC_RECONF_CONFIRM_EVENT code: */ -#define ACI_L2CAP_COC_RECONF_CONFIRM_VSEVT_CODE 0x0813U - -/* ACI_L2CAP_COC_DISCONNECT_EVENT code: */ -#define ACI_L2CAP_COC_DISCONNECT_VSEVT_CODE 0x0814U - -/* ACI_L2CAP_COC_FLOW_CONTROL_EVENT code: */ -#define ACI_L2CAP_COC_FLOW_CONTROL_VSEVT_CODE 0x0815U - -/* ACI_L2CAP_COC_RX_DATA_EVENT code: */ -#define ACI_L2CAP_COC_RX_DATA_VSEVT_CODE 0x0816U - -/* ACI_L2CAP_COC_TX_POOL_AVAILABLE_EVENT code: */ -#define ACI_L2CAP_COC_TX_POOL_AVAILABLE_VSEVT_CODE 0x0817U - -/* ACI HAL vendor specific event codes - */ - -/* ACI_HAL_END_OF_RADIO_ACTIVITY_EVENT code: */ -#define ACI_HAL_END_OF_RADIO_ACTIVITY_VSEVT_CODE 0x0004U - -/* ACI_HAL_SCAN_REQ_REPORT_EVENT code: */ -#define ACI_HAL_SCAN_REQ_REPORT_VSEVT_CODE 0x0005U - -/* ACI_HAL_FW_ERROR_EVENT code: */ -#define ACI_HAL_FW_ERROR_VSEVT_CODE 0x0006U - -/* ------------------------------------------------------------------------- */ - -/* Status codes */ - -/* Returned when the command has completed with success - */ -#define BLE_STATUS_SUCCESS 0x00U - -/* The Connection Identifier does not exist at SMP level. - */ -#define BLE_STATUS_UNKNOWN_CONNECTION_ID 0x40U - -/* The Host failed while performing the requested operation. - */ -#define BLE_STATUS_FAILED 0x41U - -/* Invalid parameters in Host commands - */ -#define BLE_STATUS_INVALID_PARAMS 0x42U - -/* The Host is already processing another request received in advance. - */ -#define BLE_STATUS_BUSY 0x43U - -/* The operation requested cannot be completed immediately by the Host - * (usually because of lack of resources). - * The operation is generally put on hold by the caller and it's usually - * retried on later time. - */ -#define BLE_STATUS_PENDING 0x45U - -/* The requested operation cannot be performed by the Host in the current - * status. - */ -#define BLE_STATUS_NOT_ALLOWED 0x46U - -/* The requested operation violates the logic of the called layer/function or - * the format of the data to be processed during the operation. - */ -#define BLE_STATUS_ERROR 0x47U - -/* The requested operation failed because of lack of memory. - * Out of memory shall be returned for situations where memory will never - * become available again (e.g. ATT database) - */ -#define BLE_STATUS_OUT_OF_MEMORY 0x48U - -/* An invalid L2CAP CID/channel has been selected to send data over. - */ -#define BLE_STATUS_INVALID_CID 0x50U - -/* The remote device in in the Blacklist and the pairing operation it requested - * cannot be performed. - */ -#define BLE_STATUS_DEV_IN_BLACKLIST 0x59U - -/* CSRK not found during validation of an incoming signed packet - */ -#define BLE_STATUS_CSRK_NOT_FOUND 0x5AU - -/* IRK not found (Currently not used) - */ -#define BLE_STATUS_IRK_NOT_FOUND 0x5BU - -/* A search for a specific remote device was unsuccessful because no entry - * exists either into NVM Database or in volatile database. - */ -#define BLE_STATUS_DEV_NOT_FOUND 0x5CU - -/* The security database is full and no more records can be added. - */ -#define BLE_STATUS_SEC_DB_FULL 0x5DU - -/* The remote device is not bonded, and no operations related to bonded devices - * may be performed (e.g. writing Gatt Client data). - */ -#define BLE_STATUS_DEV_NOT_BONDED 0x5EU - -/* The encryption key size used for encrypting the link is insufficient\n - */ -#define BLE_STATUS_INSUFFICIENT_ENC_KEYSIZE 0x5FU - -/* The attribute handle is invalid. - */ -#define BLE_STATUS_INVALID_HANDLE 0x60U - -/* There aren't sufficient Attributes handles available for allocation during - * creation of Services, Characteristics or Descriptors. - */ -#define BLE_STATUS_OUT_OF_HANDLE 0x61U - -/* The requested GATT operation is not allowed in this context/status or using - * the provided parameters. - * This is a specific GATT error, different from generic Not Allowed error, - * because it refers to specific GATT specifications/rules. - */ -#define BLE_STATUS_INVALID_OPERATION 0x62U - -/* The characteristic has already been added to the database. - */ -#define BLE_STATUS_CHARAC_ALREADY_EXISTS 0x63U - -/* The requested operation failed for a temporary lack of resources - * (e.g. packet pool or timers), but it may be retried later when resources may - * become available (packets or timers may have been released by other - * consumers). - */ -#define BLE_STATUS_INSUFFICIENT_RESOURCES 0x64U - -/* Notification/Indication can't be sent to the requested remote device because - * it doesn't satisfy the needed security permission. - */ -#define BLE_STATUS_SEC_PERMISSION_ERROR 0x65U - -/* The address of the device could not be resolved using the IRK stored\n - */ -#define BLE_STATUS_ADDRESS_NOT_RESOLVED 0x70U - -/* Returned when no valid slots are available - * (e.g. when there are no available state machines). - */ -#define BLE_STATUS_NO_VALID_SLOT 0x82U - -/* The only slot available is not long enough to satisfy scan window request. - */ -#define BLE_STATUS_SCAN_WINDOW_SHORT 0x83U - -/* Returned when the maximum requested interval to be allocated is shorter - * then the current anchor period and there is no submultiple for the - * current anchor period that is between the minimum and the maximum requested - * intervals. - */ -#define BLE_STATUS_NEW_INTERVAL_FAILED 0x84U - -/* Returned when the maximum requested interval to be allocated is greater - * than the current anchor period and there is no multiple of the anchor - * period that is between the minimum and the maximum requested intervals. - */ -#define BLE_STATUS_INTERVAL_TOO_LARGE 0x85U - -/* Returned when the current anchor period or a new one can be found that - * is compatible to the interval range requested by the new slot but the - * maximum available length that can be allocated is less than the minimum - * requested slot length. - */ -#define BLE_STATUS_LENGTH_FAILED 0x86U - -/* Returned when a timeout occurs at BLE application interface - */ -#define BLE_STATUS_TIMEOUT 0xFFU - -/* ------------------------------------------------------------------------- */ - -/* Characteristic value lengths - */ -#define DEVICE_NAME_CHARACTERISTIC_LEN 8 -#define APPEARANCE_CHARACTERISTIC_LEN 2 -#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN 1 -#define RECONNECTION_ADDR_CHARACTERISTIC_LEN 6 -#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN 8 - -/* Adv. lengths - */ -#define MAX_ADV_DATA_LEN 31U -#define BD_ADDR_SIZE 6U - -/* AD types for adv. data and scan response data - */ -#define AD_TYPE_FLAGS 0x01U -#define AD_TYPE_16_BIT_SERV_UUID 0x02U -#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST 0x03U -#define AD_TYPE_32_BIT_SERV_UUID 0x04U -#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST 0x05U -#define AD_TYPE_128_BIT_SERV_UUID 0x06U -#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST 0x07U -#define AD_TYPE_SHORTENED_LOCAL_NAME 0x08U -#define AD_TYPE_COMPLETE_LOCAL_NAME 0x09U -#define AD_TYPE_TX_POWER_LEVEL 0x0AU -#define AD_TYPE_CLASS_OF_DEVICE 0x0DU -#define AD_TYPE_SEC_MGR_TK_VALUE 0x10U -#define AD_TYPE_SEC_MGR_OOB_FLAGS 0x11U -#define AD_TYPE_SLAVE_CONN_INTERVAL 0x12U -#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST 0x14U -#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST 0x15U -#define AD_TYPE_SERVICE_DATA 0x16U -#define AD_TYPE_APPEARANCE 0x19U -#define AD_TYPE_ADVERTISING_INTERVAL 0x1AU -#define AD_TYPE_LE_ROLE 0x1CU -#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST 0x1FU -#define AD_TYPE_URI 0x24U -#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFFU - -/* Flag bits for Flags AD Type - */ -#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE 0x01 -#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE 0x02 -#define FLAG_BIT_BR_EDR_NOT_SUPPORTED 0x04 -#define FLAG_BIT_LE_BR_EDR_CONTROLLER 0x08 -#define FLAG_BIT_LE_BR_EDR_HOST 0x10 - -/* Appearance values - */ -#define GAP_APPEARANCE_UNKNOWN 0x0000 -#define GAP_APPEARANCE_GENERIC_PHONE 0x0040 -#define GAP_APPEARANCE_GENERIC_COMPUTER 0x0080 -#define GAP_APPEARANCE_GENERIC_WATCH 0x00C0 -#define GAP_APPEARANCE_WATCH_SPORT_WATCH 0x00C1 -#define GAP_APPEARANCE_GENERIC_CLOCK 0x0100 -#define GAP_APPEARANCE_GENERIC_DISPLAY 0x0140 -#define GAP_APPEARANCE_GENERIC_REMOTE_CONTROL 0x0180 -#define GAP_APPEARANCE_GENERIC_EYE_GLASSES 0x01C0 -#define GAP_APPEARANCE_GENERIC_TAG 0x0200 -#define GAP_APPEARANCE_GENERIC_KEYRING 0x0240 -#define GAP_APPEARANCE_GENERIC_MEDIA_PLAYER 0x0280 -#define GAP_APPEARANCE_GENERIC_BARCODE_SCANNER 0x02C0 -#define GAP_APPEARANCE_GENERIC_THERMOMETER 0x0300 -#define GAP_APPEARANCE_THERMOMETER_EAR 0x0301 -#define GAP_APPEARANCE_GENERIC_HEART_RATE_SENSOR 0x0340 -#define GAP_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 0x0341 -#define GAP_APPEARANCE_GENERIC_BLOOD_PRESSURE 0x0380 -#define GAP_APPEARANCE_BLOOD_PRESSURE_ARM 0x0381 -#define GAP_APPEARANCE_BLOOD_PRESSURE_WRIST 0x0382 -#define GAP_APPEARANCE_HUMAN_INTERFACE_DEVICE 0x03C0 -#define GAP_APPEARANCE_KEYBOARD 0x03C1 -#define GAP_APPEARANCE_MOUSE 0x03C2 -#define GAP_APPEARANCE_JOYSTICK 0x03C3 -#define GAP_APPEARANCE_GAMEPAD 0x03C4 -#define GAP_APPEARANCE_DIGITIZER_TABLET 0x03C5 -#define GAP_APPEARANCE_CARD_READER 0x03C6 -#define GAP_APPEARANCE_DIGITAL_PEN 0x03C7 -#define GAP_APPEARANCE_BARCODE_SCANNER 0x03C8 -#define GAP_APPEARANCE_GENERIC_GLUCOSE_METER 0x0400 -#define GAP_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 0x0440 -#define GAP_APPEARANCE_RUNNING_WALKING_IN_SHOE 0x0441 -#define GAP_APPEARANCE_RUNNING_WALKING_ON_SHOE 0x0442 -#define GAP_APPEARANCE_RUNNING_WALKING_ON_HIP 0x0443 -#define GAP_APPEARANCE_GENERIC_CYCLING 0x0480 -#define GAP_APPEARANCE_CYCLING_CYCLING_COMPUTER 0x0481 -#define GAP_APPEARANCE_CYCLING_SPEED_SENSOR 0x0482 -#define GAP_APPEARANCE_CYCLING_CADENCE_SENSOR 0x0483 -#define GAP_APPEARANCE_CYCLING_POWER_SENSOR 0x0484 -#define GAP_APPEARANCE_CYCLING_SPEED_AND_CADENCE_SENSOR 0x0485 -#define GAP_APPEARANCE_GENERIC_PULSE_OXYMETER 0x0C40 -#define GAP_APPEARANCE_FINGERTIP 0x0C41 -#define GAP_APPEARANCE_WRIST_WORN 0x0C42 -#define GAP_APPEARANCE_GENERIC_WEIGHT_SCALE 0x0C80 -#define GAP_APPEARANCE_GENERIC_OUTDOOR_SPORT_ACTIVITY 0x1440 -#define GAP_APPEARANCE_LOCATION_DISPLAY_DEVICE 0x1441 -#define GAP_APPEARANCE_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE 0x1442 -#define GAP_APPEARANCE_LOCATION_POD 0x1443 -#define GAP_APPEARANCE_LOCATION_AND_NAVIGATION_POD 0x1444 -#define GAP_APPEARANCE_GENERIC_ENVIRONMENTAL_SENSOR 0x1640 - -/* Privacy flag values - */ -#define PRIVACY_ENABLED 0x02 -#define PRIVACY_DISABLED 0x00 - -/* Intervals in terms of 625 micro sec - */ -#define DIR_CONN_ADV_INT_MIN 0x190U /* 250 ms */ -#define DIR_CONN_ADV_INT_MAX 0x320U /* 500 ms */ -#define UNDIR_CONN_ADV_INT_MIN 0x800U /* 1.28 s */ -#define UNDIR_CONN_ADV_INT_MAX 0x1000U /* 2.56 s */ -#define LIM_DISC_ADV_INT_MIN 0x190U /* 250 ms */ -#define LIM_DISC_ADV_INT_MAX 0x320U /* 500 ms */ -#define GEN_DISC_ADV_INT_MIN 0x800U /* 1.28 s */ -#define GEN_DISC_ADV_INT_MAX 0x1000U /* 2.56 s */ - -/* GAP Roles - */ -#define GAP_PERIPHERAL_ROLE 0x01U -#define GAP_BROADCASTER_ROLE 0x02U -#define GAP_CENTRAL_ROLE 0x04U -#define GAP_OBSERVER_ROLE 0x08U - -/* GAP procedure codes - * Procedure codes for ACI_GAP_PROC_COMPLETE_EVENT event - * and ACI_GAP_TERMINATE_GAP_PROC command. - */ -#define GAP_LIMITED_DISCOVERY_PROC 0x01U -#define GAP_GENERAL_DISCOVERY_PROC 0x02U -#define GAP_NAME_DISCOVERY_PROC 0x04U -#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC 0x08U -#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC 0x10U -#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC 0x20U -#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC 0x40U -#define GAP_OBSERVATION_PROC 0x80U - -/* Advertising Types - */ -#define GAP_ADV_IND 0x00U -#define GAP_ADV_HIGH_DC_DIRECT_IND 0x01U -#define GAP_ADV_SCAN_IND 0x02U -#define GAP_ADV_NONCONN_IND 0x03U -#define GAP_ADV_LOW_DC_DIRECT_IND 0x04U - -/* ------------------------------------------------------------------------- */ - -/* IO capabilities - */ -#define IO_CAP_DISPLAY_ONLY 0x00U -#define IO_CAP_DISPLAY_YES_NO 0x01U -#define IO_CAP_KEYBOARD_ONLY 0x02U -#define IO_CAP_NO_INPUT_NO_OUTPUT 0x03U -#define IO_CAP_KEYBOARD_DISPLAY 0x04U - -/* Authentication requirements - */ -#define NO_BONDING 0x00U -#define BONDING 0x01U - -/* MITM protection requirements - */ -#define MITM_PROTECTION_NOT_REQUIRED 0x00U -#define MITM_PROTECTION_REQUIRED 0x01U - -/* Out-Of-Band data - */ -#define OOB_AUTH_DATA_ABSENT 0x00U -#define OOB_AUTH_DATA_PRESENT 0x01U - -/* Authorization requirements - */ -#define AUTHORIZATION_NOT_REQUIRED 0x00U -#define AUTHORIZATION_REQUIRED 0x01U - -/* Connection authorization - */ -#define CONNECTION_AUTHORIZED 0x01U -#define CONNECTION_REJECTED 0x02U - -/* Keypress notification support - */ -#define KEYPRESS_NOT_SUPPORTED 0x00U -#define KEYPRESS_SUPPORTED 0x01U - -/* Use fixed pin - */ -#define USE_FIXED_PIN_FOR_PAIRING_ALLOWED 0x00U -#define USE_FIXED_PIN_FOR_PAIRING_FORBIDDEN 0x01U - -/* SMP pairing status (ACI_GAP_PAIRING_COMPLETE_EVENT) - */ -#define SMP_PAIRING_STATUS_SUCCESS 0x00U -#define SMP_PAIRING_STATUS_SMP_TIMEOUT 0x01U -#define SMP_PAIRING_STATUS_PAIRING_FAILED 0x02U -#define SMP_PAIRING_STATUS_ENCRYPT_FAILED 0x03U - -/* SMP pairing failed reason code (ACI_GAP_PAIRING_COMPLETE_EVENT) - */ -#define OOB_NOT_AVAILABLE 0x02 -#define AUTH_REQ_CANNOT_BE_MET 0x03 -#define CONFIRM_VALUE_FAILED 0x04 -#define PAIRING_NOT_SUPPORTED 0x05 -#define INSUFF_ENCRYPTION_KEY_SIZE 0x06 -#define CMD_NOT_SUPPORTED 0x07 -#define UNSPECIFIED_REASON 0x08 -#define VERY_EARLY_NEXT_ATTEMPT 0x09 -#define SM_INVALID_PARAMS 0x0A -#define SMP_SC_DHKEY_CHECK_FAILED 0x0B -#define SMP_SC_NUMCOMPARISON_FAILED 0x0C - -/* Passkey input type detected (ACI_GAP_PASSKEY_INPUT) - */ -#define PASSKEY_ENTRY_STARTED 0x00U -#define PASSKEY_DIGIT_ENTERED 0x01U -#define PASSKEY_DIGIT_ERASED 0x02U -#define PASSKEY_CLEARED 0x03U -#define PASSKEY_ENTRY_COMPLETED 0x04U - -/* Numeric Comparison Confirm Value - * (ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO) - */ -#define NUMERIC_COMPARISON_CONFIRM_NO 0x00U -#define NUMERIC_COMPARISON_CONFIRM_YES 0x01U - -/* OOB Device Type (ACI_GAP_SET_OOB_DATA) - */ -#define OOB_DEVICE_TYPE_LOCAL 0x00U -#define OOB_DEVICE_TYPE_REMOTE 0x01U - -/* OOB Data Type (ACI_GAP_GET_OOB_DATA / ACI_GAP_SET_OOB_DATA) - */ -#define OOB_DATA_TYPE_LP_TK 0x00U -#define OOB_DATA_TYPE_SC_RANDOM 0x01U -#define OOB_DATA_TYPE_SC_CONFIRM 0x02U - -/* ------------------------------------------------------------------------- */ - -/* GATT UUIDs - */ -#define PRIMARY_SERVICE_UUID 0x2800U -#define SECONDARY_SERVICE_UUID 0x2801U -#define INCLUDE_SERVICE_UUID 0x2802U -#define CHARACTERISTIC_UUID 0x2803U -#define CHAR_EXTENDED_PROP_DESC_UUID 0x2900U -#define CHAR_USER_DESC_UUID 0x2901U -#define CHAR_CLIENT_CONFIG_DESC_UUID 0x2902U -#define CHAR_SERVER_CONFIG_DESC_UUID 0x2903U -#define CHAR_FORMAT_DESC_UUID 0x2904U -#define CHAR_AGGR_FMT_DESC_UUID 0x2905U -#define GATT_SERVICE_UUID 0x1801U -#define SERVICE_CHANGED_UUID 0x2A05U - -/* GAP UUIDs - */ -#define GAP_SERVICE_UUID 0x1800U -#define DEVICE_NAME_UUID 0x2A00U -#define APPEARANCE_UUID 0x2A01U -#define PERIPHERAL_PRIVACY_FLAG_UUID 0x2A02U -#define RECONNECTION_ADDR_UUID 0x2A03U -#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID 0x2A04U -#define CENTRAL_ADDRESS_RESOLUTION_UUID 0x2AA6U -#define RESOLVABLE_PRIVATE_ADDRESS_ONLY_UUID 0x2AC9U - -/* Access permissions for an attribute - */ -#define ATTR_NO_ACCESS 0x00U -#define ATTR_ACCESS_READ_ONLY 0x01U -#define ATTR_ACCESS_WRITE_REQ_ONLY 0x02U -#define ATTR_ACCESS_READ_WRITE 0x03U -#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE 0x04U -#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED 0x08U -#define ATTR_ACCESS_WRITE_ANY 0x0EU -#define ATTR_ACCESS_ANY 0x0FU - -/* Characteristic properties - */ -#define CHAR_PROP_NONE 0x00U -#define CHAR_PROP_BROADCAST 0x01U -#define CHAR_PROP_READ 0x02U -#define CHAR_PROP_WRITE_WITHOUT_RESP 0x04U -#define CHAR_PROP_WRITE 0x08U -#define CHAR_PROP_NOTIFY 0x10u -#define CHAR_PROP_INDICATE 0x20U -#define CHAR_PROP_SIGNED_WRITE 0x40U -#define CHAR_PROP_EXT 0x80U - -/* Security permissions for an attribute - */ -#define ATTR_PERMISSION_NONE 0x00U /* No security. */ -#define ATTR_PERMISSION_AUTHEN_READ 0x01U /* Need authentication to read */ -#define ATTR_PERMISSION_AUTHOR_READ 0x02U /* Need authorization to read */ -#define ATTR_PERMISSION_ENCRY_READ 0x04U /* Need encryption to read */ -#define ATTR_PERMISSION_AUTHEN_WRITE 0x08U /* Need authentication to write */ -#define ATTR_PERMISSION_AUTHOR_WRITE 0x10U /* Need authorization to write */ -#define ATTR_PERMISSION_ENCRY_WRITE 0x20U /* Need encryption to write */ - -/* Type of UUID (16 bit or 128 bit) - */ -#define UUID_TYPE_16 0x01U -#define UUID_TYPE_128 0x02U - -/* Type of service (primary or secondary) - */ -#define PRIMARY_SERVICE 0x01U -#define SECONDARY_SERVICE 0x02U - -/* Gatt Event Mask - * Type of event generated by GATT server - * See aci_gatt_add_char. - */ -#define GATT_DONT_NOTIFY_EVENTS 0x00 -#define GATT_NOTIFY_ATTRIBUTE_WRITE 0x01 -#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP 0x02 -#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP 0x04 - -/* Type of characteristic length (see ACI_GATT_ADD_CHAR) - */ -#define CHAR_VALUE_LEN_CONSTANT 0x00 -#define CHAR_VALUE_LEN_VARIABLE 0x01 - -/* Encryption key size - */ -#define MIN_ENCRY_KEY_SIZE 7U -#define MAX_ENCRY_KEY_SIZE 16U - -/* Format - */ -#define FORMAT_UINT8 0x04U -#define FORMAT_UINT16 0x06U -#define FORMAT_SINT16 0x0EU -#define FORMAT_SINT24 0x0FU - -/* Unit - */ -#define UNIT_UNITLESS 0x2700 -#define UNIT_TEMP_CELSIUS 0x272F -#define UNIT_PRESSURE_BAR 0x2780 - -/* ------------------------------------------------------------------------- */ - -/* Advertising policy for filtering (white list related) - * See HCI_LE_SET_ADVERTISING_PARAMETERS - */ -#define NO_WHITE_LIST_USE 0X00U -#define WHITE_LIST_FOR_ONLY_SCAN 0X01U -#define WHITE_LIST_FOR_ONLY_CONN 0X02U -#define WHITE_LIST_FOR_ALL 0X03U - -/* Advertising channels - */ -#define ADV_CH_37 0x01 -#define ADV_CH_38 0x02 -#define ADV_CH_39 0x04 - -/* ------------------------------------------------------------------------- */ - -/* Offset for configuration values (see ACI_HAL_WRITE_CONFIG_DATA) - */ -#define CONFIG_DATA_PUBADDR_OFFSET 0x00U -#define CONFIG_DATA_ER_OFFSET 0x08U -#define CONFIG_DATA_IR_OFFSET 0x18U -#define CONFIG_DATA_RANDOM_ADDRESS_OFFSET 0x2EU - -/* Length for configuration values (see ACI_HAL_WRITE_CONFIG_DATA) - */ -#define CONFIG_DATA_PUBADDR_LEN 6 -#define CONFIG_DATA_ER_LEN 16 -#define CONFIG_DATA_IR_LEN 16 -#define CONFIG_DATA_RANDOM_ADDRESS_LEN 6 - -/* ------------------------------------------------------------------------- */ - - -#endif /* BLE_DEFS_H__ */ diff --git a/lib_blewbxx/core/ble_legacy.h b/lib_blewbxx/core/ble_legacy.h deleted file mode 100644 index 29d272e41..000000000 --- a/lib_blewbxx/core/ble_legacy.h +++ /dev/null @@ -1,289 +0,0 @@ -/***************************************************************************** - * @file ble_legacy.h - * @author MCD - * @brief This file contains legacy definitions used for BLE. - ***************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_LEGACY_H__ -#define BLE_LEGACY_H__ - - -/* ------------------------------------------------------------------------- */ - - -/* - * The event code in the @ref hci_event_pckt structure. - * If event code is HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE, application can use @ref evt_blecore_aci - * structure to parse the packet. - */ - -#define EVT_VENDOR HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE /* 0xFF */ - -#define EVT_CONN_COMPLETE HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE /* 0x03 */ -#define EVT_DISCONN_COMPLETE HCI_DISCONNECTION_COMPLETE_EVT_CODE /* 0x05 */ -#define EVT_LE_META_EVENT HCI_LE_META_EVT_CODE /* 0x3E */ -#define EVT_LE_CONN_UPDATE_COMPLETE HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE /* 0x03 */ -#define EVT_LE_CONN_COMPLETE HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE /* 0x01 */ -#define EVT_LE_ADVERTISING_REPORT HCI_LE_ADVERTISING_REPORT_SUBEVT_CODE /* 0x02 */ -#define EVT_LE_PHY_UPDATE_COMPLETE HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE /* 0x0C */ -#define EVT_LE_ENHANCED_CONN_COMPLETE HCI_LE_ENHANCED_CONNECTION_COMPLETE_SUBEVT_CODE /* 0x0A */ - -typedef PACKED(struct) _hci_uart_pckt -{ - uint8_t type; - uint8_t data[1]; -} hci_uart_pckt; - -typedef PACKED(struct) _hci_event_pckt -{ - uint8_t evt; - uint8_t plen; - uint8_t data[1]; -} hci_event_pckt; - -typedef PACKED(struct) _evt_le_meta_event -{ - uint8_t subevent; - uint8_t data[1]; -} evt_le_meta_event; - -/** - * Vendor specific event for BLE core. - */ -typedef PACKED(struct) _evt_blecore_aci -{ - uint16_t ecode; /**< One of the BLE core event codes. */ - uint8_t data[1]; -} evt_blecore_aci; - -#define evt_blue_aci evt_blecore_aci - - -/* BLE core event codes */ -#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE /*(0x0C01)*/ -#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT ACI_GATT_PROC_TIMEOUT_VSEVT_CODE /*(0x0C02)*/ -#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP ACI_ATT_EXCHANGE_MTU_RESP_VSEVT_CODE /*(0x0C03)*/ -#define EVT_BLUE_ATT_FIND_INFORMATION_RESP ACI_ATT_FIND_INFO_RESP_VSEVT_CODE /*(0x0C04)*/ -#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP ACI_ATT_FIND_BY_TYPE_VALUE_RESP_VSEVT_CODE /*(0x0C05)*/ -#define EVT_BLUE_ATT_READ_BY_TYPE_RESP ACI_ATT_READ_BY_TYPE_RESP_VSEVT_CODE /*(0x0C06)*/ -#define EVT_BLUE_ATT_READ_RESP ACI_ATT_READ_RESP_VSEVT_CODE /*(0x0C07)*/ -#define EVT_BLUE_ATT_READ_BLOB_RESP ACI_ATT_READ_BLOB_RESP_VSEVT_CODE /*(0x0C08)*/ -#define EVT_BLUE_ATT_READ_MULTIPLE_RESP ACI_ATT_READ_MULTIPLE_RESP_VSEVT_CODE /*(0x0C09)*/ -#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP ACI_ATT_READ_BY_GROUP_TYPE_RESP_VSEVT_CODE /*(0x0C0A)*/ -#define EVT_BLUE_ATT_PREPARE_WRITE_RESP ACI_ATT_PREPARE_WRITE_RESP_VSEVT_CODE /*(0x0C0C)*/ -#define EVT_BLUE_ATT_EXEC_WRITE_RESP ACI_ATT_EXEC_WRITE_RESP_VSEVT_CODE /*(0x0C0D)*/ -#define EVT_BLUE_GATT_INDICATION ACI_GATT_INDICATION_VSEVT_CODE /*(0x0C0E)*/ -#define EVT_BLUE_GATT_NOTIFICATION ACI_GATT_NOTIFICATION_VSEVT_CODE /*(0x0C0F)*/ -#define EVT_BLUE_GATT_PROCEDURE_COMPLETE ACI_GATT_PROC_COMPLETE_VSEVT_CODE /*(0x0C10)*/ -#define EVT_BLUE_GATT_ERROR_RESP ACI_GATT_ERROR_RESP_VSEVT_CODE /*(0x0C11)*/ -#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_VSEVT_CODE /*(0x0C12)*/ -#define EVT_BLUE_GATT_WRITE_PERMIT_REQ ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE /*(0x0C13)*/ -#define EVT_BLUE_GATT_READ_PERMIT_REQ ACI_GATT_READ_PERMIT_REQ_VSEVT_CODE /*(0x0C14)*/ -#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ ACI_GATT_READ_MULTI_PERMIT_REQ_VSEVT_CODE /*(0x0C15)*/ -#define EVT_BLUE_GATT_TX_POOL_AVAILABLE ACI_GATT_TX_POOL_AVAILABLE_VSEVT_CODE /*(0x0C16)*/ -#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE /*(0x0C17)*/ -#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ ACI_GATT_PREPARE_WRITE_PERMIT_REQ_VSEVT_CODE /*(0x0C18)*/ - -#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE ACI_GAP_LIMITED_DISCOVERABLE_VSEVT_CODE /*(0x0400)*/ -#define EVT_BLUE_GAP_PAIRING_CMPLT ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE /*(0x0401)*/ -#define EVT_BLUE_GAP_PASS_KEY_REQUEST ACI_GAP_PASS_KEY_REQ_VSEVT_CODE /*(0x0402)*/ -#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST ACI_GAP_AUTHORIZATION_REQ_VSEVT_CODE /*(0x0403)*/ -#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED ACI_GAP_SLAVE_SECURITY_INITIATED_VSEVT_CODE /*(0X0404)*/ -#define EVT_BLUE_GAP_BOND_LOST ACI_GAP_BOND_LOST_VSEVT_CODE /*(0X0405)*/ - -#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) /*removed*/ - -#define EVT_BLUE_GAP_PROCEDURE_COMPLETE ACI_GAP_PROC_COMPLETE_VSEVT_CODE /*(0x0407)*/ -#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED ACI_GAP_ADDR_NOT_RESOLVED_VSEVT_CODE /*(0x0408)*/ -#define EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE /*(0x0409)*/ -#define EVT_BLUE_GAP_KEYPRESS_NOTIFICATION ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE /*(0x040A)*/ - -#define EVT_BLUE_L2CAP_CONNECTION_UPDATE_REQ ACI_L2CAP_CONNECTION_UPDATE_REQ_VSEVT_CODE /*(0x0802)*/ -#define EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE /*(0x0800)*/ - - -/* Macro to get RSSI from advertising report #0. - * "p" must be a pointer to the event parameters buffer - */ -#define HCI_LE_ADVERTISING_REPORT_RSSI_0(p) \ - (*(int8_t*)((&((hci_le_advertising_report_event_rp0*)(p))-> \ - Advertising_Report[0].Length_Data) + 1 + \ - ((hci_le_advertising_report_event_rp0*)(p))-> \ - Advertising_Report[0].Length_Data)) - - -/* ------------------------------------------------------------------------- */ - - -/* Bluetooth 48 bit address (in little-endian order). - */ -typedef uint8_t tBDAddr[6]; - - -/* ------------------------------------------------------------------------- */ - - -/* Error Codes as specified by the specification - */ -#define ERR_CMD_SUCCESS HCI_SUCCESS_ERR_CODE /*0x00*/ -#define ERR_UNKNOWN_HCI_COMMAND HCI_UNKNOWN_HCI_COMMAND_ERR_CODE /*0x01*/ -#define ERR_UNKNOWN_CONN_IDENTIFIER HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERR_CODE /*0x02*/ -#define ERR_AUTH_FAILURE HCI_AUTHENTICATION_FAILURE_ERR_CODE /*0x05*/ -#define ERR_PIN_OR_KEY_MISSING HCI_PIN_OR_KEY_MISSING_ERR_CODE /*0x06*/ -#define ERR_MEM_CAPACITY_EXCEEDED HCI_MEMORY_CAPACITY_EXCEEDED_ERR_CODE /*0x07*/ -#define ERR_CONNECTION_TIMEOUT HCI_CONNECTION_TIMEOUT_ERR_CODE /*0x08*/ -#define ERR_COMMAND_DISALLOWED HCI_COMMAND_DISALLOWED_ERR_CODE /*0x0C*/ -#define ERR_UNSUPPORTED_FEATURE HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERR_CODE /*0x11*/ -#define ERR_INVALID_HCI_CMD_PARAMS HCI_INVALID_HCI_COMMAND_PARAMETERS_ERR_CODE /*0x12*/ -#define ERR_RMT_USR_TERM_CONN HCI_REMOTE_USER_TERMINATED_CONNECTION_ERR_CODE /*0x13*/ -#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES 0x14 -#define ERR_RMT_DEV_TERM_CONN_POWER_OFF 0x15 -#define ERR_LOCAL_HOST_TERM_CONN HCI_CONNECTION_TERMINATED_BY_LOCAL_HOST_ERR_CODE /*0x16*/ -#define ERR_UNSUPP_RMT_FEATURE HCI_LMP_FEATURE_ERR_CODE /*0x1A*/ -#define ERR_INVALID_LMP_PARAM HCI_INVALID_LL_PARAMETERS_ERR_CODE /*0x1E*/ -#define ERR_UNSPECIFIED_ERROR HCI_UNSPECIFIED_ERROR_ERR_CODE /*0x1F*/ -#define ERR_LL_RESP_TIMEOUT HCI_LL_RESPONSE_TIMEOUT_ERR_CODE /*0x22*/ -#define ERR_LMP_PDU_NOT_ALLOWED HCI_LMP_PDU_NOT_ALLOWED_ERR_CODE /*0x24*/ -#define ERR_INSTANT_PASSED HCI_INSTANT_PASSED_ERR_CODE /*0x28*/ -#define ERR_PAIR_UNIT_KEY_NOT_SUPP 0x29 -#define ERR_CONTROLLER_BUSY HCI_DIFFERENT_TRANSACTION_COLLISION_ERR_CODE /*0x3A*/ -#define ERR_DIRECTED_ADV_TIMEOUT HCI_ADVERTISING_TIMEOUT_ERR_CODE /*0x3C*/ -#define ERR_CONN_END_WITH_MIC_FAILURE HCI_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE_ERR_CODE /*0x3D*/ -#define ERR_CONN_FAILED_TO_ESTABLISH HCI_CONNECTION_FAILED_TO_BE_ESTABLISHED_ERR_CODE /*0x3E*/ - -/* ------------------------------------------------------------------------- */ - - -/* Bluetooth address types - */ -#define PUBLIC_ADDR 0X00U -#define RANDOM_ADDR 0X01U -#define STATIC_RANDOM_ADDR 0X01U -#define RESOLVABLE_PRIVATE_ADDR 0X02U -#define NON_RESOLVABLE_PRIVATE_ADDR 0X03U - - -/* Scan_types Scan types - */ -#define PASSIVE_SCAN 0x00U -#define ACTIVE_SCAN 0x01U - - -/* ------------------------------------------------------------------------- */ - - -/* Various obsolete definitions - */ - -#define LIM_DISC_MODE_TIMEOUT 180000 /* 180 seconds */ -#define PRIVATE_ADDR_INT_TIMEOUT 900000 /* 15 minutes */ - -#define BLE_STATUS_SEC_UNKNOWN_CONNECTION_ID 0x40 -#define BLE_STATUS_INVALID_LEN_PDU 0x44 -#define FLASH_READ_FAILED 0x49 -#define FLASH_WRITE_FAILED 0x4A -#define FLASH_ERASE_FAILED 0x4B -#define TIMER_NOT_VALID_LAYER 0x54 -#define TIMER_INSUFFICIENT_RESOURCES 0x55 -#define BLE_STATUS_DEV_NOT_FOUND_IN_DB 0x5C -#define BLE_STATUS_INVALID_PARAMETER 0x61 -#define BLE_INSUFFICIENT_ENC_KEYSIZE 0x65 -#define BLE_STATUS_ADDR_NOT_RESOLVED 0x70 -#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED 0xF0 -#define BLE_STATUS_NULL_PARAM 0xF1 - -#define ATT_MTU 23 - -#define DEVICE_NAME_LEN 7 - -#define CONFIG_DATA_DIV_OFFSET 0x06 -#define CONFIG_DATA_DIV_LEN 2 - -#define USE_FIXED_PIN_FOR_PAIRING 0x00 -#define DONOT_USE_FIXED_PIN_FOR_PAIRING 0x01 - -#define SM_LINK_AUTHENTICATED 0x01 -#define SM_LINK_AUTHORIZED 0x02 -#define SM_LINK_ENCRYPTED 0x04 - -#define SM_PAIRING_SUCCESS SMP_PAIRING_STATUS_SUCCESS /*0x00*/ -#define SM_PAIRING_TIMEOUT SMP_PAIRING_STATUS_SMP_TIMEOUT /*0x01*/ -#define SM_PAIRING_FAILED SMP_PAIRING_STATUS_PAIRING_FAILED /*0x02*/ - -#define PASSKEY_ENTRY_FAILED 0x01 - -#define ADV_IND GAP_ADV_IND /*0*/ -#define ADV_DIRECT_IND 1 -#define ADV_SCAN_IND GAP_ADV_SCAN_IND /*2*/ -#define ADV_NONCONN_IND GAP_ADV_NONCONN_IND /*3*/ -#define SCAN_RSP 4 -#define HIGH_DUTY_CYCLE_DIRECTED_ADV GAP_ADV_HIGH_DC_DIRECT_IND /*1*/ -#define LOW_DUTY_CYCLE_DIRECTED_ADV GAP_ADV_LOW_DC_DIRECT_IND /*4*/ - -#define ADV_INTERVAL_LOWEST_CONN 0X0020 -#define ADV_INTERVAL_HIGHEST 0X4000 -#define ADV_INTERVAL_LOWEST_NONCONN 0X00A0 - - -/* ------------------------------------------------------------------------- */ - - -/* - * BLE_DEFAULT_MAX_ATT_MTU: maximum supported ATT MTU size. - */ -#define BLE_DEFAULT_MAX_ATT_MTU 158 - -/* - * BLE_DEFAULT_MBLOCKS_COUNT: default memory blocks count - */ -#define BLE_DEFAULT_MBLOCKS_COUNT(n_link) \ - BLE_MBLOCKS_CALC(BLE_DEFAULT_PREP_WRITE_LIST_SIZE, \ - BLE_DEFAULT_MAX_ATT_MTU, n_link) - - -#define TOTAL_DEVICE_ID_DATA_SIZE 56 - - -/* ------------------------------------------------------------------------- */ - - -/* Deprecative name for LE Read Remote Features command - */ -#define hci_le_read_remote_used_features hci_le_read_remote_features -#define hci_le_read_remote_used_features_complete_event_rp0 \ - hci_le_read_remote_features_complete_event_rp0 - - -/* ------------------------------------------------------------------------- */ - - -/* Byte order conversions -*/ -#define htob( d, n ) (d) /* LE */ -#define btoh( d, n ) (d) /* LE */ - - -/* Events table - */ -#define HCI_LE_META_EVENT_TABLE_SIZE HCI_LE_EVENT_TABLE_SIZE -#define HCI_VENDOR_SPECIFIC_EVENT_TABLE_SIZE HCI_VS_EVENT_TABLE_SIZE -#define hci_le_meta_event_table hci_le_event_table -#define hci_vendor_specific_event_table hci_vs_event_table - - -/* ------------------------------------------------------------------------- */ - - -#endif /* BLE_LEGACY_H__ */ diff --git a/lib_blewbxx/core/ble_std.h b/lib_blewbxx/core/ble_std.h deleted file mode 100644 index 1b5feb433..000000000 --- a/lib_blewbxx/core/ble_std.h +++ /dev/null @@ -1,165 +0,0 @@ -/****************************************************************************** - * @file ble_std.h - * @author MCD - * @brief BLE standard definitions - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef BLE_STD_H__ -#define BLE_STD_H__ - - -/* HCI packet type */ -#define HCI_COMMAND_PKT_TYPE 0x01 -#define HCI_ACLDATA_PKT_TYPE 0x02 -#define HCI_EVENT_PKT_TYPE 0x04 - -/* HCI packet header size */ -#define HCI_COMMAND_HDR_SIZE 4 -#define HCI_ACLDATA_HDR_SIZE 5 -#define HCI_EVENT_HDR_SIZE 3 - -/* HCI parameters length */ -#define HCI_COMMAND_MAX_PARAM_LEN (255+18) -#define HCI_ACLDATA_MAX_DATA_LEN 251 /* HC_LE_Data_Packet_Length */ -#define HCI_EVENT_MAX_PARAM_LEN 255 - -/* HCI packet maximum size */ -#define HCI_COMMAND_PKT_MAX_SIZE \ - (HCI_COMMAND_HDR_SIZE + HCI_COMMAND_MAX_PARAM_LEN) -#define HCI_ACLDATA_PKT_MAX_SIZE \ - (HCI_ACLDATA_HDR_SIZE + HCI_ACLDATA_MAX_DATA_LEN) -#define HCI_EVENT_PKT_MAX_SIZE \ - (HCI_EVENT_HDR_SIZE + HCI_EVENT_MAX_PARAM_LEN) - -/* HCI Event codes */ - -/* HCI_DISCONNECTION_COMPLETE_EVENT code: */ -#define HCI_DISCONNECTION_COMPLETE_EVT_CODE 0x05 - -/* HCI_ENCRYPTION_CHANGE_EVENT code: */ -#define HCI_ENCRYPTION_CHANGE_EVT_CODE 0x08 - -/* HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE EVENT code: */ -#define HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVT_CODE 0x0C - -/* HCI_COMMAND_COMPLETE_EVENT code: */ - #define HCI_COMMAND_COMPLETE_EVT_CODE 0x0E - -/* HCI_COMMAND_STATUS_EVENT code: */ - #define HCI_COMMAND_STATUS_EVT_CODE 0x0F - -/* HCI_HARDWARE_ERROR_EVENT code: */ - #define HCI_HARDWARE_ERROR_EVT_CODE 0x10 - -/* HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT code: */ - #define HCI_NUMBER_OF_COMPLETED_PACKETS_EVT_CODE 0x13 - -/* HCI_DATA_BUFFER_OVERFLOW_EVENT code: */ - #define HCI_DATA_BUFFER_OVERFLOW_EVT_CODE 0x1A - -/* HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT code: */ -#define HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVT_CODE 0x30 - -/* */ -#define HCI_LE_META_EVT_CODE 0x3E - -/* */ -#define HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE 0xFF - -/* HCI LE SubEvent codes */ - - /* HCI_LE_CONNECTION_COMPLETE_EVENT code: */ - #define HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE 0x01 - - /* HCI_LE_ADVERTISING_REPORT_EVENT code: */ - #define HCI_LE_ADVERTISING_REPORT_SUBEVT_CODE 0x02 - - /* HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT code: */ - #define HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE 0x03 - - /* HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT code: */ - #define HCI_LE_READ_REMOTE_FEATURES_COMPLETE_SUBEVT_CODE 0x04 - - /* HCI_LE_LONG_TERM_KEY_REQUEST_EVENT code: */ - #define HCI_LE_LONG_TERM_KEY_REQUEST_SUBEVT_CODE 0x05 - - /* HCI_LE_DATA_LENGTH_CHANGE_EVENT code: */ - #define HCI_LE_DATA_LENGTH_CHANGE_SUBEVT_CODE 0x07 - - /* HCI_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE_EVENT code: */ - #define HCI_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE_SUBEVT_CODE 0x08 - - /* HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT code: */ - #define HCI_LE_GENERATE_DHKEY_COMPLETE_SUBEVT_CODE 0x09 - - /* HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT code: */ - #define HCI_LE_ENHANCED_CONNECTION_COMPLETE_SUBEVT_CODE 0x0A - - /* HCI_LE_DIRECT_ADVERTISING_REPORT_EVENT code: */ - #define HCI_LE_DIRECT_ADVERTISING_REPORT_SUBEVT_CODE 0x0B - - /* HCI_LE_PHY_UPDATE_COMPLETE_EVENT code: */ - #define HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE 0x0C - -/* HCI error code */ -#define HCI_SUCCESS_ERR_CODE 0x00 -#define HCI_UNKNOWN_HCI_COMMAND_ERR_CODE 0x01 -#define HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERR_CODE 0x02 -#define HCI_AUTHENTICATION_FAILURE_ERR_CODE 0x05 -#define HCI_PIN_OR_KEY_MISSING_ERR_CODE 0x06 -#define HCI_MEMORY_CAPACITY_EXCEEDED_ERR_CODE 0x07 -#define HCI_CONNECTION_TIMEOUT_ERR_CODE 0x08 -#define HCI_COMMAND_DISALLOWED_ERR_CODE 0x0C -#define HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERR_CODE 0x11 -#define HCI_INVALID_HCI_COMMAND_PARAMETERS_ERR_CODE 0x12 -#define HCI_REMOTE_USER_TERMINATED_CONNECTION_ERR_CODE 0x13 -#define HCI_CONNECTION_TERMINATED_BY_LOCAL_HOST_ERR_CODE 0x16 -#define HCI_LMP_FEATURE_ERR_CODE 0x1A -#define HCI_INVALID_LL_PARAMETERS_ERR_CODE 0x1E -#define HCI_UNSPECIFIED_ERROR_ERR_CODE 0x1F -#define HCI_LL_RESPONSE_TIMEOUT_ERR_CODE 0x22 -#define HCI_LL_PROCEDURE_COLLISION_ERR_CODE 0x23 -#define HCI_LMP_PDU_NOT_ALLOWED_ERR_CODE 0x24 -#define HCI_INSTANT_PASSED_ERR_CODE 0x28 -#define HCI_DIFFERENT_TRANSACTION_COLLISION_ERR_CODE 0x2A -#define HCI_PARAMETER_OUT_OF_MANDATORY_RANGE_ERR_CODE 0x30 -#define HCI_HOST_BUSY_PAIRING_ERR_CODE 0x38 -#define HCI_CONTROLLER_BUSY_ERR_CODE 0x3A -#define HCI_ADVERTISING_TIMEOUT_ERR_CODE 0x3C -#define HCI_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE_ERR_CODE 0x3D -#define HCI_CONNECTION_FAILED_TO_BE_ESTABLISHED_ERR_CODE 0x3E - -/* HCI_LE_Read_PHY */ -#define HCI_TX_PHY_LE_1M 0x01 -#define HCI_TX_PHY_LE_2M 0x02 -#define HCI_TX_PHY_LE_CODED 0x03 -#define HCI_RX_PHY_LE_1M 0x01 -#define HCI_RX_PHY_LE_2M 0x02 -#define HCI_RX_PHY_LE_CODED 0x03 - -/* HCI_LE_Set_PHY */ -#define HCI_ALL_PHYS_TX_NO_PREF 0x01 -#define HCI_ALL_PHYS_RX_NO_PREF 0x02 -#define HCI_TX_PHYS_LE_1M_PREF 0x01 -#define HCI_TX_PHYS_LE_2M_PREF 0x02 -#define HCI_TX_PHYS_LE_CODED_PREF 0x04 -#define HCI_RX_PHYS_LE_1M_PREF 0x01 -#define HCI_RX_PHYS_LE_2M_PREF 0x02 -#define HCI_RX_PHYS_LE_CODED_PREF 0x04 - - -#endif /* BLE_STD_H__ */ - -/*********************** (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_blewbxx/core/doc/STM32WB_BLE_Wireless_Interface.html b/lib_blewbxx/core/doc/STM32WB_BLE_Wireless_Interface.html deleted file mode 100644 index d88efa0af..000000000 --- a/lib_blewbxx/core/doc/STM32WB_BLE_Wireless_Interface.html +++ /dev/null @@ -1,6889 +0,0 @@ -

STM32WB BLE Wireless Interface

This document describes the STM32WB BLE Application Commands Interface (ACI) and Host Commands Interface (HCI).

STM32WB Series website

Revision history

December 2018 - Rev 1.0 - First release for interface 1.0

February 2019 - Rev 1.1 - Modified HCI_HARDWARE_ERROR_EVENT comment

March 2019 - Rev 1.2 - Removed unused event documentation

March 2019 - Rev 1.3 - Modification ACI_HAL_FW_ERROR_EVENT error code

March 2019 - Rev 1.4 - Changed default mask of HCI_SET_EVENT_MASK

May 2019 - Rev 1.5 - ACI_GATT_NOTIFICATION_EXT_EVENT added

June 2019 - Rev 1.6 - Changed comment on usage of Char Handles in multiple ACI_GATT commands; Added ACI_GATT_INDICATION_EXT_EVENT

June 2019 - Rev 1.7 - Changed descriptions of ACI_ATT_READ_BY_TYPE_REQ and ACI_GATT_READ_USING_CHAR_UUID

July 2019 - Rev 1.8 - Reworked error codes section; Added GAP_ prefix to the GAP procedure bitmap definitions

September 2019 - Rev 1.9 - Added ACI_GATT_READ_EXT_EVENT; Modified ACI_GAP_CONFIGURE_WHITELIST comment

October 2019 - Rev 1.10 - Changed descriptions of ACI_GATT_WRITE_WITHOUT_RESP and ACI_GATT_SIGNED_WRITE_WITHOUT_RESP; Removed obsolete configuration data elements

November 2019 - Rev 1.11 - Completed description of ACI_GAP_INIT; Added specific pairing status definitions

November 2019 - Rev 1.12 - Fixed status error codes

January 2020 - Rev 1.13 - Removed DIV unused configuration data; Fixed naming of HCI_LE_READ_REMOTE_FEATURES command and complete event

March 2020 - Rev 1.14 - Removed unused HCI_Data_Buffer_Overflow event; Fixed naming of FW_Error_Type possible values; Fixed pairing status possible values

March 2020 - Rev 1.15 - Added GAP scan timeout value

April 2020 - Rev 1.16 - Fixed various format issues; Added LO and PO columns for command and event tables.

May 2020 - Rev 1.17 - Updated PO stack features; Added comment in HCI_LE_ADVERTISING_REPORT_EVENT description.

June 2020 - Rev 1.18 - Added BO column for command and event tables; Fixed advertising commands description; Fixed various format issues.

June 2020 - Rev 1.19 - Completed interval possible values for ACI_GAP_SET_DIRECT_CONNECTABLE.

July 2020 - Rev 1.20 - Added HCI_LE_SET_PRIVACY_MODE.

July 2020 - Rev 1.21 - Updated "beacon only" stack features.

September 2020 - Rev 1.22 - Fixed various minor issues.

November 2020 - Rev 1.23 - Added connection-oriented channels feature; Added HCI_LE_READ_TRANSMIT_POWER; Updated PO variant.

December 2020 - Rev 1.24 - Added BF column for command and event tables.

January 2021 - Rev 1.25 - Added Link_Status possible values.

Contents

HCI/ACI commands

HCI/ACI events

Status error codes

HCI/ACI commands

HCI commands

HCI TESTING commands

ACI HAL commands

ACI GAP commands

ACI GATT/ATT commands

ACI L2CAP commands

Note: in the command tables, a "Y" in the "BF", "PO", "LO" or "BO" column, means that the corresponding command applies to the "Basic Features", "Peripheral Only", "Link Layer Only" or "Beacon Only" variant of the BLE stack, respectively.

HCI commands

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CommandOpcodeBFPOLOBO
HCI_DISCONNECT

0x0406

-

Y

-
HCI_READ_REMOTE_VERSION_INFORMATION

0x041D

-

Y

-

Y

-

Y

-
HCI_SET_EVENT_MASK

0x0C01

-

Y

-

Y

-

Y

-

Y

-
HCI_RESET

0x0C03

-

Y

-

Y

-

Y

-

Y

-
HCI_READ_TRANSMIT_POWER_LEVEL

0x0C2D

-

Y

-

Y

-

Y

-
HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL

0x0C31

-

Y

-
HCI_HOST_BUFFER_SIZE

0x0C33

-

Y

-
HCI_HOST_NUMBER_OF_COMPLETED_PACKETS

0x0C35

-

Y

-
HCI_READ_LOCAL_VERSION_INFORMATION

0x1001

-

Y

-

Y

-

Y

-

Y

-
HCI_READ_LOCAL_SUPPORTED_COMMANDS

0x1002

-

Y

-

Y

-
HCI_READ_LOCAL_SUPPORTED_FEATURES

0x1003

-

Y

-

Y

-
HCI_READ_BD_ADDR

0x1009

-

Y

-

Y

-

Y

-

Y

-
HCI_READ_RSSI

0x1405

-

Y

-

Y

-

Y

-

Y

-
HCI_LE_SET_EVENT_MASK

0x2001

-

Y

-

Y

-

Y

-

Y

-
HCI_LE_READ_BUFFER_SIZE

0x2002

-

Y

-

Y

-
HCI_LE_READ_LOCAL_SUPPORTED_FEATURES

0x2003

-

Y

-

Y

-
HCI_LE_SET_RANDOM_ADDRESS

0x2005

-

Y

-

Y

-
HCI_LE_SET_ADVERTISING_PARAMETERS

0x2006

-

Y

-

Y

-
HCI_LE_READ_ADVERTISING_CHANNEL_TX_POWER

0x2007

-

Y

-

Y

-
HCI_LE_SET_ADVERTISING_DATA

0x2008

-

Y

-

Y

-
HCI_LE_SET_SCAN_RESPONSE_DATA

0x2009

-

Y

-

Y

-

Y

-

Y

-
HCI_LE_SET_ADVERTISE_ENABLE

0x200A

-

Y

-

Y

-
HCI_LE_SET_SCAN_PARAMETERS

0x200B

-

Y

-

Y

-
HCI_LE_SET_SCAN_ENABLE

0x200C

-

Y

-

Y

-
HCI_LE_CREATE_CONNECTION

0x200D

-

Y

-
HCI_LE_CREATE_CONNECTION_CANCEL

0x200E

-

Y

-
HCI_LE_READ_WHITE_LIST_SIZE

0x200F

-

Y

-

Y

-
HCI_LE_CLEAR_WHITE_LIST

0x2010

-

Y

-

Y

-
HCI_LE_ADD_DEVICE_TO_WHITE_LIST

0x2011

-

Y

-

Y

-
HCI_LE_REMOVE_DEVICE_FROM_WHITE_LIST

0x2012

-

Y

-

Y

-
HCI_LE_CONNECTION_UPDATE

0x2013

-

Y

-
HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION

0x2014

-

Y

-
HCI_LE_READ_CHANNEL_MAP

0x2015

-

Y

-

Y

-

Y

-
HCI_LE_READ_REMOTE_FEATURES

0x2016

-

Y

-

Y

-

Y

-
HCI_LE_ENCRYPT

0x2017

-

Y

-
HCI_LE_RAND

0x2018

-

Y

-

Y

-

Y

-

Y

-
HCI_LE_START_ENCRYPTION

0x2019

-

Y

-
HCI_LE_LONG_TERM_KEY_REQUEST_REPLY

0x201A

-

Y

-
HCI_LE_LONG_TERM_KEY_REQUESTED_NEGATIVE_REPLY

0x201B

-

Y

-
HCI_LE_READ_SUPPORTED_STATES

0x201C

-

Y

-

Y

-
HCI_LE_SET_DATA_LENGTH

0x2022

-

Y

-

Y

-

Y

-
HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH

0x2023

-

Y

-

Y

-

Y

-
HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH

0x2024

-

Y

-

Y

-

Y

-
HCI_LE_READ_LOCAL_P256_PUBLIC_KEY

0x2025

-

Y

-

Y

-

Y

-
HCI_LE_GENERATE_DHKEY

0x2026

-

Y

-
HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST

0x2027

-

Y

-
HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST

0x2028

-

Y

-
HCI_LE_CLEAR_RESOLVING_LIST

0x2029

-

Y

-
HCI_LE_READ_RESOLVING_LIST_SIZE

0x202A

-

Y

-
HCI_LE_READ_PEER_RESOLVABLE_ADDRESS

0x202B

-

Y

-
HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS

0x202C

-

Y

-
HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE

0x202D

-

Y

-
HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT

0x202E

-

Y

-
HCI_LE_READ_MAXIMUM_DATA_LENGTH

0x202F

-

Y

-

Y

-

Y

-
HCI_LE_READ_PHY

0x2030

-

Y

-
HCI_LE_SET_DEFAULT_PHY

0x2031

-

Y

-
HCI_LE_SET_PHY

0x2032

-

Y

-
HCI_LE_READ_TRANSMIT_POWER

0x204B

-

Y

-

Y

-
HCI_LE_SET_PRIVACY_MODE

0x204E

-

Y

-

HCI_DISCONNECT

Description

The HCI_DISCONNECT is used to terminate an existing connection. The Connection_Handle command parameter indicates which connection is to be disconnected. The Reason command parameter indicates the reason for ending the connection. The remote Controller will receive the Reason command parameter in the HCI_DISCONNECTION_COMPLETE_EVENT event. All synchronous connections on a physical link should be disconnected before the ACL connection on the same physical connection is disconnected.
(See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.1.6)

Input parameters

- - - -
ParameterSizeDescriptionPossible values

Connection_Handle

-

2

-

Connection handle for which the command applies.

-
  • 0x0000 ... 0x0EFF
  • Reason

    -

    1

    -

    The reason for ending the connection.

    -
  • 0x05: Authentication Failure
  • 0x13: Remote User Terminated Connection
  • 0x14: Remote Device Terminated Connection due to Low Resources
  • 0x15: Remote Device Terminated Connection due to Power Off
  • 0x1A: Unsupported Remote Feature
  • 0x3B: Unacceptable Connection Parameters
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_DISCONNECTION_COMPLETE_EVENT
  • HCI_READ_REMOTE_VERSION_INFORMATION

    Description

    This command will obtain the values for the version information for the remote device identified by the Connection_Handle parameter. The Connection_Handle must be a Connection_Handle for an ACL or LE connection.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.1.23)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT
  • HCI_SET_EVENT_MASK

    Description

    The Set_Event_Mask command is used to control which events are generated by the HCI for the Host. If the bit in the Event_Mask is set to a one, then the event associated with that bit will be enabled. For an LE Controller, the LE Meta Event bit in the Event_Mask shall enable or disable all LE events in the LE Meta Event (see Section 7.7.65). The Host has to deal with each event that occurs. The event mask allows the Host to control how much it is interrupted.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.3.1)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Event_Mask

    -

    8

    -

    Event mask. Default: 0x20001FFFFFFFFFFF

    -

    Bitmask of:

  • 0x0000000000000000: No events specified
  • 0x0000000000000010: Disconnection Complete Event
  • 0x0000000000000080: Encryption Change Event
  • 0x0000000000000800: Read Remote Version Information Complete Event
  • 0x0000000000008000: Hardware Error Event
  • 0x0000800000000000: Encryption Key Refresh Complete Event
  • 0x2000000000000000: LE Meta-Event
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_RESET

    Description

    The Reset command resets the Link Layer on an LE Controller. The Reset command shall not affect the used HCI transport layer since the HCI transport layers may have reset mechanisms of their own. After the reset is completed, the current operational state is lost, the Controller enters standby mode and the Controller automatically reverts to the default values for the parameters for which default values are defined in the specification.
    Note: The Reset command does not necessarily perform a hardware reset. This is implementation defined.
    The Host shall not send additional HCI commands before the Command Complete event related to the Reset command has been received.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.3.2)

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_READ_TRANSMIT_POWER_LEVEL

    Description

    This command reads the values for the Transmit_Power_Level parameter for the specified Connection_Handle. The Connection_Handle shall be a Connection_Handle for an ACL connection.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.3.35)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Type

    -

    1

    -

    Current or maximum transmit power level.

    -
  • 0x00: Read Current Transmit Power Level.
  • 0x01: Read Maximum Transmit Power Level.
  • Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Transmit_Power_Level

    -

    1

    -

    Size: 1 Octet (signed integer) -Units: dBm

    -
  • -30 ... 20
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL

    Description

    This command is used by the Host to turn flow control on or off for data and/or voice sent in the direction from the Controller to the Host. If flow control is turned off, the Host should not send the Host_Number_Of_Completed_Packets command. That command will be ignored by the Controller if it is sent by the Host and flow control is off. If flow control is turned on for HCI ACL Data Packets and off for HCI synchronous Data Packets, Host_Number_Of_Completed_Packets commands sent by the Host should only contain Connection_Handles for ACL connections. If flow control is turned off for HCI ACL Data Packets and on for HCI synchronous Data Packets, Host_Number_Of_Completed_Packets commands sent by the Host should only contain Connection_Handles for synchronous connections. If flow control is turned on for HCI ACL Data Packets and HCI synchronous Data Packets, the Host will send Host_Number_Of_Completed_Packets commands both for ACL connections and synchronous connections.
    The Flow_Control_Enable parameter shall only be changed if no connections exist.
    (See Bluetooth Spec v.5.0, Vol. 2, Part E, 7.3.38)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Flow_Control_Enable

    -

    1

    -

    Enable/Disable the Flow Control

    -
  • 0x00: Flow control off in direction from Controller to Host. Default.
  • 0x01: Flow control on for HCI ACL Data Packets and off for HCI synchronous.Data Packets in direction from Controller to Host.
  • 0x02: Flow control off for HCI ACL Data Packets and on for HCI synchronous.Data Packets in direction from Controller to Host.
  • 0x03: Flow control on both for HCI ACL Data Packets and HCI synchronous.Data Packets in direction from Controller to Host.
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_HOST_BUFFER_SIZE

    Description

    The Host_Buffer_Size command is used by the Host to notify the Controller about the maximum size of the data portion of HCI ACL and synchronous Data Packets sent from the Controller to the Host. The Controller shall segment the data to be transmitted from the Controller to the Host according to these sizes, so that the HCI Data Packets will contain data with up to these sizes. The Host_Buffer_Size command also notifies the Controller about the total number of HCI ACL and synchronous Data Packets that can be stored in the data buffers of the Host. If flow control from the Controller to the Host is turned off, and the Host_Buffer_Size command has not been issued by the Host, this means that the Controller will send HCI Data Packets to the Host with any lengths the Controller wants to use, and it is assumed that the data buffer sizes of the Host are unlimited. If flow control from the Controller to the Host is turned on, the Host_Buffer_Size command shall after a power-on or a reset always be sent by the Host before the first Host_Number_Of_Completed_Packets command is sent.
    The Set Controller To Host Flow Control Command is used to turn flow control on or off.
    The Host_ACL_Data_Packet_Length command parameter will be used to determine the size of the L2CAP segments contained in ACL Data Packets, which are transferred from the Controller to the Host.
    The Host_Synchronous_Data_Packet_Length command parameter is used to determine the maximum size of HCI synchronous Data Packets. Both the Host and the Controller shall support command and event packets, where the data portion (excluding header) contained in the packets is 255 octets in size.
    The Host_Total_Num_ACL_Data_Packets command parameter contains the total number of HCI ACL Data Packets that can be stored in the data buffers of the Host. The Controller will determine how the buffers are to be divided between different Connection_Handles.
    The Host_Total_Num_Synchronous_Data_Packets command parameter gives the same information for HCI synchronous Data Packets.
    Note: The Host_ACL_Data_Packet_Length and Host_Synchronous_Data_Packet_Length command parameters do not include the length of the HCI Data Packet header.
    (See Bluetooth Spec v.5.0, Vol. 2, Part E, 7.3.39)

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Host_ACL_Data_Packet_Length

    -

    2

    -

    Maximum length (in octets) of the data portion of each HCI ACL Data Packet that the Host is able to accept. Must be greater or equal to 251 bytes

    -

    Host_Synchronous_Data_Packet_Length

    -

    1

    -

    Maximum length (in octets) of the data portion of each HCI synchronous Data Packet that the Host is able to accept.

    -

    Host_Total_Num_ACL_Data_Packets

    -

    2

    -

    Total number of HCI ACL Data Packets that can be stored in the data buffers of the Host.

    -

    Host_Total_Num_Synchronous_Data_Packets

    -

    2

    -

    Total number of HCI synchronous Data Packets that can be stored in the data buffers of the Host.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_HOST_NUMBER_OF_COMPLETED_PACKETS

    Description

    The Host_Number_Of_Completed_Packets command is used by the Host to indicate to the Controller the number of HCI Data Packets that have been completed for each Connection_Handle since the previous Host_Number_Of_Completed_Packets command was sent to the Controller. This means that the corresponding buffer space has been freed in the Host. Based on this information, and the Host_Total_Num_ACL_Data_Packets and Host_Total_Num_Synchronous_Data_Packets command parameters of the Host_Buffer_Size command, the Controller can determine for which Connection_Handles the following HCI Data Packets should be sent to the Host. The command should only be issued by the Host if flow control in the direction from the Controller to the Host is on and there is at least one connection, or if the Controller is in local loopback mode. Otherwise, the command will be ignored by the Controller. When the Host has completed one or more HCI Data Packet(s) it shall send a Host_Number_Of_Completed_Packets command to the Controller, until it finally reports that all pending HCI Data Packets have been completed. The frequency at which this command is sent is manufacturer specific.
    The Set Controller To Host Flow Control Command is used to turn flow control on or off. If flow control from the Controller to the Host is turned on, the Host_Buffer_Size command shall always be sent by the Host after a power-on or a reset before the first Host_Number_Of_Completed_Packets command is sent.
    Note: The Host_Number_Of_Completed_Packets command is a special command in the sense that no event is normally generated after the command has completed. The command may be sent at any time by the Host when there is at least one connection, or if the Controller is in local loopback mode independent of other commands. The normal flow control for commands is not used for the Host_Number_Of_Completed_Packets command.
    (See Bluetooth Spec v.5.0, Vol. 2, Part E, 7.3.40)

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Number_Of_Handles

    -

    1

    -

    The number of Connection_Handles and Host_Num_Of_Completed_Packets parameters pairs contained in this command.

    -

    0-255

    -

    Connection_Handle[i]

    -

    Number_Of_Handles * 2

    -

    Connection_Handle

    -

    0x0000-0x0EFF

    -

    Host_Num_Of_Completed_Packets[i]

    -

    Number_Of_Handles * 2

    -

    The number of HCI Data Packets that have been completed for the associated Connection_Handle since the previous time the event was returned.

    -

    0x0000-0xFFFF

    -

    Output parameters

    None

    Events generated

    Normally, no event is generated after the Host_Number_Of_Completed_Packets command has completed. However, if the Host_Number_Of_Completed_Packets command contains one or more invalid parameters, the Controller shall return a Command Complete event with a failure status indicating the Invalid HCI Command Parameters error code. The Host may send the Host_Number_Of_Completed_Packets command at any time when there is at least one connection, or if the Controller is in local loopback mode. The normal flow control for commands is not used for this command.

    HCI_READ_LOCAL_VERSION_INFORMATION

    Description

    This command reads the values for the version information for the local Controller. The HCI Version information defines the version information of the HCI layer. The LMP/PAL Version information defines the version of the LMP or PAL. The Manufacturer_Name information indicates the manufacturer of the local device. The HCI Revision and LMP/PAL Subversion are implementation dependent.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.4.1)

    Input parameters

    None

    Output parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    HCI_Version

    -

    1

    -

    See Bluetooth Assigned Numbers (https://www.bluetooth.org/en-us/specification/assigned-numbers)

    -

    HCI_Revision

    -

    2

    -

    Revision of the Current HCI in the BR/EDR Controller.

    -

    LMP_PAL_Version

    -

    1

    -

    Version of the Current LMP or PAL in the Controller. -See Bluetooth Assigned Numbers (https://www.bluetooth.org/en-us/specification/assigned-numbers)

    -

    Manufacturer_Name

    -

    2

    -

    Manufacturer Name of the BR/EDR Controller. -See Bluetooth Assigned Numbers (https://www.bluetooth.org/en-us/specification/assigned-numbers)

    -

    LMP_PAL_Subversion

    -

    2

    -

    Subversion of the Current LMP or PAL in the Controller. This value is -implementation dependent.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_READ_LOCAL_SUPPORTED_COMMANDS

    Description

    This command reads the list of HCI commands supported for the local Controller. This command shall return the Supported_Commands configuration parameter. It is implied that if a command is listed as supported, the feature underlying that command is also supported.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.4.2)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Supported_Commands

    -

    64

    -

    Bit mask for each HCI Command. If a bit is 1, the Controller supports the corresponding command and the features required for the command. -Unsupported or undefined commands shall be set to 0.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_READ_LOCAL_SUPPORTED_FEATURES

    Description

    This command requests a list of the supported features for the local Controller. This command will return a list of the LMP features. For details see Part C, Link Manager Protocol Specification on page 227.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.4.3)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    LMP_Features

    -

    8

    -

    Bit Mask List of LMP features.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_READ_BD_ADDR

    Description

    On an LE Controller, this command shall read the Public Device Address as defined in [Vol 6] Part B, Section 1.3, Device Address. If this Controller does not have a Public Device Address, the value 0x000000000000 shall be returned.
    On an LE Controller, the public address shall be the same as the BD_ADDR.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.4.6)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    BD_ADDR

    -

    6

    -

    BD_ADDR ( Bluetooth Device Address) of the Device.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_READ_RSSI

    Description

    This command reads the Received Signal Strength Indication (RSSI) value from a Controller. For an LE transport, a Connection_Handle is used as the Handle command parameter and return parameter. The meaning of the RSSI metric is an absolute receiver signal strength value in dBm to +/- 6 dB accuracy. If the RSSI cannot be read, the RSSI metric shall be set to 127.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.5.4)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • RSSI

    -

    1

    -

    N Size: 1 Octet (signed integer) -Units: dBm

    -
  • 127: RSSI not available
  • -127 ... 20
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_EVENT_MASK

    Description

    The LE_Set_Event_Mask command is used to control which LE events are generated by the HCI for the Host. If the bit in the LE_Event_Mask is set to a one, then the event associated with that bit will be enabled. The Host has to deal with each event that is generated by an LE Controller. The event mask allows the Host to control which events will interrupt it.
    For LE events to be generated, the LE Meta-Event bit in the Event_Mask shall also be set. If that bit is not set, then LE events shall not be generated, regardless of how the LE_Event_Mask is set.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.1)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    LE_Event_Mask

    -

    8

    -

    LE event mask. Default: 0x00000000000FFFFF.

    -

    Bitmask of:

  • 0x0000000000000000: No LE events specified
  • 0x0000000000000001: LE Connection Complete Event
  • 0x0000000000000002: LE Advertising Report Event
  • 0x0000000000000004: LE Connection Update Complete Event
  • 0x0000000000000008: LE Read Remote Used Features Complete Event
  • 0x0000000000000010: LE Long Term Key Request Event
  • 0x0000000000000020: LE Remote Connection Parameter Request Event
  • 0x0000000000000040: LE Data Length Change Event
  • 0x0000000000000080: LE Read Local P-256 Public Key Complete Event
  • 0x0000000000000100: LE Generate DHKey Complete Event
  • 0x0000000000000200: LE Enhanced Connection Complete Event
  • 0x0000000000000400: LE Direct Advertising Report Event
  • 0x0000000000000800: LE PHY Update Complete Event
  • 0x0000000000001000: LE Extended Advertising Report Event
  • 0x0000000000002000: LE Periodic Advertising Sync Established Event
  • 0x0000000000004000: LE Periodic Advertising Report Event
  • 0x0000000000008000: LE Periodic Advertising Sync Lost Event
  • 0x0000000000010000: LE Extended Scan Timeouout Event
  • 0x0000000000020000: LE Extended Advertising Set Terminated Event
  • 0x0000000000040000: LE Scan Request Received Event
  • 0x0000000000080000: LE Channel Selection Algorithm Event
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_BUFFER_SIZE

    Description

    The LE_Read_Buffer_Size command is used to read the maximum size of the data portion of HCI LE ACL Data Packets sent from the Host to the Controller.
    The Host will segment the data transmitted to the Controller according to these values, so that the HCI Data Packets will contain data with up to this size. The LE_Read_Buffer_Size command also returns the total number of HCI LE ACL Data Packets that can be stored in the data buffers of the Controller. The LE_Read_Buffer_Size command must be issued by the Host before it sends any data to an LE Controller (see Section 4.1.1).
    If the Controller returns a length value of zero, the Host shall use the Read_Buffer_Size command to determine the size of the data buffers.
    Note: Both the Read_Buffer_Size and LE_Read_Buffer_Size commands may return buffer length and number of packets parameter values that are nonzero.
    The HC_LE_ACL_Data_Packet_Length return parameter shall be used to determine the size of the L2CAP PDU segments contained in ACL Data Packets, which are transferred from the Host to the Controller to be broken up into packets by the Link Layer. Both the Host and the Controller shall support command and event packets, where the data portion (excluding header) contained in the packets is 255 octets in size. The HC_Total_Num_LE_ACL_Data_Packets return parameter contains the total number of HCI ACL Data Packets that can be stored in the data buffers of the Controller. The Host determines how the buffers are to be divided between different Connection Handles.
    Note: The HC_LE_ACL_Data_Packet_Length return parameter does not include the length of the HCI Data Packet header.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.2)

    Input parameters

    None

    Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    HC_LE_ACL_Data_Packet_Length

    -

    2

    -

    0x0000 No dedicated LE Buffer - use Read_Buffer_Size command. -0x0001 - 0xFFFF Maximum length (in octets) of the data portion of each HCI ACL Data Packet that the Controller is able to accept.

    -

    HC_Total_Num_LE_ACL_Data_Packets

    -

    1

    -

    0x00 No dedicated LE Buffer - use Read_Buffer_Size command. -0x01 - 0xFF Total number of HCI ACL Data Packets that can be stored in the data buffers of the Controller.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_LOCAL_SUPPORTED_FEATURES

    Description

    This command requests the list of the supported LE features for the Controller.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.3)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    LE_Features

    -

    8

    -

    Bit Mask List of LE features. See Core v5.0, Vol. 6, Part B, Section 4.6.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_RANDOM_ADDRESS

    Description

    The LE_Set_Random_Address command is used by the Host to set the LE Random Device Address in the Controller (see [Vol 6] Part B, Section 1.3).
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.4)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Random_Address

    -

    6

    -

    Random Device Address.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_ADVERTISING_PARAMETERS

    Description

    The LE_Set_Advertising_Parameters command is used by the Host to set the advertising parameters.
    The Advertising_Interval_Min shall be less than or equal to the Advertising_Interval_Max.
    The Advertising_Interval_Min and Advertising_Interval_Max should not be the same value to enable the Controller to determine the best advertising interval given other activities.
    For high duty cycle directed advertising, i.e. when Advertising_Type is 0x01 (ADV_DIRECT_IND, high duty cycle), the Advertising_Interval_Min and Advertising_Interval_Max parameters are not used and shall be ignored.
    The Advertising_Type is used to determine the packet type that is used for advertising when advertising is enabled.
    The Advertising_Interval_Min and Advertising_Interval_Max shall not be set to less than 0x00A0 (100 ms) if the Advertising_Type is set to 0x02 (ADV_SCAN_IND) or 0x03 (ADV_NONCONN_IND). The Own_Address_Type determines if the advertising packets are identified with the Public Device Address of the device, or a Random Device Address as written by the LE_Set_Random_Address command.
    If directed advertising is performed, i.e. when Advertising_Type is set to 0x01 (ADV_DIRECT_IND, high duty cycle) or 0x04 (ADV_DIRECT_IND, low duty cycle mode), then the Direct_Address_Type and Direct_Address shall be valid, otherwise they shall be ignored by the Controller and not used.
    The Advertising_Channel_Map is a bit field that indicates the advertising channels that shall be used when transmitting advertising packets. At least one channel bit shall be set in the Advertising_Channel_Map parameter.
    The Advertising_Filter_Policy parameter shall be ignored when directed advertising is enabled.
    The Host shall not issue this command when advertising is enabled in the Controller; if it is the Command Disallowed error code shall be used.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.5)

    Input parameters

    - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Advertising_Interval_Min

    -

    2

    -

    Minimum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Advertising_Interval_Max

    -

    2

    -

    Maximum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Advertising_Type

    -

    1

    -

    Advertising type

    -
  • 0x00: ADV_IND (Connectable undirected advertising)
  • 0x01: ADV_DIRECT_IND, high duty cycle (Connectable high duty cycle directed advertising)
  • 0x02: ADV_SCAN_IND (Scannable undirected advertising)
  • 0x03: ADV_NONCONN_IND (Non connectable undirected advertising)
  • 0x04: ADV_DIRECT_IND_LDC, low duty cycle (Connectable low duty cycle directed advertising)
  • Own_Address_Type

    -

    1

    -
    -
    Own address type.
    -
      -
    • 0x00: Public Device Address
    • -
    • 0x01 Random Device Address
    • -
    • 0x02: Controller generates Resolvable Private Address based on the local IRK from resolving list. If resolving list contains no matching entry, use public address.
    • -
    • 0x03: Controller generates Resolvable Private Address based on the local IRK from resolving list. If resolving list contains no matching entry, use random address from LE_Set_Random_Address.
    • -
    -
    -
    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • 0x02: Resolvable Private Address or Public Address
  • 0x03: Resolvable Private Address or Random Address
  • Peer_Address_Type

    -

    1

    -

    The address type of the peer device.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Peer_Address

    -

    6

    -

    Public Device Address, Random Device Address, Public Identity Address or Random (static) Identity Address of the device to be connected.

    -

    Advertising_Channel_Map

    -

    1

    -

    Advertising channel map. -Default: 00000111b (all channels enabled).

    -

    Bitmask of:

  • 0x01: ch 37
  • 0x02: ch 38
  • 0x04: ch 39
  • Advertising_Filter_Policy

    -

    1

    -

    Advertising filter policy.

    -
  • 0x00: Allow Scan Request from Any, Allow Connect Request from Any
  • 0x01: Allow Scan Request from White List Only, Allow Connect Request from Any
  • 0x02: Allow Scan Request from Any, Allow Connect Request from White List Only
  • 0x03: Allow Scan Request from White List Only, Allow Connect Request from White List Only
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_ADVERTISING_CHANNEL_TX_POWER

    Description

    The LE_Read_Advertising_Channel_Tx_Power command is used by the Host to read the transmit power level used for LE advertising channel packets.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.6)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Transmit_Power_Level

    -

    1

    -

    Size: 1 Octet (signed integer) -Units: dBm -Accuracy: +/- 4 dBm

    -
  • -20 ... 10
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_ADVERTISING_DATA

    Description

    The LE_Set_Advertising_Data command is used to set the data used in advertising packets that have a data field.
    Only the significant part of the Advertising_Data is transmitted in the advertising packets, as defined in [Vol 3] Part C, Section 11.,
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.7)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Advertising_Data_Length

    -

    1

    -

    The number of significant octets in the following data field

    -

    Advertising_Data

    -

    31

    -

    31 octets of data formatted as defined in [Vol 3] Part C, Section 11.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_SCAN_RESPONSE_DATA

    Description

    This command is used to provide data used in Scanning Packets that have a data field.
    Only the significant part of the Scan_Response_Data is transmitted in the Scanning Packets, as defined in [Vol 3] Part C, Section 11.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.8)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Scan_Response_Data_Length

    -

    1

    -

    The number of significant octets in the following data field

    -

    Scan_Response_Data

    -

    31

    -

    31 octets of data formatted as defined in [Vol 3] Part C, Section 11.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_ADVERTISE_ENABLE

    Description

    The LE_Set_Advertise_Enable command is used to request the Controller to start or stop advertising. The Controller manages the timing of advertisements as per the advertising parameters given in the LE_Set_Advertising_Parameters command.
    The Controller shall continue advertising until the Host issues an LE_Set_Advertise_Enable command with Advertising_Enable set to 0x00 (Advertising is disabled) or until a connection is created or until the Advertising is timed out due to high duty cycle Directed Advertising. In these cases, advertising is then disabled.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.9)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Advertising_Enable

    -

    1

    -

    Enable/disable advertise. Default is 0 (disabled).

    -
  • 0x00: Advertising is disabled
  • 0x01: Advertising is enabled
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_CONNECTION_COMPLETE_EVENT
  • HCI_LE_SET_SCAN_PARAMETERS

    Description

    The LE_Set_Scan_Parameters command is used to set the scan parameters.
    The LE_Scan_Type parameter controls the type of scan to perform.
    The LE_Scan_Interval and LE_Scan_Window parameters are recommendations from the Host on how long (LE_Scan_Window) and how frequently (LE_Scan_Interval) the Controller should scan (See [Vol 6] Part B, Section 4.4.3). The LE_Scan_Window parameter shall always be set to a value smaller or equal to the value set for the LE_Scan_Interval parameter. If they are set to the same value scanning should be run continuously.
    The Own_Address_Type parameter determines the address used (Public or Random Device Address) when performing active scan.
    The Host shall not issue this command when scanning is enabled in the Controller; if it is the Command Disallowed error code shall be used.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.10)

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Type

    -

    1

    -

    Passive or active scanning. With active scanning SCAN_REQ packets are sent.

    -
  • 0x00: Passive Scanning
  • 0x01: Active scanning
  • LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -
    -
    Own address type.
    -
      -
    • 0x00: Public Device Address
    • -
    • 0x01 Random Device Address
    • -
    • 0x02: Controller generates Resolvable Private Address based on the local IRK from resolving list. If resolving list contains no matching entry, use public address.
    • -
    • 0x03: Controller generates Resolvable Private Address based on the local IRK from resolving list. If resolving list contains no matching entry, use random address from LE_Set_Random_Address.
    • -
    -
    -
    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • 0x02: Resolvable Private Address or Public Address
  • 0x03: Resolvable Private Address or Random Address
  • Scanning_Filter_Policy

    -

    1

    -

    0x00 Accept all advertisement packets. Directed advertising packets which are not addressed for this device shall be ignored. -0x01 Ignore advertisement packets from devices not in the White List Only. Directed advertising packets which are not addressed for this device shall be ignored -0x02 Accept all undirected advertisement packets. Directed advertisement packets where initiator address is a RPA and Directed advertisement packets addressed to this device shall be accepted. -0x03 Accept all undirected advertisement packets from devices that are in the White List.Directed advertisement packets where initiator address is RPA and Directed advertisement packets addressed to this device shall be accepted.

    -
  • 0x00: Accept all
  • 0x01: Ignore devices not in the White List
  • 0x02: Accept all (use resolving list)
  • 0x03: Ignore devices not in the White List (use resolving list)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_SCAN_ENABLE

    Description

    The LE_Set_Scan_Enable command is used to start scanning. Scanning is used to discover advertising devices nearby.
    The Filter_Duplicates parameter controls whether the Link Layer shall filter duplicate advertising reports to the Host, or if the Link Layer should generate advertising reports for each packet received.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.11)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Enable

    -

    1

    -

    Enable/disable scan. Default is 0 (disabled).

    -
  • 0x00: Scanning disabled
  • 0x01: Scanning enabled
  • Filter_Duplicates

    -

    1

    -

    Enable/disable duplicate filtering.

    -
  • 0x00: Duplicate filtering disabled
  • 0x01: Duplicate filtering enabled
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_ADVERTISING_REPORT_EVENT
  • HCI_LE_CREATE_CONNECTION

    Description

    The LE_Create_Connection command is used to create a Link Layer connection to a connectable advertiser.
    The LE_Scan_Interval and LE_Scan_Window parameters are recommendations from the Host on how long (LE_Scan_Window) and how frequently (LE_Scan_Interval) the Controller should scan. The LE_Scan_Window parameter shall be set to a value smaller or equal to the value set for the LE_Scan_Interval parameter. If both are set to the same value, scanning should run continuously.
    The Initiator_Filter_Policy is used to determine whether the White List is used.
    If the White List is not used, the Peer_Address_Type and the Peer_Address parameters specify the address type and address of the advertising device to connect to.
    The Link Layer shall set the address in the CONNECT_REQ packets to either the Public Device Address or the Random Device Addressed based on the Own_Address_Type parameter.
    The Conn_Interval_Min and Conn_Interval_Max parameters define the minimum and maximum allowed connection interval. The Conn_Interval_Min parameter shall not be greater than the Conn_Interval_Max parameter.
    The Conn_Latency parameter defines the maximum allowed connection latency (see [Vol 6] Part B, Section 4.5.1).
    The Supervision_Timeout parameter defines the link supervision timeout for the connection. The Supervision_Timeout in milliseconds shall be larger than (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. (See [Vol 6] Part B, Section 4.5.2).
    The Minimum_CE_Length and Maximum_CE_Length parameters are informative parameters providing the Controller with the expected minimum and maximum length of the connection events. The Minimum_CE_Length parameter shall be less than or equal to the Maximum_CE_Length parameter.
    The Host shall not issue this command when another LE_Create_Connection is pending in the Controller; if this does occur the Controller shall return the Command Disallowed error code shall be used.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.12)

    Input parameters

    - - - - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Initiator_Filter_Policy

    -

    1

    -

    0x00 White list is not used to determine which advertiser to connect to. -Peer_Address_Type and Peer_Address shall be used. -0x01 White list is used to determine which advertiser to connect to. -Peer_Address_Type and Peer_Address shall be ignored.

    -
  • 0x00: White list not used
  • 0x01: White list used
  • Peer_Address_Type

    -

    1

    -

    Address type -0x00 Public Device Address -0x01 Random Device Address -0x02 Public Identity Address (Corresponds to Resolved Private Address) -0x03 Random (Static) Identity Address (Corresponds to Resolved Private Address)

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • 0x02: Public Identity Address
  • 0x03: Random (Static) Identity Address
  • Peer_Address

    -

    6

    -

    Public Device Address or Random Device Address of the device to be connected.

    -

    Own_Address_Type

    -

    1

    -
    -
    Own address type.
    -
      -
    • 0x00: Public Device Address
    • -
    • 0x01 Random Device Address
    • -
    • 0x02: Controller generates Resolvable Private Address based on the local IRK from resolving list. If resolving list contains no matching entry, use public address.
    • -
    • 0x03: Controller generates Resolvable Private Address based on the local IRK from resolving list. If resolving list contains no matching entry, use random address from LE_Set_Random_Address.
    • -
    -
    -
    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • 0x02: Resolvable Private Address or Public Address
  • 0x03: Resolvable Private Address or Random Address
  • Conn_Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • Minimum_CE_Length

    -

    2

    -

    Information parameter about the minimum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Maximum_CE_Length

    -

    2

    -

    Information parameter about the maximum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_CONNECTION_COMPLETE_EVENT
  • HCI_LE_CREATE_CONNECTION_CANCEL

    Description

    The LE_Create_Connection_Cancel command is used to cancel the LE_Create_Connection command. This command shall only be issued after the LE_Create_Connection command has been issued, a Command Status event has been received for the LE Create Connection command and before the LE Connection Complete event.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.13)

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_CONNECTION_COMPLETE_EVENT
  • HCI_LE_READ_WHITE_LIST_SIZE

    Description

    The LE_Read_White_List_Size command is used to read the total number of white list entries that can be stored in the Controller.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.14)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    White_List_Size

    -

    1

    -

    Total number of white list entries that can be stored in the Controller.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_CLEAR_WHITE_LIST

    Description

    The LE_Clear_White_List command is used to clear the white list stored in the Controller.
    This command can be used at any time except when:
    - the advertising filter policy uses the white list and advertising is enabled.
    - the scanning filter policy uses the white list and scanning is enabled.
    - the initiator filter policy uses the white list and an LE_Create_Connection command is outstanding.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.15)

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_ADD_DEVICE_TO_WHITE_LIST

    Description

    The LE_Add_Device_To_White_List command is used to add a single device to the white list stored in the Controller.
    This command can be used at any time except when:
    - the advertising filter policy uses the white list and advertising is enabled.
    - the scanning filter policy uses the white list and scanning is enabled.
    - the initiator filter policy uses the white list and a create connection command is outstanding.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.16)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Address_Type

    -

    1

    -

    Address type.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Address

    -

    6

    -

    Public Device Address or Random Device Address.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_REMOVE_DEVICE_FROM_WHITE_LIST

    Description

    The LE_Remove_Device_From_White_List command is used to remove a single device from the white list stored in the Controller.
    This command can be used at any time except when:
    - the advertising filter policy uses the white list and advertising is enabled.
    - the scanning filter policy uses the white list and scanning is enabled.
    - the initiator filter policy uses the white list and a create connection command is outstanding.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.17)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Address_Type

    -

    1

    -

    Address type.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Address

    -

    6

    -

    Public Device Address or Random Device Address.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_CONNECTION_UPDATE

    Description

    The LE_Connection_Update command is used to change the Link Layer connection parameters of a connection. This command is supported only on master side.
    The Conn_Interval_Min and Conn_Interval_Max parameters are used to define the minimum and maximum allowed connection interval. The Conn_Interval_Min parameter shall not be greater than the Conn_Interval_Max parameter.
    The Conn_Latency parameter shall define the maximum allowed connection latency.
    The Supervision_Timeout parameter shall define the link supervision timeout for the LE link. The Supervision_Timeout in milliseconds shall be larger than (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds.
    The Minimum_CE_Length and Maximum_CE_Length are information parameters providing the Controller with a hint about the expected minimum and maximum length of the connection events. The Minimum_CE_Length shall be less than or equal to the Maximum_CE_Length.
    The actual parameter values selected by the Link Layer may be different from the parameter values provided by the Host through this command.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.18)

    Input parameters

    - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Conn_Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • Minimum_CE_Length

    -

    2

    -

    Information parameter about the minimum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Maximum_CE_Length

    -

    2

    -

    Information parameter about the maximum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT
  • HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION

    Description

    The LE_Set_Host_Channel_Classification command allows the Host to specify a channel classification for data channels based on its "local information". This classification persists until overwritten with a subsequent LE_Set_Host_Channel_Classification command or until the Controller is reset using the Reset command (see [Vol 6] Part B, Section 4.5.8.1).
    If this command is used, the Host should send it within 10 seconds of knowing that the channel classification has changed. The interval between two successive commands sent shall be at least one second.
    This command shall only be used when the local device supports the Master role.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.19)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    LE_Channel_Map

    -

    5

    -

    This parameter contains 37 1-bit fields. -The nth such field (in the range 0 to 36) contains the value for the link layer channel index n. -Channel n is bad = 0. -Channel n is unknown = 1. -The most significant bits are reserved and shall be set to 0. -At least one channel shall be marked as unknown.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_CHANNEL_MAP

    Description

    The LE_Read_Channel_Map command returns the current Channel_Map for the specified Connection_Handle. The returned value indicates the state of the Channel_Map specified by the last transmitted or received Channel_Map (in a CONNECT_REQ or LL_CHANNEL_MAP_REQ message) for the specified Connection_Handle, regardless of whether the Master has received an acknowledgement.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.20)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • LE_Channel_Map

    -

    5

    -

    This parameter contains 37 1-bit fields. -The nth such field (in the range 0 to 36) contains the value for the -link layer channel index n. -Channel n is unused = 0. -Channel n is used = 1. -The most significant bits are reserved and shall be set to 0.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_REMOTE_FEATURES

    Description

    This command requests a list of the used LE features from the remote device.
    This command shall return a list of the used LE features. For details see [Vol 6] Part B, Section 4.6.
    This command may be issued on both the master and slave.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.21)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT
  • HCI_LE_ENCRYPT

    Description

    The LE_Encrypt command is used to request the Controller to encrypt the Plaintext_Data in the command using the Key given in the command and returns the Encrypted_Data to the Host. The AES-128 bit block cypher is defined in NIST Publication FIPS-197 (http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf).
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.22)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Key

    -

    16

    -

    128 bit key for the encryption of the data given in the command.

    -

    Plaintext_Data

    -

    16

    -

    128 bit data block that is requested to be encrypted.

    -

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Encrypted_Data

    -

    16

    -

    128 bit encrypted data block.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_RAND

    Description

    The LE_Rand command is used to request the Controller to generate 8 octets of random data to be sent to the Host. The Random_Number shall be generated according to [Vol 2] Part H, Section 2 if the LE Feature (LL Encryption) is supported.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.23)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Random_Number

    -

    8

    -

    Random Number

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_START_ENCRYPTION

    Description

    The LE_Start_Encryption command is used to authenticate the given encryption key associated with the remote device specified by the connection handle, and once authenticated will encrypt the connection. The parameters are as defined in [Vol 3] Part H, Section 2.4.4.
    If the connection is already encrypted then the Controller shall pause connection encryption before attempting to authenticate the given encryption key, and then re-encrypt the connection. While encryption is paused no user data shall be transmitted.
    On an authentication failure, the connection shall be automatically disconnected by the Link Layer. If this command succeeds, then the connection shall be encrypted.
    This command shall only be used when the local device's role is Master.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.24)

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Random_Number

    -

    8

    -

    64 bit random number.

    -

    Encrypted_Diversifier

    -

    2

    -

    16 bit encrypted diversifier.

    -

    Long_Term_Key

    -

    16

    -

    128 bit long term key.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_ENCRYPTION_CHANGE_EVENT
  • HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT
  • HCI_LE_LONG_TERM_KEY_REQUEST_REPLY

    Description

    The LE_Long_Term_Key_Request_Reply command is used to reply to an LE Long Term Key Request event from the Controller, and specifies the Long_Term_Key parameter that shall be used for this Connection_Handle. The Long_Term_Key is used as defined in [Vol 6] Part B, Section 5.1.3.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.25)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Long_Term_Key

    -

    16

    -

    128 bit long term key.

    -

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_LONG_TERM_KEY_REQUESTED_NEGATIVE_REPLY

    Description

    The LE_Long_Term_Key_Request_Negative_Reply command is used to reply to an LE Long Term Key Request event from the Controller if the Host cannot provide a Long Term Key for this Connection_Handle.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.26)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_SUPPORTED_STATES

    Description

    The LE_Read_Supported_States command reads the states and state combinations that the link layer supports. See [Vol 6] Part B, Section 1.1.1.
    LE_States is an 8-octet bit field. If a bit is set to 1 then this state or state combination is supported by the Controller. Multiple bits in LE_States may be set to 1 to indicate support for multiple state and state combinations.
    All the Advertising type with the Initiate State combinations shall be set only if the corresponding Advertising types and Master Role combination are set.
    All the Scanning types and the Initiate State combinations shall be set only if the corresponding Scanning types and Master Role combination are set.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.27)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    LE_States

    -

    8

    -

    State or state combination is supported by the Controller. -See Core v5.0, Vol.2, part E, Ch. 7.8.27.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_DATA_LENGTH

    Description

    The LE_Set_Data_Length command allows the Host to suggest maximum transmission packet size and maximum packet transmission time (connMaxTxOctets and connMaxTxTime - see Bluetooth Specification v5.0 [Vol 6] Part B, Section 4.5.10) to be used for a given connection. The Controller may use smaller or larger values based on local information.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • TxOctets

    -

    2

    -

    Preferred maximum number of payload octets that the local Controller should include in a single Link Layer packet on this connection.

    -
  • 0x001B ... 0x00FB
  • TxTime

    -

    2

    -

    Preferred maximum number of microseconds that the local Controller should use to transmit a single Link Layer packet on this connection.

    -
  • 0x0148 ... 0x4290
  • Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH

    Description

    The LE_Read_Suggested_Default_Data_Length command allows the Host to read the Host's suggested values (SuggestedMaxTxOctets and SuggestedMaxTxTime) for the Controller's maximum transmitted number of payload octets and maximum packet transmission time to be used for new connections (see Bluetooth Specification v5.0 [Vol 6] Part B, Section 4.5.10).

    Input parameters

    None

    Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    SuggestedMaxTxOctets

    -

    2

    -

    The Host's suggested value for the Controller's maximum transmitted number of payload octets to be used for new connections.

    -
  • 0x001B ... 0x00FB
  • SuggestedMaxTxTime

    -

    2

    -

    The Host's suggested value for the Controller's maximum packet transmission time to be used for new connections.

    -
  • 0x0148 ... 0x4290
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH

    Description

    The LE_Write_Suggested_Default_Data_Length command allows the Host to specify its suggested values for the Controller's maximum transmission number of payload octets and maximum packet transmission time to be used for new connections. The Controller may use smaller or larger values for connInitialMaxTxOctets and connInitialMaxTxTime based on local information.
    (see Bluetooth Specification [Vol 6] Part B, Section 4.5.10).

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    SuggestedMaxTxOctets

    -

    2

    -

    The Host's suggested value for the Controller's maximum transmitted number of payload octets to be used for new connections.

    -
  • 0x001B ... 0x00FB
  • SuggestedMaxTxTime

    -

    2

    -

    The Host's suggested value for the Controller's maximum packet transmission time to be used for new connections.

    -
  • 0x0148 ... 0x4290
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_LOCAL_P256_PUBLIC_KEY

    Description

    The LE_Read_Local_P-256_Public_Key command is used to return the local P-256 public key from the Controller. The Controller shall generate a new P-256 public/private key pair upon receipt of this command.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.36)

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE_EVENT
  • HCI_LE_GENERATE_DHKEY

    Description

    The LE_Generate_DHKey command is used to initiate generation of a Diffie-Hellman key in the Controller for use over the LE transport. This command takes the remote P-256 public key as input. The Diffie-Hellman key generation uses the private key generated by LE_Read_Local_P256_Public_Key command.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.37)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Remote_P256_Public_Key

    -

    64

    -

    The remote P-256 public key in X, Y format: -Octets 31-0: X co-ordinate -Octets 63-32: Y co-ordinate -Little Endian Format

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT
  • HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST

    Description

    The LE_Add_Device_To_Resolving_List command is used to add one device to the list of address translations used to resolve Resolvable Private Addresses in the Controller.
    This command cannot be used when address translation is enabled in the Controller and:
    - Advertising is enabled
    - Scanning is enabled
    - Create connection command is outstanding
    This command can be used at any time when address translation is disabled in the Controller.
    When a Controller cannot add a device to the resolving list because the list is full, it shall respond with error code 0x07 (Memory Capacity Exceeded).
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.38)

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Peer_Identity_Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Peer_Identity_Address

    -

    6

    -

    Public or Random (static) Identity address of the peer device

    -

    Peer_IRK

    -

    16

    -

    IRK of the peer device

    -

    Local_IRK

    -

    16

    -

    IRK of the local device

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST

    Description

    The LE_Remove_Device_From_Resolving_List command is used to remove one device from the list of address translations used to resolve Resolvable Private Addresses in the controller.
    This command cannot be used when address translation is enabled in the Controller and:
    - Advertising is enabled
    - Scanning is enabled
    - Create connection command is outstanding
    This command can be used at any time when address translation is disabled in the Controller.
    When a Controller cannot remove a device from the resolving list because it is not found, it shall respond with error code 0x02 (Unknown Connection Identifier).
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.39)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Peer_Identity_Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Peer_Identity_Address

    -

    6

    -

    Public or Random (static) Identity address of the peer device

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_CLEAR_RESOLVING_LIST

    Description

    The LE_Clear_Resolving_List command is used to remove all devices from the list of address translations used to resolve Resolvable Private Addresses in the Controller.
    This command cannot be used when address translation is enabled in the Controller and:
    - Advertising is enabled
    - Scanning is enabled
    - Create connection command is outstanding
    This command can be used at any time when address translation is disabled in the Controller.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.40)

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_RESOLVING_LIST_SIZE

    Description

    The LE_Read_Resolving_List_Size command is used to read the total number of address translation entries in the resolving list that can be stored in the Controller.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.41)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Resolving_List_Size

    -

    1

    -

    Number of address translation entries in the resolving list

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_PEER_RESOLVABLE_ADDRESS

    Description

    The LE_Read_Peer_Resolvable_Address command is used to get the current peer Resolvable Private Address being used for the corresponding peer Public and Random (static) Identity Address. The peer's resolvable address being used may change after the command is called.
    This command can be used at any time.
    When a Controller cannot find a Resolvable Private Address associated with the Peer Identity Address, it shall respond with error code 0x02 (Unknown Connection Identifier).
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.42)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Peer_Identity_Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Peer_Identity_Address

    -

    6

    -

    Public or Random (static) Identity address of the peer device

    -

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Peer_Resolvable_Address

    -

    6

    -

    Resolvable Private Address being used by the peer device

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS

    Description

    The LE_Read_Local_Resolvable_Address command is used to get the current local Resolvable Private Address being used for the corresponding peer Identity Address. The local's resolvable address being used may change after the command is called.
    This command can be used at any time.
    When a Controller cannot find a Resolvable Private Address associated with the Peer Identity Address, it shall respond with error code 0x02 (Unknown Connection Identifier).
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.43)

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Peer_Identity_Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Peer_Identity_Address

    -

    6

    -

    Public or Random (static) Identity address of the peer device

    -

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Local_Resolvable_Address

    -

    6

    -

    Resolvable Private Address being used by the local device

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE

    Description

    The LE_Set_Address_Resolution_Enable command is used to enable resolution of Resolvable Private Addresses in the Controller. This causes the Controller to use the resolving list whenever the Controller receives a local or peer Resolvable Private Address.
    This command can be used at any time except when:
    - Advertising is enabled
    - Scanning is enabled
    - Create connection command is outstanding
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, Section 7.8.44)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Address_Resolution_Enable

    -

    1

    -

    Enable/disable address resolution in the controller. -0x00: Address Resolution in controller disabled (default), -0x01: Address Resolution in controller enabled

    -
  • 0x00: Address Resolution in controller disabled (default)
  • 0x01: Address Resolution in controller enabled
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT

    Description

    The LE_Set_Resolvable_Private_Address_Timeout command set the length of time the controller uses a Resolvable Private Address before a new resolvable private address is generated and starts being used. This timeout applies to all addresses generated by the controller.
    (See Bluetooth Specification v.5.0 [Vol 2] Part E, Section 7.8.45)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    RPA_Timeout

    -

    2

    -

    RPA_Timeout measured in seconds. -Range for N: 0x0001 - 0xA1B8 (1 sec - approximately 11.5 hours) -Default: N= 0x0384 (900 secs or 15 minutes)

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_MAXIMUM_DATA_LENGTH

    Description

    The LE_Read_Maximum_Data_Length command allows the Host to read the Controller's maximum supported payload octets and packet duration times for transmission and reception (supportedMaxTxOctets and supportedMaxTxTime, supportedMaxRxOctets, and supportedMaxRxTime, see Bluetooth Specification v5.0 [Vol 6] Part B, Section 4.5.10).

    Input parameters

    None

    Output parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    supportedMaxTxOctets

    -

    2

    -

    Maximum number of payload octets that the local Controller supports for transmission of a single Link Layer packet on a data connection.

    -
  • 0x001B ... 0x00FB
  • supportedMaxTxTime

    -

    2

    -

    Maximum time, in microseconds, that the local Controller supports for transmission of a single Link Layer packet on a data connection.

    -
  • 0x0148 ... 0x4290
  • supportedMaxRxOctets

    -

    2

    -

    Maximum number of payload octets that the local Controller supports for reception of a single Link Layer packet on a data connection.

    -
  • 0x001B ... 0x00FB
  • supportedMaxRxTime

    -

    2

    -

    Maximum time, in microseconds, that the local Controller supports for reception of a single Link Layer packet on a data connection.

    -
  • 0x0148 ... 0x4290
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_READ_PHY

    Description

    The LE_Read_PHY command is used to read the current transmitter PHY and receiver PHY on the connection identified by the Connection_Handle. see Bluetooth Specification [Vol 2] part E, Section 7.8.47

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • TX_PHY

    -

    1

    -

    Transmitter PHY in use

    -
  • 0x01: The transmitter PHY for the connection is LE 1M
  • 0x02: The transmitter PHY for the connection is LE 2M
  • 0x03: The transmitter PHY for the connection is LE Coded -(Not supported by STM32WB)
  • RX_PHY

    -

    1

    -

    Receiver PHY in use

    -
  • 0x01: The receiver PHY for the connection is LE 1M
  • 0x02: The receiver PHY for the connection is LE 2M
  • 0x03: The receiver PHY for the connection is LE Coded -(Not supported by STM32WB)
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_DEFAULT_PHY

    Description

    The LE_Set_Default_PHY command allows the Host to specify its preferred values for the transmitter PHY and receiver PHY to be used for all subsequent connections over the LE transport.
    The ALL_PHYS parameter is a bit field that allows the Host to specify, for each
    direction, whether it has no preference among the PHYs that the Controller supports in a given direction or whether it has specified particular PHYs that it prefers in the TX_PHYS or RX_PHYS parameter.
    The TX_PHYS parameter is a bit field that indicates the transmitter PHYs that the Host prefers the Controller to use. If the ALL_PHYS parameter specifies that the Host has no preference, the TX_PHYS parameter is ignored; otherwise at least one bit shall be set to 1.
    The RX_PHYS parameter is a bit field that indicates the receiver PHYs that the Host prefers the Controller to use. If the ALL_PHYS parameter specifies that the Host has no preference, the RX_PHYS parameter is ignored; otherwise at least one bit shall be set to 1.
    See Bluetooth Specification [Vol2] Part E Section 7.8.48

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    ALL_PHYS

    -

    1

    -

    Host preferences for TX PHY and RX PHY

    -
  • 0x00 ... 0x03
  • TX_PHYS

    -

    1

    -

    Host preferences for TX PHY (no LE coded support)

    -
  • 0x00 ... 0x03
  • RX_PHYS

    -

    1

    -

    Host preferences for RX PHY (no LE coded support)

    -
  • 0x00 ... 0x03
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_PHY

    Description

    The LE_Set_PHY command is used to set the PHY preferences for the connection identified by the Connection_Handle. The Controller might not be able to make the change (e.g. because the peer does not support the requested PHY) or may decide that the current PHY is preferable.
    The ALL_PHYS parameter is a bit field that allows the Host to specify, for each direction, whether it has no preference among the PHYs that the Controller supports in a given direction or whether it has specified particular PHYs that it prefers in the TX_PHYS or RX_PHYS parameter.
    The TX_PHYS parameter is a bit field that indicates the transmitter PHYs that the Host prefers the Controller to use. If the ALL_PHYS parameter specifies that the Host has no preference, the TX_PHYS parameter is ignored; otherwise at least one bit shall be set to 1.
    The RX_PHYS parameter is a bit field that indicates the receiver PHYs that the Host prefers the Controller to use. If the ALL_PHYS parameter specifies that the Host has no preference, the RX_PHYS parameter is ignored; otherwise at least one bit shall be set to 1.
    If, for at least one direction, the Host has specified a preference and the current PHY is not one of those preferred, the Controller shall request a change. Otherwise the Controller may, but need not, request a change.
    The PHY preferences provided by the LE Set PHY command override those provided via the LE Set Default PHY command (Section 7.8.48) or any preferences previously set using the LE Set PHY command on the same connection.
    The PHY_options parameter is a bit field that allows the Host to specify options for PHYs. The default value for a new connection shall be all zero bits. The Controller may override any preferred coding for transmitting on the LE Coded PHY.
    The Host may specify a preferred coding even if it prefers not to use the LE Coded transmitter PHY since the Controller may override the PHY preference.
    (See Bluetooth Specification v5.0 [Vol 6] Part B, Section 7.8.49)

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • ALL_PHYS

    -

    1

    -

    Host preferences for TX PHY and RX PHY

    -
  • 0x00 ... 0x03
  • TX_PHYS

    -

    1

    -

    Host preferences for TX PHY (no LE coded support)

    -
  • 0x00 ... 0x03
  • RX_PHYS

    -

    1

    -

    Host preferences for RX PHY (no LE coded support)

    -
  • 0x00 ... 0x03
  • PHY_options

    -

    2

    -

    Not supported

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_PHY_UPDATE_COMPLETE_EVENT
  • HCI_LE_READ_TRANSMIT_POWER

    Description

    This command is used to read the minimum and maximum transmit powers supported by the Controller.

    Input parameters

    None

    Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Min_TX_Power

    -

    1

    -

    Signed integer. Units: dBm

    -
  • -127 ... 20
  • Max_TX_Power

    -

    1

    -

    Signed integer. Units: dBm

    -
  • -127 ... 20
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_SET_PRIVACY_MODE

    Description

    This command is used to allow the Host to specify the privacy mode to be used for a given entry on the resolving list.
    (See Bluetooth Specification v.5.0 [Vol 2] Part E, Section 7.8.77)

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Peer_Identity_Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Peer_Identity_Address

    -

    6

    -

    Public or Random (static) Identity address of the peer device

    -

    Privacy_Mode

    -

    1

    -

    Privacy Mode.

    -
  • 0x00: Use Network Privacy Mode
  • 0x01: Use Device Privacy Mode
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI TESTING commands

    - - - - - - -
    CommandOpcodeBFPOLOBO
    HCI_LE_RECEIVER_TEST

    0x201D

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_TRANSMITTER_TEST

    0x201E

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_TEST_END

    0x201F

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_ENHANCED_RECEIVER_TEST

    0x2033

    -

    Y

    -
    HCI_LE_ENHANCED_TRANSMITTER_TEST

    0x2034

    -

    Y

    -

    HCI_LE_RECEIVER_TEST

    Description

    This command is used to start a test where the DUT receives test reference packets at a fixed interval. The tester generates the test reference packets.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.28)

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    RX_Frequency

    -

    1

    -

    N = (F - 2402) / 2 -Frequency Range : 2402 MHz to 2480 MHz

    -
  • 0x00 ... 0x27
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_TRANSMITTER_TEST

    Description

    This command is used to start a test where the DUT generates test reference packets at a fixed interval. The Controller shall transmit at maximum power.
    An LE Controller supporting the LE_Transmitter_Test command shall support Packet_Payload values 0x00, 0x01 and 0x02. An LE Controller may support other values of Packet_Payload.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.29)

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    TX_Frequency

    -

    1

    -

    N = (F - 2402) / 2 -Frequency Range : 2402 MHz to 2480 MHz

    -
  • 0x00 ... 0x27
  • Length_Of_Test_Data

    -

    1

    -

    Length in bytes of payload data in each packet.

    -
  • 0x00 ... 0x25
  • Packet_Payload

    -

    1

    -

    Type of packet payload.

    -
  • 0x00: Pseudo-Random bit sequence 9
  • 0x01: Pattern of alternating bits '11110000'
  • 0x02: Pattern of alternating bits '10101010'
  • 0x03: Pseudo-Random bit sequence 15
  • 0x04: Pattern of All '1' bits
  • 0x05: Pattern of All '0' bits
  • 0x06: Pattern of alternating bits '00001111'
  • 0x07: Pattern of alternating bits '0101'
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_TEST_END

    Description

    This command is used to stop any test which is in progress. The Number_Of_Packets for a transmitter test shall be reported as 0x0000. The Number_Of_Packets is an unsigned number and contains the number of received packets.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.8.30)

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Number_Of_Packets

    -

    2

    -

    Number of packets received

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_ENHANCED_RECEIVER_TEST

    Description

    This command is used to start a test where the DUT receives test reference packets at a fixed interval. The tester generates the test reference packets.
    (See Bluetooth Specification v5.0 [Vol 6] Part B, Section 7.8.50)

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    RX_Frequency

    -

    1

    -

    N = (F - 2402) / 2 -Frequency Range : 2402 MHz to 2480 MHz

    -
  • 0x00 ... 0x27
  • PHY

    -

    1

    -

    PHY to use for test packet

    -
  • 0x00: Reserved for future use
  • 0x01: Transmitter set to use the LE 1M PHY
  • 0x02: Transmitter set to use the LE 2M PHY
  • 0x03: Transmitter set to use the LE Coded PHY with S=8 data coding
  • 0x04: Transmitter set to use the LE Coded PHY with S=2 data coding
  • Modulation_Index

    -

    1

    -

    Modulation index capability of the transmitter

    -
  • 0x00: Assume transmitter will have a standard modulation index
  • 0x01: Assume transmitter will have a stable modulation index
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_ENHANCED_TRANSMITTER_TEST

    Description

    This command is used to start a test where the DUT generates test reference packets at a fixed interval. The Controller shall transmit at maximum power.
    An LE Controller supporting the LE_Enhanced Transmitter_Test command shall support Packet_Payload values 0x00, 0x01 and 0x02. An LE Controller supporting the LE Coded PHY shall also support Packet_Payload value 0x04 (not supported by STM32WB). An LE Controller may support other values of Packet_Payload.
    (See Bluetooth Specification v5.0 [Vol 6] Part B, Section 7.8.51)

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    TX_Frequency

    -

    1

    -

    N = (F - 2402) / 2 -Frequency Range : 2402 MHz to 2480 MHz

    -
  • 0x00 ... 0x27
  • Length_Of_Test_Data

    -

    1

    -

    Length in bytes of payload data in each packet.

    -
  • 0x00 ... 0x25
  • Packet_Payload

    -

    1

    -

    Type of packet payload.

    -
  • 0x00: Pseudo-Random bit sequence 9
  • 0x01: Pattern of alternating bits '11110000'
  • 0x02: Pattern of alternating bits '10101010'
  • 0x03: Pseudo-Random bit sequence 15
  • 0x04: Pattern of All '1' bits
  • 0x05: Pattern of All '0' bits
  • 0x06: Pattern of alternating bits '00001111'
  • 0x07: Pattern of alternating bits '0101'
  • PHY

    -

    1

    -

    PHY to use for test packet

    -
  • 0x00: Reserved for future use
  • 0x01: Transmitter set to use the LE 1M PHY
  • 0x02: Transmitter set to use the LE 2M PHY
  • 0x03: Transmitter set to use the LE Coded PHY with S=8 data coding
  • 0x04: Transmitter set to use the LE Coded PHY with S=2 data coding
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI HAL commands

    - - - - - - - - - - - - - - - - - - - - -
    CommandOpcodeBFPOLOBO
    ACI_HAL_GET_FW_BUILD_NUMBER

    0xFC00

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    ACI_HAL_WRITE_CONFIG_DATA

    0xFC0C

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    ACI_HAL_READ_CONFIG_DATA

    0xFC0D

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    ACI_HAL_SET_TX_POWER_LEVEL

    0xFC0F

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    ACI_HAL_LE_TX_TEST_PACKET_NUMBER

    0xFC14

    -

    Y

    -

    Y

    -
    ACI_HAL_TONE_START

    0xFC15

    -

    Y

    -

    Y

    -
    ACI_HAL_TONE_STOP

    0xFC16

    -

    Y

    -

    Y

    -
    ACI_HAL_GET_LINK_STATUS

    0xFC17

    -

    Y

    -
    ACI_HAL_SET_RADIO_ACTIVITY_MASK

    0xFC18

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    ACI_HAL_GET_ANCHOR_PERIOD

    0xFC19

    -

    Y

    -
    ACI_HAL_SET_EVENT_MASK

    0xFC1A

    -
    ACI_HAL_SET_SMP_ENG_CONFIG

    0xFC1B

    -
    ACI_HAL_GET_PM_DEBUG_INFO

    0xFC1C

    -

    Y

    -
    ACI_HAL_READ_RADIO_REG

    0xFC30

    -

    Y

    -

    Y

    -
    ACI_HAL_WRITE_RADIO_REG

    0xFC31

    -

    Y

    -

    Y

    -
    ACI_HAL_READ_RAW_RSSI

    0xFC32

    -

    Y

    -

    Y

    -
    ACI_HAL_RX_START

    0xFC33

    -

    Y

    -

    Y

    -
    ACI_HAL_RX_STOP

    0xFC34

    -

    Y

    -

    Y

    -
    ACI_HAL_STACK_RESET

    0xFC3B

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -

    ACI_HAL_GET_FW_BUILD_NUMBER

    Description

    This command returns the build number associated with the firmware version currently running

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Build_Number

    -

    2

    -

    Build number of the firmware.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_WRITE_CONFIG_DATA

    Description

    This command writes a value to a low level configure data structure. It is useful to setup directly some low level parameters for the system in the runtime.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Offset

    -

    1

    -

    Offset of the element in the configuration data structure -which has to be written.

    -
  • 0x00: CONFIG_DATA_PUBADDR_OFFSET; -Bluetooth public address; 6 bytes
  • 0x08: CONFIG_DATA_ER_OFFSET; -Encryption root key used to derive LTK and CSRK; 16 bytes
  • 0x18: CONFIG_DATA_IR_OFFSET; -Identity root key used to derive LTK and CSRK; 16 bytes
  • 0x2E: CONFIG_DATA_RANDOM_ADDRESS_WR; -Static Random Address; 6 bytes
  • Length

    -

    1

    -

    Length of data to be written

    -

    Value

    -

    Length

    -

    Data to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_READ_CONFIG_DATA

    Description

    This command requests the value in the low level configure data structure.
    The number of read bytes changes for different Offset.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Offset

    -

    1

    -

    Offset of the element in the configuration data structure -which has to be read.

    -
  • 0x00: CONFIG_DATA_PUBADDR_OFFSET; -Bluetooth public address; 6 bytes
  • 0x08: CONFIG_DATA_ER_OFFSET; -Encryption root key used to derive LTK and CSRK; 16 bytes
  • 0x18: CONFIG_DATA_IR_OFFSET -Identity root key used to derive LTK and CSRK; 16 bytes
  • 0x80: CONFIG_DATA_RANDOM_ADDRESS -Static random address; 6 bytes (read-only)
  • Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Data_Length

    -

    1

    -

    Length of Data in octets

    -

    Data

    -

    Data_Length

    -

    Data field associated with Offset parameter

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_SET_TX_POWER_LEVEL

    Description

    This command sets the TX power level of the device. By controlling the PA_LEVEL, that determines the output power level (dBm) at the IC pin.
    When the system starts up or reboots, the default TX power level will be used, which is the maximum value of 6 dBm. Once this command is given, the output power will be changed instantly, regardless if there is Bluetooth communication going on or not. For example, for debugging purpose, the device can be set to advertise all the time. And use this command to observe the signal strength changing.
    The system will keep the last received TX power level from the command, i.e. the 2nd command overwrites the previous TX power level. The new TX power level remains until another Set TX Power command, or the system reboots.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    En_High_Power

    -

    1

    -

    Enable High Power mode - Deprecated and ignored on STM32WB

    -
  • 0x00: Standard Power
  • 0x01: High Power
  • PA_Level

    -

    1

    -

    Power amplifier output level. Output power is indicative and it depends on the PCB layout and associated -components.Here the values are given at the IC pin

    -
  • 0x00: -40 dBm
  • 0x01: -20.85 dBm
  • 0x02: -19.75 dBm
  • 0x03: -18.85 dBm
  • 0x04: -17.6 dBm
  • 0x05: -16.5 dBm
  • 0x06: -15.25 dBm
  • 0x07: -14.1 dBm
  • 0x08: -13.15 dBm
  • 0x09: -12.05 dBm
  • 0x0A: -10.9 dBm
  • 0x0B: -9.9 dBm
  • 0x0C: -8.85 dBm
  • 0x0D: -7.8 dBm
  • 0x0E: -6.9 dBm
  • 0x0F: -5.9 dBm
  • 0x10: -4.95 dBm
  • 0x11: -4 dBm
  • 0x12: -3.15 dBm
  • 0x13: -2.45 dBm
  • 0x14: -1.8 dBm
  • 0x15: -1.3 dBm
  • 0x16: -0.85 dBm
  • 0x17: -0.5 dBm
  • 0x18: -0.15 dBm
  • 0x19: 0 dBm
  • 0x1A: +1 dBm
  • 0x1B: +2 dBm
  • 0x1C: +3 dBm
  • 0x1D: +4 dBm
  • 0x1E: +5 dBm
  • 0x1F: +6 dBm
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_LE_TX_TEST_PACKET_NUMBER

    Description

    This command returns the number of packets sent in Direct Test Mode.
    When the Direct TX test is started, a 32-bit counter is used to count how many packets have been transmitted.
    This command can be used to check how many packets have been sent during the Direct TX test.
    The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. The counter is not cleared until the next Direct TX test starts.

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Number_Of_Packets

    -

    4

    -

    Number of packets sent during the last Direct TX test.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_TONE_START

    Description

    This command starts a carrier frequency, i.e. a tone, on a specific channel. The frequency sine wave at the specific channel may be used for debugging purpose only. The channel ID is a parameter from 0x00 to 0x27 for the 40 BLE channels, e.g. 0x00 for 2.402 GHz, 0x01 for 2.404 GHz etc.
    This command should not be used when normal Bluetooth activities are ongoing.
    The tone should be stopped by ACI_HAL_TONE_STOP command.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    RF_Channel

    -

    1

    -

    BLE Channel ID, from 0x00 to 0x27 meaning (2.402 + 2*0xXX) GHz -Device will continuously emit 0s, that means that the tone -will be at the channel center frequency less the maximum -frequency deviation (250kHz).

    -
  • 0x00 ... 0x27
  • Freq_offset

    -

    1

    -

    Frequency Offset for tone channel

    -
  • 0x00 ... 0xFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_TONE_STOP

    Description

    This command is used to stop the previously started ACI_HAL_TONE_START command.

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_GET_LINK_STATUS

    Description

    This command returns the status of the 8 Bluetooth low energy links managed by the device

    Input parameters

    None

    Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Link_Status

    -

    8

    -

    Array of link status (8 links). Each link status is 1 byte.

    -
  • 0x00: Idle
  • 0x01: Advertising
  • 0x02: Connected in slave role
  • 0x03: Scanning
  • 0x04: Reserved
  • 0x05: Connected in master role
  • 0x06: TX test mode
  • 0x07: RX test mode
  • Link_Connection_Handle

    -

    16

    -

    Array of connection handles (2 bytes) for 8 links.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_SET_RADIO_ACTIVITY_MASK

    Description

    This command set the bitmask associated to ACI_HAL_END_OF_RADIO_ACTIVITY_EVENT.
    Only the radio activities enabled in the mask will be reported to application by ACI_HAL_END_OF_RADIO_ACTIVITY_EVENT

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Radio_Activity_Mask

    -

    2

    -

    Bitmask of radio events

    -

    Bitmask of:

  • 0x0001: Idle
  • 0x0002: Advertising
  • 0x0004: Connection event slave
  • 0x0008: Scanning
  • 0x0010: Connection request
  • 0x0020: Connection event master
  • 0x0040: TX test mode
  • 0x0080: RX test mode
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_END_OF_RADIO_ACTIVITY_EVENT
  • ACI_HAL_GET_ANCHOR_PERIOD

    Description

    This command returns information about the Anchor Period to help application in selecting slot timings when operating in multi-link scenarios.

    Input parameters

    None

    Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Anchor_Period

    -

    4

    -

    Current anchor period. -T = N * 0.625 ms.

    -

    Max_Free_Slot

    -

    4

    -

    Maximum available time that can be allocated for a new slot. -T = N * 0.625 ms.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_SET_EVENT_MASK

    Description

    This command is used to enable/disable the generation of HAL events

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Event_Mask

    -

    4

    -

    Mask to enable/disable generation of HAL events

    -

    Bitmask of:

  • 0x00000000: No events specified (Default)
  • 0x00000001: ACI_HAL_SCAN_REQ_REPORT_EVENT
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_SET_SMP_ENG_CONFIG

    Description

    This command is used to provide a specific engineering setup to the Security Manager Protocol Layer. It may be used during development/debug only!

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    SMP_Config

    -

    4

    -

    Mask to configure SMP engineering knobs

    -

    Bitmask of:

  • 0x00000000: Default config (all reset)
  • 0x00000001: Cheat Level 1 ON
  • 0x00000002: RFU
  • 0x00000003: Cheat Level 3 ON
  • 0x00000004: RFU
  • 0x00000005: Cheat Level 5 ON
  • 0x00000006: Cheat Level 6 ON
  • 0x00000007: Cheat Level 7 ON
  • 0x00000010: DBG messages ON
  • 0x00000100: Debug Public Key ON
  • 0x00000107: Debug KEY On + DBG msg Off + CL=7
  • 0x00000117: Debug KEY On + DBG msg On + CL=7
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_GET_PM_DEBUG_INFO

    Description

    This command is used to retrieve TX, RX and total buffer count allocated for ACL packets.

    Input parameters

    None

    Output parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Allocated_For_TX

    -

    1

    -

    MBlocks allocated for TXing

    -

    Allocated_For_RX

    -

    1

    -

    MBlocks allocated for RXing

    -

    Allocated_MBlocks

    -

    1

    -

    Overall allocated MBlocks

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_READ_RADIO_REG

    Description

    This command Reads Register value from the RF module.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Register_Address

    -

    1

    -

    Address of the register to be read

    -

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    reg_val

    -

    1

    -

    Register value

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_WRITE_RADIO_REG

    Description

    This command writes Register value to the RF module.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Register_Address

    -

    1

    -

    Address of the register to be written

    -

    Register_Value

    -

    1

    -

    Value to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_READ_RAW_RSSI

    Description

    This command returns the raw value of the RSSI.

    Input parameters

    None

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Value

    -

    3

    -

    RAW RSSI value

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_RX_START

    Description

    This command does set up the RF to listen to a specific RF channel.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    RF_Channel

    -

    1

    -

    BLE Channel ID, from 0x00 to 0x27 meaning (2.402 + 2*0xXX) GHz -Device will continuously emit 0s, that means that the tone -will be at the channel center frequency less the maximum -frequency deviation (250kHz).

    -
  • 0x00 ... 0x27
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_RX_STOP

    Description

    This command stop a previous ACI_HAL_RX_START command.

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_HAL_STACK_RESET

    Description

    This command is equivalent to HCI_RESET but ensures the sleep mode is entered immediately after its completion.

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI GAP commands

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    CommandOpcodeBFPOLOBO
    ACI_GAP_SET_NON_DISCOVERABLE

    0xFC81

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_LIMITED_DISCOVERABLE

    0xFC82

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_DISCOVERABLE

    0xFC83

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_DIRECT_CONNECTABLE

    0xFC84

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_IO_CAPABILITY

    0xFC85

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_AUTHENTICATION_REQUIREMENT

    0xFC86

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_AUTHORIZATION_REQUIREMENT

    0xFC87

    -

    Y

    -

    Y

    -
    ACI_GAP_PASS_KEY_RESP

    0xFC88

    -

    Y

    -

    Y

    -
    ACI_GAP_AUTHORIZATION_RESP

    0xFC89

    -

    Y

    -

    Y

    -
    ACI_GAP_INIT

    0xFC8A

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_NON_CONNECTABLE

    0xFC8B

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_UNDIRECTED_CONNECTABLE

    0xFC8C

    -

    Y

    -

    Y

    -
    ACI_GAP_SLAVE_SECURITY_REQ

    0xFC8D

    -

    Y

    -

    Y

    -
    ACI_GAP_UPDATE_ADV_DATA

    0xFC8E

    -

    Y

    -

    Y

    -
    ACI_GAP_DELETE_AD_TYPE

    0xFC8F

    -

    Y

    -

    Y

    -
    ACI_GAP_GET_SECURITY_LEVEL

    0xFC90

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_EVENT_MASK

    0xFC91

    -

    Y

    -

    Y

    -
    ACI_GAP_CONFIGURE_WHITELIST

    0xFC92

    -

    Y

    -

    Y

    -
    ACI_GAP_TERMINATE

    0xFC93

    -

    Y

    -

    Y

    -
    ACI_GAP_CLEAR_SECURITY_DB

    0xFC94

    -

    Y

    -

    Y

    -
    ACI_GAP_ALLOW_REBOND

    0xFC95

    -

    Y

    -

    Y

    -
    ACI_GAP_START_LIMITED_DISCOVERY_PROC

    0xFC96

    -

    Y

    -
    ACI_GAP_START_GENERAL_DISCOVERY_PROC

    0xFC97

    -

    Y

    -
    ACI_GAP_START_NAME_DISCOVERY_PROC

    0xFC98

    -

    Y

    -
    ACI_GAP_START_AUTO_CONNECTION_ESTABLISH_PROC

    0xFC99

    -

    Y

    -
    ACI_GAP_START_GENERAL_CONNECTION_ESTABLISH_PROC

    0xFC9A

    -

    Y

    -
    ACI_GAP_START_SELECTIVE_CONNECTION_ESTABLISH_PROC

    0xFC9B

    -

    Y

    -
    ACI_GAP_CREATE_CONNECTION

    0xFC9C

    -

    Y

    -
    ACI_GAP_TERMINATE_GAP_PROC

    0xFC9D

    -

    Y

    -
    ACI_GAP_START_CONNECTION_UPDATE

    0xFC9E

    -

    Y

    -
    ACI_GAP_SEND_PAIRING_REQ

    0xFC9F

    -

    Y

    -
    ACI_GAP_RESOLVE_PRIVATE_ADDR

    0xFCA0

    -

    Y

    -
    ACI_GAP_SET_BROADCAST_MODE

    0xFCA1

    -

    Y

    -
    ACI_GAP_START_OBSERVATION_PROC

    0xFCA2

    -

    Y

    -
    ACI_GAP_GET_BONDED_DEVICES

    0xFCA3

    -

    Y

    -

    Y

    -
    ACI_GAP_IS_DEVICE_BONDED

    0xFCA4

    -

    Y

    -

    Y

    -
    ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO

    0xFCA5

    -

    Y

    -

    Y

    -
    ACI_GAP_PASSKEY_INPUT

    0xFCA6

    -

    Y

    -

    Y

    -
    ACI_GAP_GET_OOB_DATA

    0xFCA7

    -

    Y

    -

    Y

    -
    ACI_GAP_SET_OOB_DATA

    0xFCA8

    -

    Y

    -

    Y

    -
    ACI_GAP_ADD_DEVICES_TO_RESOLVING_LIST

    0xFCA9

    -

    Y

    -

    Y

    -
    ACI_GAP_REMOVE_BONDED_DEVICE

    0xFCAA

    -

    Y

    -

    Y

    -

    ACI_GAP_SET_NON_DISCOVERABLE

    Description

    Put the device in non-discoverable mode. This command disables the LL advertising.

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_LIMITED_DISCOVERABLE

    Description

    Put the device in limited discoverable mode (as defined in Bluetooth Specification v.5.0, Vol. 3, Part C, section 9.2.3). The device will be discoverable for maximum period of TGAP (lim_adv_timeout) = 180 seconds (from errata). The advertising can be disabled at any time by issuing ACI_GAP_SET_NON_DISCOVERABLE command.
    The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP will use default values for adv intervals for limited discoverable mode (250 ms and 500 ms respectively).
    To allow a fast connection, the host can set Local_Name, Service_Uuid_List, Slave_Conn_Interval_Min and Slave_Conn_Interval_Max. If provided, these data will be inserted into the advertising packet payload as AD data. These parameters are optional in this command. These values can be set in advertised data using ACI_GAP_UPDATE_ADV_DATA command separately.
    The total size of data in advertising packet cannot exceed 31 bytes.
    With this command, the BLE Stack will also add automatically the following standard AD types:
    - AD Flags
    - Power Level
    When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates ACI_GAP_LIMITED_DISCOVERABLE_EVENT event.

    Input parameters

    - - - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Advertising_Type

    -

    1

    -

    Advertising type

    -
  • 0x00: ADV_IND (Connectable undirected advertising)
  • 0x02: ADV_SCAN_IND (Scannable undirected advertising)
  • 0x03: ADV_NONCONN_IND (Non connectable undirected advertising)
  • Advertising_Interval_Min

    -

    2

    -

    Minimum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Advertising_Interval_Max

    -

    2

    -

    Maximum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Advertising_Filter_Policy

    -

    1

    -

    Advertising filter policy: not applicable (the value of Advertising_Filter_Policy parameter is not used inside the Stack)

    -

    Local_Name_Length

    -

    1

    -

    Length of the local_name field in octets. -If length is set to 0x00, Local_Name parameter is not used.

    -

    Local_Name

    -

    Local_Name_Length

    -

    Local name of the device. First byte must be 0x08 for Shortened Local Name or 0x09 for Complete Local Name. No NULL character at the end.

    -

    Service_Uuid_length

    -

    1

    -

    Length of the Service Uuid List in octets. -If there is no service to be advertised, set this field to 0x00.

    -

    Service_Uuid_List

    -

    Service_Uuid_length

    -

    This is the list of the UUIDs as defined in Volume 3, Section 11 of GAP Specification. First byte is the AD Type. -See also Supplement to the Bluetooth Core 5.0 specification.

    -

    Slave_Conn_Interval_Min

    -

    2

    -

    Slave connection interval minimum value suggested by Peripheral. -If Slave_Conn_Interval_Min and Slave_Conn_Interval_Max are not 0x0000, Slave Connection Interval Range AD structure will be added in advertising data. -Connection interval is defined in the following manner: -connIntervalmin = Slave_Conn_Interval_Min x 1.25ms.

    -
  • 0x0000 (NaN)
  • 0xFFFF (NaN) : No specific minimum
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Slave_Conn_Interval_Max

    -

    2

    -

    Slave connection interval maximum value suggested by Peripheral. -If Slave_Conn_Interval_Min and Slave_Conn_Interval_Max are not 0x0000, Slave Connection Interval Range AD structure will be added in advertising data. -Connection interval is defined in the following manner: -connIntervalmax = Slave_Conn_Interval_Max x 1.25ms

    -
  • 0x0000 (NaN)
  • 0xFFFF (NaN) : No specific maximum
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GAP_LIMITED_DISCOVERABLE_EVENT
  • ACI_GAP_SET_DISCOVERABLE

    Description

    Put the device in general discoverable mode (as defined in Bluetooth Specification v.5.0, Vol. 3, Part C, section 9.2.4). The device will be discoverable until the host issues the ACI_GAP_SET_NON_DISCOVERABLE command. The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses the default values for adv intervals for general discoverable mode.
    When using connectable undirected advertising events:
    - Adv_Interval_Min = 30 ms
    - Adv_Interval_Max = 60 ms
    When using non-connectable advertising events or scannable undirected advertising events:
    - Adv_Interval_Min = 100 ms
    - Adv_Interval_Max = 150 ms
    Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range.
    If provided, these data will be inserted into the advertising packet payload as AD data.
    These parameters are optional in this command. These values can be also set using ACI_GAP_UPDATE_ADV_DATA command separately.
    The total size of data in advertising packet cannot exceed 31 bytes.
    With this command, the BLE Stack will also add automatically the following standard AD types:
    - AD Flags
    - TX Power Level

    Input parameters

    - - - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Advertising_Type

    -

    1

    -

    Advertising type

    -
  • 0x00: ADV_IND (Connectable undirected advertising)
  • 0x02: ADV_SCAN_IND (Scannable undirected advertising)
  • 0x03: ADV_NONCONN_IND (Non connectable undirected advertising)
  • Advertising_Interval_Min

    -

    2

    -

    Minimum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Advertising_Interval_Max

    -

    2

    -

    Maximum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Advertising_Filter_Policy

    -

    1

    -

    Advertising filter policy: not applicable (the value of Advertising_Filter_Policy parameter is not used inside the Stack)

    -

    Local_Name_Length

    -

    1

    -

    Length of the local_name field in octets. -If length is set to 0x00, Local_Name parameter is not used.

    -

    Local_Name

    -

    Local_Name_Length

    -

    Local name of the device. First byte must be 0x08 for Shortened Local Name or 0x09 for Complete Local Name. No NULL character at the end.

    -

    Service_Uuid_length

    -

    1

    -

    Length of the Service Uuid List in octets. -If there is no service to be advertised, set this field to 0x00.

    -

    Service_Uuid_List

    -

    Service_Uuid_length

    -

    This is the list of the UUIDs as defined in Volume 3, Section 11 of GAP Specification. First byte is the AD Type. -See also Supplement to the Bluetooth Core 5.0 specification.

    -

    Slave_Conn_Interval_Min

    -

    2

    -

    Slave connection interval minimum value suggested by Peripheral. -If Slave_Conn_Interval_Min and Slave_Conn_Interval_Max are not 0x0000, Slave Connection Interval Range AD structure will be added in advertising data. -Connection interval is defined in the following manner: -connIntervalmin = Slave_Conn_Interval_Min x 1.25ms.

    -
  • 0x0000 (NaN)
  • 0xFFFF (NaN) : No specific minimum
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Slave_Conn_Interval_Max

    -

    2

    -

    Slave connection interval maximum value suggested by Peripheral. -If Slave_Conn_Interval_Min and Slave_Conn_Interval_Max are not 0x0000, Slave Connection Interval Range AD structure will be added in advertising data. -Connection interval is defined in the following manner: -connIntervalmax = Slave_Conn_Interval_Max x 1.25ms

    -
  • 0x0000 (NaN)
  • 0xFFFF (NaN) : No specific maximum
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_DIRECT_CONNECTABLE

    Description

    Set the device in direct connectable mode (as defined in Bluetooth Specification v.5.0, Vol. 3, Part C, section 9.3.3). Device uses direct connectable mode to advertise using High Duty cycle advertisement events or Low Duty cycle advertisement events and the address as either what is specified in the Own Address Type parameter. The command specifies the type of the advertising used.
    If the privacy is enabled, the Type parameter in reconnection address is used for advertising, otherwise the address of the type specified in OwnAddrType is used.
    The device stays in directed connectable mode only for 1.28 seconds. If no connection is established within this duration, the device enters non discoverable mode and advertising has to be again enabled explicitly.
    The controller generates a HCI_LE_CONNECTION_COMPLETE_EVENT event with the status set to HCI_ADVERTISING_TIMEOUT_ERR_CODE if the connection was not established and BLE_STATUS_SUCCESS (0x00) if the connection was successfully established.
    If Host privacy is enabled this command returns BLE_STATUS_INVALID_PARAMS.

    Input parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • Directed_Advertising_Type

    -

    1

    -

    Advertising type

    -
  • 0x01: High Duty Cycle Directed Advertising
  • 0x04: Low Duty Cycle Directed Advertising
  • Direct_Address_Type

    -

    1

    -

    The address type of the peer device.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Direct_Address

    -

    6

    -

    Initiator Bluetooth address

    -

    Advertising_Interval_Min

    -

    2

    -

    Minimum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0006 (3.750 ms) : for High Duty Cycle Directed Advertising
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) : for Low Duty Cycle Directed Advertising
  • Advertising_Interval_Max

    -

    2

    -

    Maximum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0006 (3.750 ms) : for High Duty Cycle Directed Advertising
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms) : for Low Duty Cycle Directed Advertising
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI_LE_CONNECTION_COMPLETE_EVENT
  • ACI_GAP_SET_IO_CAPABILITY

    Description

    Set the IO capabilities of the device. This command has to be given only when the device is not in a connected state.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    IO_Capability

    -

    1

    -

    IO capability of the device.

    -
  • 0x00: IO_CAP_DISPLAY_ONLY
  • 0x01: IO_CAP_DISPLAY_YES_NO
  • 0x02: IO_CAP_KEYBOARD_ONLY
  • 0x03: IO_CAP_NO_INPUT_NO_OUTPUT
  • 0x04: IO_CAP_KEYBOARD_DISPLAY
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_AUTHENTICATION_REQUIREMENT

    Description

    Set the authentication requirements for the device. If the OOB_Enable is set to 0, the following 16 octets of OOB_Data will be ignored on reception. This command has to be given only when the device is not in a connected state.

    Input parameters

    - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Bonding_Mode

    -

    1

    -

    Bonding mode. -Only if bonding is enabled (0x01), the bonding information is stored in flash

    -
  • 0x00: No-bonding mode
  • 0x01: Bonding mode
  • MITM_Mode

    -

    1

    -

    MITM mode.

    -
  • 0x00: MITM protection not required
  • 0x01: MITM protection required
  • SC_Support

    -

    1

    -

    LE Secure connections support

    -
  • 0x00: Secure Connections Pairing not supported
  • 0x01: Secure Connections Pairing supported but optional
  • 0x02: Secure Connections Pairing supported and mandatory (SC Only Mode)
  • KeyPress_Notification_Support

    -

    1

    -

    Keypress notification support

    -
  • 0x00: Keypress notification not supported
  • 0x01: Keypress notification supported
  • Min_Encryption_Key_Size

    -

    1

    -

    Minimum encryption key size to be used during pairing

    -

    Max_Encryption_Key_Size

    -

    1

    -

    Maximum encryption key size to be used during pairing

    -

    Use_Fixed_Pin

    -

    1

    -

    Use or not fixed pin. If set to 0x00, then during the pairing process the application will not be requested for a pin (Fixed_Pin will be used). -If set to 0x01, then during pairing process if a passkey is required the application will be notified

    -
  • 0x00: use a fixed pin
  • 0x01: do not use a fixed pin
  • Fixed_Pin

    -

    4

    -

    Fixed pin to be used during pairing if MIMT protection is enabled. -Any random value between 0 to 999999

    -
  • 0 ... 999999
  • Identity_Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_AUTHORIZATION_REQUIREMENT

    Description

    Set the authorization requirements of the device. This command has to be given when connected to a device if authorization is required to access services which require authorization.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Authorization_Enable

    -

    1

    -

    Enable the authorization in the device and when a remote device tries to read/write a characteristic with authorization requirements, the stack will send back an error response with "Insufficient authorization" error code. After pairing is complete an ACI_GAP_AUTHORIZATION_REQ_EVENT will be sent to the Host.

    -
  • 0x00: Authorization not required
  • 0x01: Authorization required
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_PASS_KEY_RESP

    Description

    This command should be send by the host in response to ACI_GAP_PASS_KEY_REQ_EVENT event. The command parameter contains the pass key which will be used during the pairing process.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Pass_Key

    -

    4

    -

    Pass key that will be used during the pairing process. -Must be a six-digit decimal number.

    -
  • 0 ... 999999
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_PAIRING_COMPLETE_EVENT
  • ACI_GAP_AUTHORIZATION_RESP

    Description

    Authorize a device to access attributes. This command should be send by the host in response to ACI_GAP_AUTHORIZATION_REQ_EVENT event.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Authorize

    -

    1

    -

    Authorization response.

    -
  • 0x01: Authorize
  • 0x02: Reject
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_INIT

    Description

    Initialize the GAP layer. Register the GAP service with the GATT.
    All the standard GAP characteristics will also be added:
    - Device Name
    - Appearance
    - Peripheral Preferred Connection Parameters (peripheral role only).
    Note that if the Peripheral Preferred Connection Parameters characteristic is added, its handle is equal to the Appearance characteristic handle plus 2.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Role

    -

    1

    -

    Bitmap of allowed roles.

    -

    Bitmask of:

  • 0x01: Peripheral
  • 0x02: Broadcaster
  • 0x04: Central
  • 0x08: Observer
  • privacy_enabled

    -

    1

    -

    Specify if privacy is enabled or not and which one .

    -
  • 0x00: Privacy disabled
  • 0x01: Privacy host enabled
  • 0x02: Privacy controller enabled
  • device_name_char_len

    -

    1

    -

    Length of the device name characteristic

    -

    Output parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Service_Handle

    -

    2

    -

    Handle of the GAP service

    -

    Dev_Name_Char_Handle

    -

    2

    -

    Device Name Characteristic handle

    -

    Appearance_Char_Handle

    -

    2

    -

    Appearance Characteristic handle

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_NON_CONNECTABLE

    Description

    Put the device into non connectable mode. This mode does not support connection. The privacy setting done in the ACI_GAP_INIT command plays a role in deciding the valid parameters for this command.
    Advertiser filter policy is internally set to 0.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Advertising_Event_Type

    -

    1

    -

    Advertising type

    -
  • 0x02: ADV_SCAN_IND (Scannable undirected advertising)
  • 0x03: ADV_NONCONN_IND (Non connectable undirected advertising)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_UNDIRECTED_CONNECTABLE

    Description

    Put the device into undirected connectable mode.
    If privacy is enabled in the device, a resolvable private address is generated and used as the advertiser's address. If not, the address of the type specified in own_addr_type is used for advertising.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Advertising_Interval_Min

    -

    2

    -

    Minimum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Advertising_Interval_Max

    -

    2

    -

    Maximum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if Host privacy (i.e. privacy 1.1) is enabled)
  • Adv_Filter_Policy

    -

    1

    -

    Advertising filter policy.

    -
  • 0x00: Allow Scan Request from Any, Allow Connect Request from Any
  • 0x03: Allow Scan Request from White List Only, Allow Connect Request from White List Only
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SLAVE_SECURITY_REQ

    Description

    Send a slave security request to the master.
    This command has to be issued to notify the master of the security requirements of the slave. The master may encrypt the link, initiate the pairing procedure, or reject the request.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GAP_SLAVE_SECURITY_INITIATED_EVENT
  • ACI_GAP_UPDATE_ADV_DATA

    Description

    This command can be used to update the advertising data for a particular AD type. If the AD type specified does not exist, then it is added to the advertising data. If the overall advertising data length is more than 31 octets after the update, then the command is rejected and the old data is retained.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    AdvDataLen

    -

    1

    -

    Length of AdvData in octets

    -

    AdvData

    -

    AdvDataLen

    -

    Advertising data used by the device while advertising.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_DELETE_AD_TYPE

    Description

    This command can be used to delete the specified AD type from the advertisement data if present.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    ADType

    -

    1

    -

    One of the AD types like in Bluetooth specification (see volume 3, Part C, 11.1)

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_GET_SECURITY_LEVEL

    Description

    This command can be used to get the current security settings of the device.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Security_Mode

    -

    1

    -

    Security mode.

    -
  • 0x01: Security Mode 1
  • 0x02: Security Mode 2
  • Security_Level

    -

    1

    -

    Security Level.

    -
  • 0x01: Security Level 1
  • 0x02: Security Level 2
  • 0x03: Security Level 3
  • 0x04: Security Level 4
  • Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_EVENT_MASK

    Description

    It allows masking events from the GAP. The default configuration is all the events masked.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    GAP_Evt_Mask

    -

    2

    -

    GAP event mask. Default: 0xFFFF.

    -

    Bitmask of:

  • 0x0000: No events
  • 0x0001: ACI_GAP_LIMITED_DISCOVERABLE_EVENT
  • 0x0002: ACI_GAP_PAIRING_COMPLETE_EVENT
  • 0x0004: ACI_GAP_PASS_KEY_REQ_EVENT
  • 0x0008: ACI_GAP_AUTHORIZATION_REQ_EVENT
  • 0x0010: ACI_GAP_SLAVE_SECURITY_INITIATED_EVENT
  • 0x0020: ACI_GAP_BOND_LOST_EVENT
  • 0x0080: ACI_GAP_PROC_COMPLETE_EVENT
  • 0x0100: ACI_L2CAP_CONNECTION_UPDATE_REQ_EVENT
  • 0x0200: ACI_L2CAP_CONNECTION_UPDATE_RESP_EVENT
  • 0x0400: ACI_L2CAP_PROC_TIMEOUT_EVENT
  • 0x0800: ACI_GAP_ADDR_NOT_RESOLVED_EVENT
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_CONFIGURE_WHITELIST

    Description

    Add addresses of bonded devices into the controller's whitelist.
    The command returns an error if it was unable to add the bonded devices into the whitelist.

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_TERMINATE

    Description

    Command the controller to terminate the connection. A HCI_DISCONNECTION_COMPLETE_EVENT event is generated when the link is disconnected.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Reason

    -

    1

    -

    The reason for ending the connection.

    -
  • 0x05: Authentication Failure
  • 0x13: Remote User Terminated Connection
  • 0x14: Remote Device Terminated Connection due to Low Resources
  • 0x15: Remote Device Terminated Connection due to Power Off
  • 0x1A: Unsupported Remote Feature
  • 0x3B: Unacceptable Connection Parameters
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_DISCONNECTION_COMPLETE_EVENT
  • ACI_GAP_CLEAR_SECURITY_DB

    Description

    Clear the security database. All the devices in the security database are removed.

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_ALLOW_REBOND

    Description

    Allows the security manager to complete the pairing procedure and re-bond with the master. This command should be given by the application when it receives the ACI_GAP_BOND_LOST_EVENT if it wants the re-bonding to happen successfully. If this command is not given on receiving the event, the bonding procedure will timeout.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_START_LIMITED_DISCOVERY_PROC

    Description

    Start the limited discovery procedure. The controller is commanded to start active scanning.
    When this procedure is started, only the devices in limited discoverable mode are returned to the upper layers.
    The procedure is terminated when either the upper layers issue a command to terminate the procedure by issuing the command ACI_GAP_TERMINATE_GAP_PROC with the procedure code set to 0x01 or a timeout happens (the timeout value is fixed at 10.24 s.). When the procedure is terminated due to any of the above reasons, ACI_GAP_PROC_COMPLETE_EVENT event is returned with the procedure code set to 0x01.
    The device found when the procedure is ongoing is returned to the upper layers through the event HCI_LE_ADVERTISING_REPORT_EVENT.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Filter_Duplicates

    -

    1

    -

    Enable/disable duplicate filtering.

    -
  • 0x00: Duplicate filtering disabled
  • 0x01: Duplicate filtering enabled
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_ADVERTISING_REPORT_EVENT
  • ACI_GAP_PROC_COMPLETE_EVENT
  • ACI_GAP_START_GENERAL_DISCOVERY_PROC

    Description

    Start the general discovery procedure. The controller is commanded to start active scanning. The procedure is terminated when either the upper layers issue a command to terminate the procedure by issuing the command ACI_GAP_TERMINATE_GAP_PROC with the procedure code set to 0x02 or a timeout happens (the timeout value is fixed at 10.24 s.). When the procedure is terminated due to any of the above reasons, ACI_GAP_PROC_COMPLETE_EVENT event is returned with the procedure code set to 0x02. The device found when the procedure is ongoing is returned to HCI_LE_ADVERTISING_REPORT_EVENT.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Filter_Duplicates

    -

    1

    -

    Enable/disable duplicate filtering.

    -
  • 0x00: Duplicate filtering disabled
  • 0x01: Duplicate filtering enabled
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_ADVERTISING_REPORT_EVENT
  • ACI_GAP_PROC_COMPLETE_EVENT
  • ACI_GAP_START_NAME_DISCOVERY_PROC

    Description

    Start the name discovery procedure. A LE_Create_Connection call will be made to the controller by GAP with the initiator filter policy set to "ignore whitelist and process connectable advertising packets only for the specified device". Once a connection is established, GATT procedure is started to read the device name characteristic. When the read is completed (successfully or unsuccessfully), a ACI_GAP_PROC_COMPLETE_EVENT event is given to the upper layer. The event also contains the name of the device if the device name was read successfully.

    Input parameters

    - - - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Peer_Address_Type

    -

    1

    -

    Address type.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Peer_Address

    -

    6

    -

    Public Device Address or Random Device Address of the device to be connected.

    -

    Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Conn_Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • Minimum_CE_Length

    -

    2

    -

    Information parameter about the minimum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Maximum_CE_Length

    -

    2

    -

    Information parameter about the maximum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GAP_PROC_COMPLETE_EVENT
  • ACI_GAP_START_AUTO_CONNECTION_ESTABLISH_PROC

    Description

    Start the auto connection establishment procedure. The devices specified are added to the white list of the controller and a LE_Create_Connection call will be made to the controller by GAP with the initiator filter policy set to "use whitelist to determine which advertiser to connect to". When a command is issued to terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller by GAP.
    The procedure is terminated when either a connection is successfully established with one of the specified devices in the white list or the procedure is explicitly terminated by issuing the command ACI_GAP_TERMINATE_GAP_PROC with the procedure code set to 0x08. A ACI_GAP_PROC_COMPLETE_EVENT event is returned with the procedure code set to 0x08.
    If controller privacy is enabled and the peer device (advertiser) is in the resolving list then the link layer will generate a RPA, if it is not then the RPA/NRPA generated by the Host will be used.

    Input parameters

    - - - - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Conn_Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • Minimum_CE_Length

    -

    2

    -

    Information parameter about the minimum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Maximum_CE_Length

    -

    2

    -

    Information parameter about the maximum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Num_of_Whitelist_Entries

    -

    1

    -

    Number of devices that have to be added to the whitelist.

    -

    Peer_Address_Type[i]

    -

    1

    -

    Address type.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Peer_Address[i]

    -

    6

    -

    Public Device Address or Random Device Address.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GAP_PROC_COMPLETE_EVENT
  • ACI_GAP_START_GENERAL_CONNECTION_ESTABLISH_PROC

    Description

    Start a general connection establishment procedure. The host enables scanning in the controller with the scanner filter policy set to "accept all advertising packets" and from the scanning results, all the devices are sent to the upper layer using the event LE_Advertising_Report. The upper layer then has to select one of the devices to which it wants to connect by issuing the command ACI_GAP_CREATE_CONNECTION. If privacy is enabled, then either a private resolvable address or a non resolvable address, based on the address type specified in the command is set as the scanner address but the gap create connection always uses a private resolvable address if the general connection establishment procedure is active.
    The procedure is terminated when a connection is established or the upper layer terminates the procedure by issuing the command ACI_GAP_TERMINATE_GAP_PROC with the procedure code set to 0x10. On completion of the procedure a ACI_GAP_PROC_COMPLETE_EVENT event is generated with the procedure code set to 0x10.
    If controller privacy is enabled and the peer device (advertiser) is in the resolving list then the link layer will generate a RPA, if it is not then the RPA/NRPA generated by the Host will be used.

    Input parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Type

    -

    1

    -

    Passive or active scanning. With active scanning SCAN_REQ packets are sent.

    -
  • 0x00: Passive Scanning
  • 0x01: Active scanning
  • LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Scanning_Filter_Policy

    -

    1

    -
    -
    Scanning filter policy:
    -
      -
    • 0x00 Accept all advertisement packets.Directed advertising packets which are not addressed for this device shall be ignored.
    • -
    • 0x01 Ignore advertisement packets from devices not in the White List Only.Directed advertising packets which are not addressed for this device shall be ignored.
    • -
    • 0x02 Accept all undirected advertisement packets (it is allowed only if controller privacy or host privacy is enabled).Directed advertisement packets where initiator address is a RPA and Directed advertisement packets addressed to this device shall be accepted.
    • -
    • 0x03 Accept all undirected advertisement packets from devices that are in the White List.Directed advertisement packets where initiator address is RPA and Directed advertisement packets addressed to this device shall be accepted.
    • -
    • NOTE: if controller privacy is enabled Scanning_Filter_Policy can only assume values 0x00 or 0x02; if Host privacy is enabled Scanning_Filter_Policy can only assume value 0x00.
    • -
    -
    -
    -
  • 0x00: Accept all
  • 0x01: Ignore devices not in the White List
  • 0x02: Accept all (use resolving list)
  • 0x03: Ignore devices not in the White List (use resolving list)
  • Filter_Duplicates

    -

    1

    -

    Enable/disable duplicate filtering.

    -
  • 0x00: Duplicate filtering disabled
  • 0x01: Duplicate filtering enabled
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GAP_PROC_COMPLETE_EVENT
  • ACI_GAP_START_SELECTIVE_CONNECTION_ESTABLISH_PROC

    Description

    Start a selective connection establishment procedure. The GAP adds the specified device addresses into white list and enables scanning in the controller with the scanner filter policy set to "accept packets only from devices in whitelist". All the devices found are sent to the upper layer by the event HCI_LE_ADVERTISING_REPORT_EVENT. The upper layer then has to select one of the devices to which it wants to connect by issuing the command ACI_GAP_CREATE_CONNECTION.
    On completion of the procedure a ACI_GAP_PROC_COMPLETE_EVENT event is generated with the procedure code set to 0x20. The procedure is terminated when a connection is established or the upper layer terminates the procedure by issuing the command ACI_GAP_TERMINATE_GAP_PROC with the procedure code set to 0x20.
    If controller privacy is enabled and the peer device (advertiser) is in the resolving list then the link layer will generate a RPA, if it is not then the RPA/NRPA generated by the Host will be used.

    Input parameters

    - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Type

    -

    1

    -

    Passive or active scanning. With active scanning SCAN_REQ packets are sent.

    -
  • 0x00: Passive Scanning
  • 0x01: Active scanning
  • LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Scanning_Filter_Policy

    -

    1

    -
    -
    Scanning filter policy:
    -
      -
    • 0x00 Accept all advertisement packets.Directed advertising packets which are not addressed for this device shall be ignored.
    • -
    • 0x01 Ignore advertisement packets from devices not in the White List Only.Directed advertising packets which are not addressed for this device shall be ignored.
    • -
    • 0x02 Accept all undirected advertisement packets (it is allowed only if controller privacy or host privacy is enabled).Directed advertisement packets where initiator address is a RPA and Directed advertisement packets addressed to this device shall be accepted.
    • -
    • 0x03 Accept all undirected advertisement packets from devices that are in the White List.Directed advertisement packets where initiator address is RPA and Directed advertisement packets addressed to this device shall be accepted.
    • -
    • NOTE: if controller privacy is enabled Scanning_Filter_Policy can only assume values 0x01 or 0x03; if Host privacy is enabled Scanning_Filter_Policy can only assume value 0x01.
    • -
    -
    -
    -
  • 0x00: Accept all
  • 0x01: Ignore devices not in the White List
  • 0x02: Accept all (use resolving list)
  • 0x03: Ignore devices not in the White List (use resolving list)
  • Filter_Duplicates

    -

    1

    -

    Enable/disable duplicate filtering.

    -
  • 0x00: Duplicate filtering disabled
  • 0x01: Duplicate filtering enabled
  • Num_of_Whitelist_Entries

    -

    1

    -

    Number of devices that have to be added to the whitelist.

    -

    Peer_Address_Type[i]

    -

    1

    -

    Address type.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Peer_Address[i]

    -

    6

    -

    Public Device Address or Random Device Address.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GAP_PROC_COMPLETE_EVENT
  • ACI_GAP_CREATE_CONNECTION

    Description

    Start the direct connection establishment procedure. A LE_Create_Connection call will be made to the controller by GAP with the initiator filter policy set to "ignore whitelist and process connectable advertising packets only for the specified device". The procedure can be terminated explicitly by the upper layer by issuing the command ACI_GAP_TERMINATE_GAP_PROC. When a command is issued to terminate the procedure by upper layer, a HCI_LE_CREATE_CONNECTION_CANCEL call will be made to the controller by GAP.
    On termination of the procedure, a HCI_LE_CONNECTION_COMPLETE_EVENT event is returned. The procedure can be explicitly terminated by the upper layer by issuing the command ACI_GAP_TERMINATE_GAP_PROC with the procedure_code set to 0x40.
    If controller privacy is enabled and the peer device (advertiser) is in the resolving list then the link layer will generate a RPA, if it is not then the RPA/NRPA generated by the Host will be used.

    Input parameters

    - - - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • Peer_Address_Type

    -

    1

    -

    The address type of the peer device.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Peer_Address

    -

    6

    -

    Public Device Address or Random Device Address of the device to be connected.

    -

    Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Conn_Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • Minimum_CE_Length

    -

    2

    -

    Information parameter about the minimum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Maximum_CE_Length

    -

    2

    -

    Information parameter about the maximum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_CONNECTION_COMPLETE_EVENT
  • ACI_GAP_TERMINATE_GAP_PROC

    Description

    Terminate the specified GAP procedure. An ACI_GAP_PROC_COMPLETE_EVENT event is returned with the procedure code set to the corresponding procedure.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Procedure_Code

    -

    1

    -

    GAP procedure bitmap.

    -
  • 0x00: No events
  • 0x01: GAP_LIMITED_DISCOVERY_PROC
  • 0x02: GAP_GENERAL_DISCOVERY_PROC
  • 0x04: GAP_NAME_DISCOVERY_PROC
  • 0x08: GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC
  • 0x10: GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC
  • 0x20: GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC
  • 0x40: GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC
  • 0x80: GAP_OBSERVATION_PROC
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_PROC_COMPLETE_EVENT
  • ACI_GAP_START_CONNECTION_UPDATE

    Description

    Start the connection update procedure (only when role is Master). A HCI_LE_CONNECTION_UPDATE is called.
    On completion of the procedure, an HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT event is returned to the upper layer.

    Input parameters

    - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Conn_Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • Minimum_CE_Length

    -

    2

    -

    Information parameter about the minimum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Maximum_CE_Length

    -

    2

    -

    Information parameter about the maximum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT
  • ACI_GAP_SEND_PAIRING_REQ

    Description

    Send the SM pairing request to start a pairing process. The authentication requirements and IO capabilities should be set before issuing this command using the ACI_GAP_SET_IO_CAPABILITY and ACI_GAP_SET_AUTHENTICATION_REQUIREMENT commands.
    A ACI_GAP_PAIRING_COMPLETE_EVENT event is returned after the pairing process is completed.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Force_Rebond

    -

    1

    -
    -
    If 1, Pairing request will be sent even if the device was previously bonded,
    -
    otherwise pairing request is not sent.
    -
    -
  • 0x00: NO
  • 0x01: YES
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GAP_PAIRING_COMPLETE_EVENT
  • ACI_GAP_RESOLVE_PRIVATE_ADDR

    Description

    This command tries to resolve the address provided with the IRKs present in its database. If the address is resolved successfully with any one of the IRKs present in the database, it returns success and also the corresponding public/static random address stored with the IRK in the database.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Address

    -

    6

    -

    Address to be resolved

    -

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Actual_Address

    -

    6

    -

    The public or static random address of the peer device, distributed during pairing phase.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_BROADCAST_MODE

    Description

    This command puts the device into broadcast mode. A privacy enabled device uses either a resolvable private address or a non-resolvable private address as specified in the Own_Addr_Type parameter of the command.

    Input parameters

    - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Advertising_Interval_Min

    -

    2

    -

    Minimum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Advertising_Interval_Max

    -

    2

    -

    Maximum advertising interval. -Time = N * 0.625 msec.

    -
  • 0x0020 (20.000 ms) ... 0x4000 (10240.000 ms)
  • Advertising_Type

    -

    1

    -

    Advertising type

    -
  • 0x02: ADV_SCAN_IND (Scannable undirected advertising)
  • 0x03: ADV_NONCONN_IND (Non connectable undirected advertising)
  • Own_Address_Type

    -

    1

    -

    If Privacy is disabled, then the address can be public or static random. -If Privacy is enabled, then the address can be a resolvable private address or a non-resolvable private address.

    -
  • 0x00: Public address
  • 0x01: Static random address
  • 0x02: Resolvable private address
  • 0x03: Non-resolvable private address
  • Adv_Data_Length

    -

    1

    -

    Length of the advertising data in the advertising packet.

    -

    Adv_Data

    -

    Adv_Data_Length

    -

    Advertising data used by the device while advertising.

    -

    Num_of_Whitelist_Entries

    -

    1

    -

    Number of devices that have to be added to the whitelist.

    -

    Peer_Address_Type[i]

    -

    1

    -

    Address type.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Peer_Address[i]

    -

    6

    -

    Public Device Address or Random Device Address.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_START_OBSERVATION_PROC

    Description

    Starts an Observation procedure, when the device is in Observer Role. The host enables scanning in the controller. The advertising reports are sent to the upper layer using standard LE Advertising Report Event. (See Bluetooth Core v5.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event).
    If controller privacy is enabled and the peer device (advertiser) is in the resolving list then the link layer will generate a RPA, if it is not then the RPA/NRPA generated by the Host will be used.

    Input parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    LE_Scan_Interval

    -

    2

    -

    This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Window

    -

    2

    -

    Amount of time for the duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval. -Time = N * 0.625 msec.

    -
  • 0x0004 (2.500 ms) ... 0x4000 (10240.000 ms)
  • LE_Scan_Type

    -

    1

    -

    Passive or active scanning. With active scanning SCAN_REQ packets are sent.

    -
  • 0x00: Passive Scanning
  • 0x01: Active scanning
  • Own_Address_Type

    -

    1

    -

    Own address type

    -
  • 0x00: Public Device Address -(only if privacy is disabled)
  • 0x01: Random Device Address -(only if privacy is disabled)
  • 0x02: Resolvable Private Address -(only if privacy is enabled)
  • 0x03: Non Resolvable Private Address -(only if privacy is enabled)
  • Filter_Duplicates

    -

    1

    -

    Enable/disable duplicate filtering.

    -
  • 0x00: Duplicate filtering disabled
  • 0x01: Duplicate filtering enabled
  • Scanning_Filter_Policy

    -

    1

    -
    -
    Scanning filter policy:
    -
      -
    • 0x00 Accept all advertisement packets (it is allowed only if controller privacy is enabled).Directed advertising packets which are not addressed for this device shall be ignored.
    • -
    • 0x01 Ignore advertisement packets from devices not in the White List Only.Directed advertising packets which are not addressed for this device shall be ignored.
    • -
    • 0x02 Accept all undirected advertisement packets (it is allowed only if controller privacy or host privacy is enabled).Directed advertisement packets where initiator address is a RPA and Directed advertisement packets addressed to this device shall be accepted.
    • -
    • 0x03 Accept all undirected advertisement packets from devices that are in the White List.Directed advertisement packets where initiator address is RPA and Directed advertisement packets addressed to this device shall be accepted.
    • -
    • NOTE: If Host privacy is enabled Scanning_Filter_Policy can only take values 0x00 or 0x01;
    • -
    -
    -
    -
  • 0x00: Accept all
  • 0x01: Ignore devices not in the White List
  • 0x02: Accept all (use resolving list)
  • 0x03: Ignore devices not in the White List (use resolving list)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • HCI_LE_ADVERTISING_REPORT_EVENT
  • ACI_GAP_GET_BONDED_DEVICES

    Description

    This command gets the list of the devices which are bonded. It returns the number of addresses and the corresponding address types and values.

    Input parameters

    None

    Output parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Num_of_Addresses

    -

    1

    -

    The number of bonded devices

    -

    Address_Type[i]

    -

    1

    -

    Address type.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Address[i]

    -

    6

    -

    Public Device Address or Random Device Address.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_IS_DEVICE_BONDED

    Description

    The command finds whether the device, whose address is specified in the command, is bonded. If the device is using a resolvable private address and it has been bonded, then the command will return BLE_STATUS_SUCCESS.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Peer_Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Peer_Address

    -

    6

    -

    Public or Random (static) Identity address of the peer device

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO

    Description

    This command allows the User to validate/confirm or not the Numeric Comparison value showed through the ACI_GAP_Numeric_Comparison_Value_Event.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Confirm_Yes_No

    -

    1

    -

    0 : The Numeric Values showed on both local and peer device are different! -1 : The Numeric Values showed on both local and peer device are equal!

    -
  • 0x00: No
  • 0x01: YES
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_PASSKEY_INPUT

    Description

    This command permits to signal to the Stack the input type detected during Passkey input.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Input_Type

    -

    1

    -

    Passkey input type detected

    -
  • 0x00: Passkey entry started
  • 0x01: Passkey digit entered
  • 0x02: Passkey digit erased
  • 0x03: Passkey cleared
  • 0x04: Passkey entry completed
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_GET_OOB_DATA

    Description

    This command is sent by the User to get (i.e. to extract from the Stack) the OOB data generated by the Stack itself.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    OOB_Data_Type

    -

    1

    -

    OOB Data type

    -
  • 0x00: TK (LP v.4.1)
  • 0x01: Random (SC v.4.2)
  • 0x02: Confirm (SC v.4.2)
  • Output parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Address

    -

    6

    -

    Public or Random (static) address of this device

    -

    OOB_Data_Type

    -

    1

    -

    OOB Data type

    -
  • 0x00: TK (LP v.4.1)
  • 0x01: Random (SC v.4.2)
  • 0x02: Confirm (SC v.4.2)
  • OOB_Data_Len

    -

    1

    -

    Length of OOB Data

    -

    OOB_Data

    -

    16

    -

    Local Pairing Data intended to the remote device to be sent via OOB.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_SET_OOB_DATA

    Description

    This command is sent (by the User) to input the OOB data arrived via OOB communication.

    Input parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Device_Type

    -

    1

    -

    OOB Device type

    -
  • 0x00: Local device
  • 0x01: Remote device
  • Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Address

    -

    6

    -

    Public or Random (static) address of the peer device

    -

    OOB_Data_Type

    -

    1

    -

    OOB Data type

    -
  • 0x00: TK (LP v.4.1)
  • 0x01: Random (SC v.4.2)
  • 0x02: Confirm (SC v.4.2)
  • OOB_Data_Len

    -

    1

    -

    Length of OOB Data

    -

    OOB_Data

    -

    16

    -

    Pairing Data received through OOB from remote device

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_ADD_DEVICES_TO_RESOLVING_LIST

    Description

    This command is used to add one device to the list of address translations used to resolve Resolvable Private Addresses in the Controller.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Num_of_Resolving_list_Entries

    -

    1

    -

    Number of devices that have to be added to the resolving list.

    -

    Peer_Identity_Address_Type[i]

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Peer_Identity_Address[i]

    -

    6

    -

    Public or Random (static) Identity address of the peer device

    -

    Clear_Resolving_List

    -

    1

    -

    Clear the resolving list

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GAP_REMOVE_BONDED_DEVICE

    Description

    This command is used to remove a specified device from bonding table

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Peer_Identity_Address_Type

    -

    1

    -

    Identity address type.

    -
  • 0x00: Public Identity Address
  • 0x01: Random (static) Identity Address
  • Peer_Identity_Address

    -

    6

    -

    Public or Random (static) Identity address of the peer device

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI GATT/ATT commands

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    CommandOpcodeBFPOLOBO
    ACI_GATT_INIT

    0xFD01

    -

    Y

    -

    Y

    -
    ACI_GATT_ADD_SERVICE

    0xFD02

    -

    Y

    -

    Y

    -
    ACI_GATT_INCLUDE_SERVICE

    0xFD03

    -

    Y

    -

    Y

    -
    ACI_GATT_ADD_CHAR

    0xFD04

    -

    Y

    -

    Y

    -
    ACI_GATT_ADD_CHAR_DESC

    0xFD05

    -

    Y

    -

    Y

    -
    ACI_GATT_UPDATE_CHAR_VALUE

    0xFD06

    -

    Y

    -

    Y

    -
    ACI_GATT_DEL_CHAR

    0xFD07

    -

    Y

    -

    Y

    -
    ACI_GATT_DEL_SERVICE

    0xFD08

    -

    Y

    -

    Y

    -
    ACI_GATT_DEL_INCLUDE_SERVICE

    0xFD09

    -

    Y

    -

    Y

    -
    ACI_GATT_SET_EVENT_MASK

    0xFD0A

    -

    Y

    -

    Y

    -
    ACI_GATT_EXCHANGE_CONFIG

    0xFD0B

    -

    Y

    -
    ACI_ATT_FIND_INFO_REQ

    0xFD0C

    -

    Y

    -
    ACI_ATT_FIND_BY_TYPE_VALUE_REQ

    0xFD0D

    -

    Y

    -
    ACI_ATT_READ_BY_TYPE_REQ

    0xFD0E

    -

    Y

    -
    ACI_ATT_READ_BY_GROUP_TYPE_REQ

    0xFD0F

    -

    Y

    -
    ACI_ATT_PREPARE_WRITE_REQ

    0xFD10

    -

    Y

    -
    ACI_ATT_EXECUTE_WRITE_REQ

    0xFD11

    -

    Y

    -
    ACI_GATT_DISC_ALL_PRIMARY_SERVICES

    0xFD12

    -

    Y

    -
    ACI_GATT_DISC_PRIMARY_SERVICE_BY_UUID

    0xFD13

    -

    Y

    -
    ACI_GATT_FIND_INCLUDED_SERVICES

    0xFD14

    -

    Y

    -
    ACI_GATT_DISC_ALL_CHAR_OF_SERVICE

    0xFD15

    -

    Y

    -
    ACI_GATT_DISC_CHAR_BY_UUID

    0xFD16

    -

    Y

    -
    ACI_GATT_DISC_ALL_CHAR_DESC

    0xFD17

    -

    Y

    -
    ACI_GATT_READ_CHAR_VALUE

    0xFD18

    -

    Y

    -
    ACI_GATT_READ_USING_CHAR_UUID

    0xFD19

    -

    Y

    -
    ACI_GATT_READ_LONG_CHAR_VALUE

    0xFD1A

    -

    Y

    -
    ACI_GATT_READ_MULTIPLE_CHAR_VALUE

    0xFD1B

    -

    Y

    -
    ACI_GATT_WRITE_CHAR_VALUE

    0xFD1C

    -

    Y

    -
    ACI_GATT_WRITE_LONG_CHAR_VALUE

    0xFD1D

    -

    Y

    -
    ACI_GATT_WRITE_CHAR_RELIABLE

    0xFD1E

    -

    Y

    -
    ACI_GATT_WRITE_LONG_CHAR_DESC

    0xFD1F

    -

    Y

    -
    ACI_GATT_READ_LONG_CHAR_DESC

    0xFD20

    -

    Y

    -
    ACI_GATT_WRITE_CHAR_DESC

    0xFD21

    -

    Y

    -
    ACI_GATT_READ_CHAR_DESC

    0xFD22

    -

    Y

    -
    ACI_GATT_WRITE_WITHOUT_RESP

    0xFD23

    -

    Y

    -
    ACI_GATT_SIGNED_WRITE_WITHOUT_RESP

    0xFD24

    -

    Y

    -
    ACI_GATT_CONFIRM_INDICATION

    0xFD25

    -

    Y

    -
    ACI_GATT_WRITE_RESP

    0xFD26

    -

    Y

    -

    Y

    -
    ACI_GATT_ALLOW_READ

    0xFD27

    -

    Y

    -

    Y

    -
    ACI_GATT_SET_SECURITY_PERMISSION

    0xFD28

    -

    Y

    -

    Y

    -
    ACI_GATT_SET_DESC_VALUE

    0xFD29

    -

    Y

    -

    Y

    -
    ACI_GATT_READ_HANDLE_VALUE

    0xFD2A

    -

    Y

    -

    Y

    -
    ACI_GATT_UPDATE_CHAR_VALUE_EXT

    0xFD2C

    -

    Y

    -

    Y

    -
    ACI_GATT_DENY_READ

    0xFD2D

    -

    Y

    -

    Y

    -
    ACI_GATT_SET_ACCESS_PERMISSION

    0xFD2E

    -

    Y

    -

    Y

    -

    ACI_GATT_INIT

    Description

    Initialize the GATT layer for server and client roles. It adds also the GATT service with Service Changed Characteristic.
    Until this command is issued the GATT channel does not process any commands even if the connection is opened. This command has to be given before using any of the GAP features.

    Input parameters

    None

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_ADD_SERVICE

    Description

    Add a service to GATT Server. When a service is created in the server, the host needs to reserve the handle ranges for this service using Max_Attribute_Records parameter. This parameter specifies the maximum number of attribute records that can be added to this service (including the service attribute, include attribute, characteristic attribute, characteristic value attribute and characteristic descriptor attribute). Handle of the created service is returned in command complete event. Service declaration is taken from the service pool.
    The attributes for characteristics and descriptors are allocated from the attribute pool.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Service_UUID_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    Service_UUID

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Service_Type

    -

    1

    -

    Service type.

    -
  • 0x01: Primary Service
  • 0x02: Secondary Service
  • Max_Attribute_Records

    -

    1

    -

    Maximum number of attribute records that can be added to this service

    -

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Service_Handle

    -

    2

    -

    Handle of the Service. -When this service is added, a handle is allocated by the server for this service. -Server also allocates a range of handles for this service from serviceHandle to <serviceHandle + max_attr_records - 1>

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_INCLUDE_SERVICE

    Description

    Include a service given by Include_Start_Handle and Include_End_Handle to another service given by Service_Handle. Attribute server creates an INCLUDE definition attribute and return the handle of this attribute in Included_handle.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Service_Handle

    -

    2

    -

    Handle of the Service to which another service has to be included.

    -

    Include_Start_Handle

    -

    2

    -

    Start Handle of the Service which has to be included in service

    -

    Include_End_Handle

    -

    2

    -

    End Handle of the Service which has to be included in service

    -

    Include_UUID_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    Include_UUID

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Include_Handle

    -

    2

    -

    Handle of the include declaration

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_ADD_CHAR

    Description

    Add a characteristic to a service.

    Input parameters

    - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Service_Handle

    -

    2

    -

    Handle of the Service to which the characteristic will be added

    -

    Char_UUID_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    Char_UUID

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Char_Value_Length

    -

    2

    -

    Maximum length of the characteristic value.

    -

    Char_Properties

    -

    1

    -

    Characteristic Properties (Volume 3, Part G, section 3.3.1.1 of Bluetooth Specification 5.0)

    -

    Bitmask of:

  • 0x00: CHAR_PROP_NONE
  • 0x01: CHAR_PROP_BROADCAST (Broadcast)
  • 0x02: CHAR_PROP_READ (Read)
  • 0x04: CHAR_PROP_WRITE_WITHOUT_RESP (Write w/o resp)
  • 0x08: CHAR_PROP_WRITE (Write)
  • 0x10: CHAR_PROP_NOTIFY (Notify)
  • 0x20: CHAR_PROP_INDICATE (Indicate)
  • 0x40: CHAR_PROP_SIGNED_WRITE (Authenticated Signed Writes)
  • 0x80: CHAR_PROP_EXT (Extended Properties)
  • Security_Permissions

    -

    1

    -

    Security permission flags.

    -

    Bitmask of:

  • 0x00: None
  • 0x01: AUTHEN_READ (Need authentication to read)
  • 0x02: AUTHOR_READ (Need authorization to read)
  • 0x04: ENCRY_READ (Need encryption to read)
  • 0x08: AUTHEN_WRITE (need authentication to write)
  • 0x10: AUTHOR_WRITE (need authorization to write)
  • 0x20: ENCRY_WRITE (need encryption to write)
  • GATT_Evt_Mask

    -

    1

    -

    GATT event mask.

    -

    Bitmask of:

  • 0x00: GATT_DONT_NOTIFY_EVENTS
  • 0x01: GATT_NOTIFY_ATTRIBUTE_WRITE
  • 0x02: GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP
  • 0x04: GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP
  • Enc_Key_Size

    -

    1

    -

    Minimum encryption key size required to read the characteristic.

    -
  • 0x07 ... 0x10
  • Is_Variable

    -

    1

    -

    Specify if the characteristic value has a fixed length or -a variable length.

    -
  • 0x00: Fixed length
  • 0x01: Variable length
  • Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Char_Handle

    -

    2

    -

    Handle of the characteristic that has been added (it is the handle of the characteristic declaration). -The attribute that holds the characteristic value is allocated at the next handle, followed by the Client Characteristic Configuration descriptor if the characteristic has CHAR_PROP_NOTIFY or CHAR_PROP_INDICATE properties.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_ADD_CHAR_DESC

    Description

    Add a characteristic descriptor to a service.

    Input parameters

    - - - - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Service_Handle

    -

    2

    -

    Handle of service to which the characteristic belongs

    -

    Char_Handle

    -

    2

    -

    Handle of the characteristic to which description has to be added

    -

    Char_Desc_Uuid_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    Char_Desc_Uuid

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Char_Desc_Value_Max_Len

    -

    1

    -

    The maximum length of the descriptor value

    -

    Char_Desc_Value_Length

    -

    1

    -

    Current Length of the characteristic descriptor value

    -

    Char_Desc_Value

    -

    Char_Desc_Value_Length

    -

    Value of the characteristic description

    -

    Security_Permissions

    -

    1

    -

    Security permission flags.

    -

    Bitmask of:

  • 0x00: None
  • 0x01: AUTHEN_READ (Need authentication to read)
  • 0x02: AUTHOR_READ (Need authorization to read)
  • 0x04: ENCRY_READ (Need encryption to read)
  • 0x08: AUTHEN_WRITE (need authentication to write)
  • 0x10: AUTHOR_WRITE (need authorization to write)
  • 0x20: ENCRY_WRITE (need encryption to write)
  • Access_Permissions

    -

    1

    -

    Access permission

    -

    Bitmask of:

  • 0x00: None
  • 0x01: READ
  • 0x02: WRITE
  • 0x04: WRITE_WO_RESP
  • 0x08: SIGNED_WRITE
  • GATT_Evt_Mask

    -

    1

    -

    GATT event mask.

    -

    Bitmask of:

  • 0x00: GATT_DONT_NOTIFY_EVENTS
  • 0x01: GATT_NOTIFY_ATTRIBUTE_WRITE
  • 0x02: GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP
  • 0x04: GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP
  • Enc_Key_Size

    -

    1

    -

    Minimum encryption key size required to read the characteristic.

    -
  • 0x07 ... 0x10
  • Is_Variable

    -

    1

    -

    Specify if the characteristic value has a fixed length or -a variable length.

    -
  • 0x00: Fixed length
  • 0x01: Variable length
  • Output parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Char_Desc_Handle

    -

    2

    -

    Handle of the characteristic descriptor

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_UPDATE_CHAR_VALUE

    Description

    Update a characteristic value in a service. If notifications (or indications) are enabled on that characteristic, a notification (or indication) is sent to the client after sending this command. The command is queued into the STM32WB command queue.
    If the buffer is full, because previous commands could not be still processed, the function will return BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or indications) are enabled and the application calls ACI_GATT_UPDATE_CHAR_VALUE at an higher rate than what is allowed by the link.
    Throughput on BLE link depends on connection interval and connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() for more info on how to suggest new connection parameters from a slave). If the application does not want to lose notifications because STM32WB buffer becomes full, it has to retry again till the function returns BLE_STATUS_SUCCESS or any other error code.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Service_Handle

    -

    2

    -

    Handle of service to which the characteristic belongs

    -

    Char_Handle

    -

    2

    -

    Handle of the characteristic declaration

    -

    Val_Offset

    -

    1

    -

    The offset from which the attribute value has to be updated. -If this is set to 0 and the attribute value is of variable length, then the length of the attribute will be set to the Char_Value_Length. -If the Val_Offset is set to a value greater than 0, then the length of the attribute will be set to the maximum length as specified for the attribute while adding the characteristic.

    -

    Char_Value_Length

    -

    1

    -

    Length of the characteristic value in octets

    -

    Char_Value

    -

    Char_Value_Length

    -

    Characteristic value

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_DEL_CHAR

    Description

    Delete the specified characteristic from the service.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Serv_Handle

    -

    2

    -

    Handle of service to which the characteristic belongs

    -

    Char_Handle

    -

    2

    -

    Handle of the characteristic which has to be deleted

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_DEL_SERVICE

    Description

    Delete the specified service from the GATT server database.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Serv_Handle

    -

    2

    -

    Handle of the service to be deleted

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_DEL_INCLUDE_SERVICE

    Description

    Delete the Include definition from the service.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Serv_Handle

    -

    2

    -

    Handle of the service to which the include service belongs

    -

    Include_Handle

    -

    2

    -

    Handle of the included service which has to be deleted

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_SET_EVENT_MASK

    Description

    Mask events from the GATT. The default configuration is all the events masked.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    GATT_Evt_Mask

    -

    4

    -

    GATT/ATT event mask.

    -
  • 0x00000001: ACI_GATT_ATTRIBUTE_MODIFIED_EVENT
  • 0x00000002: ACI_GATT_PROC_TIMEOUT_EVENT
  • 0x00000004: ACI_ATT_EXCHANGE_MTU_RESP_EVENT
  • 0x00000008: ACI_ATT_FIND_INFO_RESP_EVENT
  • 0x00000010: ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT
  • 0x00000020: ACI_ATT_READ_BY_TYPE_RESP_EVENT
  • 0x00000040: ACI_ATT_READ_RESP_EVENT
  • 0x00000080: ACI_ATT_READ_BLOB_RESP_EVENT
  • 0x00000100: ACI_ATT_READ_MULTIPLE_RESP_EVENT
  • 0x00000200: ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT
  • 0x00000800: ACI_ATT_PREPARE_WRITE_RESP_EVENT
  • 0x00001000: ACI_ATT_EXEC_WRITE_RESP_EVENT
  • 0x00002000: ACI_GATT_INDICATION_EVENT
  • 0x00004000: ACI_GATT_NOTIFICATION_EVENT
  • 0x00008000: ACI_GATT_ERROR_RESP_EVENT
  • 0x00010000: ACI_GATT_PROC_COMPLETE_EVENT
  • 0x00020000: ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT
  • 0x00040000: ACI_GATT_TX_POOL_AVAILABLE_EVENT
  • 0x00100000: ACI_GATT_READ_EXT_EVENT
  • 0x00200000: ACI_GATT_INDICATION_EXT_EVENT
  • 0x00400000: ACI_GATT_NOTIFICATION_EXT_EVENT
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_EXCHANGE_CONFIG

    Description

    Perform an ATT MTU exchange procedure.
    When the ATT MTU exchange procedure is completed, a ACI_ATT_EXCHANGE_MTU_RESP_EVENT event is generated. A ACI_GATT_PROC_COMPLETE_EVENT event is also generated to indicate the end of the procedure.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_EXCHANGE_MTU_RESP_EVENT
  • ACI_ATT_FIND_INFO_REQ

    Description

    Send a Find Information Request.
    This command is used to obtain the mapping of attribute handles with their associated types. The responses of the procedure are given through the ACI_ATT_FIND_INFO_RESP_EVENT event. The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT event.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Start_Handle

    -

    2

    -

    First requested handle number

    -

    End_Handle

    -

    2

    -

    Last requested handle number

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_FIND_INFO_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_ATT_FIND_BY_TYPE_VALUE_REQ

    Description

    Send a Find By Type Value Request
    The Find By Type Value Request is used to obtain the handles of attributes that have a given 16-bit UUID attribute type and a given attribute value.
    The responses of the procedure are given through the ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT event.
    The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT event.

    Input parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Start_Handle

    -

    2

    -

    First requested handle number

    -

    End_Handle

    -

    2

    -

    Last requested handle number

    -

    UUID

    -

    2

    -

    2 octet UUID to find (little-endian)

    -

    Attribute_Val_Length

    -

    1

    -

    Length of attribute value (maximum value is ATT_MTU - 7).

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Attribute value to find

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_ATT_READ_BY_TYPE_REQ

    Description

    Send a Read By Type Request.
    The Read By Type Request is used to obtain the values of attributes where the attribute type is known but the handle is not known.
    The responses are given through the ACI_ATT_READ_BY_TYPE_RESP_EVENT event.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Start_Handle

    -

    2

    -

    First requested handle number

    -

    End_Handle

    -

    2

    -

    Last requested handle number

    -

    UUID_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    UUID

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_BY_TYPE_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_ATT_READ_BY_GROUP_TYPE_REQ

    Description

    Send a Read By Group Type Request.
    The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping attribute types are: "Primary Service", "Secondary Service" and "Characteristic".
    The responses of the procedure are given through the ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT event.
    The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Start_Handle

    -

    2

    -

    First requested handle number

    -

    End_Handle

    -

    2

    -

    Last requested handle number

    -

    UUID_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    UUID

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_ATT_PREPARE_WRITE_REQ

    Description

    Send a Prepare Write Request.
    The Prepare Write Request is used to request the server to prepare to write the value of an attribute.
    The responses of the procedure are given through the ACI_ATT_PREPARE_WRITE_RESP_EVENT event.
    The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the attribute to be written

    -

    Val_Offset

    -

    2

    -

    The offset of the first octet to be written

    -

    Attribute_Val_Length

    -

    1

    -

    Length of attribute value (maximum value is ATT_MTU - 5).

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    The value of the attribute to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_PREPARE_WRITE_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_ATT_EXECUTE_WRITE_REQ

    Description

    Send an Execute Write Request.
    The Execute Write Request is used to request the server to write or cancel the write of all the prepared values currently held in the prepare queue from this client.
    The result of the procedure is given through the ACI_ATT_EXEC_WRITE_RESP_EVENT event.
    The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT event.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Execute

    -

    1

    -

    Execute or cancel writes.

    -
  • 0x00: Cancel all prepared writes
  • 0x01: Immediately write all pending prepared values
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_EXEC_WRITE_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_DISC_ALL_PRIMARY_SERVICES

    Description

    Start the GATT client procedure to discover all primary services on the server.
    The responses of the procedure are given through the ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT event.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_DISC_PRIMARY_SERVICE_BY_UUID

    Description

    Start the procedure to discover the primary services of the specified UUID on the server.
    The responses of the procedure are given through the ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT event.
    The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT event.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • UUID_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    UUID

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_FIND_INCLUDED_SERVICES

    Description

    Start the procedure to find all included services.
    The responses of the procedure are given through the ACI_ATT_READ_BY_TYPE_RESP_EVENT event.
    The end of the procedure is indicated by a ACI_GATT_PROC_COMPLETE_EVENT event.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Start_Handle

    -

    2

    -

    Start attribute handle of the service

    -

    End_Handle

    -

    2

    -

    End attribute handle of the service

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_BY_TYPE_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_DISC_ALL_CHAR_OF_SERVICE

    Description

    Start the procedure to discover all the characteristics of a given service.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. Before procedure completion the response packets are given through ACI_ATT_READ_BY_TYPE_RESP_EVENT event.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Start_Handle

    -

    2

    -

    Start attribute handle of the service

    -

    End_Handle

    -

    2

    -

    End attribute handle of the service

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_BY_TYPE_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_DISC_CHAR_BY_UUID

    Description

    Start the procedure to discover all the characteristics specified by a UUID.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. Before procedure completion the response packets are given through ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT event.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Start_Handle

    -

    2

    -

    Start attribute handle of the service

    -

    End_Handle

    -

    2

    -

    End attribute handle of the service

    -

    UUID_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    UUID

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_DISC_ALL_CHAR_DESC

    Description

    Start the procedure to discover all characteristic descriptors on the server.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. Before procedure completion the response packets are given through ACI_ATT_FIND_INFO_RESP_EVENT event.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Char_Handle

    -

    2

    -

    Handle of the characteristic value

    -

    End_Handle

    -

    2

    -

    End handle of the characteristic

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_FIND_INFO_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_READ_CHAR_VALUE

    Description

    Start the procedure to read the attribute value.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. Before procedure completion the response packet is given through ACI_ATT_READ_RESP_EVENT event.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the characteristic value to be read

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_READ_USING_CHAR_UUID

    Description

    This command sends a Read By Type Request packet to the server in order to read the value attribute of the characteristics specified by the UUID.
    When the procedure is completed, an ACI_GATT_PROC_COMPLETE_EVENT event is generated. Before procedure completion, the response packet is given through one ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT event per reported attribute.
    Note: the number of bytes of a value reported by ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT event can not exceed BLE_EVT_MAX_PARAM_LEN - 7 i.e. 248 bytes for default value of BLE_EVT_MAX_PARAM_LEN.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Start_Handle

    -

    2

    -

    Starting handle of the range to be searched

    -

    End_Handle

    -

    2

    -

    End handle of the range to be searched

    -

    UUID_Type

    -

    1

    -

    UUID type: 0x01 = 16 bits UUID while 0x02 = 128 bits UUID

    -

    UUID

    -

    2 or 16

    -

    16-bit UUID or 128-bit UUID

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_READ_LONG_CHAR_VALUE

    Description

    Start the procedure to read a long characteristic value.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. Before procedure completion the response packets are given through ACI_ATT_READ_BLOB_RESP_EVENT event.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the characteristic value to be read

    -

    Val_Offset

    -

    2

    -

    Offset from which the value needs to be read

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_BLOB_RESP_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_READ_MULTIPLE_CHAR_VALUE

    Description

    Start a procedure to read multiple characteristic values from a server.
    This sub-procedure is used to read multiple Characteristic Values from a server when the client knows the Characteristic Value Handles.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. Before procedure completion the response packets are given through ACI_ATT_READ_MULTIPLE_RESP_EVENT event.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Number_of_Handles

    -

    1

    -

    The number of handles for which the value has to be read

    -

    Handle[i]

    -

    2

    -

    The handles for which the attribute value has to be read

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_MULTIPLE_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_WRITE_CHAR_VALUE

    Description

    Start the procedure to write a characteristic value.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the characteristic value to be written

    -

    Attribute_Val_Length

    -

    1

    -

    Length of the value to be written

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Value to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GATT_ERROR_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_WRITE_LONG_CHAR_VALUE

    Description

    Start the procedure to write a long characteristic value.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. During the procedure, ACI_ATT_PREPARE_WRITE_RESP_EVENT and ACI_ATT_EXEC_WRITE_RESP_EVENT events are raised.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the characteristic value to be written

    -

    Val_Offset

    -

    2

    -

    Offset at which the attribute has to be written

    -

    Attribute_Val_Length

    -

    1

    -

    Length of the value to be written

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Value to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_ATT_PREPARE_WRITE_RESP_EVENT
  • ACI_ATT_EXEC_WRITE_RESP_EVENT
  • ACI_GATT_WRITE_CHAR_RELIABLE

    Description

    Start the procedure to write a characteristic reliably.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. During the procedure, ACI_ATT_PREPARE_WRITE_RESP_EVENT and ACI_ATT_EXEC_WRITE_RESP_EVENT events are raised.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the attribute to be written

    -

    Val_Offset

    -

    2

    -

    Offset at which the attribute has to be written

    -

    Attribute_Val_Length

    -

    1

    -

    Length of the value to be written

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Value to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_ATT_PREPARE_WRITE_RESP_EVENT
  • ACI_ATT_EXEC_WRITE_RESP_EVENT
  • ACI_GATT_WRITE_LONG_CHAR_DESC

    Description

    Start the procedure to write a long characteristic descriptor.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. During the procedure, ACI_ATT_PREPARE_WRITE_RESP_EVENT and ACI_ATT_EXEC_WRITE_RESP_EVENT events are raised.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the attribute to be written

    -

    Val_Offset

    -

    2

    -

    Offset at which the attribute has to be written

    -

    Attribute_Val_Length

    -

    1

    -

    Length of the value to be written

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Value to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_ATT_PREPARE_WRITE_RESP_EVENT
  • ACI_ATT_EXEC_WRITE_RESP_EVENT
  • ACI_GATT_READ_LONG_CHAR_DESC

    Description

    Start the procedure to read a long characteristic value.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated. Before procedure completion the response packets are given through ACI_ATT_READ_BLOB_RESP_EVENT event.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the characteristic descriptor

    -

    Val_Offset

    -

    2

    -

    Offset from which the value needs to be read

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_BLOB_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_WRITE_CHAR_DESC

    Description

    Start the procedure to write a characteristic descriptor.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the attribute to be written

    -

    Attribute_Val_Length

    -

    1

    -

    Length of the value to be written

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Value to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_READ_CHAR_DESC

    Description

    Start the procedure to read the descriptor specified.
    When the procedure is completed, a ACI_GATT_PROC_COMPLETE_EVENT event is generated.
    Before procedure completion the response packet is given through ACI_ATT_READ_RESP_EVENT event.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the descriptor to be read

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_ATT_READ_RESP_EVENT
  • ACI_GATT_PROC_COMPLETE_EVENT
  • ACI_GATT_WRITE_WITHOUT_RESP

    Description

    Start the procedure to write a characteristic value without waiting for any response from the server. No events are generated after this command is executed. The length of the value to be written must not exceed (ATT_MTU - 3); it must also not exceed (BLE_EVT_MAX_PARAM_LEN - 5) i.e. 250 for BLE_EVT_MAX_PARAM_LEN default value.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the characteristic value to be written

    -

    Attribute_Val_Length

    -

    1

    -

    Length of the value to be written

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Value to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_SIGNED_WRITE_WITHOUT_RESP

    Description

    Start a signed write without response from the server.
    The procedure is used to write a characteristic value with an authentication signature without waiting for any response from the server. It cannot be used when the link is encrypted. The length of the value to be written must not exceed (ATT_MTU - 15); it must also not exceed (BLE_EVT_MAX_PARAM_LEN - 5) i.e. 250 for BLE_EVT_MAX_PARAM_LEN default value.

    Input parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the characteristic value to be written

    -

    Attribute_Val_Length

    -

    1

    -

    Length of the value to be written

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Value to be written

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_CONFIRM_INDICATION

    Description

    Allow application to confirm indication. This command has to be sent when the application receives the event ACI_GATT_INDICATION_EVENT.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_WRITE_RESP

    Description

    Allow or reject a write request from a client.
    This command has to be sent by the application when it receives the
    ACI_GATT_WRITE_PERMIT_REQ_EVENT. If the write can be allowed, then the status and error code has to be set to 0. If the write cannot be allowed, then the status has to be set to 1 and the error code has to be set to the error code that has to be passed to the client.

    Input parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Attr_Handle

    -

    2

    -

    Handle of the attribute that was passed in the event ACI_GATT_WRITE_PERMIT_REQ_EVENT

    -

    Write_status

    -

    1

    -

    If the value can be written or not.

    -
  • 0x00: The value can be written to the attribute specified by attr_handle
  • 0x01: The value cannot be written to the attribute specified by the attr_handle
  • Error_Code

    -

    1

    -

    The error code that has to be passed to the client in case the write has to be rejected

    -

    Attribute_Val_Length

    -

    1

    -

    Length of the value to be written as passed in the event ACI_GATT_WRITE_PERMIT_REQ_EVENT

    -

    Attribute_Val

    -

    Attribute_Val_Length

    -

    Value as passed in the event ACI_GATT_WRITE_PERMIT_REQ_EVENT

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_ALLOW_READ

    Description

    Allow the GATT server to send a response to a read request from a client.
    The application has to send this command when it receives the
    ACI_GATT_READ_PERMIT_REQ_EVENT or ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT. This command indicates to the stack that the response can be sent to the client. So if the application wishes to update any of the attributes before they are read by the client, it has to update the characteristic values using the ACI_GATT_UPDATE_CHAR_VALUE and then give this command. The application should perform the required operations within 30 seconds. Otherwise the GATT procedure will be timeout.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_SET_SECURITY_PERMISSION

    Description

    This command sets the security permission for the attribute handle specified. Currently the setting of security permission is allowed only for client configuration descriptor.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Serv_Handle

    -

    2

    -

    Handle of the service which contains the attribute whose security permission has to be modified

    -

    Attr_Handle

    -

    2

    -

    Handle of the attribute whose security permission has to be modified

    -

    Security_Permissions

    -

    1

    -

    Security permission flags.

    -

    Bitmask of:

  • 0x00: None
  • 0x01: AUTHEN_READ (Need authentication to read)
  • 0x02: AUTHOR_READ (Need authorization to read)
  • 0x04: ENCRY_READ (Need encryption to read)
  • 0x08: AUTHEN_WRITE (need authentication to write)
  • 0x10: AUTHOR_WRITE (need authorization to write)
  • 0x20: ENCRY_WRITE (need encryption to write)
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_SET_DESC_VALUE

    Description

    This command sets the value of the descriptor specified by charDescHandle.

    Input parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Serv_Handle

    -

    2

    -

    Handle of the service which contains the characteristic descriptor

    -

    Char_Handle

    -

    2

    -

    Handle of the characteristic which contains the descriptor

    -

    Char_Desc_Handle

    -

    2

    -

    Handle of the descriptor whose value has to be set

    -

    Val_Offset

    -

    2

    -

    Offset from which the descriptor value has to be updated

    -

    Char_Desc_Value_Length

    -

    1

    -

    Length of the descriptor value

    -

    Char_Desc_Value

    -

    Char_Desc_Value_Length

    -

    Descriptor value

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_READ_HANDLE_VALUE

    Description

    Reads the value of the attribute handle specified from the local GATT database.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Attr_Handle

    -

    2

    -

    Handle of the attribute to read

    -

    Offset

    -

    2

    -

    Offset from which the value needs to be read

    -

    Value_Length_Requested

    -

    2

    -

    Maximum number of octets to be returned as attribute value

    -

    Output parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Length

    -

    2

    -

    Length of the attribute value

    -

    Value_Length

    -

    2

    -

    Length in octets of the Value parameter

    -

    Value

    -

    Value_Length

    -

    Attribute value

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_UPDATE_CHAR_VALUE_EXT

    Description

    This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute up to 512 bytes and indicate selectively the generation of Indication/Notification.

    Input parameters

    - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Conn_Handle_To_Notify

    -

    2

    -

    Connection handle to notify. Notify all subscribed clients if equal to 0x0000

    -

    Service_Handle

    -

    2

    -

    Handle of service to which the characteristic belongs

    -

    Char_Handle

    -

    2

    -

    Handle of the characteristic declaration

    -

    Update_Type

    -

    1

    -
    -
    Allow Notification or Indication generation,
    -
    if enabled in the client characteristic configuration descriptor
    -
    -

    Bitmask of:

  • 0x00: Do not notify
  • 0x01: Notification
  • 0x02: Indication
  • Char_Length

    -

    2

    -

    Total length of the characteristic value. -In case of a variable size characteristic, this field specifies the new length of the characteristic value after the update; in case of fixed length characteristic this field is ignored.

    -

    Value_Offset

    -

    2

    -

    The offset from which the attribute value has to be updated.

    -

    Value_Length

    -

    1

    -

    Length of the Value parameter in octets

    -

    Value

    -

    Value_Length

    -

    Updated characteristic value

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_DENY_READ

    Description

    Deny the GATT server to send a response to a read request from a client.
    The application may send this command when it receives the ACI_GATT_READ_PERMIT_REQ_EVENT or ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT.
    This command indicates to the stack that the client is not allowed to read the requested characteristic due to e.g. application restrictions.
    The Error code shall be either 0x08 (Insufficient Authorization) or a value in the range 0x80-0x9F (Application Error).
    The application should issue the ACI_GATT_DENY_READ or ACI_GATT_ALLOW_READ command within 30 seconds from the reception of the ACI_GATT_READ_PERMIT_REQ_EVENT or ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT events; otherwise the GATT procedure issues a timeout.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Error_Code

    -

    1

    -

    Error code for the command

    -
  • 0x08: Insufficient Authorization
  • 0x80 ... 0x9F: Application Error
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_GATT_SET_ACCESS_PERMISSION

    Description

    This command sets the access permission for the attribute handle specified.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Serv_Handle

    -

    2

    -

    Handle of the service which contains the attribute whose access permission has to be modified

    -

    Attr_Handle

    -

    2

    -

    Handle of the attribute whose security permission has to be modified

    -

    Access_Permissions

    -

    1

    -

    Access permission

    -

    Bitmask of:

  • 0x00: None
  • 0x01: READ
  • 0x02: WRITE
  • 0x04: WRITE_WO_RESP
  • 0x08: SIGNED_WRITE
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI L2CAP commands

    - - - - - - - - - - -
    CommandOpcodeBFPOLOBO
    ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_REQ

    0xFD81

    -

    Y

    -

    Y

    -
    ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_RESP

    0xFD82

    -

    Y

    -
    ACI_L2CAP_COC_CONNECT

    0xFD88

    -
    ACI_L2CAP_COC_CONNECT_CONFIRM

    0xFD89

    -
    ACI_L2CAP_COC_RECONF

    0xFD8A

    -
    ACI_L2CAP_COC_RECONF_CONFIRM

    0xFD8B

    -
    ACI_L2CAP_COC_DISCONNECT

    0xFD8C

    -
    ACI_L2CAP_COC_FLOW_CONTROL

    0xFD8D

    -
    ACI_L2CAP_COC_TX_DATA

    0xFD8E

    -

    ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_REQ

    Description

    Send an L2CAP connection parameter update request from the slave to the master.
    An ACI_L2CAP_CONNECTION_UPDATE_RESP_EVENT event is raised when the master responds to the request (accepts or rejects).

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Conn_Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Slave_latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Timeout_Multiplier

    -

    2

    -

    Defines connection timeout parameter in the following manner: Timeout Multiplier * 10ms.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_STATUS_EVENT
  • ACI_L2CAP_CONNECTION_UPDATE_RESP_EVENT
  • ACI_L2CAP_PROC_TIMEOUT_EVENT
  • ACI_L2CAP_COMMAND_REJECT_EVENT
  • ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_RESP

    Description

    Accept or reject a connection update. This command should be sent in response to an ACI_L2CAP_CONNECTION_UPDATE_REQ_EVENT event from the controller. The accept parameter has to be set if the connection parameters given in the event are acceptable.

    Input parameters

    - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Conn_Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Slave_latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Timeout_Multiplier

    -

    2

    -

    Defines connection timeout parameter in the following manner: Timeout Multiplier * 10ms.

    -

    Minimum_CE_Length

    -

    2

    -

    Information parameter about the minimum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Maximum_CE_Length

    -

    2

    -

    Information parameter about the maximum length of connection needed for this LE connection. -Time = N * 0.625 msec.

    -
  • 0x0000 (0.000 ms) ... 0xFFFF (40959.375 ms)
  • Identifier

    -

    1

    -

    Identifier received in ACI_L2CAP_Connection_Update_Req event.

    -

    Accept

    -

    1

    -

    Specify if connection update parameters are acceptable or not.

    -
  • 0x00: Reject
  • 0x01: Accept
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_L2CAP_COC_CONNECT

    Description

    This command sends a Credit Based Connection Request packet on the specified connection. See Bluetooth Core specification Vol.3 Part A.

    Input parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • SPSM

    -

    2

    -

    Simplified Protocol/Service Multiplexer.

    -
  • 0x0001 ... 0x00FF
  • MTU

    -

    2

    -

    Maximum Transmission Unit.

    -
  • 23 ... 65535
  • MPS

    -

    2

    -

    Maximum payload size (in octets).

    -
  • 23 ... 65533
  • Initial_Credits

    -

    2

    -

    Number of K-frames that can be received on the created channel(s) by the L2CAP layer entity sending this packet.

    -
  • 0 ... 65535
  • Channel_Number

    -

    1

    -

    Number of channels to be created. If this parameter is set to 0, it requests the creation of one LE credit based connection-oriented channel. Otherwise, it requests the creation of one or more enhanced credit based connection-oriented channels.

    -
  • 0 ... 5
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_L2CAP_COC_CONNECT_CONFIRM_EVENT
  • ACI_L2CAP_PROC_TIMEOUT_EVENT
  • ACI_L2CAP_COMMAND_REJECT_EVENT
  • ACI_L2CAP_COC_CONNECT_CONFIRM

    Description

    This command sends a Credit Based Connection Response packet. It must be used upon receipt of a connection request through an ACI_L2CAP_COC_CONNECT_EVENT event. See Bluetooth Core specification Vol.3 Part A.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • MTU

    -

    2

    -

    Maximum Transmission Unit.

    -
  • 23 ... 65535
  • MPS

    -

    2

    -

    Maximum payload size (in octets).

    -
  • 23 ... 65533
  • Initial_Credits

    -

    2

    -

    Number of K-frames that can be received on the created channel(s) by the L2CAP layer entity sending this packet.

    -
  • 0 ... 65535
  • Result

    -

    2

    -

    This parameter indicates the outcome of the request. A value of 0x0000 indicates success while a non-zero value indicates the request is refused.

    -
  • 0x0000 ... 0x000C
  • Output parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Channel_Number

    -

    1

    -

    Number of created channels. It is the length of Channel_Index_List.

    -
  • 0 ... 5
  • Channel_Index_List

    -

    Channel_Number

    -

    List of channel indexes for which the primitive applies.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_L2CAP_COC_RECONF

    Description

    This command sends a Credit Based Reconfigure Request packet on the specified connection. See Bluetooth Core specification Vol.3 Part A.

    Input parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • MTU

    -

    2

    -

    Maximum Transmission Unit.

    -
  • 23 ... 65535
  • MPS

    -

    2

    -

    Maximum payload size (in octets).

    -
  • 23 ... 65533
  • Channel_Number

    -

    1

    -

    Number of created channels. It is the length of Channel_Index_List.

    -
  • 1 ... 5
  • Channel_Index_List

    -

    Channel_Number

    -

    List of channel indexes for which the primitive applies.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_L2CAP_COC_RECONF_CONFIRM_EVENT
  • ACI_L2CAP_PROC_TIMEOUT_EVENT
  • ACI_L2CAP_COMMAND_REJECT_EVENT
  • ACI_L2CAP_COC_RECONF_CONFIRM

    Description

    This command sends a Credit Based Reconfigure Response packet. It must be used upon receipt of a Credit Based Reconfigure Request through an ACI_L2CAP_COC_RECONF_EVENT event. See Bluetooth Core specification Vol.3 Part A.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Result

    -

    2

    -

    This parameter indicates the outcome of the request. A value of 0x0000 indicates success while a non-zero value indicates the request is refused.

    -
  • 0x0000 ... 0x000C
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_L2CAP_COC_DISCONNECT

    Description

    This command sends a Disconnection Request signaling packet on the specified connection-oriented channel. See Bluetooth Core specification Vol.3 Part A.
    The ACI_L2CAP_COC_DISCONNECT_EVENT event is received when the disconnection of the channel is effective.

    Input parameters

    - - -
    ParameterSizeDescriptionPossible values

    Channel_Index

    -

    1

    -

    Index of the connection-oriented channel for which the primitive applies.

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_L2CAP_COC_DISCONNECT_EVENT
  • ACI_L2CAP_PROC_TIMEOUT_EVENT
  • ACI_L2CAP_COMMAND_REJECT_EVENT
  • ACI_L2CAP_COC_FLOW_CONTROL

    Description

    This command sends a Flow Control Credit signaling packet on the specified connection-oriented channel. See Bluetooth Core specification Vol.3 Part A.

    Input parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Channel_Index

    -

    1

    -

    Index of the connection-oriented channel for which the primitive applies.

    -

    Credits

    -

    2

    -

    Number of credits the receiving device can increment, corresponding to the number of K-frames that can be sent to the peer device sending the Flow Control Credit packet.

    -
  • 1 ... 65535
  • Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • ACI_L2CAP_COC_TX_DATA

    Description

    This command sends a K-frame packet on the specified connection-oriented channel. See Bluetooth Core specification Vol.3 Part A.
    Note: for the first K-frame of the SDU, the Information data shall contain the L2CAP SDU Length coded on two octets followed by the K-frame information payload. For the next K-frames of the SDU, the Information data shall only contain the K-frame information payload.
    The Length value must not exceed (BLE_CMD_MAX_PARAM_LEN - 3) i.e. 252 for BLE_CMD_MAX_PARAM_LEN default value.

    Input parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Channel_Index

    -

    1

    -

    Index of the connection-oriented channel for which the primitive applies.

    -

    Length

    -

    2

    -

    Length of Data (in octets)

    -

    Data

    -

    Length

    -

    Information data

    -

    Output parameters

    - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Events generated

  • HCI_COMMAND_COMPLETE_EVENT
  • HCI/ACI events

    HCI events

    HCI LE meta events

    ACI GAP events

    ACI GATT/ATT events

    ACI L2CAP events

    ACI HAL events

    Note: in the event tables, a "Y" in the "BF", "PO", "LO" or "BO" column, means that the corresponding event applies to the "Basic Features", "Peripheral Only", "Link Layer Only" or "Beacon Only" variant of the BLE stack, respectively.

    HCI events

    - - - - - - - - - -
    Event nameEvent codeBFPOLOBO
    HCI_DISCONNECTION_COMPLETE_EVENT

    0x05

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_ENCRYPTION_CHANGE_EVENT

    0x08

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT

    0x0C

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_COMMAND_COMPLETE_EVENT

    0x0E

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_COMMAND_STATUS_EVENT

    0x0F

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_HARDWARE_ERROR_EVENT

    0x10

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT

    0x13

    -

    Y

    -
    HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT

    0x30

    -

    Y

    -

    Y

    -

    Y

    -

    HCI_DISCONNECTION_COMPLETE_EVENT

    Description

    The Disconnection Complete event occurs when a connection is terminated.
    The status parameter indicates if the disconnection was successful or not. The reason parameter indicates the reason for the disconnection if the disconnection was successful. If the disconnection was not successful, the value of the reason parameter can be ignored by the Host. For example, this can be the case if the Host has issued the Disconnect command and there was a parameter error, or the command was not presently allowed, or a Connection_Handle that didn't correspond to a connection was given.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection_Handle which was disconnected.

    -
  • 0x0000 ... 0x0EFF
  • Reason

    -

    1

    -

    Reason for disconnection (see Bluetooth Core Specification [Vol 2] Part D, Error Codes).

    -

    HCI_ENCRYPTION_CHANGE_EVENT

    Description

    The Encryption Change event is used to indicate that the change of the encryption mode has been completed. The Connection_Handle will be a Connection_Handle for an ACL connection. The Encryption_Enabled event parameter specifies the new Encryption_Enabled parameter for the Connection_Handle specified by the Connection_Handle event parameter. This event will occur on both devices to notify the Hosts when Encryption has changed for the specified Connection_Handle between two devices. Note: This event shall not be generated if encryption is paused or resumed; during a role switch, for example.
    The meaning of the Encryption_Enabled parameter depends on whether the Host has indicated support for Secure Connections in the Secure_Connections_Host_Support parameter. When Secure_Connections_Host_Support is 'disabled' or the Connection_Handle refers to an LE link, the Controller shall only use Encryption_Enabled values 0x00 (OFF) and 0x01 (ON).
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.7.8)

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Encryption_Enabled

    -

    1

    -

    Link Level Encryption.

    -
  • 0x00: Link Level Encryption OFF
  • 0x01: Link Level Encryption is ON with AES-CCM
  • HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT

    Description

    The Read Remote Version Information Complete event is used to indicate the completion of the process obtaining the version information of the remote Controller specified by the Connection_Handle event parameter. The Connection_Handle shall be for an ACL connection.
    The Version event parameter defines the specification version of the LE Controller.
    The Manufacturer_Name event parameter indicates the manufacturer of the remote Controller. The Subversion event parameter is controlled by the manufacturer and is implementation dependent. The Subversion event parameter defines the various revisions that each version of the Bluetooth hardware will go through as design processes change and errors are fixed. This allows the software to determine what Bluetooth hardware is being used and, if necessary, to work around various bugs in the hardware.
    When the Connection_Handle is associated with an LE-U logical link, the Version event parameter shall be Link Layer VersNr parameter, the Manufacturer_Name event parameter shall be the CompId parameter, and the Subversion event parameter shall be the SubVersNr parameter.
    (See Bluetooth Specification v.5.0, Vol. 2, Part E, 7.7.12)

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • Version

    -

    1

    -

    Version of the Current LMP in the remote Controller

    -

    Manufacturer_Name

    -

    2

    -

    Manufacturer Name of the remote Controller

    -

    Subversion

    -

    2

    -

    Subversion of the LMP in the remote Controller

    -

    HCI_COMMAND_COMPLETE_EVENT

    Description

    The Command Complete event is used by the Controller for most commands to transmit return status of a command and the other event parameters that are specified for the issued HCI command.
    The Num_HCI_Command_Packets event parameter allows the Controller to indicate the number of HCI command packets the Host can send to the Controller.
    If the Controller requires the Host to stop sending commands, the Num_HCI_Command_Packets event parameter will be set to zero. To indicate to the Host that the Controller is ready to receive HCI command packets, the Controller generates a Command Complete event with the Command_Opcode 0x0000, and the Num_HCI_Command_Packets event parameter is set to 1 or more. See each command for the parameters that are returned by this event.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Num_HCI_Command_Packets

    -

    1

    -

    The Number of HCI command packets which are allowed to be sent to the Controller from the Host.

    -

    Command_Opcode

    -

    2

    -

    Opcode of the command which caused this event.

    -

    Return_Parameters

    -

    variable

    -

    This is the return parameter(s) for the command specified in the Command_Opcode event parameter. See each command's definition for the list of return parameters associated with that command.

    -

    HCI_COMMAND_STATUS_EVENT

    Description

    The Command Status event is used to indicate that the command described by the Command_Opcode parameter has been received, and that the Controller is currently performing the task for this command. This event is needed to provide mechanisms for asynchronous operation, which makes it possible to prevent the Host from waiting for a command to finish. If the command cannot begin to execute (a parameter error may have occurred, or the command may currently not be allowed), the Status event parameter will contain the corresponding error code, and no complete event will follow since the command was not started. The Num_HCI_Command_Packets event parameter allows the Controller to indicate the number of HCI command packets the Host can send to the Controller. If the Controller requires the Host to stop sending commands, the Num_HCI_Command_Packets event parameter will be set to zero. To indicate to the Host that the Controller is ready to receive HCI command packets, the Controller generates a Command Status event with Status 0x00 and Command_Opcode 0x0000, and the Num_HCI_Command_Packets event parameter is set to 1 or more.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Num_HCI_Command_Packets

    -

    1

    -

    The Number of HCI command packets which are allowed to be sent to the Controller from the Host.

    -

    Command_Opcode

    -

    2

    -

    Opcode of the command which caused this event.

    -

    HCI_HARDWARE_ERROR_EVENT

    Description

    The Hardware Error event is used to indicate some implementation specific type of hardware failure for the controller. This event is used to notify the Host that a hardware failure has occurred in the Controller.

    Event parameters

    - - -
    ParameterSizeDescriptionPossible values

    Hardware_Code

    -

    1

    -

    Hardware Error Event code. -Error code 0 is not used. -Error code 1 is bluecore act2 error detected. -Error code 2 is bluecore time overrun error detected. -Error code 3 is internal FIFO full.

    -
  • 0x00: Not used
  • 0x01: event_act2 error
  • 0x02: event_time_overrun error
  • 0x03: event_fifo_full error
  • HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT

    Description

    The Number Of Completed Packets event is used by the Controller to indicate to the Host how many HCI Data Packets have been completed (transmitted or flushed) for each Connection_Handle since the previous Number Of Completed Packets event was sent to the Host. This means that the corresponding buffer space has been freed in the Controller. Based on this information, and the HC_Total_Num_ACL_Data_Packets and HC_Total_Num_Synchronous_Data_Packets return parameter of the Read_Buffer_Size command, the Host can determine for which Connection_Handles the following HCI Data Packets should be sent to the Controller. The Number Of Completed Packets event must not be sent before the corresponding Connection Complete event. While the Controller has HCI data packets in its buffer, it must keep sending the Number Of Completed Packets event to the Host at least periodically, until it finally reports that all the pending ACL Data Packets have been transmitted or flushed.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Number_of_Handles

    -

    1

    -

    The number of Connection_Handles and Num_HCI_Data_Packets parameters pairs contained in this event

    -

    Connection_Handle[i]

    -

    2

    -

    Connection handle

    -

    HC_Num_Of_Completed_Packets[i]

    -

    2

    -

    The number of HCI Data Packets that have been completed (transmitted or flushed) for the associated Connection_Handle since the previous time the event was returned.

    -

    HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT

    Description

    The Encryption Key Refresh Complete event is used to indicate to the Host that the encryption key was refreshed on the given Connection_Handle any time encryption is paused and then resumed.
    If the Encryption Key Refresh Complete event was generated due to an encryption pause and resume operation embedded within a change connection link key procedure, the Encryption Key Refresh Complete event shall be sent prior to the Change Connection Link Key Complete event.
    If the Encryption Key Refresh Complete event was generated due to an encryption pause and resume operation embedded within a role switch procedure, the Encryption Key Refresh Complete event shall be sent prior to the Role Change event.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the command applies.

    -
  • 0x0000 ... 0x0EFF
  • HCI LE meta events

    - - - - - - - - - - - - -
    Event nameLE subevent codeBFPOLOBO
    HCI_LE_CONNECTION_COMPLETE_EVENT

    0x01

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_ADVERTISING_REPORT_EVENT

    0x02

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT

    0x03

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT

    0x04

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_LONG_TERM_KEY_REQUEST_EVENT

    0x05

    -

    Y

    -
    HCI_LE_DATA_LENGTH_CHANGE_EVENT

    0x07

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE_EVENT

    0x08

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT

    0x09

    -

    Y

    -
    HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT

    0x0A

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_DIRECT_ADVERTISING_REPORT_EVENT

    0x0B

    -

    Y

    -

    Y

    -

    Y

    -
    HCI_LE_PHY_UPDATE_COMPLETE_EVENT

    0x0C

    -

    Y

    -

    HCI_LE_CONNECTION_COMPLETE_EVENT

    Description

    The LE Connection Complete event indicates to both of the Hosts forming the connection that a new connection has been created. Upon the creation of the connection a Connection_Handle shall be assigned by the Controller, and passed to the Host in this event. If the connection establishment fails this event shall be provided to the Host that had issued the LE_Create_Connection command.
    This event indicates to the Host which issued a LE_Create_Connection command and received a Command Status event if the connection establishment failed or was successful.
    The Master_Clock_Accuracy parameter is only valid for a slave. On a master, this parameter shall be set to 0x00. See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.1

    Event parameters

    - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Role

    -

    1

    -

    Role of the local device in the connection.

    -
  • 0x00: Master
  • 0x01: Slave
  • Peer_Address_Type

    -

    1

    -

    The address type of the peer device.

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • Peer_Address

    -

    6

    -

    Public Device Address or Random Device Address of the peer device

    -

    Conn_Interval

    -

    2

    -

    Connection interval used on this connection. -Time = N * 1.25 msec

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • Master_Clock_Accuracy

    -

    1

    -

    Master clock accuracy. Only valid for a slave.

    -
  • 0x00: 500 ppm
  • 0x01: 250 ppm
  • 0x02: 150 ppm
  • 0x03: 100 ppm
  • 0x04: 75 ppm
  • 0x05: 50 ppm
  • 0x06: 30 ppm
  • 0x07: 20 ppm
  • HCI_LE_ADVERTISING_REPORT_EVENT

    Description

    The LE Advertising Report event indicates that a device or multiple devices have responded to an active scan or received some information during a passive scan. The Controller may queue these advertising reports and send information from multiple devices in one LE Advertising Report event (see Bluetooth spec 5.0 vol 2 [part E] 7.7.65.2). In the current BLE stack version, only one report is sent per event (Num_Reports = 1).

    Event parameters

    - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Num_Reports

    -

    1

    -

    Number of responses in this event.

    -
  • 0x01
  • Event_Type[i]

    -

    1

    -

    Type of advertising report event: -ADV_IND: Connectable undirected advertising', -ADV_DIRECT_IND: Connectable directed advertising, -ADV_SCAN_IND: Scannable undirected advertising, -ADV_NONCONN_IND: Non connectable undirected advertising, -SCAN_RSP: Scan response.

    -
  • 0x00: ADV_IND
  • 0x01: ADV_DIRECT_IND
  • 0x02: ADV_SCAN_IND
  • 0x03: ADV_NONCONN_IND
  • 0x04: SCAN_RSP
  • Address_Type[i]

    -

    1

    -

    Address type -0x00 Public Device Address -0x01 Random Device Address -0x02 Public Identity Address (Corresponds to Resolved Private Address) -0x03 Random (Static) Identity Address (Corresponds to Resolved Private Address)

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • 0x02: Public Identity Address
  • 0x03: Random (Static) Identity Address
  • Address[i]

    -

    6

    -

    Public Device Address or Random Device Address of the device to be connected.

    -

    Length_Data[i]

    -

    1

    -

    Length of the Data[i] field for each device which responded.

    -
  • 0 ... 31
  • Data[i]

    -

    Length_Data[i]

    -

    Length_Data[i] octets of advertising or scan response data formatted -as defined in [Vol 3] Part C, Section 8.

    -

    RSSI[i]

    -

    1

    -

    N Size: 1 Octet (signed integer) -Units: dBm

    -
  • 127: RSSI not available
  • -127 ... 20
  • HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT

    Description

    The LE Connection Update Complete event is used to indicate that the Controller process to update the connection has completed.
    On a slave, if no connection parameters are updated, then this event shall not be issued.
    On a master, this event shall be issued if the Connection_Update command was sent. See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.3

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Conn_Interval

    -

    2

    -

    Connection interval used on this connection. -Time = N * 1.25 msec

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT

    Description

    The LE Read Remote Features Complete event is used to indicate the completion of the process of the Controller obtaining the used features of the remote Bluetooth device specified by the Connection_Handle event parameter.
    See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.4

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • LE_Features

    -

    8

    -

    Bit Mask List of used LE features. For details see LE Link Layer specification.

    -

    HCI_LE_LONG_TERM_KEY_REQUEST_EVENT

    Description

    The LE Long Term Key Request event indicates that the master device is attempting to encrypt or re-encrypt the link and is requesting the Long Term Key from the Host.
    (See [Vol 6] Part B, Section 5.1.3)and Bluetooth spec 5.0 vol 2 [part E] 7.7.65.5

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Random_Number

    -

    8

    -

    64-bit random number

    -

    Encrypted_Diversifier

    -

    2

    -

    16-bit encrypted diversifier

    -

    HCI_LE_DATA_LENGTH_CHANGE_EVENT

    Description

    The LE Data Length Change event notifies the Host of a change to either the maximum Payload length or the maximum transmission time of packets in either direction. The values reported are the maximum that will actually be used on the connection following the change, except that on the LE Coded PHY a packet taking up to 2704 us to transmit may be sent even though the corresponding parameter has a lower value.
    See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.7

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • MaxTxOctets

    -

    2

    -

    The maximum number of payload octets in a Link Layer packet that the local Controller will send on this connection (connEffectiveMaxTxOctets defined in [Vol 6] Part B, Section 4.5.10).

    -
  • 0x001B ... 0x00FB
  • MaxTxTime

    -

    2

    -

    The maximum time that the local Controller will take to send a Link Layer packet on this connection (connEffectiveMaxTxTime defined in [Vol 6] Part B, Section 4.5.10).

    -
  • 0x0148 ... 0x4290
  • MaxRxOctets

    -

    2

    -

    The maximum number of payload octets in a Link Layer packet that the local Controller expects to receive on this connection (connEffectiveMaxRxOctets defined in [Vol 6] Part B, Section 4.5.10).

    -
  • 0x001B ... 0x00FB
  • MaxRxTime

    -

    2

    -

    The maximum time that the local Controller expects to take to receive a Link Layer packet on this connection (connEffectiveMaxRxTime defined in [Vol 6] Part B, Section 4.5.10).

    -
  • 0x0148 ... 0x4290
  • HCI_LE_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE_EVENT

    Description

    This event is generated when local P-256 key generation is complete.
    See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.8

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Local_P256_Public_Key

    -

    64

    -

    Local P-256 public key.

    -

    HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT

    Description

    This event indicates that LE Diffie Hellman key generation has been completed by the Controller.
    See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.9

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    DHKey

    -

    32

    -

    Diffie Hellman Key

    -

    HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT

    Description

    The LE Enhanced Connection Complete event indicates to both of the Hosts forming the connection that a new connection has been created. Upon the creation of the connection a Connection_Handle shall be assigned by the Controller, and passed to the Host in this event. If the connection establishment fails, this event shall be provided to the Host that had issued the LE_Create_Connection command.
    If this event is unmasked and LE Connection Complete event is unmasked, only the LE Enhanced Connection Complete event is sent when a new connection has been completed.
    This event indicates to the Host that issued a LE_Create_Connection command and received a Command Status event if the connection establishment failed or was successful.
    The Master_Clock_Accuracy parameter is only valid for a slave. On a master, this parameter shall be set to 0x00.
    See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.10

    Event parameters

    - - - - - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Role

    -

    1

    -

    Role of the local device in the connection.

    -
  • 0x00: Master
  • 0x01: Slave
  • Peer_Address_Type

    -

    1

    -

    Address type -0x00 Public Device Address -0x01 Random Device Address -0x02 Public Identity Address (Corresponds to Resolved Private Address) -0x03 Random (Static) Identity Address (Corresponds to Resolved Private Address)

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • 0x02: Public Identity Address
  • 0x03: Random (Static) Identity Address
  • Peer_Address

    -

    6

    -

    Public Device Address, Random Device Address, Public Identity Address or Random (static) Identity Address of the device to be connected.

    -

    Local_Resolvable_Private_Address

    -

    6

    -

    Resolvable Private Address being used by the local device for this connection. -This is only valid when the Own_Address_Type is set to 0x02 or 0x03. For other Own_Address_Type values, the Controller shall return all zeros.

    -

    Peer_Resolvable_Private_Address

    -

    6

    -

    Resolvable Private Address being used by the peer device for this connection. -This is only valid for Peer_Address_Type 0x02 and 0x03. For other Peer_Address_Type values, the Controller shall return all zeros.

    -

    Conn_Interval

    -

    2

    -

    Connection interval used on this connection. -Time = N * 1.25 msec

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Conn_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Supervision_Timeout

    -

    2

    -

    Supervision timeout for the LE Link. -It shall be a multiple of 10 ms and larger than (1 + connSlaveLatency) * connInterval * 2. -Time = N * 10 msec.

    -
  • 0x000A (100 ms) ... 0x0C80 (32000 ms)
  • Master_Clock_Accuracy

    -

    1

    -

    Master clock accuracy. Only valid for a slave.

    -
  • 0x00: 500 ppm
  • 0x01: 250 ppm
  • 0x02: 150 ppm
  • 0x03: 100 ppm
  • 0x04: 75 ppm
  • 0x05: 50 ppm
  • 0x06: 30 ppm
  • 0x07: 20 ppm
  • HCI_LE_DIRECT_ADVERTISING_REPORT_EVENT

    Description

    The LE Direct Advertising Report event indicates that directed advertisements have been received where the advertiser is using a resolvable private address for the InitA field in the ADV_DIRECT_IND PDU and the Scanning_Filter_Policy is equal to 0x02 or 0x03, see HCI_LE_Set_Scan_Parameters.
    Direct_Address_Type and Direct_Addres is the address the directed advertisements are being directed to. Address_Type and Address is the address of the advertiser sending the directed advertisements.
    See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.11.

    Event parameters

    - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Num_Reports

    -

    1

    -

    Number of responses in this event.

    -
  • 0x01
  • Event_Type[i]

    -

    1

    -

    Advertising type

    -
  • 0x01: Connectable directed advertising (ADV_DIRECT_IND)
  • Address_Type[i]

    -

    1

    -

    Address type -0x00 Public Device Address -0x01 Random Device Address -0x02 Public Identity Address (Corresponds to Resolved Private Address) -0x03 Random (Static) Identity Address (Corresponds to Resolved Private Address)

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • 0x02: Public Identity Address
  • 0x03: Random (Static) Identity Address
  • Address[i]

    -

    6

    -

    Public Device Address, Random Device Address, Public Identity Address or Random (static) Identity Address of the advertising device.

    -

    Direct_Address_Type[i]

    -

    1

    -

    0x01 Random Device Address

    -
  • 0x01: Random Device Address
  • Direct_Address[i]

    -

    6

    -

    Random Device Address

    -

    RSSI[i]

    -

    1

    -

    N Size: 1 Octet (signed integer) -Units: dBm

    -
  • 127: RSSI not available
  • -127 ... 20
  • HCI_LE_PHY_UPDATE_COMPLETE_EVENT

    Description

    The LE PHY Update Complete Event is used to indicate that the Controller has changed the transmitter PHY or receiver PHY in use.
    If the Controller changes the transmitter PHY, the receiver PHY, or both PHYs, this event shall be issued.
    If an LE_Set_PHY command was sent and the Controller determines that neither PHY will change as a result, it issues this event immediately.
    See See Bluetooth spec 5.0 vol 2 [part E] 7.7.65.12.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Status

    -

    1

    -

    Status error code.

    -

    Connection_Handle

    -

    2

    -

    Connection handle to be used to identify the connection with the peer device.

    -
  • 0x0000 ... 0x0EFF
  • TX_PHY

    -

    1

    -

    Transmitter PHY in use

    -
  • 0x01: The transmitter PHY for the connection is LE 1M
  • 0x02: The transmitter PHY for the connection is LE 2M
  • 0x03: The transmitter PHY for the connection is LE Coded -(Not supported by STM32WB)
  • RX_PHY

    -

    1

    -

    Receiver PHY in use

    -
  • 0x01: The receiver PHY for the connection is LE 1M
  • 0x02: The receiver PHY for the connection is LE 2M
  • 0x03: The receiver PHY for the connection is LE Coded -(Not supported by STM32WB)
  • ACI GAP events

    - - - - - - - - - - - -
    Event nameVendor specific subevent codeBFPOLOBO
    ACI_GAP_LIMITED_DISCOVERABLE_EVENT

    0x0400

    -

    Y

    -

    Y

    -
    ACI_GAP_PAIRING_COMPLETE_EVENT

    0x0401

    -

    Y

    -

    Y

    -
    ACI_GAP_PASS_KEY_REQ_EVENT

    0x0402

    -

    Y

    -

    Y

    -
    ACI_GAP_AUTHORIZATION_REQ_EVENT

    0x0403

    -

    Y

    -

    Y

    -
    ACI_GAP_SLAVE_SECURITY_INITIATED_EVENT

    0x0404

    -

    Y

    -

    Y

    -
    ACI_GAP_BOND_LOST_EVENT

    0x0405

    -

    Y

    -

    Y

    -
    ACI_GAP_PROC_COMPLETE_EVENT

    0x0407

    -

    Y

    -

    Y

    -
    ACI_GAP_ADDR_NOT_RESOLVED_EVENT

    0x0408

    -

    Y

    -

    Y

    -
    ACI_GAP_NUMERIC_COMPARISON_VALUE_EVENT

    0x0409

    -

    Y

    -

    Y

    -
    ACI_GAP_KEYPRESS_NOTIFICATION_EVENT

    0x040A

    -

    Y

    -

    Y

    -

    ACI_GAP_LIMITED_DISCOVERABLE_EVENT

    Description

    This event is generated by the controller when the limited discoverable mode ends due to timeout. The timeout is 180 seconds.

    Event parameters

    None

    ACI_GAP_PAIRING_COMPLETE_EVENT

    Description

    This event is generated when the pairing process has completed successfully or a pairing procedure timeout has occurred or the pairing has failed. This is to notify the application that we have paired with a remote device so that it can take further actions or to notify that a timeout has occurred so that the upper layer can decide to disconnect the link.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle on which the pairing procedure completed

    -

    Status

    -

    1

    -

    Pairing status

    -
  • 0x00: Success
  • 0x01: SMP timeout
  • 0x02: Pairing failed
  • 0x03: Encryption failed
  • Reason

    -

    1

    -

    Pairing reason error code (valid in case of pairing failed status)

    -
  • 0x02: OOB_NOT_AVAILABLE
  • 0x03: AUTH_REQ_CANNOT_BE_MET
  • 0x04: CONFIRM_VALUE_FAILED
  • 0x05: PAIRING_NOT_SUPPORTED
  • 0x06: INSUFF_ENCRYPTION_KEY_SIZE
  • 0x07: CMD_NOT_SUPPORTED
  • 0x08: UNSPECIFIED_REASON
  • 0x09: VERY_EARLY_NEXT_ATTEMPT
  • 0x0A: SM_INVALID_PARAMS
  • 0x0B: SMP_SC_DHKEY_CHECK_FAILED
  • 0x0C: SMP_SC_NUMCOMPARISON_FAILED
  • ACI_GAP_PASS_KEY_REQ_EVENT

    Description

    This event is generated by the Security manager to the application when a passkey is required for pairing. When this event is received, the application has to respond with the ACI_GAP_PASS_KEY_RESP command.

    Event parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the passkey has been requested.

    -

    ACI_GAP_AUTHORIZATION_REQ_EVENT

    Description

    This event is generated by the Security manager to the application when the application has set that authorization is required for reading/writing of attributes. This event will be generated as soon as the pairing is complete. When this event is received, ACI_GAP_AUTHORIZATION_RESP command should be used to respond by the application.

    Event parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which authorization has been requested.

    -

    ACI_GAP_SLAVE_SECURITY_INITIATED_EVENT

    Description

    This event is generated when the slave security request is successfully sent to the master.

    Event parameters

    None

    ACI_GAP_BOND_LOST_EVENT

    Description

    This event is generated when a pairing request is issued in response to a slave security request from a master which has previously bonded with the slave. When this event is received, the upper layer has to issue the command ACI_GAP_ALLOW_REBOND in order to allow the slave to continue the pairing process with the master.

    Event parameters

    None

    ACI_GAP_PROC_COMPLETE_EVENT

    Description

    This event is sent by the GAP to the upper layers when a procedure previously started has been terminated by the upper layer or has completed for any other reason

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Procedure_Code

    -

    1

    -

    Terminated procedure.

    -
  • 0x01: GAP_LIMITED_DISCOVERY_PROC
  • 0x02: GAP_GENERAL_DISCOVERY_PROC
  • 0x04: GAP_NAME_DISCOVERY_PROC
  • 0x08: GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC
  • 0x10: GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC
  • 0x20: GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC
  • 0x40: GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC
  • 0x80: GAP_OBSERVATION_PROC
  • Status

    -

    1

    -

    Status error code.

    -

    Data_Length

    -

    1

    -

    Length of Data in octets

    -

    Data

    -

    Data_Length

    -

    Procedure Specific Data: -- For Name Discovery Procedure: the name of the peer device if the procedure completed successfully.

    -

    ACI_GAP_ADDR_NOT_RESOLVED_EVENT

    Description

    This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral is unsuccessful in resolving the resolvable address of the peer device after connecting to it.

    Event parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the private address could not be resolved with any of the stored IRK's.

    -

    ACI_GAP_NUMERIC_COMPARISON_VALUE_EVENT

    Description

    This event is sent only during SC v.4.2 Pairing, when Numeric Comparison Association model is selected, in order to show the Numeric Value generated, and to ask for Confirmation to the User. When this event is received, the application has to respond with the ACI_GAP_NUMERIC_COMPARISON_RESP command.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle related to the underlying Pairing

    -

    Numeric_Value

    -

    4

    -

    ACI_GAP_KEYPRESS_NOTIFICATION_EVENT

    Description

    This event is sent only during SC v.4.2 Pairing, when Keypress Notifications are supported, in order to show the input type signalled by the peer device, having Keyboard only I/O capabilities. When this event is received, no action is required to the User.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle related to the underlying Pairing

    -

    Notification_Type

    -

    1

    -

    Type of Keypress input notified/signaled by peer device (having Keyboard only I/O capabilities

    -

    ACI GATT/ATT events

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Event nameVendor specific subevent codeBFPOLOBO
    ACI_GATT_ATTRIBUTE_MODIFIED_EVENT

    0x0C01

    -

    Y

    -

    Y

    -
    ACI_GATT_PROC_TIMEOUT_EVENT

    0x0C02

    -

    Y

    -

    Y

    -
    ACI_ATT_EXCHANGE_MTU_RESP_EVENT

    0x0C03

    -

    Y

    -

    Y

    -
    ACI_ATT_FIND_INFO_RESP_EVENT

    0x0C04

    -

    Y

    -
    ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT

    0x0C05

    -

    Y

    -
    ACI_ATT_READ_BY_TYPE_RESP_EVENT

    0x0C06

    -

    Y

    -
    ACI_ATT_READ_RESP_EVENT

    0x0C07

    -

    Y

    -
    ACI_ATT_READ_BLOB_RESP_EVENT

    0x0C08

    -

    Y

    -
    ACI_ATT_READ_MULTIPLE_RESP_EVENT

    0x0C09

    -

    Y

    -
    ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT

    0x0C0A

    -

    Y

    -
    ACI_ATT_PREPARE_WRITE_RESP_EVENT

    0x0C0C

    -

    Y

    -
    ACI_ATT_EXEC_WRITE_RESP_EVENT

    0x0C0D

    -

    Y

    -
    ACI_GATT_INDICATION_EVENT

    0x0C0E

    -

    Y

    -
    ACI_GATT_NOTIFICATION_EVENT

    0x0C0F

    -

    Y

    -
    ACI_GATT_PROC_COMPLETE_EVENT

    0x0C10

    -

    Y

    -

    Y

    -
    ACI_GATT_ERROR_RESP_EVENT

    0x0C11

    -

    Y

    -
    ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT

    0x0C12

    -

    Y

    -
    ACI_GATT_WRITE_PERMIT_REQ_EVENT

    0x0C13

    -

    Y

    -

    Y

    -
    ACI_GATT_READ_PERMIT_REQ_EVENT

    0x0C14

    -

    Y

    -

    Y

    -
    ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT

    0x0C15

    -

    Y

    -

    Y

    -
    ACI_GATT_TX_POOL_AVAILABLE_EVENT

    0x0C16

    -

    Y

    -

    Y

    -
    ACI_GATT_SERVER_CONFIRMATION_EVENT

    0x0C17

    -

    Y

    -

    Y

    -
    ACI_GATT_PREPARE_WRITE_PERMIT_REQ_EVENT

    0x0C18

    -

    Y

    -

    Y

    -
    ACI_GATT_READ_EXT_EVENT

    0x0C1D

    -

    Y

    -
    ACI_GATT_INDICATION_EXT_EVENT

    0x0C1E

    -

    Y

    -
    ACI_GATT_NOTIFICATION_EXT_EVENT

    0x0C1F

    -

    Y

    -

    ACI_GATT_ATTRIBUTE_MODIFIED_EVENT

    Description

    This event is generated to the application by the GATT server when a client modifies any attribute on the server, as consequence of one of the following GATT procedures:
    - write without response
    - signed write without response
    - write characteristic value
    - write long characteristic value
    - reliable write.

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    The connection handle which modified the attribute.

    -

    Attr_Handle

    -

    2

    -

    Handle of the attribute that was modified.

    -

    Offset

    -

    2

    -

    Bits 14-0: offset from which the write has been performed by the peer device. Bit 15 is used as flag: when set to 1 it indicates that more data are to come (fragmented event in case of long attribute data).

    -

    Attr_Data_Length

    -

    2

    -

    Length of Attr_Data in octets

    -

    Attr_Data

    -

    Attr_Data_Length

    -

    The modified value

    -

    ACI_GATT_PROC_TIMEOUT_EVENT

    Description

    This event is generated by the client/server to the application on a GATT timeout (30 seconds). This is a critical event that should not happen during normal operating conditions. It is an indication of either a major disruption in the communication link or a mistake in the application which does not provide a reply to GATT procedures. After this event, the GATT channel is closed and no more GATT communication can be performed. The applications is exptected to issue an ACI_GAP_TERMINATE to disconnect from the peer device. It is important to leave an 100 ms blank window before sending the ACI_GAP_TERMINATE, since immediately after this event, system could save important information in non volatile memory.

    Event parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle on which the GATT procedure has timed out

    -

    ACI_ATT_EXCHANGE_MTU_RESP_EVENT

    Description

    This event is generated in response to an Exchange MTU request. See ACI_GATT_EXCHANGE_CONFIG.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Server_RX_MTU

    -

    2

    -

    Attribute server receive MTU size

    -

    ACI_ATT_FIND_INFO_RESP_EVENT

    Description

    This event is generated in response to a Find Information Request. See ACI_ATT_FIND_INFO_REQ and Find Information Response in Bluetooth Core v5.0 spec. This event is also generated in response to ACI_GATT_DISC_ALL_CHAR_DESC

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Format

    -

    1

    -

    Format of the hanndle-uuid pairs

    -

    Event_Data_Length

    -

    1

    -

    Length of Handle_UUID_Pair in octets

    -

    Handle_UUID_Pair

    -

    Event_Data_Length

    -

    A sequence of handle-uuid pairs. if format=1, each pair is:[2 octets for handle, 2 octets for UUIDs], if format=2, each pair is:[2 octets for handle, 16 octets for UUIDs]

    -

    ACI_ATT_FIND_BY_TYPE_VALUE_RESP_EVENT

    Description

    This event is generated in response to a ACI_ATT_FIND_BY_TYPE_VALUE_REQ

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Num_of_Handle_Pair

    -

    1

    -

    Number of attribute, group handle pairs

    -

    Found_Attribute_Handle[i]

    -

    2

    -

    Found Attribute handle

    -

    Group_End_Handle[i]

    -

    2

    -

    Group End handle

    -

    ACI_ATT_READ_BY_TYPE_RESP_EVENT

    Description

    This event is generated in response to a ACI_ATT_READ_BY_TYPE_REQ. See ACI_GATT_FIND_INCLUDED_SERVICES and ACI_GATT_DISC_ALL_CHAR_DESC.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Handle_Value_Pair_Length

    -

    1

    -

    The size of each attribute handle-value pair

    -

    Data_Length

    -

    1

    -

    Length of Handle_Value_Pair_Data in octets

    -

    Handle_Value_Pair_Data

    -

    Data_Length

    -

    Attribute Data List as defined in Bluetooth Core v5.0 spec. A sequence of handle-value pairs: [2 octets for Attribute Handle, (Handle_Value_Pair_Length - 2 octets) for Attribute Value]

    -

    ACI_ATT_READ_RESP_EVENT

    Description

    This event is generated in response to a Read Request. See ACI_GATT_READ_CHAR_VALUE.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Event_Data_Length

    -

    1

    -

    Length of following data

    -

    Attribute_Value

    -

    Event_Data_Length

    -

    The value of the attribute.

    -

    ACI_ATT_READ_BLOB_RESP_EVENT

    Description

    This event can be generated during a read long characteristic value procedure. See ACI_GATT_READ_LONG_CHAR_VALUE.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Event_Data_Length

    -

    1

    -

    Length of following data

    -

    Attribute_Value

    -

    Event_Data_Length

    -

    Part of the attribute value.

    -

    ACI_ATT_READ_MULTIPLE_RESP_EVENT

    Description

    This event is generated in response to a Read Multiple Request.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Event_Data_Length

    -

    1

    -

    Length of following data

    -

    Set_Of_Values

    -

    Event_Data_Length

    -

    A set of two or more values. -A concatenation of attribute values for each of the attribute handles in the request in the order that they were requested.

    -

    ACI_ATT_READ_BY_GROUP_TYPE_RESP_EVENT

    Description

    This event is generated in response to a Read By Group Type Request. See ACI_GATT_DISC_ALL_PRIMARY_SERVICES.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Data_Length

    -

    1

    -

    The size of each attribute data

    -

    Data_Length

    -

    1

    -

    Length of Attribute_Data_List in octets

    -

    Attribute_Data_List

    -

    Data_Length

    -

    Attribute Data List as defined in Bluetooth Core v5.0 spec. A sequence of attribute handle, end group handle, attribute value tuples: [2 octets for Attribute Handle, 2 octets End Group Handle, (Attribute_Data_Length - 4 octets) for Attribute Value]

    -

    ACI_ATT_PREPARE_WRITE_RESP_EVENT

    Description

    This event is generated in response to a ACI_ATT_PREPARE_WRITE_REQ.

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute to be written

    -

    Offset

    -

    2

    -

    The offset of the first octet to be written.

    -

    Part_Attribute_Value_Length

    -

    1

    -

    Length of Part_Attribute_Value in octets

    -

    Part_Attribute_Value

    -

    Part_Attribute_Value_Length

    -

    The value of the attribute to be written

    -

    ACI_ATT_EXEC_WRITE_RESP_EVENT

    Description

    This event is generated in response to an Execute Write Request.

    Event parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • ACI_GATT_INDICATION_EVENT

    Description

    This event is generated when an indication is received from the server.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute

    -

    Attribute_Value_Length

    -

    1

    -

    Length of Attribute_Value in octets

    -

    Attribute_Value

    -

    Attribute_Value_Length

    -

    The current value of the attribute

    -

    ACI_GATT_NOTIFICATION_EVENT

    Description

    This event is generated when a notification is received from the server.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute

    -

    Attribute_Value_Length

    -

    1

    -

    Length of Attribute_Value in octets

    -

    Attribute_Value

    -

    Attribute_Value_Length

    -

    The current value of the attribute

    -

    ACI_GATT_PROC_COMPLETE_EVENT

    Description

    This event is generated when a GATT client procedure completes either with error or successfully.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Error_Code

    -

    1

    -

    Indicates whether the procedure completed with an error or was successful (see "Status error codes" section)

    -

    ACI_GATT_ERROR_RESP_EVENT

    Description

    This event is generated when an Error Response is received from the server. The error response can be given by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended with an error, but this error event is part of the procedure itself.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Req_Opcode

    -

    1

    -

    The request that generated this error response

    -

    Attribute_Handle

    -

    2

    -

    The attribute handle that generated this error response

    -

    Error_Code

    -

    1

    -

    The reason why the request has generated an error response (ATT error codes)

    -
  • 0x01: Invalid handle
  • 0x02: Read not permitted
  • 0x03: Write not permitted
  • 0x04: Invalid PDU
  • 0x05: Insufficient authentication
  • 0x06: Request not supported
  • 0x07: Invalid offset
  • 0x08: Insufficient authorization
  • 0x09: Prepare queue full
  • 0x0A: Attribute not found
  • 0x0B: Attribute not long
  • 0x0C: Insufficient encryption key size
  • 0x0D: Invalid attribute value length
  • 0x0E: Unlikely error
  • 0x0F: Insufficient encryption
  • 0x10: Unsupported group type
  • 0x11: Insufficient resources
  • ACI_GATT_DISC_READ_CHAR_BY_UUID_RESP_EVENT

    Description

    This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using Characteristic UUID" procedure.
    The attribute value will be a service declaration as defined in Bluetooth Core v5.0.spec (vol.3, Part G, ch. 3.3.1), when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a* "Read using Characteristic UUID" has been performed.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute

    -

    Attribute_Value_Length

    -

    1

    -

    Length of Attribute_Value in octets

    -

    Attribute_Value

    -

    Attribute_Value_Length

    -

    The attribute value will be a service declaration as defined in Bluetooth Core v5.0 (vol.3, Part G, ch. 3.3.1), when a "Discover Characteristics By UUID" has been started. -It will be the value of the Characteristic if a "Read using Characteristic UUID" has been performed.

    -

    ACI_GATT_WRITE_PERMIT_REQ_EVENT

    Description

    This event is given to the application when a write request, write command or signed write command is received by the server from the client. This event will be given to the application only if the event bit for this event generation is set when the characteristic was added.
    When this event is received, the application has to check whether the value being requested for write can be allowed to be written and respond with the command ACI_GATT_WRITE_RESP.
    The details of the parameters of the command can be found. Based on the response from the application, the attribute value will be modified by the stack. If the write is rejected by the application, then the value of the attribute will not be modified. In case of a write REQ, an error response will be sent to the client, with the error code as specified by the application.
    In case of write/signed write commands, no response is sent to the client but the attribute is not modified.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute

    -

    Data_Length

    -

    1

    -

    Length of Data field

    -

    Data

    -

    Data_Length

    -

    The data that the client has requested to write

    -

    ACI_GATT_READ_PERMIT_REQ_EVENT

    Description

    This event is given to the application when a read request or read blob request is received by the server from the client. This event will be given to the application only if the event bit for this event generation is set when the characteristic was added.
    On receiving this event, the application can update the value of the handle if it desires and when done, it has to send the ACI_GATT_ALLOW_READ command to indicate to the stack that it can send the response to the client.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute

    -

    Offset

    -

    2

    -

    Contains the offset from which the read has been requested

    -

    ACI_GATT_READ_MULTI_PERMIT_REQ_EVENT

    Description

    This event is given to the application when a read multiple request or read by type request is received by the server from the client. This event will be given to the application only if the event bit for this event generation is set when the characteristic was added.
    On receiving this event, the application can update the values of the handles if it desires and when done, it has to send the ACI_GATT_ALLOW_READ command to indicate to the stack that it can send the response to the client.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection which requested to read the attribute

    -

    Number_of_Handles

    -

    1

    -

    Handle[i]

    -

    2

    -

    ACI_GATT_TX_POOL_AVAILABLE_EVENT

    Description

    Each time BLE stack raises the error code BLE_STATUS_INSUFFICIENT_RESOURCES (0x64), the ACI_GATT_TX_POOL_AVAILABLE_EVENT event is generated as soon as there are at least two buffers available for notifications or write commands.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Available_Buffers

    -

    2

    -

    Number of buffers available

    -

    ACI_GATT_SERVER_CONFIRMATION_EVENT

    Description

    This event is generated when the client has sent the confirmation to a previously sent indication

    Event parameters

    - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • ACI_GATT_PREPARE_WRITE_PERMIT_REQ_EVENT

    Description

    This event is given to the application when a prepare write request is received by the server from the client. This event will be given to the application only if the event bit for this event generation is set when the characteristic was added.
    When this event is received, the application has to check whether the value being requested for write can be allowed to be written and respond with the command ACI_GATT_WRITE_RESP. Based on the response from the application, the attribute value will be modified by the stack.
    If the write is rejected by the application, then the value of the attribute will not be modified and an error response will be sent to the client, with the error code as specified by the application.

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute

    -

    Offset

    -

    2

    -

    The offset from which the prepare write has been requested

    -

    Data_Length

    -

    1

    -

    Length of Data field

    -

    Data

    -

    Data_Length

    -

    The data that the client has requested to write

    -

    ACI_GATT_READ_EXT_EVENT

    Description

    When it is enabled with ACI_GATT_SET_EVENT_MASK, this event is generated instead of ACI_ATT_READ_RESP_EVENT / ACI_ATT_READ_BLOB_RESP_EVENT / ACI_ATT_READ_MULTIPLE_RESP_EVENT.
    This event should be used instead of those events when ATT_MTU > (BLE_EVT_MAX_PARAM_LEN - 4) i.e. ATT_MTU > 251 for BLE_EVT_MAX_PARAM_LEN default value.

    Event parameters

    - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Offset

    -

    2

    -

    Bits 14-0: offset in octets from which Attribute_Value data starts. Bit 15 is used as flag: when set to 1 it indicates that more data are to come (fragmented event in case of long attribute data).

    -

    Event_Data_Length

    -

    2

    -

    Length of following data

    -

    Attribute_Value

    -

    Event_Data_Length

    -

    The value of the attribute(s).

    -

    ACI_GATT_INDICATION_EXT_EVENT

    Description

    When it is enabled with ACI_GATT_SET_EVENT_MASK and when an indication is received from the server, this event is generated instead of ACI_GATT_INDICATION_EVENT.
    This event should be used instead of ACI_GATT_INDICATION_EVENT when ATT_MTU > (BLE_EVT_MAX_PARAM_LEN - 4) i.e. ATT_MTU > 251 for BLE_EVT_MAX_PARAM_LEN default value.

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute

    -

    Offset

    -

    2

    -

    Bits 14-0: offset in octets from which Attribute_Value data starts. Bit 15 is used as flag: when set to 1 it indicates that more data are to come (fragmented event in case of long attribute data).

    -

    Attribute_Value_Length

    -

    2

    -

    Length of Attribute_Value in octets

    -

    Attribute_Value

    -

    Attribute_Value_Length

    -

    The current value of the attribute

    -

    ACI_GATT_NOTIFICATION_EXT_EVENT

    Description

    When it is enabled with ACI_GATT_SET_EVENT_MASK and when a notification is received from the server, this event is generated instead of ACI_GATT_NOTIFICATION_EVENT.
    This event should be used instead of ACI_GATT_NOTIFICATION_EVENT when ATT_MTU > (BLE_EVT_MAX_PARAM_LEN - 4) i.e. ATT_MTU > 251 for BLE_EVT_MAX_PARAM_LEN default value.

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Connection handle for which the event applies.

    -
  • 0x0000 ... 0x0EFF
  • Attribute_Handle

    -

    2

    -

    The handle of the attribute

    -

    Offset

    -

    2

    -

    Bits 14-0: offset in octets from which Attribute_Value data starts. Bit 15 is used as flag: when set to 1 it indicates that more data are to come (fragmented event in case of long attribute data).

    -

    Attribute_Value_Length

    -

    2

    -

    Length of Attribute_Value in octets

    -

    Attribute_Value

    -

    Attribute_Value_Length

    -

    The current value of the attribute

    -

    ACI L2CAP events

    - - - - - - - - - - - - - -
    Event nameVendor specific subevent codeBFPOLOBO
    ACI_L2CAP_CONNECTION_UPDATE_RESP_EVENT

    0x0800

    -

    Y

    -

    Y

    -
    ACI_L2CAP_PROC_TIMEOUT_EVENT

    0x0801

    -

    Y

    -

    Y

    -
    ACI_L2CAP_CONNECTION_UPDATE_REQ_EVENT

    0x0802

    -

    Y

    -
    ACI_L2CAP_COMMAND_REJECT_EVENT

    0x080A

    -

    Y

    -

    Y

    -
    ACI_L2CAP_COC_CONNECT_EVENT

    0x0810

    -
    ACI_L2CAP_COC_CONNECT_CONFIRM_EVENT

    0x0811

    -
    ACI_L2CAP_COC_RECONF_EVENT

    0x0812

    -
    ACI_L2CAP_COC_RECONF_CONFIRM_EVENT

    0x0813

    -
    ACI_L2CAP_COC_DISCONNECT_EVENT

    0x0814

    -
    ACI_L2CAP_COC_FLOW_CONTROL_EVENT

    0x0815

    -
    ACI_L2CAP_COC_RX_DATA_EVENT

    0x0816

    -
    ACI_L2CAP_COC_TX_POOL_AVAILABLE_EVENT

    0x0817

    -

    ACI_L2CAP_CONNECTION_UPDATE_RESP_EVENT

    Description

    This event is generated when the master responds to the connection update request packet with a connection update response packet.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection where this event occurred.

    -
  • 0x0000 ... 0x0EFF
  • Result

    -

    2

    -

    ACI_L2CAP_PROC_TIMEOUT_EVENT

    Description

    This event is generated when the master does not respond to the connection update request packet with a connection update response packet or a command reject packet within 30 seconds.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection where this event occurred.

    -
  • 0x0000 ... 0x0EFF
  • Data_Length

    -

    1

    -

    Length of following data

    -

    Data

    -

    Data_Length

    -

    ACI_L2CAP_CONNECTION_UPDATE_REQ_EVENT

    Description

    The event is given by the L2CAP layer when a connection update request is received from the slave. The upper layer which receives this event has to respond by sending a ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_RESP command.

    Event parameters

    - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection where this event occurred.

    -
  • 0x0000 ... 0x0EFF
  • Identifier

    -

    1

    -

    This is the identifier which associate the request to the response.

    -

    L2CAP_Length

    -

    2

    -

    Length of the L2CAP connection update request.

    -

    Interval_Min

    -

    2

    -

    Minimum value for the connection event interval. This shall be less than or equal to Conn_Interval_Max. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Interval_Max

    -

    2

    -

    Maximum value for the connection event interval. This shall be greater than or equal to Conn_Interval_Min. -Time = N * 1.25 msec.

    -
  • 0x0006 (7.50 ms) ... 0x0C80 (4000.00 ms)
  • Slave_Latency

    -

    2

    -

    Slave latency for the connection in number of connection events.

    -
  • 0x0000 ... 0x01F3
  • Timeout_Multiplier

    -

    2

    -

    Defines connection timeout parameter in the following manner: Timeout Multiplier * 10ms.

    -

    ACI_L2CAP_COMMAND_REJECT_EVENT

    Description

    This event is generated upon receipt of a valid Command Reject packet (e.g. when the master responds to the Connection Update Request packet with a Command Reject packet).

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection where this event occurred.

    -
  • 0x0000 ... 0x0EFF
  • Identifier

    -

    1

    -

    This is the identifier which associate the request to the response.

    -

    Reason

    -

    2

    -

    Reason

    -

    Data_Length

    -

    1

    -

    Length of following data

    -

    Data

    -

    Data_Length

    -

    Data field associated with Reason

    -

    ACI_L2CAP_COC_CONNECT_EVENT

    Description

    This event is generated when receiving a valid Credit Based Connection Request packet. See Bluetooth Core specification Vol.3 Part A.

    Event parameters

    - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection where this event occurred.

    -
  • 0x0000 ... 0x0EFF
  • SPSM

    -

    2

    -

    Simplified Protocol/Service Multiplexer.

    -
  • 0x0001 ... 0x00FF
  • MTU

    -

    2

    -

    Maximum Transmission Unit.

    -
  • 23 ... 65535
  • MPS

    -

    2

    -

    Maximum payload size (in octets).

    -
  • 23 ... 65533
  • Initial_Credits

    -

    2

    -

    Number of K-frames that can be received on the created channel(s) by the L2CAP layer entity sending this packet.

    -
  • 0 ... 65535
  • Channel_Number

    -

    1

    -

    Number of channels to be created. If this parameter is set to 0, it requests the creation of one LE credit based connection-oriented channel. Otherwise, it requests the creation of one or more enhanced credit based connection-oriented channels.

    -
  • 0 ... 5
  • ACI_L2CAP_COC_CONNECT_CONFIRM_EVENT

    Description

    This event is generated when receiving a valid Credit Based Connection Response packet. See Bluetooth Core specification Vol.3 Part A.

    Event parameters

    - - - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection where this event occurred.

    -
  • 0x0000 ... 0x0EFF
  • MTU

    -

    2

    -

    Maximum Transmission Unit.

    -
  • 23 ... 65535
  • MPS

    -

    2

    -

    Maximum payload size (in octets).

    -
  • 23 ... 65533
  • Initial_Credits

    -

    2

    -

    Number of K-frames that can be received on the created channel(s) by the L2CAP layer entity sending this packet.

    -
  • 0 ... 65535
  • Result

    -

    2

    -

    This parameter indicates the outcome of the request. A value of 0x0000 indicates success while a non-zero value indicates the request is refused.

    -
  • 0x0000 ... 0x000C
  • Channel_Number

    -

    1

    -

    Number of created channels. It is the length of Channel_Index_List.

    -
  • 0 ... 5
  • Channel_Index_List

    -

    Channel_Number

    -

    List of channel indexes for which the primitive applies.

    -

    ACI_L2CAP_COC_RECONF_EVENT

    Description

    This event is generated when receiving a valid Credit Based Reconfigure Request packet. See Bluetooth Core specification Vol.3 Part A.

    Event parameters

    - - - - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection where this event occurred.

    -
  • 0x0000 ... 0x0EFF
  • MTU

    -

    2

    -

    Maximum Transmission Unit.

    -
  • 23 ... 65535
  • MPS

    -

    2

    -

    Maximum payload size (in octets).

    -
  • 23 ... 65533
  • Channel_Number

    -

    1

    -

    Number of created channels. It is the length of Channel_Index_List.

    -
  • 1 ... 5
  • Channel_Index_List

    -

    Channel_Number

    -

    List of channel indexes for which the primitive applies.

    -

    ACI_L2CAP_COC_RECONF_CONFIRM_EVENT

    Description

    This event is generated when receiving a valid Credit Based Reconfigure Response packet. See Bluetooth Core specification Vol.3 Part A.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Connection_Handle

    -

    2

    -

    Handle of the connection where this event occurred.

    -
  • 0x0000 ... 0x0EFF
  • Result

    -

    2

    -

    This parameter indicates the outcome of the request. A value of 0x0000 indicates success while a non-zero value indicates the request is refused.

    -
  • 0x0000 ... 0x000C
  • ACI_L2CAP_COC_DISCONNECT_EVENT

    Description

    This event is generated when a connection-oriented channel is disconnected following an L2CAP channel termination procedure. See Bluetooth Core specification Vol.3 Part A.

    Event parameters

    - - -
    ParameterSizeDescriptionPossible values

    Channel_Index

    -

    1

    -

    Index of the connection-oriented channel for which the primitive applies.

    -

    ACI_L2CAP_COC_FLOW_CONTROL_EVENT

    Description

    This event is generated when receiving a valid Flow Control Credit signaling packet. See Bluetooth Core specification Vol.3 Part A.

    Event parameters

    - - - -
    ParameterSizeDescriptionPossible values

    Channel_Index

    -

    1

    -

    Index of the connection-oriented channel for which the primitive applies.

    -

    Credits

    -

    2

    -

    Number of credits the receiving device can increment, corresponding to the number of K-frames that can be sent to the peer device sending the Flow Control Credit packet.

    -
  • 1 ... 65535
  • ACI_L2CAP_COC_RX_DATA_EVENT

    Description

    This event is generated when receiving a valid K-frame packet on a connection-oriented channel. See Bluetooth Core specification Vol.3 Part A.
    Note: for the first K-frame of the SDU, the Information data contains the L2CAP SDU Length coded on two octets followed by the K-frame information payload. For the next K-frames of the SDU, the Information data only contains the K-frame information payload.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Channel_Index

    -

    1

    -

    Index of the connection-oriented channel for which the primitive applies.

    -

    Length

    -

    2

    -

    Length of Data (in octets)

    -

    Data

    -

    Length

    -

    Information data

    -

    ACI_L2CAP_COC_TX_POOL_AVAILABLE_EVENT

    Description

    Each time ACI_L2CAP_COC_TX_DATA raises the error code BLE_STATUS_INSUFFICIENT_RESOURCES (0x64), the ACI_L2CAP_COC_TX_POOL_AVAILABLE_EVENT event is generated as soon as there is a free buffer available for sending K-frames.

    Event parameters

    None

    ACI HAL events

    - - - - -
    Event nameVendor specific subevent codeBFPOLOBO
    ACI_HAL_END_OF_RADIO_ACTIVITY_EVENT

    0x0004

    -

    Y

    -

    Y

    -

    Y

    -

    Y

    -
    ACI_HAL_SCAN_REQ_REPORT_EVENT

    0x0005

    -
    ACI_HAL_FW_ERROR_EVENT

    0x0006

    -

    Y

    -

    Y

    -

    ACI_HAL_END_OF_RADIO_ACTIVITY_EVENT

    Description

    This event is generated when the device completes a radio activity and provide information when a new radio acitivity will be performed.
    Informtation provided includes type of radio activity and absolute time in system ticks when a new radio acitivity is schedule, if any. Application can use this information to schedule user activities synchronous to selected radio activitities. A command ACI_HAL_SET_RADIO_ACTIVITY_MASK is provided to enable radio activity events of user interests, by default no events are enabled.
    User should take into account that enablinng radio events in application with intense radio activity could lead to a fairly high rate of events generated.
    Application use cases includes synchronizing notification with connection interval, switiching antenna at the end of advertising or performing flash erase operation while radio is idle.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    Last_State

    -

    1

    -

    Completed radio events

    -
  • 0x00: Idle
  • 0x01: Advertising
  • 0x02: Connection event slave
  • 0x03: Scanning
  • 0x04: Connection request
  • 0x05: Connection event slave
  • 0x06: TX test mode
  • 0x07: RX test mode
  • Next_State

    -

    1

    -

    Incoming radio events

    -
  • 0x00: Idle
  • 0x01: Advertising
  • 0x02: Connection event slave
  • 0x03: Scanning
  • 0x04: Connection request
  • 0x05: Connection event slave
  • 0x06: TX test mode
  • 0x07: RX test mode
  • Next_State_SysTime

    -

    4

    -

    32bit absolute current time expressed in internal time units.

    -

    ACI_HAL_SCAN_REQ_REPORT_EVENT

    Description

    This event is reported to the application after a scan request is received and a scan reponse is scheduled to be transmitted.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    RSSI

    -

    1

    -

    N Size: 1 Octet (signed integer) -Units: dBm

    -
  • 127: RSSI not available
  • -127 ... 20
  • Peer_Address_Type

    -

    1

    -

    Address type -0x00 Public Device Address -0x01 Random Device Address -0x02 Public Identity Address (Corresponds to Resolved Private Address) -0x03 Random (Static) Identity Address (Corresponds to Resolved Private Address)

    -
  • 0x00: Public Device Address
  • 0x01: Random Device Address
  • 0x02: Public Identity Address
  • 0x03: Random (Static) Identity Address
  • Peer_Address

    -

    6

    -

    Public Device Address or Random Device Address of the peer device

    -

    ACI_HAL_FW_ERROR_EVENT

    Description

    This event is generated to report firmware error information.

    Event parameters

    - - - - -
    ParameterSizeDescriptionPossible values

    FW_Error_Type

    -

    1

    -

    FW Error type

    -
  • 0x01: L2CAP recombination failure
  • 0x02: GATT unexpected peer message
  • 0x03: NVM level warning
  • 0x04: COC RX data length too large
  • Data_Length

    -

    1

    -

    Length of Data in octets

    -

    Data

    -

    Data_Length

    -

    The error event info

    -

    Status error codes

    Status error codes are used for the return status of all commands. Only the codes from 0 to 0x3E are used for HCI commands (see Core Specification v5.0, Vol. 2, part D), while more codes are defined for ACI commands (see table below).

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Status error codeDescription

    0x00

    -

    Success

    -

    0x01

    -

    Unknown HCI Command

    -

    0x02

    -

    Unknown Connection Identifier

    -

    0x03

    -

    Hardware Failure

    -

    0x05

    -

    Authentication Failure

    -

    0x06

    -

    PIN or Key Missing

    -

    0x07

    -

    Memory Capacity Exceeded

    -

    0x08

    -

    Connection Timeout

    -

    0x09

    -

    Connection Limit Exceeded

    -

    0x0B

    -

    ACL Connection Already Exists

    -

    0x0C

    -

    Command Disallowed

    -

    0x0D

    -

    Connection Rejected Due To Limited Resources

    -

    0x0E

    -

    Connection Rejected Due To Security Reasons

    -

    0x0F

    -

    Connection Rejected due to Unacceptable BD_ADDR

    -

    0x10

    -

    Connection Accept Timeout Exceeded

    -

    0x11

    -

    Unsupported Feature Or Parameter Value

    -

    0x12

    -

    Invalid HCI Command Parameters

    -

    0x13

    -

    Remote User Terminated Connection

    -

    0x14

    -

    Remote Device Terminated Connection due to Low Resources

    -

    0x15

    -

    Remote Device Terminated Connection due to Power Off

    -

    0x16

    -

    Connection Terminated By Local Host

    -

    0x17

    -

    Repeated Attempts

    -

    0x18

    -

    Pairing Not Allowed

    -

    0x19

    -

    Unknown LMP PDU

    -

    0x1A

    -

    Unsupported Remote Feature / Unsupported LMP Feature

    -

    0x1E

    -

    Invalid LMP Parameters

    -

    0x1F

    -

    Unspecified Error

    -

    0x20

    -

    Unsupported LMP Parameter Value

    -

    0x21

    -

    Role Change Not Allowed

    -

    0x22

    -

    LMP Response Timeout / LL Response Timeout

    -

    0x23

    -

    LMP Error Transaction Collision

    -

    0x24

    -

    LMP PDU Not Allowed

    -

    0x25

    -

    Encryption Mode Not Acceptable

    -

    0x26

    -

    Link Key cannot be Changed

    -

    0x28

    -

    Instant Passed

    -

    0x29

    -

    Pairing With Unit Key Not Supported

    -

    0x2A

    -

    Different Transaction Collision

    -

    0x2E

    -

    Channel Assessment Not Supported

    -

    0x2F

    -

    Insufficient Security

    -

    0x30

    -

    Parameter Out Of Mandatory Range

    -

    0x32

    -

    Role Switch Pending

    -

    0x34

    -

    Reserved Slot Violation

    -

    0x35

    -

    Role Switch Failed

    -

    0x37

    -

    Secure Simple Pairing Not Supported by Host

    -

    0x38

    -

    Host Busy - Pairing

    -

    0x39

    -

    Connection Rejected due to No Suitable Channel Found

    -

    0x3A

    -

    Controller Busy

    -

    0x3B

    -

    Unacceptable Connection Interval

    -

    0x3C

    -

    Directed Advertising Timeout

    -

    0x3D

    -

    Connection Terminated Due to MIC Failure

    -

    0x3E

    -

    Connection Failed to be Established

    -

    0x40

    -

    Unknown connection identifier at SMP level

    -

    0x41

    -

    Failed

    -

    0x42

    -

    Invalid parameters

    -

    0x43

    -

    Busy

    -

    0x45

    -

    Pending

    -

    0x46

    -

    Not allowed

    -

    0x47

    -

    Host error

    -

    0x48

    -

    Out of memory

    -

    0x50

    -

    Invalid CID

    -

    0x59

    -

    Device in blacklist

    -

    0x5A

    -

    CSRK not found

    -

    0x5B

    -

    IRK not found

    -

    0x5C

    -

    Device not found in DB

    -

    0x5D

    -

    Security DB full

    -

    0x5E

    -

    Device not bonded

    -

    0x5F

    -

    Insufficient encryption key size

    -

    0x60

    -

    Invalid handle

    -

    0x61

    -

    Out of handles

    -

    0x62

    -

    Invalid operation

    -

    0x63

    -

    Characteristic already exist

    -

    0x64

    -

    Insufficient resources

    -

    0x65

    -

    Security permission error

    -

    0x70

    -

    Address not resolved

    -

    0x82

    -

    No valid slot

    -

    0x83

    -

    Short window

    -

    0x84

    -

    New interval failed

    -

    0x85

    -

    Too large interval

    -

    0x86

    -

    Slot length failed

    -
    \ No newline at end of file diff --git a/lib_blewbxx/core/template/ble_bufsize.h b/lib_blewbxx/core/template/ble_bufsize.h deleted file mode 100644 index 40c68dacd..000000000 --- a/lib_blewbxx/core/template/ble_bufsize.h +++ /dev/null @@ -1,157 +0,0 @@ -/***************************************************************************** - * @file ble_bufsize.h - * @author MCD - * @brief Definition of BLE stack buffers size - ***************************************************************************** - * @attention - * - *

    © Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

    - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ***************************************************************************** - */ - -#ifndef BLE_BUFSIZE_H__ -#define BLE_BUFSIZE_H__ - - -/* - * BLE_DEFAULT_ATT_MTU: minimum MTU value that GATT must support. - */ -#define BLE_DEFAULT_ATT_MTU 23 - -/* - * BLE_DEFAULT_MAX_ATT_SIZE: maximum attribute size. - */ -#define BLE_DEFAULT_MAX_ATT_SIZE 512 - -/* - * BLE_PREP_WRITE_X_ATT: compute how many Prepare Write Request are needed to - * write a characteristic with size 'max_att' when the used ATT_MTU value is - * equal to BLE_DEFAULT_ATT_MTU (23). - */ -#define BLE_PREP_WRITE_X_ATT(max_att) \ - (DIVC(max_att, BLE_DEFAULT_ATT_MTU - 5) * 2) - -/* - * BLE_DEFAULT_PREP_WRITE_LIST_SIZE: default minimum Prepare Write List size. - */ -#define BLE_DEFAULT_PREP_WRITE_LIST_SIZE \ - BLE_PREP_WRITE_X_ATT(BLE_DEFAULT_MAX_ATT_SIZE) - -/* - * BLE_MEM_BLOCK_X_MTU: compute how many memory blocks are needed to compose - * an ATT packet with ATT_MTU=mtu. - */ -#define BLE_MEM_BLOCK_SIZE 32 - -#define BLE_MEM_BLOCK_X_TX(mtu) \ - (DIVC((mtu) + 4U, BLE_MEM_BLOCK_SIZE) + 1U) - -#define BLE_MEM_BLOCK_X_RX(mtu, n_link) \ - ((DIVC((mtu) + 4U, BLE_MEM_BLOCK_SIZE) + 2U) * (n_link) + 1) - -#define BLE_MEM_BLOCK_X_MTU(mtu, n_link) \ - (BLE_MEM_BLOCK_X_TX(mtu) + BLE_MEM_BLOCK_X_RX(mtu, n_link)) - -/* - * BLE_MBLOCKS_SECURE_CONNECTIONS: minimum number of blocks required for - * secure connections - */ -#define BLE_MBLOCKS_SECURE_CONNECTIONS 4 - -/* - * BLE_MBLOCKS_CALC: minimum number of buffers needed by the stack. - * This is the minimum racomanded value and depends on: - * - pw: size of Prepare Write List - * - mtu: ATT_MTU size - * - n_link: maximum number of simultaneous connections - */ -#define BLE_MBLOCKS_CALC(pw, mtu, n_link) \ - ((pw) + MAX(BLE_MEM_BLOCK_X_MTU(mtu, n_link), \ - BLE_MBLOCKS_SECURE_CONNECTIONS)) - -/* - * BLE_FIXED_BUFFER_SIZE_BYTES: - * A part of the RAM, is dinamically allocated by initilizing all the pointers - * defined in a global context variable "mem_alloc_ctx_p". - * This initialization is made in the Dynamic_allocator functions, which - * assing a portion of RAM given by the external application to the above - * mentioned "global pointers". - * - * The size of this Dynamic RAM is made of 2 main components: - * - a part that is parameters-dependent (num of links, GATT buffers, ...), - * and which value is explicited by the following macro; - * - a part, that may be considered "fixed", i.e. independent from the above - * mentioned parameters. -*/ -#if (BEACON_ONLY != 0) -#define BLE_FIXED_BUFFER_SIZE_BYTES 6212 /* Beacon only */ -#elif (LL_ONLY != 0) -#define BLE_FIXED_BUFFER_SIZE_BYTES 6272 /* LL only */ -#elif (SLAVE_ONLY != 0) -#define BLE_FIXED_BUFFER_SIZE_BYTES 6712 /* Peripheral only */ -#elif (BASIC_FEATURES != 0) -#define BLE_FIXED_BUFFER_SIZE_BYTES 6972 /* Basic Features */ -#else -#define BLE_FIXED_BUFFER_SIZE_BYTES 7240 /* Full stack */ -#endif - -/* - * BLE_PER_LINK_SIZE_BYTES: additional memory size used per link - */ -#if (BEACON_ONLY != 0) -#define BLE_PER_LINK_SIZE_BYTES 148 /* Beacon only */ -#elif (LL_ONLY != 0) -#define BLE_PER_LINK_SIZE_BYTES 196 /* LL only */ -#elif (SLAVE_ONLY != 0) -#define BLE_PER_LINK_SIZE_BYTES 332 /* Peripheral only */ -#elif (BASIC_FEATURES != 0) -#define BLE_PER_LINK_SIZE_BYTES 332 /* Basic Features */ -#else -#define BLE_PER_LINK_SIZE_BYTES 384 /* Full stack */ -#endif - -/* - * BLE_TOTAL_BUFFER_SIZE: this macro returns the amount of memory, in bytes, - * needed for the storage of data structures (except GATT database elements) - * whose size depends on the number of supported connections. - * - * @param n_link: Maximum number of simultaneous connections that the device - * will support. Valid values are from 1 to 8. - * - * @param mblocks_count: Number of memory blocks allocated for packets. - */ -#define BLE_TOTAL_BUFFER_SIZE(n_link, mblocks_count) \ - (BLE_FIXED_BUFFER_SIZE_BYTES + \ - (BLE_PER_LINK_SIZE_BYTES * (n_link)) + \ - ((BLE_MEM_BLOCK_SIZE + 12) * (mblocks_count))) - -/* - * BLE_TOTAL_BUFFER_SIZE_GATT: this macro returns the amount of memory, - * in bytes, needed for the storage of GATT database elements. - * - * @param num_gatt_attributes: Maximum number of Attributes (i.e. the number - * of characteristic + the number of characteristic values + the number of - * descriptors, excluding the services) that can be stored in the GATT - * database. Note that certain characteristics and relative descriptors are - * added automatically during device initialization so this parameters should - * be 9 plus the number of user Attributes - * - * @param num_gatt_services: Maximum number of Services that can be stored in - * the GATT database. Note that the GAP and GATT services are automatically - * added so this parameter should be 2 plus the number of user services - * - * @param att_value_array_size: Size of the storage area for Attribute values. - */ -#define BLE_TOTAL_BUFFER_SIZE_GATT(num_gatt_attributes, num_gatt_services, att_value_array_size) \ - (((((att_value_array_size) - 1) | 3) + 1) + \ - (40 * (num_gatt_attributes)) + (48 * (num_gatt_services))) - - -#endif /* BLE_BUFSIZE_H__ */ diff --git a/lib_blewbxx/core/template/compiler.h b/lib_blewbxx/core/template/compiler.h deleted file mode 100644 index d02c30fe5..000000000 --- a/lib_blewbxx/core/template/compiler.h +++ /dev/null @@ -1,156 +0,0 @@ -/***************************************************************************** - * @file compiler.h - * @author MCD - * @brief This file contains the definitions which are compiler dependent. - ***************************************************************************** - * @attention - * - *

    © Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

    - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef COMPILER_H__ -#define COMPILER_H__ - - -/** - * @brief This is the section dedicated to IAR toolchain - */ -#if defined(__ICCARM__) || defined(__IAR_SYSTEMS_ASM__) - -#ifndef __WEAK -#define __WEAK __weak -#endif - -#define QUOTE_(a) #a - -/** - * @brief PACKED - * Use the PACKED macro for variables that needs to be packed. - * Usage: PACKED(struct) myStruct_s - * PACKED(union) myStruct_s - */ -#define PACKED(decl) __packed decl - -/** - * @brief SECTION - * Use the SECTION macro to assign data or code in a specific section. - * Usage: SECTION(".my_section") - */ -#define SECTION(name) _Pragma(QUOTE_(location=name)) - -/** - * @brief ALIGN_DEF - * Use the ALIGN_DEF macro to specify the alignment of a variable. - * Usage: ALIGN_DEF(4) - */ -#define ALIGN_DEF(v) _Pragma(QUOTE_(data_alignment=v)) - -/** - * @brief NO_INIT - * Use the NO_INIT macro to declare a not initialized variable. - * Usage: NO_INIT(int my_no_init_var) - * Usage: NO_INIT(uint16_t my_no_init_array[10]) - */ -#define NO_INIT(var) __no_init var - -/** - * @brief This is the section dedicated to GNU toolchain - */ -#else -#ifdef __GNUC__ - -#ifndef __WEAK -#define __WEAK __attribute__((weak)) -#endif - -/** - * @brief PACKED - * Use the PACKED macro for variables that needs to be packed. - * Usage: PACKED(struct) myStruct_s - * PACKED(union) myStruct_s - */ -#undef PACKED -#define PACKED(decl) decl __attribute__((packed)) - -/** - * @brief SECTION - * Use the SECTION macro to assign data or code in a specific section. - * Usage: SECTION(".my_section") - */ -#define SECTION(name) __attribute__((section(name))) - -/** - * @brief ALIGN_DEF - * Use the ALIGN_DEF macro to specify the alignment of a variable. - * Usage: ALIGN_DEF(4) - */ -#define ALIGN_DEF(N) __attribute__((aligned(N))) - -/** - * @brief NO_INIT - * Use the NO_INIT macro to declare a not initialized variable. - * Usage: NO_INIT(int my_no_init_var) - * Usage: NO_INIT(uint16_t my_no_init_array[10]) - */ -#define NO_INIT(var) var __attribute__((section(".noinit"))) - -/** - * @brief This is the section dedicated to Keil toolchain - */ -#else -#ifdef __CC_ARM - -#ifndef __WEAK -#define __WEAK __weak -#endif - -/** - * @brief PACKED - * Use the PACKED macro for variables that needs to be packed. - * Usage: PACKED(struct) myStruct_s - * PACKED(union) myStruct_s - */ -#define PACKED(decl) decl __attribute__((packed)) - -/** - * @brief SECTION - * Use the SECTION macro to assign data or code in a specific section. - * Usage: SECTION(".my_section") - */ -#define SECTION(name) __attribute__((section(name))) - -/** - * @brief ALIGN_DEF - * Use the ALIGN_DEF macro to specify the alignment of a variable. - * Usage: ALIGN_DEF(4) - */ -#define ALIGN_DEF(N) __attribute__((aligned(N))) - -/** - * @brief NO_INIT - * Use the NO_INIT macro to declare a not initialized variable. - * Usage: NO_INIT(int my_no_init_var) - * Usage: NO_INIT(uint16_t my_no_init_array[10]) - */ -#define NO_INIT(var) var __attribute__((section("NoInit"))) - -#else - -#error Neither ICCARM, CC ARM nor GNUC C detected. Define your macros. - -#endif -#endif -#endif - - -#endif /* COMPILER_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***/ diff --git a/lib_blewbxx/core/template/osal.c b/lib_blewbxx/core/template/osal.c deleted file mode 100644 index 6d662798e..000000000 --- a/lib_blewbxx/core/template/osal.c +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************** - * @file osal.c - * @author MCD - * @brief Implements the interface defined in "osal.h" needed by the stack. - * Actually, only memset, memcpy and memcmp wrappers are implemented. - ***************************************************************************** - * @attention - * - *

    © Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

    - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#include -#include "osal.h" - - -/** - * Osal_MemCpy - * - */ - -void* Osal_MemCpy( void *dest, const void *src, unsigned int size ) -{ - return memcpy( dest, src, size ); -} - -/** - * Osal_MemSet - * - */ - -void* Osal_MemSet( void *ptr, int value, unsigned int size ) -{ - return memset( ptr, value, size ); -} - -/** - * Osal_MemCmp - * - */ -int Osal_MemCmp( const void *s1, const void *s2, unsigned int size ) -{ - return memcmp( s1, s2, size ); -} diff --git a/lib_blewbxx/core/template/osal.h b/lib_blewbxx/core/template/osal.h deleted file mode 100644 index abfa90733..000000000 --- a/lib_blewbxx/core/template/osal.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************** - * @file osal.h - * @author MCD - * @brief This header file defines the OS abstraction layer used by - * the BLE stack. OSAL defines the set of functions which needs to be - * ported to target operating system and target platform. - * Actually, only memset, memcpy and memcmp wrappers are defined. - ***************************************************************************** - * @attention - * - *

    © Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

    - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#ifndef OSAL_H__ -#define OSAL_H__ - - -/** - * This function copies size number of bytes from a - * memory location pointed by src to a destination - * memory location pointed by dest - * - * @param[in] dest Destination address - * @param[in] src Source address - * @param[in] size size in the bytes - * - * @return Address of the destination - */ - -extern void* Osal_MemCpy( void *dest, const void *src, unsigned int size ); - -/** - * This function sets first number of bytes, specified - * by size, to the destination memory pointed by ptr - * to the specified value - * - * @param[in] ptr Destination address - * @param[in] value Value to be set - * @param[in] size Size in the bytes - * - * @return Address of the destination - */ - -extern void* Osal_MemSet( void *ptr, int value, unsigned int size ); - -/** - * This function compares n bytes of two regions of memory - * - * @param[in] s1 First buffer to compare. - * @param[in] s2 Second buffer to compare. - * @param[in] size Number of bytes to compare. - * - * @return 0 if the two buffers are equal, 1 otherwise - */ -extern int Osal_MemCmp( const void *s1, const void *s2, unsigned int size ); - - -#endif /* OSAL_H__ */ diff --git a/lib_blewbxx/include/ble_cmd.h b/lib_blewbxx/include/ble_cmd.h new file mode 100644 index 000000000..f4351dda0 --- /dev/null +++ b/lib_blewbxx/include/ble_cmd.h @@ -0,0 +1,100 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include +#include "ble_types.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + uint16_t hci_cmd_opcode; + uint8_t hci_cmd_buffer[255]; + uint16_t hci_cmd_buffer_length; +} ble_cmd_data_t; + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ + +/* HCI cmd */ +void ble_hci_forge_cmd_reset(ble_cmd_data_t *cmd_data); +void ble_hci_forge_cmd_disconnect(ble_cmd_data_t *cmd_data, uint16_t connection_handle); +void ble_hci_forge_cmd_set_scan_response_data(ble_cmd_data_t *cmd_data, + uint8_t scan_response_data_length, + const uint8_t *scan_response_data); + +/* ACI HAL cmd */ +void ble_aci_hal_forge_cmd_write_config_data(ble_cmd_data_t *cmd_data, + uint8_t offset, + uint8_t length, + const uint8_t *value); +void ble_aci_hal_forge_cmd_set_tx_power_level(ble_cmd_data_t *cmd_data, + uint8_t enable_high_power, + uint8_t pa_level); + +/* ACI GAP cmd */ +void ble_aci_gap_forge_cmd_init(ble_cmd_data_t *cmd_data, + uint8_t role, + uint8_t privacy_enabled, + uint8_t device_name_char_len); +void ble_aci_gap_forge_cmd_set_io_capability(ble_cmd_data_t *cmd_data, uint8_t io_capability); +void ble_aci_gap_forge_cmd_set_authentication_requirement(ble_cmd_data_t *cmd_data, + ble_cmd_set_auth_req_data_t *data); +void ble_aci_gap_forge_cmd_numeric_comparison_value_confirm_yesno(ble_cmd_data_t *cmd_data, + uint16_t connection_handle, + uint8_t confirm_yes_no); +void ble_aci_gap_forge_cmd_pass_key_resp(ble_cmd_data_t *cmd_data, + uint16_t connection_handle, + uint32_t pass_key); +void ble_aci_gap_forge_cmd_clear_security_db(ble_cmd_data_t *cmd_data); +void ble_aci_gap_forge_cmd_set_discoverable(ble_cmd_data_t *cmd_data, + ble_cmd_set_discoverable_data_t *data); +void ble_aci_gap_forge_cmd_set_non_discoverable(ble_cmd_data_t *cmd_data); +void ble_aci_gap_forge_cmd_update_adv_data(ble_cmd_data_t *cmd_data, + uint8_t adv_data_length, + const uint8_t *adv_data); + +/* ACI L2CAP cmd */ +void ble_aci_l2cap_forge_cmd_connection_parameter_update(ble_cmd_data_t *cmd_data, + uint16_t connection_handle, + uint16_t min_conn_interval, + uint16_t max_conn_interval, + uint16_t conn_latency, + uint16_t supervision_timeout); + +/* ACI GATT cmd */ +void ble_aci_gatt_forge_cmd_init(ble_cmd_data_t *cmd_data); +void ble_aci_gatt_forge_cmd_add_service(ble_cmd_data_t *cmd_data, + uint8_t service_uuid_type, + const uint8_t *service_uuid, + uint8_t service_type, + uint8_t max_attribute_records); +void ble_aci_gatt_forge_cmd_add_char(ble_cmd_data_t *cmd_data, ble_cmd_add_char_data_t *data); +void ble_aci_gatt_forge_cmd_update_char_value(ble_cmd_data_t *cmd_data, + uint16_t service_handle, + uint16_t char_handle, + uint8_t val_offset, + uint8_t char_value_length, + const uint8_t *char_value); +void ble_aci_gatt_forge_cmd_write_resp(ble_cmd_data_t *cmd_data, + uint16_t connection_handle, + uint16_t attribute_handle, + uint8_t write_status, + uint8_t error_code, + uint8_t attribute_val_length, + const uint8_t *attribute_val); +void ble_aci_gatt_forge_cmd_confirm_indication(ble_cmd_data_t *cmd_data, + uint16_t connection_handle); +void ble_aci_gatt_forge_cmd_exchange_config(ble_cmd_data_t *cmd_data, uint16_t connection_handle); + +/* +aci_gap_clear_security_db(); +aci_gap_pass_key_resp +*/ diff --git a/lib_blewbxx/include/ble_ledger.h b/lib_blewbxx/include/ble_ledger.h new file mode 100644 index 000000000..ddda34d22 --- /dev/null +++ b/lib_blewbxx/include/ble_ledger.h @@ -0,0 +1,67 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include +#include "os_id.h" +#include "lcx_crc.h" +#include "ble_types.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + BLE_LEDGER_PROFILE_APDU = 0x0001, + BLE_LEDGER_PROFILE_U2F = 0x0004, +} ble_ledger_profile_mask_e; + +/* Exported defines --------------------------------------------------------*/ +#define LEDGER_BLE_get_mac_address(address) \ + { \ + unsigned char se_serial[8] = {0}; \ + os_serial(se_serial, sizeof(se_serial)); \ + unsigned int uid = cx_crc16(se_serial, 4); \ + address[0] = uid; \ + address[1] = uid >> 8; \ + uid = cx_crc16(se_serial + 4, 4); \ + address[2] = uid; \ + address[3] = uid >> 8; \ + address[4] = 0xF3; \ + address[5] = 0xDE; \ + } + +#define BLE_SLAVE_CONN_INTERVAL_MIN 12 // 15ms +#define BLE_SLAVE_CONN_INTERVAL_MAX 24 // 30ms + +#define BLE_ADVERTISING_INTERVAL_MIN 48 // 30ms +#define BLE_ADVERTISING_INTERVAL_MAX 96 // 60ms + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern uint8_t BLE_LEDGER_apdu_buffer[OS_IO_BUFFER_SIZE + 1]; + +/* Exported functions prototypes--------------------------------------------- */ +void BLE_LEDGER_init(os_io_init_ble_t *init, uint8_t force_restart); +void BLE_LEDGER_start(void); +void BLE_LEDGER_stop(void); + +void BLE_LEDGER_reset_pairings(void); +void BLE_LEDGER_accept_pairing(uint8_t status); +void BLE_LEDGER_name_changed(void); + +// Rx +int BLE_LEDGER_rx_seph_evt(uint8_t *seph_buffer, + uint16_t seph_buffer_length, + uint8_t *apdu_buffer, + uint16_t apdu_buffer_max_length); + +// Tx +uint32_t BLE_LEDGER_send(const uint8_t *packet, uint16_t packet_length, uint32_t timeout_ms); + +// Check APDU +int32_t BLE_LEDGER_data_ready(uint8_t *buffer, uint16_t max_length); + +// Setting +void BLE_LEDGER_setting(uint32_t profile_id, uint32_t setting_id, uint8_t *buffer, uint16_t length); diff --git a/lib_blewbxx/include/ble_ledger_profile_apdu.h b/lib_blewbxx/include/ble_ledger_profile_apdu.h new file mode 100644 index 000000000..5a1051514 --- /dev/null +++ b/lib_blewbxx/include/ble_ledger_profile_apdu.h @@ -0,0 +1,46 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include +#include "ble_cmd.h" +#include "ble_ledger_types.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + BLE_LEDGER_PROFILE_APDU_SETTING_ID_TRANSFER_MODE = 1, +} ble_ledger_profile_apdu_setting_id_e; + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern const ble_profile_info_t BLE_LEDGER_PROFILE_apdu_info; + +/* Exported functions prototypes--------------------------------------------- */ +void BLE_LEDGER_PROFILE_apdu_init(ble_cmd_data_t *cmd_data, void *cookie); +uint8_t BLE_LEDGER_PROFILE_apdu_create_db(uint8_t *hci_buffer, uint16_t length, void *cookie); +uint8_t BLE_LEDGER_PROFILE_apdu_handle_in_range(uint16_t gatt_handle, void *cookie); + +void BLE_LEDGER_PROFILE_apdu_connection_evt(ble_connection_t *connection, void *cookie); +void BLE_LEDGER_PROFILE_apdu_connection_update_evt(ble_connection_t *connection, void *cookie); +void BLE_LEDGER_PROFILE_apdu_encryption_changed(uint8_t encrypted, void *cookie); + +uint8_t BLE_LEDGER_PROFILE_apdu_att_modified(uint8_t *hci_buffer, uint16_t length, void *cookie); +uint8_t BLE_LEDGER_PROFILE_apdu_write_permit_req(uint8_t *hci_buffer, + uint16_t length, + void *cookie); +uint8_t BLE_LEDGER_PROFILE_apdu_mtu_changed(uint16_t mtu, void *cookie); + +uint8_t BLE_LEDGER_PROFILE_apdu_write_rsp_ack(void *cookie); +uint8_t BLE_LEDGER_PROFILE_apdu_update_char_value_ack(void *cookie); + +uint8_t BLE_LEDGER_PROFILE_apdu_send_packet(const uint8_t *packet, uint16_t length, void *cookie); + +int32_t BLE_LEDGER_PROFILE_apdu_data_ready(uint8_t *buffer, uint16_t max_length, void *cookie); + +void BLE_LEDGER_PROFILE_apdu_setting(uint32_t id, uint8_t *buffer, uint16_t length, void *cookie); diff --git a/lib_blewbxx/include/ble_ledger_profile_u2f.h b/lib_blewbxx/include/ble_ledger_profile_u2f.h new file mode 100644 index 000000000..e69de29bb diff --git a/lib_blewbxx/include/ble_ledger_types.h b/lib_blewbxx/include/ble_ledger_types.h new file mode 100644 index 000000000..a6f1b1a10 --- /dev/null +++ b/lib_blewbxx/include/ble_ledger_types.h @@ -0,0 +1,95 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include +#include "ble_types.h" +#include "ble_cmd.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + BLE_PROFILE_STATUS_OK = 0x00, + BLE_PROFILE_STATUS_OK_AND_SEND_PACKET = 0x01, + BLE_PROFILE_STATUS_OK_PROCEDURE_END = 0x02, + BLE_PROFILE_STATUS_BAD_PARAMETERS = 0xFF, +} ble_profile_status_e; + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + uint16_t connection_handle; + uint8_t role_slave; + uint8_t peer_address_random; + uint8_t peer_address[6]; + uint16_t conn_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; + uint8_t tx_phy; + uint8_t rx_phy; + uint16_t max_tx_octets; + uint16_t max_tx_time; + uint16_t max_rx_octets; + uint16_t max_rx_time; + uint8_t encrypted; +} ble_connection_t; + +typedef void (*ble_profile_init_t)(ble_cmd_data_t *cmd_data, void *cookie); +typedef uint8_t (*ble_profile_create_db_t)(uint8_t *hci_buffer, uint16_t length, void *cookie); +typedef uint8_t (*ble_profile_handle_in_range_t)(uint16_t gatt_handle, void *cookie); + +typedef void (*ble_profile_connection_evt_t)(ble_connection_t *connection, void *cookie); +typedef void (*ble_profile_connection_update_evt_t)(ble_connection_t *connection, void *cookie); +typedef void (*ble_profile_encryption_changed_t)(uint8_t encrypted, void *cookie); + +typedef uint8_t (*ble_profile_att_modified_t)(uint8_t *hci_buffer, uint16_t length, void *cookie); +typedef uint8_t (*ble_profile_write_permit_req_t)(uint8_t *hci_buffer, + uint16_t length, + void *cookie); +typedef uint8_t (*ble_profile_mtu_changed_t)(uint16_t mtu, void *cookie); + +typedef uint8_t (*ble_profile_write_rsp_ack_t)(void *cookie); +typedef uint8_t (*ble_profile_update_char_value_ack_t)(void *cookie); + +typedef uint8_t (*ble_profile_send_packet_t)(const uint8_t *packet, uint16_t length, void *cookie); + +typedef int32_t (*ble_profile_data_ready_t)(uint8_t *buffer, uint16_t max_length, void *cookie); + +typedef void (*ble_profile_setting_t)(uint32_t id, uint8_t *buffer, uint16_t length, void *cookie); + +typedef struct ble_profile_info_t_ { + uint8_t type; // ble_ledger_profile_mask_e + + ble_uuid_t service_uuid; + + ble_profile_init_t init; + ble_profile_create_db_t create_db; + ble_profile_handle_in_range_t handle_in_range; + + ble_profile_connection_evt_t connection_evt; + ble_profile_connection_update_evt_t connection_update_evt; + ble_profile_encryption_changed_t encryption_changed; + + ble_profile_att_modified_t att_modified; + ble_profile_write_permit_req_t write_permit_req; + ble_profile_mtu_changed_t mtu_changed; + + ble_profile_write_rsp_ack_t write_rsp_ack; + ble_profile_update_char_value_ack_t update_char_val_ack; + + ble_profile_send_packet_t send_packet; + + ble_profile_data_ready_t data_ready; + + ble_profile_setting_t setting; + + void *cookie; +} ble_profile_info_t; + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ diff --git a/lib_blewbxx/include/ble_types.h b/lib_blewbxx/include/ble_types.h new file mode 100644 index 000000000..297448f73 --- /dev/null +++ b/lib_blewbxx/include/ble_types.h @@ -0,0 +1,215 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include + +/* Exported enumerations -----------------------------------------------------*/ + +/* HCI Error codes */ +typedef enum { + HCI_SUCCESS_ERR_CODE = 0x00, +} ble_hci_error_codes_e; + +/* HCI Event codes */ +typedef enum { + HCI_DISCONNECTION_COMPLETE_EVT_CODE = 0x05, + HCI_ENCRYPTION_CHANGE_EVT_CODE = 0x08, + HCI_COMMAND_COMPLETE_EVT_CODE = 0x0e, + HCI_COMMAND_STATUS_EVT_CODE = 0x0f, + HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVT_CODE = 0x30, + HCI_LE_META_EVT_CODE = 0x3E, + HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE = 0xFF, +} ble_hci_evt_codes_e; + +/* HCI Cmd codes */ +typedef enum { + HCI_DISCONNECT_CMD_CODE = 0x0406, + HCI_LE_SET_SCAN_RESPONSE_DATA_CMD_CODE = 0x2009, + HCI_RESET_CMD_CODE = 0x0c03, +} ble_hci_cmd_codes_e; + +/* HCI LE SubEvent codes */ +typedef enum { + HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE = 0x01, + HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE = 0x03, + HCI_LE_DATA_LENGTH_CHANGE_SUBEVT_CODE = 0x07, + HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE = 0x0c, +} ble_hci_subevt_codes_e; + +/* SMP pairing status */ +typedef enum { + SMP_PAIRING_STATUS_SUCCESS = 0x00U, + SMP_PAIRING_STATUS_SMP_TIMEOUT = 0x01U, + SMP_PAIRING_STATUS_PAIRING_FAILED = 0x02U, + SMP_PAIRING_STATUS_ENCRYPT_FAILED = 0x03U, +} ble_smp_pairing_status_e; + +/* ACI vendor specific event codes */ +typedef enum { + // GAP + ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE = 0x0401, + ACI_GAP_PASS_KEY_REQ_VSEVT_CODE = 0x0402, + ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE = 0x0409, + + // L2CAP + ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE = 0x0800, + + // ATT + ACI_ATT_EXCHANGE_MTU_RESP_VSEVT_CODE = 0x0c03, + + // GATT + ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE = 0x0c01, + ACI_GATT_PROC_TIMEOUT_VSEVT_CODE = 0x0c02, + ACI_GATT_INDICATION_VSEVT_CODE = 0x0c0e, + ACI_GATT_PROC_COMPLETE_VSEVT_CODE = 0x0c10, + ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE = 0x0c13, +} ble_aci_evt_codes_e; + +/* ACI vendor specific cmd codes */ +typedef enum { + ACI_HAL_WRITE_CONFIG_DATA_CMD_CODE = 0xfc0c, + ACI_HAL_SET_TX_POWER_LEVEL_CMD_CODE = 0xfc0f, + ACI_GAP_SET_NON_DISCOVERABLE_CMD_CODE = 0xfc81, + ACI_GAP_SET_DISCOVERABLE_CMD_CODE = 0xfc83, + ACI_GAP_SET_IO_CAPABILITY_CMD_CODE = 0xfc85, + ACI_GAP_SET_AUTHENTICATION_REQUIREMENT_CMD_CODE = 0xfc86, + ACI_GAP_PASS_KEY_RESP_CMD_CODE = 0xfc88, + ACI_GAP_INIT_CMD_CODE = 0xfc8a, + ACI_GAP_UPDATE_ADV_DATA_CMD_CODE = 0xfc8e, + ACI_GAP_CLEAR_SECURITY_DB_CMD_CODE = 0xfc94, + ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO_CMD_CODE = 0xfca5, + ACI_GATT_INIT_CMD_CODE = 0xfd01, + ACI_GATT_ADD_SERVICE_CMD_CODE = 0xfd02, + ACI_GATT_ADD_CHAR_CMD_CODE = 0xfd04, + ACI_GATT_UPDATE_CHAR_VALUE_CMD_CODE = 0xfd06, + ACI_GATT_EXCHANGE_CONFIG_CMD_CODE = 0xfd0b, + ACI_GATT_CONFIRM_INDICATION_CMD_CODE = 0xfd25, + ACI_GATT_WRITE_RESP_CMD_CODE = 0xfd26, + ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_CMD_CODE = 0xfd81, +} ble_aci_cmd_codes_e; + +/* Adv/Scan AD types*/ +typedef enum { + BLE_AD_TYPE_FLAGS = 0x01, + BLE_AD_TYPE_COMPLETE_LOCAL_NAME = 0x09, + BLE_AD_AD_TYPE_128_BIT_SERV_UUID = 0x06, + BLE_AD_AD_TYPE_SLAVE_CONN_INTERVAL = 0x12, +} ble_ad_types_e; + +/* AD type Flags*/ +typedef enum { + BLE_AD_TYPE_FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE = 0x02, + BLE_AD_TYPE_FLAG_BIT_BR_EDR_NOT_SUPPORTED = 0x04, +} ble_ad_type_flags_e; + +/* Characteristic properties */ +typedef enum { + BLE_CHAR_PROP_READ = 0x02, + BLE_CHAR_PROP_WRITE_WITHOUT_RESP = 0x04, + BLE_CHAR_PROP_WRITE = 0x08, + BLE_CHAR_PROP_NOTIFY = 0x10, +} ble_char_prop_e; + +/* GATT notify events*/ +typedef enum { + BLE_GATT_DONT_NOTIFY_EVENTS = 0x00, + BLE_GATT_NOTIFY_ATTRIBUTE_WRITE = 0x01, + BLE_GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP = 0x02, + BLE_GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP = 0x04, +} ble_gatt_notify_events_e; + +/* UUID */ +typedef enum { + BLE_GATT_UUID_TYPE_16 = 0x01, + BLE_GATT_UUID_TYPE_128 = 0x02, +} ble_gatt_uuid_e; + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + uint8_t bonding_mode; + uint8_t mitm_mode; + uint8_t sc_support; + uint8_t key_press_notification_support; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t identity_address_type; +} ble_cmd_set_auth_req_data_t; + +typedef struct { + uint8_t advertising_type; + uint16_t advertising_interval_min; + uint16_t advertising_interval_max; + uint8_t own_address_type; + uint8_t advertising_filter_policy; + uint8_t local_name_length; + const uint8_t *local_name; + uint8_t service_uuid_length; + const uint8_t *service_uuid_list; + uint16_t slave_conn_interval_min; + uint16_t slave_conn_interval_max; +} ble_cmd_set_discoverable_data_t; + +typedef struct { + uint16_t service_handle; + uint8_t char_uuid_type; + const uint8_t *char_uuid; + uint16_t char_value_length; + uint8_t char_properties; + uint8_t security_permissions; + uint8_t gatt_evt_mask; + uint8_t enc_key_size; + uint8_t is_variable; +} ble_cmd_add_char_data_t; + +typedef struct { + uint8_t type; // ble_gatt_uuid_e + uint8_t value[16]; +} ble_uuid_t; + +/* Exported defines --------------------------------------------------------*/ +/* Configuration value */ +#define BLE_CONFIG_DATA_RANDOM_ADDRESS_OFFSET 0x2e +#define BLE_CONFIG_DATA_RANDOM_ADDRESS_LEN 6 + +/* HCI */ +#define HCI_EVENT_PKT_TYPE 0x04 + +/* GAP init*/ +#define BLE_GAP_PERIPHERAL_ROLE 0x01 +#define BLE_GAP_PRIVACY_DISABLED 0x00 +#define BLE_GAP_IO_CAP_DISPLAY_YES_NO 0x01 + +/* GAP set authentication */ +#define BLE_GAP_BONDING_ENABLED 0x01 +#define BLE_GAP_MITM_PROTECTION_REQUIRED 0x01 +#define BLE_GAP_KEYPRESS_NOT_SUPPORTED 0x00 +#define BLE_GAP_MIN_ENCRYPTION_KEY_SIZE 8 +#define BLE_GAP_MAX_ENCRYPTION_KEY_SIZE 16 +#define BLE_GAP_USE_FIXED_PIN_FOR_PAIRING_FORBIDDEN 0x01 +#define BLE_GAP_STATIC_RANDOM_ADDR 0x01 + +/* GAP ADV/SCAN */ +#define BLE_GAP_MAX_ADV_DATA_LEN 31 +#define BLE_GAP_MAX_LOCAL_NAME_LENGTH 20 +#define BLE_GAP_ADV_IND 0x00 +#define BLE_GAP_RANDOM_ADDR_TYPE 0X01 +#define BLE_GAP_NO_WHITE_LIST_USE 0X00 + +/* ATT/GATT */ +#define BLE_ATT_DEFAULT_MTU 23 +#define BLE_ATT_MAX_MTU_SIZE 156 +#define BLE_GATT_UUID_TYPE_128 0x02 +#define BLE_GATT_PRIMARY_SERVICE 0x01 +#define BLE_GATT_MAX_SERVICE_RECORDS 9 +#define BLE_GATT_ATTR_PERMISSION_AUTHEN_WRITE 0x08 +#define BLE_GATT_INVALID_HANDLE 0xFFFF + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ diff --git a/lib_blewbxx/src/ble_cmd.c b/lib_blewbxx/src/ble_cmd.c new file mode 100644 index 000000000..a95c18abd --- /dev/null +++ b/lib_blewbxx/src/ble_cmd.c @@ -0,0 +1,416 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "os.h" +#include "ble_cmd.h" +#include + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +static void start_packet_with_opcode(ble_cmd_data_t *cmd_data, uint16_t opcode); + +/* Exported variables --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ + +/* Private functions ---------------------------------------------------------*/ +static void start_packet_with_opcode(ble_cmd_data_t *cmd_data, uint16_t opcode) +{ + cmd_data->hci_cmd_opcode = opcode; + cmd_data->hci_cmd_buffer_length = 2; + U2BE_ENCODE(cmd_data->hci_cmd_buffer, 0, cmd_data->hci_cmd_opcode); +} + +/* Exported functions --------------------------------------------------------*/ +void ble_hci_forge_cmd_reset(ble_cmd_data_t *cmd_data) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, HCI_RESET_CMD_CODE); +} + +void ble_hci_forge_cmd_disconnect(ble_cmd_data_t *cmd_data, uint16_t connection_handle) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, HCI_DISCONNECT_CMD_CODE); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 2, connection_handle); + cmd_data->hci_cmd_buffer_length = 4; +} + +void ble_hci_forge_cmd_set_scan_response_data(ble_cmd_data_t *cmd_data, + uint8_t scan_response_data_length, + const uint8_t *scan_response_data) +{ + if ((!cmd_data) || (!scan_response_data) + || ((uint16_t) (scan_response_data_length + 3) + > (uint16_t) sizeof(cmd_data->hci_cmd_buffer))) { + return; + } + + memset(&cmd_data->hci_cmd_buffer, 0, sizeof(cmd_data->hci_cmd_buffer)); + start_packet_with_opcode(cmd_data, HCI_LE_SET_SCAN_RESPONSE_DATA_CMD_CODE); + cmd_data->hci_cmd_buffer[2] = scan_response_data_length; + memcpy(&cmd_data->hci_cmd_buffer[3], scan_response_data, scan_response_data_length); + cmd_data->hci_cmd_buffer_length + = MIN(BLE_GAP_MAX_ADV_DATA_LEN + 3, sizeof(cmd_data->hci_cmd_buffer)); +} + +void ble_aci_hal_forge_cmd_write_config_data(ble_cmd_data_t *cmd_data, + uint8_t offset, + uint8_t length, + const uint8_t *value) +{ + if ((!cmd_data) || (!value) + || ((uint16_t) (length + 4) > (uint16_t) sizeof(cmd_data->hci_cmd_buffer))) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_HAL_WRITE_CONFIG_DATA_CMD_CODE); + cmd_data->hci_cmd_buffer[2] = offset; + cmd_data->hci_cmd_buffer[3] = length; + memcpy(&cmd_data->hci_cmd_buffer[4], value, length); + cmd_data->hci_cmd_buffer_length = 4 + length; +} + +void ble_aci_hal_forge_cmd_set_tx_power_level(ble_cmd_data_t *cmd_data, + uint8_t enable_high_power, + uint8_t pa_level) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_HAL_SET_TX_POWER_LEVEL_CMD_CODE); + cmd_data->hci_cmd_buffer[2] = enable_high_power; + cmd_data->hci_cmd_buffer[3] = pa_level; + cmd_data->hci_cmd_buffer_length = 4; +} + +void ble_aci_gap_forge_cmd_init(ble_cmd_data_t *cmd_data, + uint8_t role, + uint8_t privacy_enabled, + uint8_t device_name_char_len) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GAP_INIT_CMD_CODE); + cmd_data->hci_cmd_buffer[2] = role; + cmd_data->hci_cmd_buffer[3] = privacy_enabled; + cmd_data->hci_cmd_buffer[4] = device_name_char_len; + cmd_data->hci_cmd_buffer_length = 5; +} + +void ble_aci_gap_forge_cmd_set_io_capability(ble_cmd_data_t *cmd_data, uint8_t io_capability) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GAP_SET_IO_CAPABILITY_CMD_CODE); + cmd_data->hci_cmd_buffer[2] = io_capability; + cmd_data->hci_cmd_buffer_length = 3; +} + +void ble_aci_gap_forge_cmd_set_authentication_requirement(ble_cmd_data_t *cmd_data, + ble_cmd_set_auth_req_data_t *data) +{ + if ((!cmd_data) || (!data)) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GAP_SET_AUTHENTICATION_REQUIREMENT_CMD_CODE); + cmd_data->hci_cmd_buffer[2] = data->bonding_mode; + cmd_data->hci_cmd_buffer[3] = data->mitm_mode; + cmd_data->hci_cmd_buffer[4] = data->sc_support; + cmd_data->hci_cmd_buffer[5] = data->key_press_notification_support; + cmd_data->hci_cmd_buffer[6] = data->min_encryption_key_size; + cmd_data->hci_cmd_buffer[7] = data->max_encryption_key_size; + cmd_data->hci_cmd_buffer[8] = data->use_fixed_pin; + U4LE_ENCODE(cmd_data->hci_cmd_buffer, 9, data->fixed_pin); + cmd_data->hci_cmd_buffer[13] = data->identity_address_type; + cmd_data->hci_cmd_buffer_length = 14; +} + +void ble_aci_gap_forge_cmd_numeric_comparison_value_confirm_yesno(ble_cmd_data_t *cmd_data, + uint16_t connection_handle, + uint8_t confirm_yes_no) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO_CMD_CODE); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 2, connection_handle); + cmd_data->hci_cmd_buffer[4] = confirm_yes_no; + cmd_data->hci_cmd_buffer_length = 5; +} +void ble_aci_gap_forge_cmd_pass_key_resp(ble_cmd_data_t *cmd_data, + uint16_t connection_handle, + uint32_t pass_key) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GAP_PASS_KEY_RESP_CMD_CODE); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 2, connection_handle); + U4LE_ENCODE(cmd_data->hci_cmd_buffer, 4, pass_key); + cmd_data->hci_cmd_buffer_length = 8; +} + +void ble_aci_gap_forge_cmd_clear_security_db(ble_cmd_data_t *cmd_data) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GAP_CLEAR_SECURITY_DB_CMD_CODE); +} + +void ble_aci_gap_forge_cmd_set_discoverable(ble_cmd_data_t *cmd_data, + ble_cmd_set_discoverable_data_t *data) +{ + if ((!cmd_data) || (!data) || (data->local_name_length > BLE_GAP_MAX_LOCAL_NAME_LENGTH)) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GAP_SET_DISCOVERABLE_CMD_CODE); + // Advertising_Type + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->advertising_type; + // Advertising_Interval_Min + U2LE_ENCODE( + cmd_data->hci_cmd_buffer, cmd_data->hci_cmd_buffer_length, data->advertising_interval_min); + cmd_data->hci_cmd_buffer_length += 2; + // Advertising_Interval_Max + U2LE_ENCODE( + cmd_data->hci_cmd_buffer, cmd_data->hci_cmd_buffer_length, data->advertising_interval_max); + cmd_data->hci_cmd_buffer_length += 2; + // Own_Address_Type + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->own_address_type; + // Advertising_Filter_Policy + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->advertising_filter_policy; + // Local_Name_Length + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->local_name_length; + // Local_Name + if (data->local_name_length && data->local_name) { + memcpy(&cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length], + data->local_name, + data->local_name_length); + } + cmd_data->hci_cmd_buffer_length += data->local_name_length; + // Service_Uuid_length + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->service_uuid_length; + // Service_Uuid_List + if (data->service_uuid_length && data->service_uuid_list) { + memcpy(&cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length], + data->service_uuid_list, + data->service_uuid_length); + } + cmd_data->hci_cmd_buffer_length += data->service_uuid_length; + // Slave_Conn_Interval_Min + U2LE_ENCODE( + cmd_data->hci_cmd_buffer, cmd_data->hci_cmd_buffer_length, data->slave_conn_interval_min); + cmd_data->hci_cmd_buffer_length += 2; + // Slave_Conn_Interval_Max + U2LE_ENCODE( + cmd_data->hci_cmd_buffer, cmd_data->hci_cmd_buffer_length, data->slave_conn_interval_max); + cmd_data->hci_cmd_buffer_length += 2; +} + +void ble_aci_gap_forge_cmd_set_non_discoverable(ble_cmd_data_t *cmd_data) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GAP_SET_NON_DISCOVERABLE_CMD_CODE); +} + +void ble_aci_gap_forge_cmd_update_adv_data(ble_cmd_data_t *cmd_data, + uint8_t adv_data_length, + const uint8_t *adv_data) +{ + if ((!cmd_data) || (!adv_data) + || ((uint16_t) (adv_data_length + 3) > (uint16_t) sizeof(cmd_data->hci_cmd_buffer))) { + return; + } + + memset(&cmd_data->hci_cmd_buffer, 0, sizeof(cmd_data->hci_cmd_buffer)); + start_packet_with_opcode(cmd_data, ACI_GAP_UPDATE_ADV_DATA_CMD_CODE); + cmd_data->hci_cmd_buffer[2] = adv_data_length; + memcpy(&cmd_data->hci_cmd_buffer[3], adv_data, adv_data_length); + cmd_data->hci_cmd_buffer_length = 3 + adv_data_length; +} + +void ble_aci_gatt_forge_cmd_init(ble_cmd_data_t *cmd_data) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GATT_INIT_CMD_CODE); +} + +void ble_aci_l2cap_forge_cmd_connection_parameter_update(ble_cmd_data_t *cmd_data, + uint16_t connection_handle, + uint16_t min_conn_interval, + uint16_t max_conn_interval, + uint16_t conn_latency, + uint16_t supervision_timeout) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_L2CAP_CONNECTION_PARAMETER_UPDATE_CMD_CODE); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 2, connection_handle); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 4, min_conn_interval); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 6, max_conn_interval); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 8, conn_latency); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 10, supervision_timeout); + cmd_data->hci_cmd_buffer_length = 12; +} + +void ble_aci_gatt_forge_cmd_add_service(ble_cmd_data_t *cmd_data, + uint8_t service_uuid_type, + const uint8_t *service_uuid, + uint8_t service_type, + uint8_t max_attribute_records) +{ + if ((!cmd_data) || (!service_uuid)) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GATT_ADD_SERVICE_CMD_CODE); + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = service_uuid_type; + if (service_uuid_type == BLE_GATT_UUID_TYPE_128) { + memcpy(&cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length], service_uuid, 16); + cmd_data->hci_cmd_buffer_length += 16; + } + else { + memcpy(&cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length], service_uuid, 2); + cmd_data->hci_cmd_buffer_length += 2; + } + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = service_type; + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = max_attribute_records; +} + +void ble_aci_gatt_forge_cmd_add_char(ble_cmd_data_t *cmd_data, ble_cmd_add_char_data_t *data) +{ + if ((!cmd_data) || (!data) || (!data->char_uuid)) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GATT_ADD_CHAR_CMD_CODE); + // Service_Handle + U2LE_ENCODE(cmd_data->hci_cmd_buffer, cmd_data->hci_cmd_buffer_length, data->service_handle); + cmd_data->hci_cmd_buffer_length += 2; + // Char_UUID_Type + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->char_uuid_type; + // Char_UUID + if (data->char_uuid_type == BLE_GATT_UUID_TYPE_128) { + memcpy(&cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length], data->char_uuid, 16); + cmd_data->hci_cmd_buffer_length += 16; + } + else { + memcpy(&cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length], data->char_uuid, 2); + cmd_data->hci_cmd_buffer_length += 2; + } + // Char_Value_Length + U2LE_ENCODE(cmd_data->hci_cmd_buffer, cmd_data->hci_cmd_buffer_length, data->char_value_length); + cmd_data->hci_cmd_buffer_length += 2; + // Char_Properties + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->char_properties; + // Security_Permissions + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->security_permissions; + // GATT_Evt_Mask + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->gatt_evt_mask; + // Enc_Key_Size + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->enc_key_size; + // Is_Variable + cmd_data->hci_cmd_buffer[cmd_data->hci_cmd_buffer_length++] = data->is_variable; +} + +void ble_aci_gatt_forge_cmd_update_char_value(ble_cmd_data_t *cmd_data, + uint16_t service_handle, + uint16_t char_handle, + uint8_t val_offset, + uint8_t char_value_length, + const uint8_t *char_value) +{ + if ((!cmd_data) + || ((uint16_t) (char_value_length + 8) > (uint16_t) sizeof(cmd_data->hci_cmd_buffer))) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GATT_UPDATE_CHAR_VALUE_CMD_CODE); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 2, service_handle); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 4, char_handle); + cmd_data->hci_cmd_buffer[6] = val_offset; + cmd_data->hci_cmd_buffer[7] = char_value_length; + if (char_value_length && char_value) { + memcpy(&cmd_data->hci_cmd_buffer[8], char_value, char_value_length); + } + cmd_data->hci_cmd_buffer_length = 8 + char_value_length; +} + +void ble_aci_gatt_forge_cmd_write_resp(ble_cmd_data_t *cmd_data, + uint16_t connection_handle, + uint16_t attribute_handle, + uint8_t write_status, + uint8_t error_code, + uint8_t attribute_val_length, + const uint8_t *attribute_val) +{ + if ((!cmd_data) + || ((uint16_t) (attribute_val_length + 8) > (uint16_t) sizeof(cmd_data->hci_cmd_buffer))) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GATT_WRITE_RESP_CMD_CODE); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 2, connection_handle); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 4, attribute_handle); + cmd_data->hci_cmd_buffer[6] = write_status; + cmd_data->hci_cmd_buffer[7] = error_code; + cmd_data->hci_cmd_buffer[8] = attribute_val_length; + if (attribute_val_length && attribute_val) { + memcpy(&cmd_data->hci_cmd_buffer[9], attribute_val, attribute_val_length); + } + cmd_data->hci_cmd_buffer_length = 9 + attribute_val_length; +} + +void ble_aci_gatt_forge_cmd_confirm_indication(ble_cmd_data_t *cmd_data, uint16_t connection_handle) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GATT_CONFIRM_INDICATION_CMD_CODE); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 2, connection_handle); + cmd_data->hci_cmd_buffer_length = 4; +} + +void ble_aci_gatt_forge_cmd_exchange_config(ble_cmd_data_t *cmd_data, uint16_t connection_handle) +{ + if (!cmd_data) { + return; + } + + start_packet_with_opcode(cmd_data, ACI_GATT_EXCHANGE_CONFIG_CMD_CODE); + U2LE_ENCODE(cmd_data->hci_cmd_buffer, 2, connection_handle); + cmd_data->hci_cmd_buffer_length = 4; +} diff --git a/lib_blewbxx/src/ble_ledger.c b/lib_blewbxx/src/ble_ledger.c new file mode 100644 index 000000000..52ba86404 --- /dev/null +++ b/lib_blewbxx/src/ble_ledger.c @@ -0,0 +1,1135 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "os.h" +#include "os_settings.h" +#include "seproxyhal_protocol.h" +#include "os_io.h" +#include "os_io_seph_cmd.h" + +#include + +#include "lcx_rng.h" + +#include "ble_cmd.h" +#include "ble_ledger.h" +#include "ble_ledger_types.h" +#include "ble_ledger_profile_apdu.h" + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ +typedef enum { + BLE_STATE_IDLE = 0xA0, + BLE_STATE_INITIALIZING, + BLE_STATE_START_ADVERTISING, + BLE_STATE_RUNNING, + BLE_STATE_STOPPING, +} ble_state_t; + +typedef enum { + BLE_INIT_STEP_IDLE, + BLE_INIT_STEP_RESET, + BLE_INIT_STEP_STATIC_ADDRESS, + BLE_INIT_STEP_GATT_INIT, + BLE_INIT_STEP_GAP_INIT, + BLE_INIT_STEP_SET_IO_CAPABILITIES, + BLE_INIT_STEP_SET_AUTH_REQUIREMENTS, + BLE_INIT_STEP_PROFILE_INIT, + BLE_INIT_STEP_PROFILE_CREATE_DB, + BLE_INIT_STEP_SET_TX_POWER_LEVEL, + BLE_INIT_STEP_CLEAR_PAIRING, + BLE_INIT_STEP_START_ADVERTISING, + BLE_INIT_STEP_END, +} ble_init_step_t; + +typedef enum { + BLE_START_ADV_STEP_IDLE, + BLE_START_ADV_STEP_STOP_ADV, + BLE_START_ADV_STEP_SET_ADV_DATAS, + BLE_START_ADV_STEP_SET_SCAN_RSP_DATAS, + BLE_START_ADV_STEP_SET_GAP_DEVICE_NAME, + BLE_START_ADV_STEP_START_ADV, + BLE_START_ADV_STEP_END, +} ble_start_start_adv_step_t; + +typedef enum { + BLE_STOPPING_STEP_IDLE, + BLE_STOPPING_STEP_DISCONNECT, + BLE_STOPPING_STEP_STOP_ADV, + BLE_STOPPING_STEP_RESET, + BLE_STOPPING_STEP_END, +} ble_stopping_step_t; + +/* Private defines------------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +typedef struct { + // General + uint8_t enabled; + ble_state_t state; + char device_name[BLE_GAP_MAX_LOCAL_NAME_LENGTH + 1]; + char device_name_length; + uint8_t random_address[BLE_CONFIG_DATA_RANDOM_ADDRESS_LEN]; + uint8_t nb_of_profile; + ble_profile_info_t *profile[2]; + uint16_t profiles; + uint8_t ble_ready; + + // Init + ble_init_step_t init_step; + + // Start advertising + ble_start_start_adv_step_t start_adv_step; + uint8_t stop_after_start; + + // Stopping + ble_stopping_step_t stopping_step; + uint8_t start_after_stop; + + // HCI + ble_cmd_data_t cmd_data; + + // GAP + uint16_t gap_service_handle; + uint16_t gap_device_name_characteristic_handle; + uint16_t gap_appearance_characteristic_handle; + uint8_t advertising_enabled; + ble_connection_t connection; + uint16_t pairing_code; + uint8_t pairing_in_progress; + + // PAIRING + uint8_t clear_pairing; + +} ble_ledger_data_t; + +#ifdef HAVE_PRINTF +#define DEBUG PRINTF +// #define DEBUG(...) +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +// Init +static void get_device_name(void); +static void init_mngr(uint8_t *hci_buffer, uint16_t length); + +// Advertising +static void start_advertising_mngr(uint16_t opcode); +static void stopping_mngr(uint16_t opcode); + +#ifdef HAVE_INAPP_BLE_PAIRING +// Pairing UX +static void ask_user_pairing_numeric_comparison(uint32_t code); +static void rsp_user_pairing_numeric_comparison(unsigned int status); +static void ask_user_pairing_passkey(void); +static void rsp_user_pairing_passkey(unsigned int status); +static void end_pairing_ux(uint8_t pairing_ok); +#endif // HAVE_INAPP_BLE_PAIRING + +// HCI +static void hci_evt_cmd_complete(uint8_t *buffer, uint16_t length); +static void hci_evt_le_meta_evt(uint8_t *buffer, uint16_t length); +static void hci_evt_vendor(uint8_t *buffer, uint16_t length); + +static uint32_t send_hci_packet(uint32_t timeout_ms); + +/* Exported variables --------------------------------------------------------*/ +uint8_t BLE_LEDGER_apdu_buffer[OS_IO_BUFFER_SIZE + 1]; + +/* Private variables ---------------------------------------------------------*/ +static ble_ledger_data_t ble_ledger_data; +static os_io_init_ble_t ble_ledger_init_data; + +/* Private functions ---------------------------------------------------------*/ +static void get_device_name(void) +{ + memset(ble_ledger_data.device_name, 0, sizeof(ble_ledger_data.device_name)); + ble_ledger_data.device_name_length = os_setting_get(OS_SETTING_DEVICENAME, + (uint8_t *) ble_ledger_data.device_name, + sizeof(ble_ledger_data.device_name) - 1); +} + +static void init_mngr(uint8_t *hci_buffer, uint16_t length) +{ + if (ble_ledger_data.init_step == BLE_INIT_STEP_IDLE) { + DEBUG("INIT START\n"); + } + else if (hci_buffer) { + uint16_t opcode = U2LE(hci_buffer, 1); + if ((ble_ledger_data.cmd_data.hci_cmd_opcode != 0xFFFF) + && (opcode != ble_ledger_data.cmd_data.hci_cmd_opcode)) { + // Unexpected event => TODO_IO + return; + } + if ((length >= 6) && (ble_ledger_data.init_step == BLE_INIT_STEP_GAP_INIT)) { + ble_ledger_data.gap_service_handle = U2LE(hci_buffer, 4); + ble_ledger_data.gap_device_name_characteristic_handle = U2LE(hci_buffer, 6); + ble_ledger_data.gap_appearance_characteristic_handle = U2LE(hci_buffer, 8); + DEBUG("GAP service handle : %04X\n", ble_ledger_data.gap_service_handle); + DEBUG("GAP device name char handle : %04X\n", + ble_ledger_data.gap_device_name_characteristic_handle); + DEBUG("GAP appearance char handle : %04X\n", + ble_ledger_data.gap_appearance_characteristic_handle); + } + if (ble_ledger_data.init_step == BLE_INIT_STEP_START_ADVERTISING) { + start_advertising_mngr(opcode); + if (ble_ledger_data.start_adv_step != BLE_START_ADV_STEP_END) { + return; + } + } + if (ble_ledger_data.init_step == BLE_INIT_STEP_CLEAR_PAIRING - 1) { + if (!ble_ledger_data.clear_pairing) { + ble_ledger_data.init_step++; + } + } + } + + ble_ledger_data.init_step++; + + switch (ble_ledger_data.init_step) { + case BLE_INIT_STEP_RESET: + ble_hci_forge_cmd_reset(&ble_ledger_data.cmd_data); + send_hci_packet(0); + break; + + case BLE_INIT_STEP_STATIC_ADDRESS: + ble_aci_hal_forge_cmd_write_config_data(&ble_ledger_data.cmd_data, + BLE_CONFIG_DATA_RANDOM_ADDRESS_OFFSET, + BLE_CONFIG_DATA_RANDOM_ADDRESS_LEN, + ble_ledger_data.random_address); + send_hci_packet(0); + break; + + case BLE_INIT_STEP_GATT_INIT: + ble_aci_gatt_forge_cmd_init(&ble_ledger_data.cmd_data); + send_hci_packet(0); + break; + + case BLE_INIT_STEP_GAP_INIT: + ble_aci_gap_forge_cmd_init(&ble_ledger_data.cmd_data, + BLE_GAP_PERIPHERAL_ROLE, + BLE_GAP_PRIVACY_DISABLED, + sizeof(ble_ledger_data.device_name) - 1); + send_hci_packet(0); + break; + + case BLE_INIT_STEP_SET_IO_CAPABILITIES: + ble_aci_gap_forge_cmd_set_io_capability(&ble_ledger_data.cmd_data, + BLE_GAP_IO_CAP_DISPLAY_YES_NO); + send_hci_packet(0); + break; + + case BLE_INIT_STEP_SET_AUTH_REQUIREMENTS: { + ble_cmd_set_auth_req_data_t data; + data.bonding_mode = BLE_GAP_BONDING_ENABLED; + data.mitm_mode = BLE_GAP_MITM_PROTECTION_REQUIRED; + data.sc_support = 1; + data.key_press_notification_support = BLE_GAP_KEYPRESS_NOT_SUPPORTED; + data.min_encryption_key_size = BLE_GAP_MIN_ENCRYPTION_KEY_SIZE; + data.max_encryption_key_size = BLE_GAP_MAX_ENCRYPTION_KEY_SIZE; + data.use_fixed_pin = BLE_GAP_USE_FIXED_PIN_FOR_PAIRING_FORBIDDEN; + data.fixed_pin = 0; + data.identity_address_type = BLE_GAP_STATIC_RANDOM_ADDR; + ble_aci_gap_forge_cmd_set_authentication_requirement(&ble_ledger_data.cmd_data, &data); + send_hci_packet(0); + break; + } + + case BLE_INIT_STEP_PROFILE_INIT: + case BLE_INIT_STEP_PROFILE_CREATE_DB: { + ble_profile_info_t *profile_info = NULL; + profile_info = ble_ledger_data.profile[0]; + if (ble_ledger_data.init_step == BLE_INIT_STEP_PROFILE_INIT) { + if (profile_info->init) { + ((ble_profile_init_t) PIC(profile_info->init))(&ble_ledger_data.cmd_data, + profile_info->cookie); + } + ble_ledger_data.init_step++; + } + if (profile_info->create_db) { + if (((ble_profile_create_db_t) PIC(profile_info->create_db))( + hci_buffer, length, profile_info->cookie) + != BLE_PROFILE_STATUS_OK_PROCEDURE_END) { + ble_ledger_data.init_step--; + send_hci_packet(0); + } + else { + init_mngr(hci_buffer, length); + } + } + else { + init_mngr(hci_buffer, length); + } + break; + } + + case BLE_INIT_STEP_SET_TX_POWER_LEVEL: + ble_aci_hal_forge_cmd_set_tx_power_level(&ble_ledger_data.cmd_data, + 1, // High power +#ifdef TARGET_STAX + 0x19); // 0 dBm +#else // !TARGET_STAX + 0x07); // -14.1 dBm +#endif // !TARGET_STAX + send_hci_packet(0); + break; + + case BLE_INIT_STEP_CLEAR_PAIRING: + ble_aci_gap_forge_cmd_clear_security_db(&ble_ledger_data.cmd_data); + send_hci_packet(0); + break; + + case BLE_INIT_STEP_START_ADVERTISING: + ble_ledger_data.cmd_data.hci_cmd_opcode = 0xFFFF; + ble_ledger_data.start_adv_step = BLE_START_ADV_STEP_IDLE; + start_advertising_mngr(0); + break; + + case BLE_INIT_STEP_END: + DEBUG("INIT END\n"); + ble_ledger_data.state = BLE_STATE_RUNNING; + break; + + default: + break; + } +} + +static void start_advertising_mngr(uint16_t opcode) +{ + uint8_t buffer[31]; + uint8_t index = 0; + + if ((ble_ledger_data.cmd_data.hci_cmd_opcode != 0xFFFF) + && (opcode != ble_ledger_data.cmd_data.hci_cmd_opcode)) { + // Unexpected event => TODO_IO + return; + } + + if (ble_ledger_data.connection.connection_handle != 0xFFFF) { + DEBUG("START ADVERTISING ABORTED : connected\n"); + ble_ledger_data.state = BLE_STATE_RUNNING; + return; + } + + if (ble_ledger_data.start_adv_step == BLE_START_ADV_STEP_IDLE) { + DEBUG("START ADVERTISING START\n"); + ble_ledger_data.start_after_stop = 0; + } + + if (ble_ledger_data.start_adv_step == BLE_START_ADV_STEP_STOP_ADV - 1) { + if (!ble_ledger_data.advertising_enabled) { + ble_ledger_data.start_adv_step++; + } + } + + if (ble_ledger_data.start_adv_step == (BLE_START_ADV_STEP_START_ADV - 1)) { + if ((os_setting_get(OS_SETTING_PLANEMODE, NULL, 0)) || ble_ledger_data.stop_after_start) { + DEBUG("START ADVERTISING ABORTED\n"); + ble_ledger_data.state = BLE_STATE_RUNNING; + BLE_LEDGER_stop(); + return; + } + } + + ble_ledger_data.start_adv_step++; + + switch (ble_ledger_data.start_adv_step) { + case BLE_START_ADV_STEP_STOP_ADV: + ble_aci_gap_forge_cmd_set_non_discoverable(&ble_ledger_data.cmd_data); + send_hci_packet(0); + break; + + case BLE_START_ADV_STEP_SET_ADV_DATAS: + ble_ledger_data.advertising_enabled = 0; + // Flags + buffer[index++] = 2; + buffer[index++] = BLE_AD_TYPE_FLAGS; + buffer[index++] = BLE_AD_TYPE_FLAG_BIT_BR_EDR_NOT_SUPPORTED + | BLE_AD_TYPE_FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE; + + // Complete Local Name + get_device_name(); + buffer[index++] = ble_ledger_data.device_name_length + 1; + buffer[index++] = BLE_AD_TYPE_COMPLETE_LOCAL_NAME; + memcpy(&buffer[index], ble_ledger_data.device_name, ble_ledger_data.device_name_length); + index += ble_ledger_data.device_name_length; + + ble_aci_gap_forge_cmd_update_adv_data(&ble_ledger_data.cmd_data, index, buffer); + send_hci_packet(0); + break; + + case BLE_START_ADV_STEP_SET_SCAN_RSP_DATAS: { + ble_profile_info_t *profile_info = NULL; + // TODO_IO : should handle every profile in the future + profile_info = ble_ledger_data.profile[0]; + // Incomplete List of 128-bit Service UUIDs + buffer[index++] = 16 + 1; + buffer[index++] = BLE_AD_AD_TYPE_128_BIT_SERV_UUID; + memcpy(&buffer[index], (uint8_t *) PIC(profile_info->service_uuid.value), 16); + index += 16; + + // Slave Connection Interval Range + buffer[index++] = 5; + buffer[index++] = BLE_AD_AD_TYPE_SLAVE_CONN_INTERVAL; + buffer[index++] = BLE_SLAVE_CONN_INTERVAL_MIN; + buffer[index++] = 0; + buffer[index++] = BLE_SLAVE_CONN_INTERVAL_MAX; + buffer[index++] = 0; + + ble_hci_forge_cmd_set_scan_response_data(&ble_ledger_data.cmd_data, index, buffer); + send_hci_packet(0); + break; + } + + case BLE_START_ADV_STEP_SET_GAP_DEVICE_NAME: + ble_aci_gatt_forge_cmd_update_char_value( + &ble_ledger_data.cmd_data, + ble_ledger_data.gap_service_handle, + ble_ledger_data.gap_device_name_characteristic_handle, + 0, + ble_ledger_data.device_name_length, + (uint8_t *) ble_ledger_data.device_name); + send_hci_packet(0); + break; + + case BLE_START_ADV_STEP_START_ADV: + get_device_name(); + buffer[0] = BLE_AD_TYPE_COMPLETE_LOCAL_NAME; + memcpy(&buffer[1], ble_ledger_data.device_name, ble_ledger_data.device_name_length); + + ble_cmd_set_discoverable_data_t data; + data.advertising_type = BLE_GAP_ADV_IND; + data.advertising_interval_min = BLE_ADVERTISING_INTERVAL_MIN; + data.advertising_interval_max = BLE_ADVERTISING_INTERVAL_MAX; + data.own_address_type = BLE_GAP_RANDOM_ADDR_TYPE; + data.advertising_filter_policy = BLE_GAP_NO_WHITE_LIST_USE; + data.local_name_length = ble_ledger_data.device_name_length + 1; + data.local_name = buffer; + data.service_uuid_length = 0; + data.service_uuid_list = NULL; + data.slave_conn_interval_min = 0; + data.slave_conn_interval_max = 0; + ble_aci_gap_forge_cmd_set_discoverable(&ble_ledger_data.cmd_data, &data); + send_hci_packet(0); + break; + + case BLE_START_ADV_STEP_END: + DEBUG("START ADVERTISING END\n"); + ble_ledger_data.advertising_enabled = 1; + ble_ledger_data.state = BLE_STATE_RUNNING; + break; + + default: + break; + } +} + +static void stopping_mngr(uint16_t opcode) +{ + if ((ble_ledger_data.cmd_data.hci_cmd_opcode != 0xFFFF) + && (opcode != ble_ledger_data.cmd_data.hci_cmd_opcode)) { + // Unexpected event => TODO_IO + return; + } + + if (ble_ledger_data.stopping_step == BLE_STOPPING_STEP_IDLE) { + DEBUG("STOPPING START\n"); + ble_ledger_data.stop_after_start = 0; + } + + if ((ble_ledger_data.stopping_step == BLE_STOPPING_STEP_DISCONNECT - 1) + && (ble_ledger_data.connection.connection_handle == 0xFFFF)) { + ble_ledger_data.stopping_step++; + } + + if ((ble_ledger_data.stopping_step == BLE_STOPPING_STEP_STOP_ADV - 1) + && (!ble_ledger_data.advertising_enabled)) { + ble_ledger_data.stopping_step++; + } + + ble_ledger_data.stopping_step++; + + switch (ble_ledger_data.stopping_step) { + case BLE_STOPPING_STEP_DISCONNECT: +#ifdef HAVE_INAPP_BLE_PAIRING + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); +#endif // HAVE_INAPP_BLE_PAIRING + ble_hci_forge_cmd_disconnect(&ble_ledger_data.cmd_data, + ble_ledger_data.connection.connection_handle); + send_hci_packet(0); + break; + + case BLE_STOPPING_STEP_STOP_ADV: + ble_aci_gap_forge_cmd_set_non_discoverable(&ble_ledger_data.cmd_data); + send_hci_packet(0); + break; + + case BLE_STOPPING_STEP_RESET: + ble_hci_forge_cmd_reset(&ble_ledger_data.cmd_data); + send_hci_packet(0); + break; + + case BLE_STOPPING_STEP_END: + DEBUG("STOPPING END\n"); + ble_ledger_data.state = BLE_STATE_IDLE; + if (ble_ledger_data.start_after_stop) { + BLE_LEDGER_start(); + } + break; + + default: + break; + } +} + +#ifdef HAVE_INAPP_BLE_PAIRING +static void ask_user_pairing_numeric_comparison(uint32_t code) +{ + bolos_ux_params_t ux_params; + + ux_params.u.pairing_request.type = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST_NUMCOMP; + ux_params.u.pairing_request.pairing_info_len = 6; + ux_params.ux_id = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST; + ux_params.len = sizeof(ux_params.u.pairing_request); + ble_ledger_data.pairing_in_progress = 1; + + SPRINTF(ux_params.u.pairing_request.pairing_info, "%06d", (unsigned int) code); + + os_io_ux_cmd_ble_pairing_request(&ux_params); +} + +static void rsp_user_pairing_numeric_comparison(unsigned int status) +{ + if (status == BOLOS_UX_OK) { + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CONFIRM_CODE_YES); + ble_aci_gap_forge_cmd_numeric_comparison_value_confirm_yesno( + &ble_ledger_data.cmd_data, ble_ledger_data.connection.connection_handle, 1); + } + else if (status == BOLOS_UX_IGNORE) { + ble_ledger_data.pairing_in_progress = 0; + ble_aci_gap_forge_cmd_numeric_comparison_value_confirm_yesno( + &ble_ledger_data.cmd_data, ble_ledger_data.connection.connection_handle, 0); + } + else { + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CONFIRM_CODE_NO); + ble_aci_gap_forge_cmd_numeric_comparison_value_confirm_yesno( + &ble_ledger_data.cmd_data, ble_ledger_data.connection.connection_handle, 0); + } + send_hci_packet(0); +} + +static void ask_user_pairing_passkey(void) +{ + bolos_ux_params_t ux_params; + + ux_params.u.pairing_request.type = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST_PASSKEY; + ux_params.u.pairing_request.pairing_info_len = 6; + ux_params.ux_id = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST; + ux_params.len = sizeof(ux_params.u.pairing_request); + ble_ledger_data.pairing_in_progress = 2; + ble_ledger_data.pairing_code = cx_rng_u32_range_func(0, 1000000, cx_rng_u32); + + SPRINTF(ux_params.u.pairing_request.pairing_info, "%06d", ble_ledger_data.pairing_code); + + os_io_ux_cmd_ble_pairing_request(&ux_params); +} + +static void rsp_user_pairing_passkey(unsigned int status) +{ + if (status == BOLOS_UX_OK) { + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_ACCEPT_PASSKEY); + ble_ledger_data.pairing_code = cx_rng_u32_range_func(0, 1000000, cx_rng_u32); + ble_aci_gap_forge_cmd_pass_key_resp(&ble_ledger_data.cmd_data, + ble_ledger_data.connection.connection_handle, + ble_ledger_data.pairing_code); + send_hci_packet(0); + } + else if (status == BOLOS_UX_IGNORE) { + ble_ledger_data.pairing_in_progress = 0; + } + else { + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CANCEL_PASSKEY); + } +} + +static void end_pairing_ux(uint8_t pairing_ok) +{ + bolos_ux_params_t ux_params; + + DEBUG("end_pairing_ux : %d (%d)\n", pairing_ok, ble_ledger_data.pairing_in_progress); + if (ble_ledger_data.pairing_in_progress) { + ux_params.ux_id = BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS; + ux_params.len = sizeof(ux_params.u.pairing_status); + ux_params.u.pairing_status.pairing_ok = pairing_ok; + os_io_ux_cmd_ble_pairing_status(&ux_params); + } +} +#endif // HAVE_INAPP_BLE_PAIRING + +static void hci_evt_cmd_complete(uint8_t *buffer, uint16_t length) +{ + if (length < 3) { + return; + } + + uint16_t opcode = U2LE(buffer, 1); + + if (ble_ledger_data.state == BLE_STATE_INITIALIZING) { + init_mngr(buffer, length); + } + else if (ble_ledger_data.state == BLE_STATE_START_ADVERTISING) { + start_advertising_mngr(opcode); + } + else if (ble_ledger_data.state == BLE_STATE_STOPPING) { + stopping_mngr(opcode); + } + else if (opcode == ACI_GATT_WRITE_RESP_CMD_CODE) { + uint8_t status = BLE_PROFILE_STATUS_OK; + ble_profile_info_t *profile_info = NULL; + profile_info = ble_ledger_data.profile[0]; + if (profile_info->write_rsp_ack) { + status = ((ble_profile_write_rsp_ack_t) PIC(profile_info->write_rsp_ack))( + profile_info->cookie); + if (status == BLE_PROFILE_STATUS_OK_AND_SEND_PACKET) { + send_hci_packet(0); + } + } + } + else if (opcode == ACI_GATT_UPDATE_CHAR_VALUE_CMD_CODE) { + uint8_t status = BLE_PROFILE_STATUS_OK; + ble_profile_info_t *profile_info = NULL; + profile_info = ble_ledger_data.profile[0]; + if (profile_info->update_char_val_ack) { + status = ((ble_profile_update_char_value_ack_t) PIC(profile_info->update_char_val_ack))( + profile_info->cookie); + if (status == BLE_PROFILE_STATUS_OK_AND_SEND_PACKET) { + send_hci_packet(0); + } + } + } + else if (opcode == ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO_CMD_CODE) { + DEBUG("ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO\n"); + } + else if (opcode == ACI_GAP_CLEAR_SECURITY_DB_CMD_CODE) { + DEBUG("ACI_GAP_CLEAR_SECURITY_DB\n"); + } + else if (opcode == ACI_GATT_CONFIRM_INDICATION_CMD_CODE) { + DEBUG("ACI_GATT_CONFIRM_INDICATION\n"); + } + else { + DEBUG("HCI EVT CMD COMPLETE 0x%04X\n", opcode); + } +} + +static void hci_evt_le_meta_evt(uint8_t *buffer, uint16_t length) +{ + if (!length) { + return; + } + + ble_profile_info_t *profile_info = NULL; + + switch (buffer[0]) { + case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE: + ble_ledger_data.connection.connection_handle = U2LE(buffer, 2); + ble_ledger_data.connection.role_slave = buffer[4]; + ble_ledger_data.connection.peer_address_random = buffer[5]; + memcpy(ble_ledger_data.connection.peer_address, &buffer[6], 6); + ble_ledger_data.connection.conn_interval = U2LE(buffer, 12); + ble_ledger_data.connection.conn_latency = U2LE(buffer, 14); + ble_ledger_data.connection.supervision_timeout = U2LE(buffer, 16); + ble_ledger_data.connection.master_clock_accuracy = buffer[18]; + ble_ledger_data.connection.encrypted = 0; + DEBUG("LE CONNECTION COMPLETE %04X - %04X- %04X- %04X\n", + ble_ledger_data.connection.connection_handle, + ble_ledger_data.connection.conn_interval, + ble_ledger_data.connection.conn_latency, + ble_ledger_data.connection.supervision_timeout); + ble_ledger_data.advertising_enabled = 0; + + profile_info = ble_ledger_data.profile[0]; + if (profile_info->connection_evt) { + ((ble_profile_connection_evt_t) PIC(profile_info->connection_evt))( + &ble_ledger_data.connection, profile_info->cookie); + } + break; + + case HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE: + ble_ledger_data.connection.connection_handle = U2LE(buffer, 2); + ble_ledger_data.connection.conn_interval = U2LE(buffer, 4); + ble_ledger_data.connection.conn_latency = U2LE(buffer, 6); + ble_ledger_data.connection.supervision_timeout = U2LE(buffer, 8); + DEBUG("LE CONNECTION UPDATE %04X - %04X- %04X- %04X\n", + ble_ledger_data.connection.connection_handle, + ble_ledger_data.connection.conn_interval, + ble_ledger_data.connection.conn_latency, + ble_ledger_data.connection.supervision_timeout); + + profile_info = ble_ledger_data.profile[0]; + if (profile_info->connection_update_evt) { + ((ble_profile_connection_update_evt_t) PIC(profile_info->connection_update_evt))( + &ble_ledger_data.connection, profile_info->cookie); + } + break; + + case HCI_LE_DATA_LENGTH_CHANGE_SUBEVT_CODE: + if (U2LE(buffer, 1) == ble_ledger_data.connection.connection_handle) { + ble_ledger_data.connection.max_tx_octets = U2LE(buffer, 3); + ble_ledger_data.connection.max_tx_time = U2LE(buffer, 5); + ble_ledger_data.connection.max_rx_octets = U2LE(buffer, 7); + ble_ledger_data.connection.max_rx_time = U2LE(buffer, 9); + DEBUG("LE DATA LENGTH CHANGE %04X - %04X- %04X- %04X\n", + ble_ledger_data.connection.max_tx_octets, + ble_ledger_data.connection.max_tx_time, + ble_ledger_data.connection.max_rx_octets, + ble_ledger_data.connection.max_rx_time); + } + break; + + case HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE: + if (U2LE(buffer, 2) == ble_ledger_data.connection.connection_handle) { + ble_ledger_data.connection.tx_phy = buffer[4]; + ble_ledger_data.connection.rx_phy = buffer[5]; + DEBUG("LE PHY UPDATE %02X - %02X\n", + ble_ledger_data.connection.tx_phy, + ble_ledger_data.connection.rx_phy); + } + break; + + default: + DEBUG("HCI LE META 0x%02X\n", buffer[0]); + break; + } +} + +static void hci_evt_vendor(uint8_t *buffer, uint16_t length) +{ + if (length < 4) { + return; + } + + uint16_t opcode = U2LE(buffer, 0); + + if (U2LE(buffer, 2) != ble_ledger_data.connection.connection_handle) { + return; + } + + switch (opcode) { +#ifdef HAVE_INAPP_BLE_PAIRING + case ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE: + DEBUG("PAIRING"); + switch (buffer[4]) { + case SMP_PAIRING_STATUS_SUCCESS: + DEBUG(" SUCCESS\n"); + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_SUCCESS); + break; + + case SMP_PAIRING_STATUS_SMP_TIMEOUT: + DEBUG(" TIMEOUT\n"); + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_TIMEOUT); + break; + + case SMP_PAIRING_STATUS_PAIRING_FAILED: + DEBUG(" FAILED : %02X\n", buffer[5]); + if (buffer[5] == 0x08) { // UNSPECIFIED_REASON + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CANCELLED_FROM_REMOTE); + } + else { + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); + } + break; + + default: + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); + break; + } + ble_ledger_data.pairing_in_progress = 0; + break; + + case ACI_GAP_PASS_KEY_REQ_VSEVT_CODE: + DEBUG("PASSKEY REQ\n"); + ask_user_pairing_passkey(); + break; + + case ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE: + DEBUG("NUMERIC COMP : %d\n", U4LE(buffer, 4)); + ask_user_pairing_numeric_comparison(U4LE(buffer, 4)); + break; +#endif // HAVE_INAPP_BLE_PAIRING + + case ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE: { + DEBUG("CONNECTION UPDATE RESP %d\n", buffer[4]); + break; + } + + case ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE: + case ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE: { + uint16_t att_handle = U2LE(buffer, 4); + ble_profile_info_t *profile_info = NULL; + profile_info = ble_ledger_data.profile[0]; + if ((profile_info->handle_in_range) + && (((ble_profile_handle_in_range_t) PIC(profile_info->handle_in_range))( + att_handle, profile_info->cookie))) { + uint8_t status = BLE_PROFILE_STATUS_OK; + if (opcode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { + if (profile_info->att_modified) { + status = ((ble_profile_att_modified_t) PIC(profile_info->att_modified))( + buffer, length, profile_info->cookie); + } + } + else if (opcode == ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE) { + if (profile_info->write_permit_req) { + status = ((ble_profile_write_permit_req_t) PIC( + profile_info->write_permit_req))(buffer, length, profile_info->cookie); + } + } + if (status == BLE_PROFILE_STATUS_OK_AND_SEND_PACKET) { + send_hci_packet(0); + } + } + else if (opcode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { + DEBUG("ATT MODIFIED %04X %d bytes at offset %d\n", + att_handle, + U2LE(buffer, 8), + U2LE(buffer, 6)); + } + break; + } + + case ACI_ATT_EXCHANGE_MTU_RESP_VSEVT_CODE: + DEBUG("MTU : %d\n", U2LE(buffer, 4)); + + ble_profile_info_t *profile_info = NULL; + profile_info = ble_ledger_data.profile[0]; + if (profile_info->mtu_changed) { + uint8_t status = BLE_PROFILE_STATUS_OK; + status = ((ble_profile_mtu_changed_t) PIC(profile_info->mtu_changed))( + U2LE(buffer, 4), profile_info->cookie); + if (status == BLE_PROFILE_STATUS_OK_AND_SEND_PACKET) { + send_hci_packet(0); + } + } + break; + + case ACI_GATT_INDICATION_VSEVT_CODE: + DEBUG("INDICATION EVT\n"); + ble_aci_gatt_forge_cmd_confirm_indication(&ble_ledger_data.cmd_data, + ble_ledger_data.connection.connection_handle); + send_hci_packet(0); + break; + + case ACI_GATT_PROC_COMPLETE_VSEVT_CODE: + DEBUG("PROCEDURE COMPLETE\n"); + break; + + case ACI_GATT_PROC_TIMEOUT_VSEVT_CODE: + DEBUG("PROCEDURE TIMEOUT\n"); +#ifdef HAVE_INAPP_BLE_PAIRING + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); +#endif // HAVE_INAPP_BLE_PAIRING + if (ble_ledger_data.connection.connection_handle != 0xFFFF) { + ble_hci_forge_cmd_disconnect(&ble_ledger_data.cmd_data, + ble_ledger_data.connection.connection_handle); + send_hci_packet(0); + } + break; + + default: + DEBUG("HCI VENDOR 0x%04X\n", opcode); + break; + } +} + +static uint32_t send_hci_packet(uint32_t timeout_ms) +{ + uint8_t hdr[3]; + + UNUSED(timeout_ms); + + hdr[0] = SEPROXYHAL_TAG_BLE_SEND; + U2BE_ENCODE(hdr, 1, ble_ledger_data.cmd_data.hci_cmd_buffer_length); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, hdr, 3, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, + ble_ledger_data.cmd_data.hci_cmd_buffer, + ble_ledger_data.cmd_data.hci_cmd_buffer_length, + NULL); + + return 0; +} + +/* Exported functions --------------------------------------------------------*/ +void BLE_LEDGER_init(os_io_init_ble_t *init, uint8_t force_restart) +{ + if (!init) { + return; + } + + if ((force_restart) || (ble_ledger_data.state < BLE_STATE_IDLE)) { + // First time BLE is started or forced to restart + memset(&ble_ledger_data, 0, sizeof(ble_ledger_data)); + ble_ledger_data.state = BLE_STATE_IDLE; + LEDGER_BLE_get_mac_address(ble_ledger_data.random_address); + DEBUG("BLE_LEDGER_init deep\n"); + } + else { + DEBUG("BLE_LEDGER_init\n"); + } + + memcpy(&ble_ledger_init_data, init, sizeof(ble_ledger_init_data)); +} + +void BLE_LEDGER_start(void) +{ + DEBUG("BLE_LEDGER_start\n"); + + if ((ble_ledger_data.state == BLE_STATE_IDLE) + || (ble_ledger_data.profiles != ble_ledger_init_data.profile_mask)) { + // BLE is not initialized + // or wanted classes have changed + ble_ledger_data.cmd_data.hci_cmd_opcode = 0xFFFF; + ble_ledger_data.state = BLE_STATE_INITIALIZING; + ble_ledger_data.init_step = BLE_INIT_STEP_IDLE; + ble_ledger_data.nb_of_profile = 0; + ble_ledger_data.connection.connection_handle = 0xFFFF; + if (ble_ledger_init_data.profile_mask & BLE_LEDGER_PROFILE_APDU) { + DEBUG("APDU "); + ble_ledger_data.profile[ble_ledger_data.nb_of_profile++] + = (ble_profile_info_t *) PIC(&BLE_LEDGER_PROFILE_apdu_info); + } +#ifdef HAVE_IO_U2F + else if (ble_ledger_init_data.profile_mask & BLE_LEDGER_PROFILE_U2F) { + DEBUG("U2F "); + // ble_ledger_data.profile[ble_ledger_data.nb_of_profile++] = + // (ble_profile_info_t*)PIC(&BLE_LEDGER_PROFILE_u2f_info); + } + DEBUG("\n"); +#endif // HAVE_IO_U2F + ble_ledger_data.profiles = ble_ledger_init_data.profile_mask; + init_mngr(NULL, 0); + } + else if (ble_ledger_data.state == BLE_STATE_RUNNING) { + ble_ledger_data.cmd_data.hci_cmd_opcode = 0xFFFF; + ble_ledger_data.state = BLE_STATE_START_ADVERTISING; + ble_ledger_data.start_adv_step = BLE_START_ADV_STEP_IDLE; + start_advertising_mngr(0); + } + else if (ble_ledger_data.state == BLE_STATE_STOPPING) { + ble_ledger_data.start_after_stop = 1; + } +} + +void BLE_LEDGER_stop(void) +{ + DEBUG("BLE_LEDGER_stop\n"); + + if (ble_ledger_data.state == BLE_STATE_RUNNING) { + ble_ledger_data.cmd_data.hci_cmd_opcode = 0xFFFF; + ble_ledger_data.state = BLE_STATE_STOPPING; + ble_ledger_data.stopping_step = BLE_STOPPING_STEP_IDLE; + stopping_mngr(0); + } + else if ((ble_ledger_data.state == BLE_STATE_INITIALIZING) + || (ble_ledger_data.state == BLE_STATE_START_ADVERTISING)) { + ble_ledger_data.stop_after_start = 1; + } +} + +void BLE_LEDGER_reset_pairings(void) +{ + ble_ledger_data.clear_pairing = 1; + if (ble_ledger_data.state == BLE_STATE_RUNNING) { + BLE_LEDGER_stop(); + BLE_LEDGER_start(); + } +} + +void BLE_LEDGER_accept_pairing(uint8_t status) +{ + if (ble_ledger_data.pairing_in_progress == 1) { + rsp_user_pairing_numeric_comparison(status); + } + else if (ble_ledger_data.pairing_in_progress == 2) { + rsp_user_pairing_passkey(status); + } +} + +void BLE_LEDGER_name_changed(void) +{ + if ((ble_ledger_data.state == BLE_STATE_RUNNING) + && (ble_ledger_data.connection.connection_handle == 0xFFFF)) { + BLE_LEDGER_stop(); + BLE_LEDGER_start(); + } +} + +int BLE_LEDGER_rx_seph_evt(uint8_t *seph_buffer, + uint16_t seph_buffer_length, + uint8_t *apdu_buffer, + uint16_t apdu_buffer_max_length) +{ + uint32_t status = 0; + + if (seph_buffer_length < 5) { + return -1; + } + + if (seph_buffer[4] == HCI_EVENT_PKT_TYPE) { + switch (seph_buffer[5]) { + case HCI_DISCONNECTION_COMPLETE_EVT_CODE: + if (seph_buffer_length < 10) { + status = -1; + } + else { + DEBUG("HCI DISCONNECTION COMPLETE code %02X\n", seph_buffer[9]); + ble_ledger_data.connection.connection_handle = 0xFFFF; + ble_ledger_data.advertising_enabled = 0; + ble_ledger_data.connection.encrypted = 0; +#ifdef HAVE_INAPP_BLE_PAIRING + end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); +#endif // HAVE_INAPP_BLE_PAIRING + if (ble_ledger_data.state == BLE_STATE_RUNNING) { + ble_ledger_data.cmd_data.hci_cmd_opcode = 0xFFFF; + ble_ledger_data.state = BLE_STATE_START_ADVERTISING; + ble_ledger_data.start_adv_step = BLE_START_ADV_STEP_IDLE; + start_advertising_mngr(0); + } + } + break; + + case HCI_ENCRYPTION_CHANGE_EVT_CODE: + if (seph_buffer_length < 10) { + status = -1; + } + else if (U2LE(seph_buffer, 8) == ble_ledger_data.connection.connection_handle) { + if (seph_buffer[10]) { + DEBUG("Link encrypted\n"); + ble_ledger_data.connection.encrypted = 1; + } + else { + DEBUG("Link not encrypted\n"); + ble_ledger_data.connection.encrypted = 0; + } + ble_profile_info_t *profile_info = NULL; + profile_info = ble_ledger_data.profile[0]; + if (profile_info->encryption_changed) { + ((ble_profile_encryption_changed_t) PIC(profile_info->encryption_changed))( + ble_ledger_data.connection.encrypted, profile_info->cookie); + } + } + else { + DEBUG("HCI ENCRYPTION CHANGE EVT %d on connection handle \n", + seph_buffer[10], + U2LE(seph_buffer, 8)); + } + break; + + case HCI_COMMAND_COMPLETE_EVT_CODE: + if (seph_buffer_length < 8) { + status = -1; + } + else { + hci_evt_cmd_complete(&seph_buffer[7], seph_buffer[6]); + } + break; + + case HCI_COMMAND_STATUS_EVT_CODE: + DEBUG("HCI COMMAND_STATUS %d - num %d - op %04X\n", + seph_buffer[7], + seph_buffer[8], + U2LE(seph_buffer, 9)); + if (ble_ledger_data.state == BLE_STATE_STOPPING) { + stopping_mngr(U2LE(seph_buffer, 9)); + } + break; + + case HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVT_CODE: + DEBUG("HCI KEY_REFRESH_COMPLETE\n"); + break; + + case HCI_LE_META_EVT_CODE: + if (seph_buffer_length < 8) { + status = -1; + } + else { + hci_evt_le_meta_evt(&seph_buffer[7], seph_buffer[6]); + } + break; + + case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE: + if (seph_buffer_length < 8) { + status = -1; + } + else { + hci_evt_vendor(&seph_buffer[7], seph_buffer[6]); + status = BLE_LEDGER_data_ready(apdu_buffer, apdu_buffer_max_length); + } + break; + + default: + break; + } + } + + return status; +} + +uint32_t BLE_LEDGER_send(const uint8_t *packet, uint16_t packet_length, uint32_t timeout_ms) +{ + uint32_t status = SWO_SUCCESS; + uint8_t ble_status = BLE_PROFILE_STATUS_OK; + ble_profile_info_t *profile_info = NULL; + + profile_info = ble_ledger_data.profile[0]; + + if (profile_info->send_packet) { + ble_status = ((ble_profile_send_packet_t) PIC(profile_info->send_packet))( + packet, packet_length, profile_info->cookie); + } + + if (ble_status == BLE_PROFILE_STATUS_OK_AND_SEND_PACKET) { + status = send_hci_packet(timeout_ms); + } + + return status; +} + +int32_t BLE_LEDGER_data_ready(uint8_t *buffer, uint16_t max_length) +{ + uint8_t index = 0; + int32_t status = 0; + + ble_profile_info_t *profile_info = NULL; + for (index = 0; index < ble_ledger_data.nb_of_profile; index++) { + profile_info = ble_ledger_data.profile[index]; + if (profile_info->data_ready) { + status = ((ble_profile_data_ready_t) PIC(profile_info->data_ready))( + buffer, max_length, profile_info->cookie); + if (status > 0) { + return status; + } + } + } + + return status; +} + +void BLE_LEDGER_setting(uint32_t profile_id, uint32_t setting_id, uint8_t *buffer, uint16_t length) +{ + uint8_t index = 0; + + ble_profile_info_t *profile_info = NULL; + for (index = 0; index < ble_ledger_data.nb_of_profile; index++) { + profile_info = ble_ledger_data.profile[index]; + if ((profile_info->type == profile_id) && (profile_info->setting)) { + ((ble_profile_setting_t) PIC(profile_info->setting))( + setting_id, buffer, length, profile_info->cookie); + } + } +} diff --git a/lib_blewbxx/src/ble_ledger_profile_apdu.c b/lib_blewbxx/src/ble_ledger_profile_apdu.c new file mode 100644 index 000000000..ac490dde0 --- /dev/null +++ b/lib_blewbxx/src/ble_ledger_profile_apdu.c @@ -0,0 +1,588 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include "os.h" +#include "os_pic.h" +#include "errors.h" +#include "ledger_protocol.h" +#include "ble_ledger.h" +#include "ble_ledger_profile_apdu.h" + +#ifdef HAVE_PRINTF +#define DEBUG PRINTF +// #define DEBUG(...) +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF + +/* Private enumerations ------------------------------------------------------*/ +typedef enum { + CREATE_DB_STEP_IDLE, + CREATE_DB_STEP_ADD_SERVICE, + CREATE_DB_STEP_ADD_NOTIFICATION_CHARACTERISTIC, + CREATE_DB_STEP_ADD_WRITE_CHARACTERISTIC, + CREATE_DB_STEP_ADD_WRITE_COMMAND_CHARACTERISTIC, + CREATE_DB__STEP_END, +} create_db_step_t; + +/* Private defines------------------------------------------------------------*/ +#define CONN_INTERVAL_MIN 12 // 15ms + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + // State + create_db_step_t create_db_step; + + // LEDGER PROTOCOL + ledger_protocol_t protocol_data; + + // ENCRYPTION + uint8_t link_is_encrypted; + + // CONNECTION + ble_connection_t *connection; + uint8_t connection_updated; + + // ATT/GATT + uint16_t gatt_service_handle; + uint16_t gatt_notification_characteristic_handle; + uint16_t gatt_write_characteristic_handle; + uint16_t gatt_write_cmd_characteristic_handle; + uint8_t mtu_negotiated; + uint8_t notifications_enabled; + uint8_t wait_write_resp_ack; + + // BLE CMD + ble_cmd_data_t *cmd_data; + + // TRANSFER MODE + uint8_t transfer_mode_wanted_enabled; + uint8_t transfer_mode_enabled; + uint8_t resp_length; + uint8_t resp[2]; + +} ledger_ble_profile_apdu_handle_t; + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +static void notify_chunk(ledger_ble_profile_apdu_handle_t *handle); +static void check_transfer_mode(ledger_ble_profile_apdu_handle_t *handle); + +/* Private variables ---------------------------------------------------------*/ +static ledger_ble_profile_apdu_handle_t ledger_apdu_profile_handle; +static uint8_t ledger_protocol_chunk_buffer[BLE_ATT_MAX_MTU_SIZE]; + +// clang-format off +#ifdef TARGET_STAX +const uint8_t charUuidTX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x01,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13}; +const uint8_t charUuidRX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x02,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13}; +const uint8_t charUuidRX2[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x03,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13}; +#else // ! TARGET_STAX +const uint8_t charUuidTX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x01,0x00,0x04,0x00,0x97,0x2C,0x00,0x34,0xD6,0x13}; +const uint8_t charUuidRX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x02,0x00,0x04,0x00,0x97,0x2C,0x00,0x34,0xD6,0x13}; +const uint8_t charUuidRX2[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x03,0x00,0x04,0x00,0x97,0x2C,0x00,0x34,0xD6,0x13}; +#endif // ! TARGET_STAX +// clang-format on + +/* Exported variables --------------------------------------------------------*/ +const ble_profile_info_t BLE_LEDGER_PROFILE_apdu_info = { + .type = BLE_LEDGER_PROFILE_APDU, + + .service_uuid + = {.type = BLE_GATT_UUID_TYPE_128, +// clang-format off +#ifdef TARGET_STAX + .value = {0x72,0x65,0x67,0x64,0x65,0x4c,0x00,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13}}, +#else // ! TARGET_STAX + .value = {0x72,0x65,0x67,0x64,0x65,0x4c,0x00,0x00,0x04,0x00,0x97,0x2C,0x00,0x34,0xD6,0x13}}, +#endif // ! TARGET_STAX + // clang-format on + + .init = BLE_LEDGER_PROFILE_apdu_init, + .create_db = BLE_LEDGER_PROFILE_apdu_create_db, + .handle_in_range = BLE_LEDGER_PROFILE_apdu_handle_in_range, + + .connection_evt = BLE_LEDGER_PROFILE_apdu_connection_evt, + .connection_update_evt = BLE_LEDGER_PROFILE_apdu_connection_update_evt, + .encryption_changed = BLE_LEDGER_PROFILE_apdu_encryption_changed, + + .att_modified = BLE_LEDGER_PROFILE_apdu_att_modified, + .write_permit_req = BLE_LEDGER_PROFILE_apdu_write_permit_req, + .mtu_changed = BLE_LEDGER_PROFILE_apdu_mtu_changed, + + .write_rsp_ack = BLE_LEDGER_PROFILE_apdu_write_rsp_ack, + .update_char_val_ack = BLE_LEDGER_PROFILE_apdu_update_char_value_ack, + + .send_packet = BLE_LEDGER_PROFILE_apdu_send_packet, + + .data_ready = BLE_LEDGER_PROFILE_apdu_data_ready, + + .setting = BLE_LEDGER_PROFILE_apdu_setting, + + .cookie = &ledger_apdu_profile_handle, +}; + +/* Private functions ---------------------------------------------------------*/ +static void notify_chunk(ledger_ble_profile_apdu_handle_t *handle) +{ + if (handle->protocol_data.tx_chunk_length >= 2) { + ble_aci_gatt_forge_cmd_update_char_value(handle->cmd_data, + handle->gatt_service_handle, + handle->gatt_notification_characteristic_handle, + 0, + handle->protocol_data.tx_chunk_length - 2, + &handle->protocol_data.tx_chunk_buffer[2]); + } +} + +static void check_transfer_mode(ledger_ble_profile_apdu_handle_t *handle) +{ + if (handle->transfer_mode_enabled != handle->transfer_mode_wanted_enabled) { + DEBUG("LEDGER_BLE_set_transfer_mode %d\n", handle->transfer_mode_wanted_enabled); + } + + if ((handle->transfer_mode_enabled == 0) && (handle->transfer_mode_wanted_enabled != 0)) { + handle->resp_length = 2; + U2BE_ENCODE(handle->resp, 0, SWO_SUCCESS); + } + + handle->transfer_mode_enabled = handle->transfer_mode_wanted_enabled; +} + +/* Exported functions --------------------------------------------------------*/ +void BLE_LEDGER_PROFILE_apdu_init(ble_cmd_data_t *cmd_data, void *cookie) +{ + if (!cmd_data || !cookie) { + return; + } + + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + memset(handle, 0, sizeof(ledger_ble_profile_apdu_handle_t)); + handle->cmd_data = cmd_data; + + memset(&handle->protocol_data, 0, sizeof(handle->protocol_data)); + handle->protocol_data.rx_apdu_buffer = BLE_LEDGER_apdu_buffer; + handle->protocol_data.rx_apdu_buffer_size = sizeof(BLE_LEDGER_apdu_buffer); + handle->protocol_data.tx_chunk_buffer = ledger_protocol_chunk_buffer; + handle->protocol_data.tx_chunk_buffer_size = sizeof(ledger_protocol_chunk_buffer); + handle->protocol_data.mtu = BLE_ATT_DEFAULT_MTU - 1; + + LEDGER_PROTOCOL_init(&handle->protocol_data, OS_IO_PACKET_TYPE_BLE_APDU); + + handle->gatt_service_handle = BLE_GATT_INVALID_HANDLE; + handle->gatt_notification_characteristic_handle = BLE_GATT_INVALID_HANDLE; + handle->gatt_write_characteristic_handle = BLE_GATT_INVALID_HANDLE; + handle->gatt_write_cmd_characteristic_handle = BLE_GATT_INVALID_HANDLE; + + handle->create_db_step = CREATE_DB_STEP_IDLE; +} + +uint8_t BLE_LEDGER_PROFILE_apdu_create_db(uint8_t *hci_buffer, uint16_t length, void *cookie) +{ + if (!hci_buffer || !cookie) { + return BLE_PROFILE_STATUS_BAD_PARAMETERS; + } + + uint8_t status = BLE_PROFILE_STATUS_OK; + + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + if (handle->create_db_step == CREATE_DB_STEP_IDLE) { + DEBUG("APDU PROFILE INIT START\n"); + } + else if ((length >= 2) && (handle->create_db_step == CREATE_DB_STEP_ADD_SERVICE)) { + handle->gatt_service_handle = U2LE(hci_buffer, 4); + DEBUG("APDU PROFILE GATT service handle : %04X\n", handle->gatt_service_handle); + } + else if ((length >= 2) + && (handle->create_db_step == CREATE_DB_STEP_ADD_NOTIFICATION_CHARACTERISTIC)) { + handle->gatt_notification_characteristic_handle = U2LE(hci_buffer, 4); + DEBUG("APDU PROFILE GATT notif char handle : %04X\n", + handle->gatt_notification_characteristic_handle); + } + else if ((length >= 2) && (handle->create_db_step == CREATE_DB_STEP_ADD_WRITE_CHARACTERISTIC)) { + handle->gatt_write_characteristic_handle = U2LE(hci_buffer, 4); + DEBUG("APDU PROFILE GATT write char handle : %04X\n", + handle->gatt_write_characteristic_handle); + } + else if ((length >= 2) + && (handle->create_db_step == CREATE_DB_STEP_ADD_WRITE_COMMAND_CHARACTERISTIC)) { + handle->gatt_write_cmd_characteristic_handle = U2LE(hci_buffer, 4); + DEBUG("APDU PROFILE GATT write cmd char handle : %04X\n", + handle->gatt_write_cmd_characteristic_handle); + } + + handle->create_db_step++; + + switch (handle->create_db_step) { + case CREATE_DB_STEP_ADD_SERVICE: + ble_aci_gatt_forge_cmd_add_service(handle->cmd_data, + BLE_LEDGER_PROFILE_apdu_info.service_uuid.type, + BLE_LEDGER_PROFILE_apdu_info.service_uuid.value, + BLE_GATT_PRIMARY_SERVICE, + BLE_GATT_MAX_SERVICE_RECORDS); + break; + + case CREATE_DB_STEP_ADD_NOTIFICATION_CHARACTERISTIC: { + ble_cmd_add_char_data_t data; + data.service_handle = handle->gatt_service_handle; + data.char_uuid_type = BLE_GATT_UUID_TYPE_128; + data.char_uuid = charUuidTX; + data.char_value_length = BLE_ATT_MAX_MTU_SIZE; + data.char_properties = BLE_CHAR_PROP_NOTIFY; + data.security_permissions = BLE_GATT_ATTR_PERMISSION_AUTHEN_WRITE; + data.gatt_evt_mask = BLE_GATT_DONT_NOTIFY_EVENTS; + data.enc_key_size = BLE_GAP_MAX_ENCRYPTION_KEY_SIZE; + data.is_variable = 1; + ble_aci_gatt_forge_cmd_add_char(handle->cmd_data, &data); + break; + } + + case CREATE_DB_STEP_ADD_WRITE_CHARACTERISTIC: { + ble_cmd_add_char_data_t data; + data.service_handle = handle->gatt_service_handle; + data.char_uuid_type = BLE_GATT_UUID_TYPE_128; + data.char_uuid = charUuidRX; + data.char_value_length = BLE_ATT_MAX_MTU_SIZE; + data.char_properties = BLE_CHAR_PROP_WRITE; + data.security_permissions = BLE_GATT_ATTR_PERMISSION_AUTHEN_WRITE; + data.gatt_evt_mask = BLE_GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + data.enc_key_size = BLE_GAP_MAX_ENCRYPTION_KEY_SIZE; + data.is_variable = 1; + ble_aci_gatt_forge_cmd_add_char(handle->cmd_data, &data); + break; + } + + case CREATE_DB_STEP_ADD_WRITE_COMMAND_CHARACTERISTIC: { + ble_cmd_add_char_data_t data; + data.service_handle = handle->gatt_service_handle; + data.char_uuid_type = BLE_GATT_UUID_TYPE_128; + data.char_uuid = charUuidRX2; + data.char_value_length = BLE_ATT_MAX_MTU_SIZE; + data.char_properties = BLE_CHAR_PROP_WRITE_WITHOUT_RESP; + data.security_permissions = BLE_GATT_ATTR_PERMISSION_AUTHEN_WRITE; + data.gatt_evt_mask = BLE_GATT_NOTIFY_ATTRIBUTE_WRITE; + data.enc_key_size = BLE_GAP_MAX_ENCRYPTION_KEY_SIZE; + data.is_variable = 1; + ble_aci_gatt_forge_cmd_add_char(handle->cmd_data, &data); + break; + } + + case CREATE_DB__STEP_END: + DEBUG("APDU PROFILE INIT END\n"); + status = BLE_PROFILE_STATUS_OK_PROCEDURE_END; + break; + + default: + break; + } + + return status; +} + +uint8_t BLE_LEDGER_PROFILE_apdu_handle_in_range(uint16_t gatt_handle, void *cookie) +{ + if (!cookie) { + return 0; + } + + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + if ((gatt_handle >= handle->gatt_service_handle) + && (gatt_handle <= handle->gatt_write_cmd_characteristic_handle + 1)) { + return 1; + } + + return 0; +} + +void BLE_LEDGER_PROFILE_apdu_connection_evt(ble_connection_t *connection, void *cookie) +{ + if (!cookie || !connection) { + return; + } + + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + handle->notifications_enabled = 0; + handle->protocol_data.mtu = BLE_ATT_DEFAULT_MTU - 1; + handle->mtu_negotiated = 0; + handle->connection_updated = 0; + handle->wait_write_resp_ack = 0; + handle->transfer_mode_enabled = 0; + handle->resp_length = 0; + handle->connection = connection; +} + +void BLE_LEDGER_PROFILE_apdu_connection_update_evt(ble_connection_t *connection, void *cookie) +{ + if (!cookie || !connection) { + return; + } + + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + handle->connection = connection; +} + +void BLE_LEDGER_PROFILE_apdu_encryption_changed(uint8_t encrypted, void *cookie) +{ + if (!cookie) { + return; + } + + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + handle->link_is_encrypted = encrypted; +} + +uint8_t BLE_LEDGER_PROFILE_apdu_att_modified(uint8_t *hci_buffer, uint16_t length, void *cookie) +{ + if (!hci_buffer || !cookie || (length < 10)) { + return BLE_PROFILE_STATUS_BAD_PARAMETERS; + } + + uint8_t status = BLE_PROFILE_STATUS_OK; + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + uint16_t connection_handle = U2LE(hci_buffer, 2); + uint16_t att_handle = U2LE(hci_buffer, 4); + uint16_t offset = U2LE(hci_buffer, 6); + uint16_t att_data_length = U2LE(hci_buffer, 8); + + if ((att_handle == handle->gatt_notification_characteristic_handle + 2) + && (att_data_length == 2) && (offset == 0)) { + // Peer device registering/unregistering for notifications + if (U2LE(hci_buffer, 10) != 0) { + DEBUG("REGISTERED FOR NOTIFICATIONS\n"); + handle->notifications_enabled = 1; + if (!handle->mtu_negotiated) { + ble_aci_gatt_forge_cmd_exchange_config(handle->cmd_data, connection_handle); + status = BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; + } + } + else { + DEBUG("NOT REGISTERED FOR NOTIFICATIONS\n"); + handle->notifications_enabled = 0; + } + } + else if ((att_handle == handle->gatt_write_cmd_characteristic_handle + 1) + && (handle->notifications_enabled) && (handle->link_is_encrypted) + && (att_data_length)) { + DEBUG("WRITE CMD %d\n", length - 8); + hci_buffer[8] = 0xDE; + hci_buffer[9] = 0xF1; + LEDGER_PROTOCOL_rx(&handle->protocol_data, &hci_buffer[8], length - 8); + + if (handle->protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { + check_transfer_mode(handle); + if (handle->transfer_mode_enabled) { + if (U2BE(handle->resp, 0) != SWO_SUCCESS) { + DEBUG("Transfer failed 0x%04x\n", U2BE(handle->resp, 0)); + handle->transfer_mode_wanted_enabled = 0; + check_transfer_mode(handle); + } + else if (handle->resp_length) { + LEDGER_PROTOCOL_tx(&handle->protocol_data, handle->resp, handle->resp_length); + handle->resp_length = 0; + notify_chunk(handle); + status = BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; + } + } + } + else if (handle->protocol_data.tx_chunk_length >= 2) { + notify_chunk(handle); + status = BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; + } + } + + return status; +} + +uint8_t BLE_LEDGER_PROFILE_apdu_write_permit_req(uint8_t *hci_buffer, uint16_t length, void *cookie) +{ + if (!hci_buffer || !cookie || (length < 7)) { + return BLE_PROFILE_STATUS_BAD_PARAMETERS; + } + + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + uint16_t connection_handle = U2LE(hci_buffer, 2); + uint16_t att_handle = U2LE(hci_buffer, 4); + uint8_t data_length = hci_buffer[6]; + + handle->wait_write_resp_ack = 1; + + if ((att_handle == handle->gatt_write_characteristic_handle + 1) + && (handle->notifications_enabled) && (handle->link_is_encrypted) && (data_length)) { + hci_buffer[5] = 0xDE; + hci_buffer[6] = 0xF1; + LEDGER_PROTOCOL_rx(&handle->protocol_data, &hci_buffer[5], length - 5); + ble_aci_gatt_forge_cmd_write_resp(handle->cmd_data, + connection_handle, + att_handle, + 0, + HCI_SUCCESS_ERR_CODE, + data_length, + &hci_buffer[7]); + } + else { + DEBUG("ATT WRITE %04X %d bytes\n", att_handle, data_length); + handle->protocol_data.tx_chunk_length = 0; + ble_aci_gatt_forge_cmd_write_resp(handle->cmd_data, + connection_handle, + att_handle, + 0, + HCI_SUCCESS_ERR_CODE, + data_length, + &hci_buffer[7]); + } + + return BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; +} + +uint8_t BLE_LEDGER_PROFILE_apdu_mtu_changed(uint16_t mtu, void *cookie) +{ + if (!cookie) { + return BLE_PROFILE_STATUS_BAD_PARAMETERS; + } + + uint8_t status = 0; + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + handle->protocol_data.mtu = mtu - 1; + handle->mtu_negotiated = 1; + + return status; +} + +uint8_t BLE_LEDGER_PROFILE_apdu_write_rsp_ack(void *cookie) +{ + if (!cookie) { + return BLE_PROFILE_STATUS_BAD_PARAMETERS; + } + + uint8_t status = BLE_PROFILE_STATUS_OK; + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + if (handle->wait_write_resp_ack != 0) { + handle->wait_write_resp_ack = 0; + if (handle->protocol_data.tx_chunk_length >= 2) { + notify_chunk(handle); + status = BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; + } + } + + return status; +} + +uint8_t BLE_LEDGER_PROFILE_apdu_update_char_value_ack(void *cookie) +{ + if (!cookie) { + return BLE_PROFILE_STATUS_BAD_PARAMETERS; + } + + uint8_t status = BLE_PROFILE_STATUS_OK; + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + handle->protocol_data.tx_chunk_length = 0; + if (!handle->transfer_mode_enabled) { + if (handle->protocol_data.tx_apdu_buffer) { + LEDGER_PROTOCOL_tx(&handle->protocol_data, NULL, 0); + notify_chunk(handle); + status = BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; + } + if (!handle->protocol_data.tx_apdu_buffer) { + handle->protocol_data.tx_chunk_length = 0; + if ((!handle->connection_updated) + && (handle->connection->conn_interval > BLE_SLAVE_CONN_INTERVAL_MIN)) { + handle->connection_updated = 1; + ble_aci_l2cap_forge_cmd_connection_parameter_update( + handle->cmd_data, + handle->connection->connection_handle, + CONN_INTERVAL_MIN, + CONN_INTERVAL_MIN, + handle->connection->conn_latency, + handle->connection->supervision_timeout); + status = BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; + } + } + } + + return status; +} + +uint8_t BLE_LEDGER_PROFILE_apdu_send_packet(const uint8_t *packet, uint16_t length, void *cookie) +{ + if (!packet || !cookie) { + return BLE_PROFILE_STATUS_BAD_PARAMETERS; + } + + uint8_t status = BLE_PROFILE_STATUS_OK; + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + if ((handle->transfer_mode_enabled != 0) && (length == 2)) { + handle->resp_length = 2; + handle->resp[0] = packet[0]; + handle->resp[1] = packet[1]; + if (handle->protocol_data.rx_apdu_length) { + LEDGER_PROTOCOL_tx(&handle->protocol_data, packet, length); + notify_chunk(handle); + status = BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; + } + } + else { + if ((handle->resp_length != 0) && (U2BE(handle->resp, 0) != SWO_SUCCESS)) { + LEDGER_PROTOCOL_tx(&handle->protocol_data, handle->resp, handle->resp_length); + } + else { + LEDGER_PROTOCOL_tx(&handle->protocol_data, packet, length); + } + handle->resp_length = 0; + + if (handle->wait_write_resp_ack == 0) { + notify_chunk(handle); + status = BLE_PROFILE_STATUS_OK_AND_SEND_PACKET; + } + } + + return status; +} + +int32_t BLE_LEDGER_PROFILE_apdu_data_ready(uint8_t *buffer, uint16_t max_length, void *cookie) +{ + int32_t status = 0; + + if (!buffer || !cookie) { + return -1; + } + + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + + PRINTF("BLE_LEDGER_PROFILE_apdu_data_ready %d\n", handle->protocol_data.rx_apdu_status); + if (handle->protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { + if (max_length < handle->protocol_data.rx_apdu_length) { + status = -1; + } + else { + memmove( + buffer, handle->protocol_data.rx_apdu_buffer, handle->protocol_data.rx_apdu_length); + status = handle->protocol_data.rx_apdu_length; + } + handle->protocol_data.rx_apdu_status = APDU_STATUS_WAITING; + handle->protocol_data.rx_apdu_length = 0; + } + + return status; +} + +void BLE_LEDGER_PROFILE_apdu_setting(uint32_t id, uint8_t *buffer, uint16_t length, void *cookie) +{ + if ((id == BLE_LEDGER_PROFILE_APDU_SETTING_ID_TRANSFER_MODE) && (buffer) && (length == 1)) { + ledger_ble_profile_apdu_handle_t *handle = (ledger_ble_profile_apdu_handle_t *) PIC(cookie); + handle->transfer_mode_wanted_enabled = buffer[0]; + } +} diff --git a/lib_blewbxx/src/ble_ledger_profile_u2f.c b/lib_blewbxx/src/ble_ledger_profile_u2f.c new file mode 100644 index 000000000..e69de29bb diff --git a/lib_blewbxx_impl/doc/mainpage.dox b/lib_blewbxx_impl/doc/mainpage.dox deleted file mode 100644 index 3ed046e5a..000000000 --- a/lib_blewbxx_impl/doc/mainpage.dox +++ /dev/null @@ -1,19 +0,0 @@ -/** @page ble_mainpage BlueTooth Low-Energy Stack - -@section ble_mainpage_intro Introduction - -This page describes the API of BLE (BlueTooth Low-Energy) Stack provided in \b NanoX and \b Stax products. - -@note TO BE COMPLETED - -@section initialization_api Initialization - -@ref LEDGER_BLE_init() function is used to initialize the BLE Stack. It must be called during IO -initialization of an application, if BLE is used. - - -@section activation_of_ble Activation of BLE - -BLE can be enabled by compiling the application with \b HAVE_BLE flag (only available on \b NanoX and \b Stax products). - -*/ diff --git a/lib_blewbxx_impl/include/ledger_ble.h b/lib_blewbxx_impl/include/ledger_ble.h index 16715cd9a..b8e28b72d 100644 --- a/lib_blewbxx_impl/include/ledger_ble.h +++ b/lib_blewbxx_impl/include/ledger_ble.h @@ -1,27 +1,8 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ +/* @BANNER@ */ #pragma once /* Includes ------------------------------------------------------------------*/ -#include -#include "os_id.h" -#include "lcx_crc.h" /* Exported enumerations -----------------------------------------------------*/ @@ -34,24 +15,3 @@ /* Exported variables --------------------------------------------------------*/ /* Exported functions prototypes--------------------------------------------- */ -void LEDGER_BLE_init(void); -void LEDGER_BLE_send(const uint8_t *packet, uint16_t packet_length); -void LEDGER_BLE_receive(const uint8_t *spi_buffer); -void LEDGER_BLE_set_recv_buffer(uint8_t *buffer, uint16_t buffer_length); -void LEDGER_BLE_enable_advertising(uint8_t enable); -void LEDGER_BLE_reset_pairings(void); -void LEDGER_BLE_accept_pairing(uint8_t status); - -#define LEDGER_BLE_get_mac_address(address) \ - { \ - unsigned char se_serial[8] = {0}; \ - os_serial(se_serial, sizeof(se_serial)); \ - unsigned int uid = cx_crc16(se_serial, 4); \ - address[0] = uid; \ - address[1] = uid >> 8; \ - uid = cx_crc16(se_serial + 4, 4); \ - address[2] = uid; \ - address[3] = uid >> 8; \ - address[4] = 0xF1; \ - address[5] = 0xDE; \ - } diff --git a/lib_blewbxx_impl/src/ledger_ble.c b/lib_blewbxx_impl/src/ledger_ble.c deleted file mode 100644 index ec3f8719f..000000000 --- a/lib_blewbxx_impl/src/ledger_ble.c +++ /dev/null @@ -1,1212 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include "os.h" -#include "os_settings.h" -#include "os_io_seproxyhal.h" - -#include "ble_hci_le.h" -#include "ble_hal_aci.h" -#include "ble_gap_aci.h" -#include "ble_l2cap_aci.h" -#include "ble_gatt_aci.h" -#include "ble_legacy.h" - -#include "lcx_rng.h" - -#include "ledger_protocol.h" -#include "ledger_ble.h" - -/* Private enumerations ------------------------------------------------------*/ -typedef enum { - BLE_STATE_INITIALIZING, - BLE_STATE_INITIALIZED, - BLE_STATE_CONFIGURE_ADVERTISING, - BLE_STATE_CONNECTING, - BLE_STATE_CONNECTED, - BLE_STATE_DISCONNECTING, -} ble_state_t; - -typedef enum { - BLE_INIT_STEP_IDLE, - BLE_INIT_STEP_RESET, - BLE_INIT_STEP_STATIC_ADDRESS, - BLE_INIT_STEP_GATT_INIT, - BLE_INIT_STEP_GAP_INIT, - BLE_INIT_STEP_SET_IO_CAPABILITIES, - BLE_INIT_STEP_SET_AUTH_REQUIREMENTS, - BLE_INIT_STEP_ADD_SERVICE, - BLE_INIT_STEP_ADD_NOTIFICATION_CHARACTERISTIC, - BLE_INIT_STEP_ADD_WRITE_CHARACTERISTIC, - BLE_INIT_STEP_ADD_WRITE_COMMAND_CHARACTERISTIC, - BLE_INIT_STEP_SET_TX_POWER_LEVEL, - BLE_INIT_STEP_CONFIGURE_ADVERTISING, - BLE_INIT_STEP_END, -} ble_init_step_t; - -typedef enum { - BLE_CONFIG_ADV_STEP_IDLE, - BLE_CONFIG_ADV_STEP_SET_ADV_DATAS, - BLE_CONFIG_ADV_STEP_SET_SCAN_RSP_DATAS, - BLE_CONFIG_ADV_STEP_SET_GAP_DEVICE_NAME, - BLE_CONFIG_ADV_STEP_START, - BLE_CONFIG_ADV_STEP_END, -} ble_config_adv_step_t; - -/* Private types, structures, unions -----------------------------------------*/ -typedef struct { - uint16_t connection_handle; - uint8_t role_slave; - uint8_t peer_address_random; - uint8_t peer_address[6]; - uint16_t conn_interval; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint8_t master_clock_accuracy; - uint8_t tx_phy; - uint8_t rx_phy; - uint16_t max_tx_octets; - uint16_t max_tx_time; - uint16_t max_rx_octets; - uint16_t max_rx_time; - uint8_t encrypted; -} ble_connection_t; - -typedef struct { - // General - ble_state_t state; - char device_name[20 + 1]; - char device_name_length; - uint8_t random_address[CONFIG_DATA_RANDOM_ADDRESS_LEN]; - - // Init - ble_init_step_t init_step; - - // Advertising configuration - ble_config_adv_step_t adv_step; - uint8_t adv_enable; - - // HCI - uint16_t hci_cmd_opcode; - - // GAP - uint16_t gap_service_handle; - uint16_t gap_device_name_characteristic_handle; - uint16_t gap_appearance_characteristic_handle; - uint8_t advertising_enabled; - ble_connection_t connection; - uint16_t pairing_code; - uint8_t pairing_in_progress; - - // L2CAP - uint8_t connection_updated; - - // ATT/GATT - uint16_t ledger_gatt_service_handle; - uint16_t ledger_gatt_notification_characteristic_handle; - uint16_t ledger_gatt_write_characteristic_handle; - uint16_t ledger_gatt_write_cmd_characteristic_handle; - uint8_t notifications_enabled; - - // PAIRING - uint8_t clear_pairing; - - // APDU - uint8_t wait_write_resp_ack; - uint16_t apdu_buffer_length; - uint8_t apdu_buffer[IO_APDU_BUFFER_SIZE]; - - // TRANSFER MODE - uint8_t transfer_mode_enable; - uint8_t resp_length; - uint8_t resp[2]; - -} ledger_ble_data_t; - -/* Private defines------------------------------------------------------------*/ -#define MAX_MTU_SIZE 156 - -#define BLE_SLAVE_CONN_INTERVAL_MIN 12 // 15ms -#define BLE_SLAVE_CONN_INTERVAL_MAX 24 // 30ms - -#define BLE_ADVERTISING_INTERVAL_MIN 48 // 30ms -#define BLE_ADVERTISING_INTERVAL_MAX 96 // 60ms - -#ifdef HAVE_PRINTF -#define LOG_BLE PRINTF -#else // !HAVE_PRINTF -#define LOG_BLE(...) -#endif // !HAVE_PRINTF - -/* Private macros-------------------------------------------------------------*/ - -/* Private functions prototypes ----------------------------------------------*/ -static void get_device_name(void); -static void configure_advertising_mngr(uint16_t opcode); -static void init_mngr(uint16_t opcode, const uint8_t *buffer, uint16_t length); -static void hci_evt_cmd_complete(const uint8_t *buffer, uint16_t length); -static void hci_evt_le_meta_evt(const uint8_t *buffer, uint16_t length); -static void hci_evt_vendor(const uint8_t *buffer, uint16_t length); -#ifdef HAVE_INAPP_BLE_PAIRING -static void end_pairing_ux(uint8_t pairing_ok); -static void ask_user_pairing_numeric_comparison(uint32_t code); -static void rsp_user_pairing_numeric_comparison(unsigned int status); -static void ask_user_pairing_passkey(void); -static void rsp_user_pairing_passkey(unsigned int status); -#endif // HAVE_INAPP_BLE_PAIRING -static void attribute_modified(const uint8_t *buffer, uint16_t length); -static void write_permit_request(const uint8_t *buffer, uint16_t length); -static void advertising_enable(uint8_t enable); -static void start_advertising(void); -static void notify_chunk(void); -static void check_transfer_mode(uint8_t enable); - -/* Exported variables --------------------------------------------------------*/ - -/* Private variables ---------------------------------------------------------*/ -// clang-format off -#ifdef TARGET_FLEX -const uint8_t service_uuid[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x00,0x00,0x04,0x30,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidTX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x01,0x00,0x04,0x30,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidRX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x02,0x00,0x04,0x30,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidRX2[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x03,0x00,0x04,0x30,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -#endif - -#ifdef TARGET_STAX -const uint8_t service_uuid[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x00,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidTX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x01,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidRX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x02,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidRX2[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x03,0x00,0x04,0x60,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -#endif - -#ifdef TARGET_NANOX -const uint8_t service_uuid[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x00,0x00,0x04,0x00,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidTX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x01,0x00,0x04,0x00,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidRX[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x02,0x00,0x04,0x00,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -const uint8_t charUuidRX2[16] = {0x72,0x65,0x67,0x64,0x65,0x4c,0x03,0x00,0x04,0x00,0x97,0x2C,0x00,0x34,0xD6,0x13,}; -#endif -// clang-format on - -static ledger_protocol_t ledger_protocol_data; -static ledger_ble_data_t ledger_ble_data; - -/* Private functions ---------------------------------------------------------*/ -static void copy_apdu_to_app(bool update_wait_status) -{ - // `rx_apdu_length` is already checked to be less than - // `rx_apdu_buffer_max_length` in `process_apdu_chunk()` - memcpy(ledger_protocol_data.rx_dst_buffer, - ledger_protocol_data.rx_apdu_buffer, - ledger_protocol_data.rx_apdu_length); - G_io_app.apdu_length = ledger_protocol_data.rx_apdu_length; - G_io_app.apdu_state = APDU_BLE; - G_io_app.apdu_media = IO_APDU_MEDIA_BLE; - ledger_protocol_data.rx_apdu_length = 0; - if (update_wait_status) { - ledger_protocol_data.rx_apdu_status = APDU_STATUS_WAITING; - } -} - -static void get_device_name(void) -{ - memset(ledger_ble_data.device_name, 0, sizeof(ledger_ble_data.device_name)); - ledger_ble_data.device_name_length = os_setting_get(OS_SETTING_DEVICENAME, - (uint8_t *) ledger_ble_data.device_name, - sizeof(ledger_ble_data.device_name) - 1); -} - -static void configure_advertising_mngr(uint16_t opcode) -{ - if ((ledger_ble_data.hci_cmd_opcode != 0xFFFF) && (opcode != ledger_ble_data.hci_cmd_opcode)) { - // Unexpected event => BLE_TODO - return; - } - - uint8_t buffer[31]; - uint8_t index = 0; - - if (ledger_ble_data.adv_step == BLE_CONFIG_ADV_STEP_IDLE) { - ledger_ble_data.connection.connection_handle = 0xFFFF; - ledger_ble_data.advertising_enabled = 0; - LOG_BLE("CONFIGURE ADVERTISING START\n"); - } - else if (ledger_ble_data.adv_step == (BLE_CONFIG_ADV_STEP_END - 1)) { - ledger_ble_data.advertising_enabled = 1; - } - - ledger_ble_data.adv_step++; - if ((ledger_ble_data.adv_step == (BLE_CONFIG_ADV_STEP_END - 1)) - && (!ledger_ble_data.adv_enable)) { - ledger_ble_data.adv_step++; - } - - switch (ledger_ble_data.adv_step) { - case BLE_CONFIG_ADV_STEP_SET_ADV_DATAS: - // Flags - buffer[index++] = 2; - buffer[index++] = AD_TYPE_FLAGS; - buffer[index++] = FLAG_BIT_BR_EDR_NOT_SUPPORTED | FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE; - - // Complete Local Name - get_device_name(); - buffer[index++] = ledger_ble_data.device_name_length + 1; - buffer[index++] = AD_TYPE_COMPLETE_LOCAL_NAME; - memcpy(&buffer[index], ledger_ble_data.device_name, ledger_ble_data.device_name_length); - index += ledger_ble_data.device_name_length; - - ledger_ble_data.hci_cmd_opcode = 0xfc8e; - aci_gap_update_adv_data(index, buffer); - break; - - case BLE_CONFIG_ADV_STEP_SET_SCAN_RSP_DATAS: - // Incomplete List of 128-bit Service UUIDs - buffer[index++] = sizeof(service_uuid) + 1; - buffer[index++] = AD_TYPE_128_BIT_SERV_UUID; - memcpy(&buffer[index], service_uuid, sizeof(service_uuid)); - index += sizeof(service_uuid); - - // Slave Connection Interval Range - buffer[index++] = 5; - buffer[index++] = AD_TYPE_SLAVE_CONN_INTERVAL; - buffer[index++] = BLE_SLAVE_CONN_INTERVAL_MIN; - buffer[index++] = 0; - buffer[index++] = BLE_SLAVE_CONN_INTERVAL_MAX; - buffer[index++] = 0; - - ledger_ble_data.hci_cmd_opcode = 0x2009; - hci_le_set_scan_response_data(index, buffer); - break; - - case BLE_CONFIG_ADV_STEP_SET_GAP_DEVICE_NAME: - ledger_ble_data.hci_cmd_opcode = 0xfd06; - aci_gatt_update_char_value(ledger_ble_data.gap_service_handle, - ledger_ble_data.gap_device_name_characteristic_handle, - 0, - ledger_ble_data.device_name_length, - (uint8_t *) ledger_ble_data.device_name); - break; - - case BLE_CONFIG_ADV_STEP_START: - ledger_ble_data.hci_cmd_opcode = 0xfc83; - advertising_enable(1); - break; - - default: - LOG_BLE("CONFIGURE ADVERTISING END\n"); - if (ledger_ble_data.state == BLE_STATE_CONFIGURE_ADVERTISING) { - ledger_ble_data.state = BLE_STATE_INITIALIZED; - } - break; - } -} - -static void init_mngr(uint16_t opcode, const uint8_t *buffer, uint16_t length) -{ - UNUSED(length); - - if ((ledger_ble_data.hci_cmd_opcode != 0xFFFF) && (opcode != ledger_ble_data.hci_cmd_opcode)) { - // Unexpected event => BLE_TODO - return; - } - - if (ledger_ble_data.init_step == BLE_INIT_STEP_IDLE) { - LOG_BLE("INIT START\n"); - } - else if ((length >= 6) && (ledger_ble_data.init_step == BLE_INIT_STEP_GAP_INIT)) { - ledger_ble_data.gap_service_handle = U2LE(buffer, 1); - ledger_ble_data.gap_device_name_characteristic_handle = U2LE(buffer, 3); - ledger_ble_data.gap_appearance_characteristic_handle = U2LE(buffer, 5); - } - else if ((length >= 2) && (ledger_ble_data.init_step == BLE_INIT_STEP_ADD_SERVICE)) { - ledger_ble_data.ledger_gatt_service_handle = U2LE(buffer, 1); - } - else if ((length >= 2) - && (ledger_ble_data.init_step == BLE_INIT_STEP_ADD_NOTIFICATION_CHARACTERISTIC)) { - ledger_ble_data.ledger_gatt_notification_characteristic_handle = U2LE(buffer, 1); - } - else if ((length >= 2) - && (ledger_ble_data.init_step == BLE_INIT_STEP_ADD_WRITE_CHARACTERISTIC)) { - ledger_ble_data.ledger_gatt_write_characteristic_handle = U2LE(buffer, 1); - } - else if ((length >= 2) - && (ledger_ble_data.init_step == BLE_INIT_STEP_ADD_WRITE_COMMAND_CHARACTERISTIC)) { - ledger_ble_data.ledger_gatt_write_cmd_characteristic_handle = U2LE(buffer, 1); - } - else if (ledger_ble_data.init_step == BLE_INIT_STEP_CONFIGURE_ADVERTISING) { - ledger_ble_data.adv_enable = !os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); - configure_advertising_mngr(opcode); - if (ledger_ble_data.adv_step != BLE_CONFIG_ADV_STEP_END) { - return; - } - } - - ledger_ble_data.init_step++; - - switch (ledger_ble_data.init_step) { - case BLE_INIT_STEP_RESET: - hci_reset(); - break; - - case BLE_INIT_STEP_STATIC_ADDRESS: - ledger_ble_data.hci_cmd_opcode = 0xfc0c; - aci_hal_write_config_data(CONFIG_DATA_RANDOM_ADDRESS_OFFSET, - CONFIG_DATA_RANDOM_ADDRESS_LEN, - ledger_ble_data.random_address); - break; - - case BLE_INIT_STEP_GATT_INIT: - ledger_ble_data.hci_cmd_opcode = 0xfd01; - aci_gatt_init(); - break; - - case BLE_INIT_STEP_GAP_INIT: - ledger_ble_data.hci_cmd_opcode = 0xfc8a; - aci_gap_init(GAP_PERIPHERAL_ROLE, - PRIVACY_DISABLED, - sizeof(ledger_ble_data.device_name) - 1, - &ledger_ble_data.gap_service_handle, - &ledger_ble_data.gap_device_name_characteristic_handle, - &ledger_ble_data.gap_appearance_characteristic_handle); - break; - - case BLE_INIT_STEP_SET_IO_CAPABILITIES: - ledger_ble_data.hci_cmd_opcode = 0xfc85; - aci_gap_set_io_capability(IO_CAP_DISPLAY_YES_NO); - break; - - case BLE_INIT_STEP_SET_AUTH_REQUIREMENTS: - ledger_ble_data.hci_cmd_opcode = 0xfc86; - aci_gap_set_authentication_requirement( - BONDING, - MITM_PROTECTION_REQUIRED, - 0x01, // LE Secure connections pairing supported but optional - KEYPRESS_NOT_SUPPORTED, - MIN_ENCRY_KEY_SIZE + 1, - MAX_ENCRY_KEY_SIZE, - DONOT_USE_FIXED_PIN_FOR_PAIRING, - 0, - STATIC_RANDOM_ADDR); - break; - - case BLE_INIT_STEP_ADD_SERVICE: - ledger_ble_data.hci_cmd_opcode = 0xfd02; - aci_gatt_add_service(UUID_TYPE_128, - (const Service_UUID_t *) service_uuid, - PRIMARY_SERVICE, - 9, - &ledger_ble_data.ledger_gatt_service_handle); - break; - - case BLE_INIT_STEP_ADD_NOTIFICATION_CHARACTERISTIC: - ledger_ble_data.hci_cmd_opcode = 0xfd04; - aci_gatt_add_char(ledger_ble_data.ledger_gatt_service_handle, - UUID_TYPE_128, - (const Char_UUID_t *) charUuidTX, - MAX_MTU_SIZE, - CHAR_PROP_NOTIFY, - ATTR_PERMISSION_AUTHEN_WRITE, - GATT_DONT_NOTIFY_EVENTS, - MAX_ENCRY_KEY_SIZE, - CHAR_VALUE_LEN_VARIABLE, - &ledger_ble_data.ledger_gatt_notification_characteristic_handle); - break; - - case BLE_INIT_STEP_ADD_WRITE_CHARACTERISTIC: - ledger_ble_data.hci_cmd_opcode = 0xfd04; - aci_gatt_add_char(ledger_ble_data.ledger_gatt_service_handle, - UUID_TYPE_128, - (const Char_UUID_t *) charUuidRX, - MAX_MTU_SIZE, - CHAR_PROP_WRITE, - ATTR_PERMISSION_AUTHEN_WRITE, - GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP, - MAX_ENCRY_KEY_SIZE, - CHAR_VALUE_LEN_VARIABLE, - &ledger_ble_data.ledger_gatt_write_characteristic_handle); - break; - - case BLE_INIT_STEP_ADD_WRITE_COMMAND_CHARACTERISTIC: - ledger_ble_data.hci_cmd_opcode = 0xfd04; - aci_gatt_add_char(ledger_ble_data.ledger_gatt_service_handle, - UUID_TYPE_128, - (const Char_UUID_t *) charUuidRX2, - MAX_MTU_SIZE, - CHAR_PROP_WRITE_WITHOUT_RESP, - ATTR_PERMISSION_AUTHEN_WRITE, - GATT_NOTIFY_ATTRIBUTE_WRITE, - MAX_ENCRY_KEY_SIZE, - CHAR_VALUE_LEN_VARIABLE, - &ledger_ble_data.ledger_gatt_write_cmd_characteristic_handle); - break; - - case BLE_INIT_STEP_SET_TX_POWER_LEVEL: - ledger_ble_data.hci_cmd_opcode = 0xfc0f; - aci_hal_set_tx_power_level(1, // High power (ignored) -#if defined(TARGET_STAX) || defined(TARGET_FLEX) - 0x19); // 0 dBm -#else // !TARGET_STAX - 0x07); // -14.1 dBm -#endif // !TARGET_STAX - break; - - case BLE_INIT_STEP_CONFIGURE_ADVERTISING: - ledger_ble_data.hci_cmd_opcode = 0xFFFF; - ledger_ble_data.adv_step = BLE_CONFIG_ADV_STEP_IDLE; - ledger_ble_data.adv_enable = !os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); - configure_advertising_mngr(0); - break; - - case BLE_INIT_STEP_END: - LOG_BLE("INIT END\n"); - if (ledger_ble_data.clear_pairing == 0xC1) { - ledger_ble_data.clear_pairing = 0; - aci_gap_clear_security_db(); - } - G_io_app.ble_ready = 1; - ledger_ble_data.state = BLE_STATE_INITIALIZED; - break; - - default: - break; - } -} - -static void hci_evt_cmd_complete(const uint8_t *buffer, uint16_t length) -{ - if (length < 3) { - return; - } - - uint16_t opcode = U2LE(buffer, 1); - - if (ledger_ble_data.state == BLE_STATE_INITIALIZING) { - init_mngr(opcode, &buffer[3], length); - } - else if (ledger_ble_data.state == BLE_STATE_CONFIGURE_ADVERTISING) { - configure_advertising_mngr(opcode); - } - else if (opcode == 0xfd26) { - // ACI_GATT_WRITE_RESP - if (ledger_ble_data.wait_write_resp_ack != 0) { - ledger_ble_data.wait_write_resp_ack = 0; - if (ledger_protocol_data.tx_chunk_length >= 2) { - G_io_app.ble_xfer_timeout = 2000; - notify_chunk(); - } - } - } - else if (opcode == 0xfd06) { - // ACI_GATT_UPDATE_CHAR_VALUE - ledger_protocol_data.tx_chunk_length = 0; - if (ledger_ble_data.transfer_mode_enable) { - if ((ledger_protocol_data.rx_apdu_length) - && (ledger_protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE)) { - copy_apdu_to_app(false); - } - } - else { - if (ledger_protocol_data.tx_apdu_buffer) { - LEDGER_PROTOCOL_tx(&ledger_protocol_data, NULL, 0); - notify_chunk(); - } - if (!ledger_protocol_data.tx_apdu_buffer) { - ledger_protocol_data.tx_chunk_length = 0; - G_io_app.ble_xfer_timeout = 0; - G_io_app.apdu_state = APDU_IDLE; - if ((!ledger_ble_data.connection_updated) - && (ledger_ble_data.connection.conn_interval > BLE_SLAVE_CONN_INTERVAL_MIN)) { - ledger_ble_data.connection_updated = 1; - aci_l2cap_connection_parameter_update_req( - ledger_ble_data.connection.connection_handle, - BLE_SLAVE_CONN_INTERVAL_MIN, - BLE_SLAVE_CONN_INTERVAL_MIN, - ledger_ble_data.connection.conn_latency, - ledger_ble_data.connection.supervision_timeout); - } - } - } - } - else if ((opcode == 0xfc81) || (opcode == 0xfc83)) { - LOG_BLE("HCI_LE_SET_ADVERTISE_ENABLE %04X %d %d\n", - ledger_ble_data.connection.connection_handle, - G_io_app.disabling_advertising, - G_io_app.enabling_advertising); - if (ledger_ble_data.connection.connection_handle != 0xFFFF) { - if (G_io_app.disabling_advertising) { - // Connected & ordered to disable ble, force disconnection -#ifdef HAVE_INAPP_BLE_PAIRING - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); -#endif // HAVE_INAPP_BLE_PAIRING - LEDGER_BLE_init(); - } - } - else if (G_io_app.disabling_advertising) { - ledger_ble_data.advertising_enabled = 0; - if (G_io_app.name_changed) { - start_advertising(); - } - } - else if (G_io_app.enabling_advertising) { - ledger_ble_data.advertising_enabled = 1; - } - else { - ledger_ble_data.advertising_enabled = 1; - } - G_io_app.disabling_advertising = 0; - G_io_app.enabling_advertising = 0; - } - else if (opcode == 0xfca5) { - LOG_BLE("ACI_GAP_NUMERIC_COMPARISON_VALUE_CONFIRM_YESNO\n"); - } - else if (opcode == 0xfc94) { - LOG_BLE("ACI_GAP_CLEAR_SECURITY_DB\n"); - } - else if (opcode == 0xfd25) { - LOG_BLE("ACI_GATT_CONFIRM_INDICATION\n"); - } - else { - LOG_BLE("HCI EVT CMD COMPLETE 0x%04X\n", opcode); - } -} - -static void hci_evt_le_meta_evt(const uint8_t *buffer, uint16_t length) -{ - if (!length) { - return; - } - - switch (buffer[0]) { - case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE: - ledger_ble_data.connection.connection_handle = U2LE(buffer, 2); - ledger_ble_data.connection.role_slave = buffer[4]; - ledger_ble_data.connection.peer_address_random = buffer[5]; - memcpy(ledger_ble_data.connection.peer_address, &buffer[6], 6); - ledger_ble_data.connection.conn_interval = U2LE(buffer, 12); - ledger_ble_data.connection.conn_latency = U2LE(buffer, 14); - ledger_ble_data.connection.supervision_timeout = U2LE(buffer, 16); - ledger_ble_data.connection.master_clock_accuracy = buffer[18]; - ledger_ble_data.connection.encrypted = 0; - ledger_ble_data.transfer_mode_enable = 0; - LOG_BLE("LE CONNECTION COMPLETE %04X - %04X- %04X- %04X\n", - ledger_ble_data.connection.connection_handle, - ledger_ble_data.connection.conn_interval, - ledger_ble_data.connection.conn_latency, - ledger_ble_data.connection.supervision_timeout); - ledger_protocol_data.mtu = ATT_MTU - 3 + 2; - ledger_ble_data.notifications_enabled = 0; - ledger_ble_data.advertising_enabled = 0; - ledger_protocol_data.mtu_negotiated = 0; - ledger_ble_data.connection_updated = 0; - break; - - case HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE: - ledger_ble_data.connection.connection_handle = U2LE(buffer, 2); - ledger_ble_data.connection.conn_interval = U2LE(buffer, 4); - ledger_ble_data.connection.conn_latency = U2LE(buffer, 6); - ledger_ble_data.connection.supervision_timeout = U2LE(buffer, 8); - LOG_BLE("LE CONNECTION UPDATE %04X - %04X- %04X- %04X\n", - ledger_ble_data.connection.connection_handle, - ledger_ble_data.connection.conn_interval, - ledger_ble_data.connection.conn_latency, - ledger_ble_data.connection.supervision_timeout); - break; - - case HCI_LE_DATA_LENGTH_CHANGE_SUBEVT_CODE: - if (U2LE(buffer, 1) == ledger_ble_data.connection.connection_handle) { - ledger_ble_data.connection.max_tx_octets = U2LE(buffer, 3); - ledger_ble_data.connection.max_tx_time = U2LE(buffer, 5); - ledger_ble_data.connection.max_rx_octets = U2LE(buffer, 7); - ledger_ble_data.connection.max_rx_time = U2LE(buffer, 9); - LOG_BLE("LE DATA LENGTH CHANGE %04X - %04X- %04X- %04X\n", - ledger_ble_data.connection.max_tx_octets, - ledger_ble_data.connection.max_tx_time, - ledger_ble_data.connection.max_rx_octets, - ledger_ble_data.connection.max_rx_time); - } - break; - - case HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE: - if (U2LE(buffer, 2) == ledger_ble_data.connection.connection_handle) { - ledger_ble_data.connection.tx_phy = buffer[4]; - ledger_ble_data.connection.rx_phy = buffer[5]; - LOG_BLE("LE PHY UPDATE %02X - %02X\n", - ledger_ble_data.connection.tx_phy, - ledger_ble_data.connection.rx_phy); - } - break; - - default: - LOG_BLE("HCI LE META 0x%02X\n", buffer[0]); - break; - } -} - -static void hci_evt_vendor(const uint8_t *buffer, uint16_t length) -{ - if (length < 4) { - return; - } - - uint16_t opcode = U2LE(buffer, 0); - - if (U2LE(buffer, 2) != ledger_ble_data.connection.connection_handle) { - return; - } - - switch (opcode) { -#ifdef HAVE_INAPP_BLE_PAIRING - case ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE: - LOG_BLE("PAIRING"); - switch (buffer[4]) { - case SMP_PAIRING_STATUS_SUCCESS: - LOG_BLE(" SUCCESS\n"); - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_SUCCESS); - break; - - case SMP_PAIRING_STATUS_SMP_TIMEOUT: - LOG_BLE(" TIMEOUT\n"); - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_TIMEOUT); - break; - - case SMP_PAIRING_STATUS_PAIRING_FAILED: - LOG_BLE(" FAILED : %02X\n", buffer[5]); - if (buffer[5] == 0x08) { // UNSPECIFIED_REASON - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CANCELLED_FROM_REMOTE); - } - else { - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); - } - break; - - default: - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); - break; - } - ledger_ble_data.pairing_in_progress = 0; - break; - - case ACI_GAP_PASS_KEY_REQ_VSEVT_CODE: - LOG_BLE("PASSKEY REQ\n"); - ask_user_pairing_passkey(); - break; - - case ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE: - LOG_BLE("NUMERIC COMP : %d\n", U4LE(buffer, 4)); - ask_user_pairing_numeric_comparison(U4LE(buffer, 4)); - break; -#endif // HAVE_INAPP_BLE_PAIRING - - case ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE: - attribute_modified(&buffer[4], length - 4); - break; - - case ACI_ATT_EXCHANGE_MTU_RESP_VSEVT_CODE: - ledger_protocol_data.mtu = U2LE(buffer, 4) - 3 + 2; - ledger_protocol_data.mtu_negotiated = 1; - LOG_BLE("MTU : %d\n", U2LE(buffer, 4)); - break; - - case ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE: - LOG_BLE("CONNECTION UPDATE RESP %d\n", buffer[4]); - break; - - case ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE: - write_permit_request(&buffer[4], length - 4); - break; - - case ACI_GATT_INDICATION_VSEVT_CODE: - LOG_BLE("INDICATION EVT\n"); - aci_gatt_confirm_indication(ledger_ble_data.connection.connection_handle); - break; - - case ACI_GATT_PROC_COMPLETE_VSEVT_CODE: - LOG_BLE("PROCEDURE COMPLETE\n"); - break; - - case ACI_GATT_PROC_TIMEOUT_VSEVT_CODE: - LOG_BLE("PROCEDURE TIMEOUT\n"); -#ifdef HAVE_INAPP_BLE_PAIRING - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); -#endif // HAVE_INAPP_BLE_PAIRING - LEDGER_BLE_init(); - break; - - default: - LOG_BLE("HCI VENDOR 0x%04X\n", opcode); - break; - } -} - -#ifdef HAVE_INAPP_BLE_PAIRING -static void end_pairing_ux(uint8_t pairing_ok) -{ - bolos_ux_params_t ux_params; - - LOG_BLE("end_pairing_ux : %d (%d)\n", pairing_ok, ledger_ble_data.pairing_in_progress); - if (ledger_ble_data.pairing_in_progress) { - ux_params.ux_id = BOLOS_UX_ASYNCHMODAL_PAIRING_CANCEL; - ux_params.u.pairing_status.pairing_ok = pairing_ok; - ux_params.len = sizeof(ux_params.u.pairing_status); - G_io_asynch_ux_callback.asynchmodal_end_callback = NULL; - os_ux(&ux_params); - } -} - -static void ask_user_pairing_numeric_comparison(uint32_t code) -{ - bolos_ux_params_t ux_params; - - ux_params.u.pairing_request.type = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST_NUMCOMP; - ux_params.ux_id = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST; - ux_params.len = sizeof(ux_params.u.pairing_request); - ledger_ble_data.pairing_in_progress = 1; - ux_params.u.pairing_request.pairing_info_len = 6; - SPRINTF(ux_params.u.pairing_request.pairing_info, "%06d", (unsigned int) code); -#if defined(TARGET_STAX) || defined(TARGET_FLEX) - G_io_asynch_ux_callback.asynchmodal_end_callback = NULL; -#else // !TARGET_STAX - G_io_asynch_ux_callback.asynchmodal_end_callback = rsp_user_pairing_numeric_comparison; -#endif // !TARGET_STAX - os_ux(&ux_params); -} - -static void rsp_user_pairing_numeric_comparison(unsigned int status) -{ - if (status == BOLOS_UX_OK) { - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CONFIRM_CODE_YES); - aci_gap_numeric_comparison_value_confirm_yesno(ledger_ble_data.connection.connection_handle, - 1); - } - else if (status == BOLOS_UX_IGNORE) { - ledger_ble_data.pairing_in_progress = 0; - aci_gap_numeric_comparison_value_confirm_yesno(ledger_ble_data.connection.connection_handle, - 0); - } - else { - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CONFIRM_CODE_NO); - aci_gap_numeric_comparison_value_confirm_yesno(ledger_ble_data.connection.connection_handle, - 0); - } -} - -static void ask_user_pairing_passkey(void) -{ - bolos_ux_params_t ux_params; - - ux_params.u.pairing_request.type = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST_PASSKEY; - ux_params.ux_id = BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST; - ux_params.len = sizeof(ux_params.u.pairing_request); - ledger_ble_data.pairing_in_progress = 1; - ledger_ble_data.pairing_code = cx_rng_u32_range_func(0, 1000000, cx_rng_u32); - ux_params.u.pairing_request.pairing_info_len = 6; - SPRINTF(ux_params.u.pairing_request.pairing_info, "%06d", ledger_ble_data.pairing_code); -#if defined(TARGET_STAX) || defined(TARGET_FLEX) - G_io_asynch_ux_callback.asynchmodal_end_callback = NULL; -#else // !TARGET_STAX - G_io_asynch_ux_callback.asynchmodal_end_callback = rsp_user_pairing_passkey; -#endif // !TARGET_STAX - os_ux(&ux_params); -} - -static void rsp_user_pairing_passkey(unsigned int status) -{ - if (status == BOLOS_UX_OK) { - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_ACCEPT_PASSKEY); - ledger_ble_data.pairing_code = cx_rng_u32_range_func(0, 1000000, cx_rng_u32); - aci_gap_pass_key_resp(ledger_ble_data.connection.connection_handle, - ledger_ble_data.pairing_code); - } - else if (status == BOLOS_UX_IGNORE) { - ledger_ble_data.pairing_in_progress = 0; - } - else { - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_CANCEL_PASSKEY); - } -} -#endif // HAVE_INAPP_BLE_PAIRING - -static void attribute_modified(const uint8_t *buffer, uint16_t length) -{ - if (length < 6) { - return; - } - - uint16_t att_handle = U2LE(buffer, 0); - uint16_t offset = U2LE(buffer, 2); - uint16_t att_data_length = U2LE(buffer, 4); - - if ((att_handle == ledger_ble_data.ledger_gatt_notification_characteristic_handle + 2) - && (att_data_length == 2) && (offset == 0)) { - // Peer device registering/unregistering for notifications - if (U2LE(buffer, 6) != 0) { - LOG_BLE("REGISTERED FOR NOTIFICATIONS\n"); - ledger_ble_data.notifications_enabled = 1; - if (!ledger_protocol_data.mtu_negotiated) { - aci_gatt_exchange_config(ledger_ble_data.connection.connection_handle); - } - } - else { - LOG_BLE("NOT REGISTERED FOR NOTIFICATIONS\n"); - ledger_ble_data.notifications_enabled = 0; - } - } - else if ((att_handle == ledger_ble_data.ledger_gatt_write_cmd_characteristic_handle + 1) - && (ledger_ble_data.notifications_enabled) && (ledger_ble_data.connection.encrypted) - && (att_data_length)) { - LOG_BLE("WRITE CMD %d\n", length - 4); - LEDGER_PROTOCOL_rx(&ledger_protocol_data, &buffer[4], length - 4); - - if (ledger_protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { - check_transfer_mode(G_io_app.transfer_mode); - if (ledger_ble_data.transfer_mode_enable) { - if (U2BE(ledger_ble_data.resp, 0) != SWO_SUCCESS) { - LOG_BLE("Transfer failed 0x%04x\n", U2BE(ledger_ble_data.resp, 0)); - G_io_app.transfer_mode = 0; - check_transfer_mode(G_io_app.transfer_mode); - copy_apdu_to_app(true); - } - else if (ledger_ble_data.resp_length) { - LEDGER_PROTOCOL_tx( - &ledger_protocol_data, ledger_ble_data.resp, ledger_ble_data.resp_length); - ledger_ble_data.resp_length = 0; - notify_chunk(); - } - } - else { - copy_apdu_to_app(true); - } - } - else if (ledger_protocol_data.tx_chunk_length >= 2) { - G_io_app.ble_xfer_timeout = 2000; - notify_chunk(); - G_io_app.apdu_state = APDU_BLE; - } - } - else { - LOG_BLE("ATT MODIFIED %04X %d bytes at offset %d\n", att_handle, att_data_length, offset); - } -} - -static void write_permit_request(const uint8_t *buffer, uint16_t length) -{ - if (length < 3) { - return; - } - - uint16_t att_handle = U2LE(buffer, 0); - uint8_t data_length = buffer[2]; - - ledger_ble_data.wait_write_resp_ack = 1; - - if ((att_handle == ledger_ble_data.ledger_gatt_write_characteristic_handle + 1) - && (ledger_ble_data.notifications_enabled) && (ledger_ble_data.connection.encrypted) - && (data_length)) { - LEDGER_PROTOCOL_rx(&ledger_protocol_data, &buffer[1], length - 1); - aci_gatt_write_resp(ledger_ble_data.connection.connection_handle, - att_handle, - 0, - HCI_SUCCESS_ERR_CODE, - data_length, - &buffer[3]); - if (ledger_protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { - copy_apdu_to_app(true); - } - } - else { - LOG_BLE("ATT WRITE %04X %d bytes\n", att_handle, data_length); - ledger_protocol_data.tx_chunk_length = 0; - aci_gatt_write_resp(ledger_ble_data.connection.connection_handle, - att_handle, - 0, - HCI_SUCCESS_ERR_CODE, - data_length, - &buffer[3]); - } -} - -static void advertising_enable(uint8_t enable) -{ - if (enable) { - uint8_t buffer[31]; - - get_device_name(); - buffer[0] = AD_TYPE_COMPLETE_LOCAL_NAME; - memcpy(&buffer[1], ledger_ble_data.device_name, ledger_ble_data.device_name_length); - aci_gap_set_discoverable(ADV_IND, - BLE_ADVERTISING_INTERVAL_MIN, - BLE_ADVERTISING_INTERVAL_MAX, - RANDOM_ADDR, - NO_WHITE_LIST_USE, - ledger_ble_data.device_name_length + 1, - buffer, - 0, - NULL, - 0, - 0); - } - else { - aci_gap_set_non_discoverable(); - } -} - -static void start_advertising(void) -{ - if (G_io_app.name_changed) { - G_io_app.name_changed = 0; - ledger_ble_data.state = BLE_STATE_CONFIGURE_ADVERTISING; - ledger_ble_data.adv_step = BLE_CONFIG_ADV_STEP_IDLE; - } - else { - ledger_ble_data.state = BLE_STATE_CONFIGURE_ADVERTISING; - ledger_ble_data.adv_step = BLE_CONFIG_ADV_STEP_START - 1; - } - ledger_ble_data.hci_cmd_opcode = 0xFFFF; - ledger_ble_data.adv_enable = !os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); - configure_advertising_mngr(0); -} - -static void notify_chunk(void) -{ - if (ledger_protocol_data.tx_chunk_length >= 2) { - aci_gatt_update_char_value(ledger_ble_data.ledger_gatt_service_handle, - ledger_ble_data.ledger_gatt_notification_characteristic_handle, - 0, - ledger_protocol_data.tx_chunk_length - 2, - &ledger_protocol_data.tx_chunk[2]); - } -} - -static void check_transfer_mode(uint8_t enable) -{ - if (ledger_ble_data.transfer_mode_enable != enable) { - LOG_BLE("LEDGER_BLE_set_transfer_mode %d\n", enable); - } - - if ((ledger_ble_data.transfer_mode_enable == 0) && (enable != 0)) { - ledger_ble_data.resp_length = 2; - U2BE_ENCODE(ledger_ble_data.resp, 0, SWO_SUCCESS); - } - - ledger_ble_data.transfer_mode_enable = enable; -} - -/* Exported functions --------------------------------------------------------*/ -void LEDGER_BLE_init(void) -{ - G_io_app.enabling_advertising = 0; - G_io_app.disabling_advertising = 0; - - if (ledger_ble_data.clear_pairing == 0xC1) { - memset(&ledger_ble_data, 0, sizeof(ledger_ble_data)); - ledger_ble_data.clear_pairing = 0xC1; - } - else { - memset(&ledger_ble_data, 0, sizeof(ledger_ble_data)); - } - - LEDGER_BLE_get_mac_address(ledger_ble_data.random_address); - ledger_ble_data.hci_cmd_opcode = 0xFFFF; - ledger_ble_data.state = BLE_STATE_INITIALIZING; - ledger_ble_data.init_step = BLE_INIT_STEP_IDLE; - - memset(&ledger_protocol_data, 0, sizeof(ledger_protocol_data)); - ledger_protocol_data.rx_apdu_buffer = ledger_ble_data.apdu_buffer; - ledger_protocol_data.rx_apdu_buffer_max_length = sizeof(ledger_ble_data.apdu_buffer); -#ifdef HAVE_LOCAL_APDU_BUFFER - ledger_protocol_data.rx_dst_buffer = NULL; -#else - ledger_protocol_data.rx_dst_buffer = G_io_apdu_buffer; -#endif - LEDGER_PROTOCOL_init(&ledger_protocol_data); - - init_mngr(0, NULL, 0); -} - -void LEDGER_BLE_set_recv_buffer(uint8_t *buffer, uint16_t buffer_length) -{ - ledger_protocol_data.rx_dst_buffer = buffer; - ledger_protocol_data.rx_apdu_buffer_max_length - = MIN(buffer_length, sizeof(ledger_ble_data.apdu_buffer)); -} - -void LEDGER_BLE_send(const uint8_t *packet, uint16_t packet_length) -{ - if ((ledger_ble_data.transfer_mode_enable != 0) && (packet_length == 2)) { - G_io_app.apdu_state = APDU_IDLE; - ledger_ble_data.resp_length = 2; - ledger_ble_data.resp[0] = packet[0]; - ledger_ble_data.resp[1] = packet[1]; - if (ledger_protocol_data.rx_apdu_length) { - LEDGER_PROTOCOL_tx(&ledger_protocol_data, packet, packet_length); - notify_chunk(); - } - } - else { - if ((ledger_ble_data.resp_length != 0) && (U2BE(ledger_ble_data.resp, 0) != SWO_SUCCESS)) { - LEDGER_PROTOCOL_tx( - &ledger_protocol_data, ledger_ble_data.resp, ledger_ble_data.resp_length); - } - else { - LEDGER_PROTOCOL_tx(&ledger_protocol_data, packet, packet_length); - } - ledger_ble_data.resp_length = 0; - - if (ledger_ble_data.wait_write_resp_ack == 0) { - notify_chunk(); - } - } -} - -void LEDGER_BLE_receive(const uint8_t *spi_buffer) -{ - if (spi_buffer[3] == HCI_EVENT_PKT_TYPE) { - switch (spi_buffer[4]) { - case HCI_DISCONNECTION_COMPLETE_EVT_CODE: - LOG_BLE("HCI DISCONNECTION COMPLETE code %02X\n", spi_buffer[9]); - ledger_ble_data.connection.connection_handle = 0xFFFF; - ledger_ble_data.advertising_enabled = 0; - ledger_ble_data.connection.encrypted = 0; - ledger_ble_data.transfer_mode_enable = 0; - G_io_app.transfer_mode = 0; -#ifdef HAVE_INAPP_BLE_PAIRING - end_pairing_ux(BOLOS_UX_ASYNCHMODAL_PAIRING_STATUS_FAILED); -#endif // HAVE_INAPP_BLE_PAIRING - if (spi_buffer[9] != 0x28) { // Error code : Instant Passed - start_advertising(); - } - else { - // Workaround to avoid unexpected start advertising event in loop (seems to be a - // bug in the stack) - LEDGER_BLE_init(); - } - break; - - case HCI_ENCRYPTION_CHANGE_EVT_CODE: - if (U2LE(spi_buffer, 7) == ledger_ble_data.connection.connection_handle) { - if (spi_buffer[9]) { - LOG_BLE("Link encrypted\n"); - ledger_ble_data.connection.encrypted = 1; - } - else { - LOG_BLE("Link not encrypted\n"); - ledger_ble_data.connection.encrypted = 0; - } - } - else { - LOG_BLE("HCI ENCRYPTION CHANGE EVT %d on connection handle \n", - spi_buffer[9], - U2LE(spi_buffer, 7)); - } - break; - - case HCI_COMMAND_COMPLETE_EVT_CODE: - hci_evt_cmd_complete(&spi_buffer[6], spi_buffer[5]); - break; - - case HCI_COMMAND_STATUS_EVT_CODE: - LOG_BLE("HCI COMMAND_STATUS\n"); - break; - - case HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVT_CODE: - LOG_BLE("HCI KEY_REFRESH_COMPLETE\n"); - break; - - case HCI_LE_META_EVT_CODE: - hci_evt_le_meta_evt(&spi_buffer[6], spi_buffer[5]); - break; - - case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE: - hci_evt_vendor(&spi_buffer[6], spi_buffer[5]); - break; - - default: - break; - } - } -} - -void LEDGER_BLE_enable_advertising(uint8_t enable) -{ - if ((G_io_app.name_changed) && (G_io_app.ble_ready) && (!enable) - && (ledger_ble_data.connection.connection_handle != 0xFFFF)) { - G_io_app.name_changed = 0; - } - else if (G_io_app.ble_ready) { - if (enable) { - G_io_app.enabling_advertising = 1; - G_io_app.disabling_advertising = 0; - } - else { - G_io_app.enabling_advertising = 0; - G_io_app.disabling_advertising = 1; - } - advertising_enable(enable); - } -} - -void LEDGER_BLE_reset_pairings(void) -{ - if (G_io_app.ble_ready) { - if (ledger_ble_data.connection.connection_handle != 0xFFFF) { - // Connected => force disconnection before clearing - ledger_ble_data.clear_pairing = 0xC1; - LEDGER_BLE_init(); - } - else { - aci_gap_clear_security_db(); - } - } -} - -void LEDGER_BLE_accept_pairing(uint8_t status) -{ - if (ledger_ble_data.pairing_in_progress == 1) { - rsp_user_pairing_numeric_comparison(status); - } - else if (ledger_ble_data.pairing_in_progress == 2) { - rsp_user_pairing_passkey(status); - } -} - -int hci_send_req(struct hci_request *p_cmd, uint8_t async) -{ - UNUSED(async); - - uint16_t opcode = ((p_cmd->ocf) & 0x03ff) | ((p_cmd->ogf) << 10); - - uint8_t tag_buffer[5]; - tag_buffer[0] = SEPROXYHAL_TAG_BLE_SEND; - tag_buffer[1] = (p_cmd->clen + 2) >> 8; - tag_buffer[2] = (p_cmd->clen + 2); - tag_buffer[3] = opcode >> 8; - tag_buffer[4] = opcode; - io_seproxyhal_spi_send(tag_buffer, 5); - io_seproxyhal_spi_send(p_cmd->cparam, p_cmd->clen); - return 0; -} - -void BLE_power(unsigned char powered, const char *discovered_name) -{ - UNUSED(discovered_name); - - LOG_BLE("BLE_power %d\n", powered); - if (powered) { - LEDGER_BLE_init(); - } -} diff --git a/lib_blewbxx_impl/stm32_wpan_common.h b/lib_blewbxx_impl/stm32_wpan_common.h deleted file mode 100644 index 9ca394025..000000000 --- a/lib_blewbxx_impl/stm32_wpan_common.h +++ /dev/null @@ -1,186 +0,0 @@ -/** - ****************************************************************************** - * @file stm32_wpan_common.h - * @author MCD Application Team - * @brief Common file to utilities - ****************************************************************************** - * @attention - * - *

    © Copyright (c) 2018 STMicroelectronics. - * All rights reserved.

    - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32_WPAN_COMMON_H -#define __STM32_WPAN_COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__CC_ARM) -#define __ASM __asm /*!< asm keyword for ARM Compiler */ -#define __INLINE __inline /*!< inline keyword for ARM Compiler */ -#define __STATIC_INLINE static __inline -#elif defined(__ICCARM__) -#define __ASM __asm /*!< asm keyword for IAR Compiler */ -#define __INLINE \ - inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ -#define __STATIC_INLINE static inline -#elif defined(__GNUC__) -#define __ASM __asm /*!< asm keyword for GNU Compiler */ -#define __INLINE inline /*!< inline keyword for GNU Compiler */ -#define __STATIC_INLINE static inline -#endif - -#include -#include -#include -#include -#include -#include "core_cmFunc.h" - -/* -------------------------------- * - * Basic definitions * - * -------------------------------- */ - -#undef NULL -#define NULL 0U - -#undef FALSE -#define FALSE 0U - -#undef TRUE -#define TRUE (!0U) - -/* -------------------------------- * - * Critical Section definition * - * -------------------------------- */ -#undef BACKUP_PRIMASK -#define BACKUP_PRIMASK() uint32_t primask_bit = __get_PRIMASK() - -#undef DISABLE_IRQ -#define DISABLE_IRQ() __disable_irq() - -#undef RESTORE_PRIMASK -#define RESTORE_PRIMASK() __set_PRIMASK(primask_bit) - -/* -------------------------------- * - * Macro delimiters * - * -------------------------------- */ -#undef M_BEGIN -#define M_BEGIN do { -#undef M_END -#define M_END \ - } \ - while (0) - -/* -------------------------------- * - * Some useful macro definitions * - * -------------------------------- */ -#undef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -#undef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -#undef MODINC -#define MODINC(a, m) \ - M_BEGIN(a)++; \ - if ((a) >= (m)) \ - (a) = 0; \ - M_END - -#undef MODDEC -#define MODDEC(a, m) \ - M_BEGIN if ((a) == 0)(a) = (m); \ - (a)--; \ - M_END - -#undef MODADD -#define MODADD(a, b, m) \ - M_BEGIN(a) += (b); \ - if ((a) >= (m)) \ - (a) -= (m); \ - M_END - -#undef MODSUB -#define MODSUB(a, b, m) MODADD(a, (m) - (b), m) - -#undef ALIGN -#ifdef WIN32 -#define ALIGN(n) -#else -#define ALIGN(n) __attribute__((aligned(n))) -#endif - -#undef PAUSE -#define PAUSE(t) \ - M_BEGIN \ - volatile int _i; \ - for (_i = t; _i > 0; _i--) \ - ; \ - M_END -#undef DIVF -#define DIVF(x, y) ((x) / (y)) - -#undef DIVC -#define DIVC(x, y) (((x) + (y) -1) / (y)) - -#undef DIVR -#define DIVR(x, y) (((x) + ((y) / 2)) / (y)) - -#undef SHRR -#define SHRR(x, n) ((((x) >> ((n) -1)) + 1) >> 1) - -#undef BITN -#define BITN(w, n) (((w)[(n) / 32] >> ((n) % 32)) & 1) - -#undef BITNSET -#define BITNSET(w, n, b) \ - M_BEGIN(w)[(n) / 32] |= ((U32) (b)) << ((n) % 32); \ - M_END - -/* -------------------------------- * - * Section attribute * - * -------------------------------- */ -#undef PLACE_IN_SECTION -#define PLACE_IN_SECTION(__x__) __attribute__((section(__x__))) - -/* ----------------------------------- * - * Packed usage (compiler dependent) * - * ----------------------------------- */ -#undef PACKED__ -#undef PACKED_STRUCT - -#if defined(__CC_ARM) -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050U) -#define PACKED__ __attribute__((packed)) -#define PACKED_STRUCT struct PACKED__ -#else -#define PACKED__(TYPE) __packed TYPE -#define PACKED_STRUCT PACKED__(struct) -#endif -#elif defined(__GNUC__) -#define PACKED__ __attribute__((packed)) -#define PACKED_STRUCT struct PACKED__ -#elif defined(__ICCARM__) -#define PACKED_STRUCT __packed struct -#elif -#define PACKED_STRUCT __packed struct -#endif - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32_WPAN_COMMON_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_cxng/src/cx_rng.h b/lib_cxng/src/cx_rng.h index 611c4a31a..fe45fe6bd 100644 --- a/lib_cxng/src/cx_rng.h +++ b/lib_cxng/src/cx_rng.h @@ -19,6 +19,10 @@ #ifndef CX_RNG_H #define CX_RNG_H +#ifdef BOLOS_OS_UPGRADER_APP +#include "osu_defines.h" +#endif + #ifdef HAVE_RNG #include diff --git a/lib_nbgl/include/nbgl_content.h b/lib_nbgl/include/nbgl_content.h index 1fa0fefe3..ca0dfacd1 100644 --- a/lib_nbgl/include/nbgl_content.h +++ b/lib_nbgl/include/nbgl_content.h @@ -17,10 +17,11 @@ extern "C" { #include #include +#include "os_io_seph_cmd.h" + #include "nbgl_types.h" #include "nbgl_obj.h" #ifdef HAVE_PIEZO_SOUND -#include "os_io_seproxyhal.h" #endif /********************** diff --git a/lib_nbgl/include/nbgl_layout.h b/lib_nbgl/include/nbgl_layout.h index bb3d35574..20bb856e8 100644 --- a/lib_nbgl/include/nbgl_layout.h +++ b/lib_nbgl/include/nbgl_layout.h @@ -16,7 +16,6 @@ extern "C" { #include "nbgl_types.h" #include "nbgl_content.h" #ifdef HAVE_PIEZO_SOUND -#include "os_io_seproxyhal.h" #endif /********************* diff --git a/lib_nbgl/src/nbgl_layout.c b/lib_nbgl/src/nbgl_layout.c index e29731280..e0a3789ad 100644 --- a/lib_nbgl/src/nbgl_layout.c +++ b/lib_nbgl/src/nbgl_layout.c @@ -20,6 +20,7 @@ #include "nbgl_screen.h" #include "nbgl_touch.h" #include "glyphs.h" +#include "os_io_seph_ux.h" #include "os_pic.h" #include "os_helpers.h" #include "lcx_rng.h" @@ -121,7 +122,7 @@ static uint8_t nbTouchableControls = 0; /********************** * STATIC PROTOTYPES **********************/ -extern const char *get_ux_loc_string(uint32_t index); +// extern const char *get_ux_loc_string(UX_LOC_STRINGS_INDEX index); #ifdef HAVE_FAST_HOLD_TO_APPROVE // Unit step in % of touchable progress bar @@ -290,7 +291,7 @@ static void touchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType) if (layout->callback != NULL) { #ifdef HAVE_PIEZO_SOUND if (layoutObj->tuneId < NBGL_NO_TUNE) { - io_seproxyhal_play_tune(layoutObj->tuneId); + os_io_seph_cmd_piezo_play_tune(layoutObj->tuneId); } #endif // HAVE_PIEZO_SOUND if (needRefresh) { @@ -422,7 +423,7 @@ static void radioTouchCallback(nbgl_obj_t *obj, if (layout->callback != NULL) { #ifdef HAVE_PIEZO_SOUND if (layout->callbackObjPool[foundRadio].tuneId < NBGL_NO_TUNE) { - io_seproxyhal_play_tune(layout->callbackObjPool[foundRadio].tuneId); + os_io_seph_cmd_piezo_play_tune(layout->callbackObjPool[foundRadio].tuneId); } nbgl_refreshSpecial(FULL_COLOR_PARTIAL_REFRESH); #endif // HAVE_PIEZO_SOUND diff --git a/lib_nbgl/src/nbgl_layout_keyboard.c b/lib_nbgl/src/nbgl_layout_keyboard.c index e18427d0d..3bccced09 100644 --- a/lib_nbgl/src/nbgl_layout_keyboard.c +++ b/lib_nbgl/src/nbgl_layout_keyboard.c @@ -19,6 +19,8 @@ #include "nbgl_screen.h" #include "nbgl_touch.h" #include "glyphs.h" +#include "os_io_seph_cmd.h" +#include "os_io_seph_ux.h" #include "os_pic.h" #include "os_helpers.h" @@ -217,7 +219,7 @@ bool keyboardSwipeCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType) if (i < (uint32_t) nbActiveButtons) { if (updateSuggestionButtons(suggestionsContainer, eventType, i)) { - io_seproxyhal_play_tune(TUNE_TAP_CASUAL); + os_io_seph_cmd_piezo_play_tune(TUNE_TAP_CASUAL); nbgl_objDraw((nbgl_obj_t *) suggestionsContainer); nbgl_refreshSpecial(FULL_COLOR_PARTIAL_REFRESH); } diff --git a/lib_nbgl/src/nbgl_obj.c b/lib_nbgl/src/nbgl_obj.c index 318aac79d..57163a4d6 100644 --- a/lib_nbgl/src/nbgl_obj.c +++ b/lib_nbgl/src/nbgl_obj.c @@ -19,9 +19,9 @@ #include "os_helpers.h" #include "os_pic.h" #include "glyphs.h" +#include "os_io_seph_ux.h" #ifdef HAVE_SERIALIZED_NBGL #include "nbgl_serialize.h" -#include "os_io_seproxyhal.h" #endif #ifdef BUILD_SCREENSHOTS #include "json_scenario.h" @@ -136,7 +136,6 @@ extern bool last_bold_state, verbose; /********************** * STATIC PROTOTYPES **********************/ -extern const char *get_ux_loc_string(uint32_t index); /********************** * GLOBAL FUNCTIONS @@ -1410,7 +1409,7 @@ static void draw_object(nbgl_obj_t *obj, nbgl_obj_t *prevObj, bool computePositi } #ifdef HAVE_SERIALIZED_NBGL - io_seproxyhal_send_nbgl_serialized(NBGL_DRAW_OBJ, obj); + io_seph_ux_send_nbgl_serialized(NBGL_DRAW_OBJ, obj); #endif if (!objRefreshAreaDone) { extendRefreshArea(&obj->area); @@ -1619,7 +1618,7 @@ bool nbgl_refreshIsNeeded(void) void nbgl_refreshReset(void) { #ifdef HAVE_SERIALIZED_NBGL - io_seproxyhal_send_nbgl_serialized(NBGL_REFRESH_AREA, (nbgl_obj_t *) &refreshArea); + io_seph_ux_send_nbgl_serialized(NBGL_REFRESH_AREA, (nbgl_obj_t *) &refreshArea); #endif refreshArea.x0 = SCREEN_WIDTH - 1; refreshArea.width = 0; diff --git a/lib_nbgl/src/nbgl_obj_keyboard.c b/lib_nbgl/src/nbgl_obj_keyboard.c index 8ff824039..c18179ae6 100644 --- a/lib_nbgl/src/nbgl_obj_keyboard.c +++ b/lib_nbgl/src/nbgl_obj_keyboard.c @@ -18,7 +18,8 @@ #include "nbgl_fonts.h" #include "nbgl_touch.h" #include "glyphs.h" -#include "os_io.h" +#include "os_io_seph_cmd.h" +#include "os_io_seph_ux.h" /********************* * DEFINES diff --git a/lib_nbgl/src/nbgl_obj_keypad.c b/lib_nbgl/src/nbgl_obj_keypad.c index 17eadf2b7..dc8d2fb22 100644 --- a/lib_nbgl/src/nbgl_obj_keypad.c +++ b/lib_nbgl/src/nbgl_obj_keypad.c @@ -18,7 +18,8 @@ #include "nbgl_fonts.h" #include "nbgl_touch.h" #include "glyphs.h" -#include "os_io_seproxyhal.h" +#include "os_io_seph_cmd.h" +#include "os_io_seph_ux.h" #include "lcx_rng.h" /********************* @@ -310,7 +311,7 @@ void nbgl_keypadTouchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType) keypad->callback(GET_DIGIT_INDEX(keypad, firstIndex) + 0x30); } else { - io_seproxyhal_play_tune(TUNE_TAP_CASUAL); + os_io_seph_cmd_piezo_play_tune(TUNE_TAP_CASUAL); } } if ((firstIndex == BACKSPACE_KEY_IDX) && (keypad->enableBackspace)) { // backspace @@ -320,7 +321,7 @@ void nbgl_keypadTouchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType) keypad->callback(BACKSPACE_KEY); } else { - io_seproxyhal_play_tune(TUNE_TAP_CASUAL); + os_io_seph_cmd_piezo_play_tune(TUNE_TAP_CASUAL); } } else if ((firstIndex == VALIDATE_KEY_IDX) && (keypad->enableValidate)) { // validate diff --git a/lib_nbgl/src/nbgl_obj_keypad_nanos.c b/lib_nbgl/src/nbgl_obj_keypad_nanos.c index 20f98414e..dc3f68a11 100644 --- a/lib_nbgl/src/nbgl_obj_keypad_nanos.c +++ b/lib_nbgl/src/nbgl_obj_keypad_nanos.c @@ -18,7 +18,6 @@ #include "nbgl_fonts.h" #include "nbgl_screen.h" #include "glyphs.h" -#include "os_io_seproxyhal.h" #include "lcx_rng.h" /********************* diff --git a/lib_nbgl/src/nbgl_screen.c b/lib_nbgl/src/nbgl_screen.c index ce6fb4f87..e2cae4bf6 100644 --- a/lib_nbgl/src/nbgl_screen.c +++ b/lib_nbgl/src/nbgl_screen.c @@ -12,7 +12,7 @@ #include "nbgl_debug.h" #include "nbgl_touch.h" #include "os_pic.h" -#include "os_io.h" +#include "os_io_seph_ux.h" #include "os_task.h" /********************* @@ -73,7 +73,7 @@ void nbgl_screenRedraw(void) #ifdef TARGET_STAX // by default, exclude only left border from touch // if any sub-object is a keyboard, this will be modified when drawing it - touch_exclude_borders(LEFT_BORDER); + touch_exclude_borders(OS_IO_TOUCH_AREA_LEFT_BORDER); #endif // TARGET_STAX nbgl_screen_reinit(); diff --git a/lib_nbgl/src/nbgl_touch.c b/lib_nbgl/src/nbgl_touch.c index 26be441d3..5fcf30e42 100644 --- a/lib_nbgl/src/nbgl_touch.c +++ b/lib_nbgl/src/nbgl_touch.c @@ -15,7 +15,6 @@ #include "nbgl_touch.h" #include "nbgl_screen.h" #include "os_pic.h" -#include "os_io_seproxyhal.h" /********************* * DEFINES diff --git a/lib_nbgl/src/nbgl_use_case.c b/lib_nbgl/src/nbgl_use_case.c index 79eb6a636..10215d64f 100644 --- a/lib_nbgl/src/nbgl_use_case.c +++ b/lib_nbgl/src/nbgl_use_case.c @@ -13,6 +13,7 @@ #include "nbgl_debug.h" #include "nbgl_use_case.h" #include "glyphs.h" +#include "os_io_seph_ux.h" #include "os_pic.h" #include "os_print.h" #include "os_helpers.h" @@ -1753,7 +1754,7 @@ static void blindSigningWarning(void) { // Play notification sound #ifdef HAVE_PIEZO_SOUND - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + os_io_seph_cmd_piezo_play_tune(TUNE_LOOK_AT_ME); #endif // HAVE_PIEZO_SOUND nbgl_useCaseChoice(&C_Warning_64px, "Blind signing ahead", @@ -1840,7 +1841,7 @@ static void useCaseReview(nbgl_operationType_t operationType, // Play notification sound if required if (playNotifSound) { #ifdef HAVE_PIEZO_SOUND - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + os_io_seph_cmd_piezo_play_tune(TUNE_LOOK_AT_ME); #endif // HAVE_PIEZO_SOUND } @@ -1886,7 +1887,7 @@ static void useCaseReviewStreamingStart(nbgl_operationType_t operationType // Play notification sound if required if (playNotifSound) { #ifdef HAVE_PIEZO_SOUND - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + os_io_seph_cmd_piezo_play_tune(TUNE_LOOK_AT_ME); #endif // HAVE_PIEZO_SOUND } @@ -2588,7 +2589,7 @@ void nbgl_useCaseStatus(const char *message, bool isSuccess, nbgl_callback_t qui onQuit = quitCallback; if (isSuccess) { #ifdef HAVE_PIEZO_SOUND - io_seproxyhal_play_tune(TUNE_LEDGER_MOMENT); + os_io_seph_cmd_piezo_play_tune(TUNE_LEDGER_MOMENT); #endif // HAVE_PIEZO_SOUND pageContext = nbgl_pageDrawLedgerInfo(&pageCallback, &ticker, message, QUIT_TOKEN); @@ -2784,7 +2785,7 @@ void nbgl_useCaseReviewStart(const nbgl_icon_details_t *icon, #ifdef HAVE_PIEZO_SOUND // Play notification sound - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + os_io_seph_cmd_piezo_play_tune(TUNE_LOOK_AT_ME); #endif // HAVE_PIEZO_SOUND pageContext = nbgl_pageDrawInfo(&pageCallback, NULL, &info); @@ -3122,7 +3123,7 @@ void nbgl_useCaseGenericReview(const nbgl_genericContents_t *contents, #ifdef HAVE_PIEZO_SOUND // Play notification sound - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + os_io_seph_cmd_piezo_play_tune(TUNE_LOOK_AT_ME); #endif // HAVE_PIEZO_SOUND displayGenericContextPage(0, true); @@ -3323,7 +3324,7 @@ void nbgl_useCaseAddressConfirmationExt(const char *addres #ifdef HAVE_PIEZO_SOUND // Play notification sound - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + os_io_seph_cmd_piezo_play_tune(TUNE_LOOK_AT_ME); #endif // HAVE_PIEZO_SOUND displayGenericContextPage(0, true); @@ -3387,7 +3388,7 @@ void nbgl_useCaseAddressReview(const char *address, #ifdef HAVE_PIEZO_SOUND // Play notification sound - io_seproxyhal_play_tune(TUNE_LOOK_AT_ME); + os_io_seph_cmd_piezo_play_tune(TUNE_LOOK_AT_ME); #endif // HAVE_PIEZO_SOUND displayGenericContextPage(0, true); diff --git a/lib_nfc/include/nfc_ledger.h b/lib_nfc/include/nfc_ledger.h new file mode 100644 index 000000000..2f851a2be --- /dev/null +++ b/lib_nfc/include/nfc_ledger.h @@ -0,0 +1,35 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + NFC_LEDGER_MODE_CARD_EMULATION = 0x00, + NFC_LEDGER_MODE_READER = 0x01, +} nfc_ledger_mode_e; + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ + +void NFC_LEDGER_init(uint8_t force_restart); +void NFC_LEDGER_start(uint8_t mode); // nfc_ledger_mode_e +void NFC_LEDGER_stop(void); + +// Rx +int NFC_LEDGER_rx_seph_apdu_evt(uint8_t *seph_buffer, + uint16_t seph_buffer_length, + uint8_t *apdu_buffer, + uint16_t apdu_buffer_max_length); + +// Tx +uint32_t NFC_LEDGER_send(const uint8_t *packet, uint16_t packet_length, uint32_t timeout_ms); diff --git a/lib_nfc/src/nfc_ledger.c b/lib_nfc/src/nfc_ledger.c new file mode 100644 index 000000000..53643820f --- /dev/null +++ b/lib_nfc/src/nfc_ledger.c @@ -0,0 +1,166 @@ +/* @BANNER@ */ + +#ifdef HAVE_NFC +/* Includes ------------------------------------------------------------------*/ +#include +#include "os.h" +#include "ledger_protocol.h" +#include "seproxyhal_protocol.h" +#include "os_io.h" +#include "os_io_seph_cmd.h" +#include "os_utils.h" +#include "nfc_ledger.h" + +/* Private enumerations ------------------------------------------------------*/ +typedef enum { + NFC_STATE_IDLE = 0xA0, + NFC_STATE_RUNNING, + NFC_STATE_STOPPED, +} nfc_state_e; + +/* Private defines------------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + nfc_state_e state; + uint8_t mode; // nfc_ledger_mode_e + ledger_protocol_t protocol_data; +} nfc_ledger_data_t; + +#ifdef HAVE_PRINTF +#define DEBUG PRINTF +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +static void nfc_ledger_send_rapdu(uint8_t *buffer, uint16_t length, uint32_t timeout_ms); + +/* Exported variables --------------------------------------------------------*/ +uint8_t NFC_LEDGER_io_buffer[OS_IO_BUFFER_SIZE + 1]; + +/* Private variables ---------------------------------------------------------*/ +static nfc_ledger_data_t nfc_ledger_data; +static uint8_t + ledger_protocol_chunk_buffer[156 + 2]; // TODO_IO : BLE buffer size, can be changed though + +/* Private functions ---------------------------------------------------------*/ +static void nfc_ledger_send_rapdu(uint8_t *buffer, uint16_t length, uint32_t timeout_ms) +{ + UNUSED(timeout_ms); + + if (length) { + unsigned char hdr[3]; + hdr[0] = SEPROXYHAL_TAG_NFC_RAPDU; + hdr[1] = length >> 8; + hdr[2] = length; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, hdr, 3, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, length, NULL); + } +} + +/* Exported functions --------------------------------------------------------*/ + +void NFC_LEDGER_init(uint8_t force_restart) +{ + if (force_restart) { + memset(&nfc_ledger_data, 0, sizeof(nfc_ledger_data)); + nfc_ledger_data.state = NFC_STATE_IDLE; + DEBUG("NFC_LEDGER_init deep\n"); + } + else { + DEBUG("NFC_LEDGER_init\n"); + } +} + +void NFC_LEDGER_start(uint8_t mode) +{ + DEBUG("NFC_LEDGER_start %d\n", mode); + + if ((nfc_ledger_data.state == NFC_STATE_IDLE) || (nfc_ledger_data.mode != mode)) { + memset(&nfc_ledger_data.protocol_data, 0, sizeof(nfc_ledger_data.protocol_data)); + nfc_ledger_data.protocol_data.rx_apdu_buffer = NFC_LEDGER_io_buffer; + nfc_ledger_data.protocol_data.rx_apdu_buffer_size = sizeof(NFC_LEDGER_io_buffer); + nfc_ledger_data.protocol_data.tx_chunk_buffer = ledger_protocol_chunk_buffer; + nfc_ledger_data.protocol_data.tx_chunk_buffer_size = sizeof(ledger_protocol_chunk_buffer); + nfc_ledger_data.protocol_data.mtu = sizeof(ledger_protocol_chunk_buffer); + nfc_ledger_data.state = NFC_STATE_STOPPED; + nfc_ledger_data.mode = mode; + } + if ((nfc_ledger_data.state == NFC_STATE_STOPPED) + && (os_setting_get(OS_SETTING_FEATURES, NULL, 0) & OS_SETTING_FEATURES_NFC_ENABLED)) { + if (nfc_ledger_data.mode == NFC_LEDGER_MODE_CARD_EMULATION) { + LEDGER_PROTOCOL_init(&nfc_ledger_data.protocol_data, OS_IO_PACKET_TYPE_NFC_APDU); + nfc_ledger_data.state = NFC_STATE_RUNNING; + os_io_nfc_cmd_power(SEPROXYHAL_TAG_NFC_POWER_ON_CE); + } + else if (nfc_ledger_data.mode == NFC_LEDGER_MODE_READER) { + LEDGER_PROTOCOL_init(&nfc_ledger_data.protocol_data, OS_IO_PACKET_TYPE_NFC_APDU_RSP); + nfc_ledger_data.state = NFC_STATE_RUNNING; + os_io_nfc_cmd_power(SEPROXYHAL_TAG_NFC_POWER_ON_READER); + } + } +} + +void NFC_LEDGER_stop(void) +{ + os_io_nfc_cmd_power(SEPROXYHAL_TAG_NFC_POWER_OFF); + nfc_ledger_data.state = NFC_STATE_STOPPED; +} + +int NFC_LEDGER_rx_seph_apdu_evt(uint8_t *seph_buffer, + uint16_t seph_buffer_length, + uint8_t *apdu_buffer, + uint16_t apdu_buffer_max_length) +{ + int status = 0; + + if (seph_buffer_length < 2) { + return -1; + } + + uint16_t length = U2BE(seph_buffer, 2); + LEDGER_PROTOCOL_rx(&nfc_ledger_data.protocol_data, &seph_buffer[4], length); + + if (nfc_ledger_data.protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { + if (apdu_buffer_max_length < nfc_ledger_data.protocol_data.rx_apdu_length) { + status = -1; + } + else { + memmove(apdu_buffer, + nfc_ledger_data.protocol_data.rx_apdu_buffer, + nfc_ledger_data.protocol_data.rx_apdu_length); + status = nfc_ledger_data.protocol_data.rx_apdu_length; + } + nfc_ledger_data.protocol_data.rx_apdu_status = APDU_STATUS_WAITING; + } + + return status; +} + +uint32_t NFC_LEDGER_send(const uint8_t *packet, uint16_t packet_length, uint32_t timeout_ms) +{ + uint32_t status = 0; + + LEDGER_PROTOCOL_tx(&nfc_ledger_data.protocol_data, packet, packet_length); + if (nfc_ledger_data.protocol_data.tx_chunk_length >= 2) { + nfc_ledger_send_rapdu(nfc_ledger_data.protocol_data.tx_chunk_buffer, + nfc_ledger_data.protocol_data.tx_chunk_length, + timeout_ms); + } + + while (nfc_ledger_data.protocol_data.tx_apdu_buffer) { + LEDGER_PROTOCOL_tx(&nfc_ledger_data.protocol_data, NULL, 0); + if (nfc_ledger_data.protocol_data.tx_chunk_length >= 2) { + nfc_ledger_send_rapdu(nfc_ledger_data.protocol_data.tx_chunk_buffer, + nfc_ledger_data.protocol_data.tx_chunk_length, + timeout_ms); + } + } + + return status; +} + +#endif // HAVE_NFC diff --git a/lib_standard_app/io.c b/lib_standard_app/io.c index 9aea6ebb8..6f90c2199 100644 --- a/lib_standard_app/io.c +++ b/lib_standard_app/io.c @@ -18,76 +18,66 @@ #include #include "os.h" -#include "io.h" +#include "os_io_legacy_types.h" +#include "os_io_seph_cmd.h" +#include "os_io_seph_ux.h" +#include "os_io_default_apdu.h" +#include "seproxyhal_protocol.h" #include "write.h" +#include "offsets.h" +#include "io.h" -#ifdef HAVE_SWAP -#include "swap.h" -#endif +#ifdef HAVE_IO_USB +#include "usbd_ledger.h" +#endif // HAVE_IO_USB + +#ifdef HAVE_BLE +#include "ble_ledger.h" +#endif // HAVE_BLE #ifdef HAVE_NFC_READER -#include "os_io_nfc.h" +#include "nfc_ledger.h" #endif // HAVE_NFC_READER +#ifdef HAVE_SWAP +#include "swap.h" +#endif + // TODO: Temporary workaround, at some point all status words should be defined by the SDK and // removed from the application #define SW_OK 0x9000 #define SW_WRONG_RESPONSE_LENGTH 0xB000 -uint8_t G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; +static uint8_t need_to_start_io; + +uint8_t G_io_seproxyhal_spi_buffer[OS_IO_SEPH_BUFFER_SIZE]; #ifdef HAVE_NFC_READER struct nfc_reader_context G_io_reader_ctx; #endif -/** - * Variable containing the length of the APDU response to send back. - */ -static uint32_t G_output_len = 0; - -/** - * IO state (READY, RECEIVING, WAITING). - */ -static io_state_e G_io_state = READY; - #ifdef HAVE_BAGL WEAK void io_seproxyhal_display(const bagl_element_t *element) { - io_seproxyhal_display_default(element); + io_seph_ux_display_bagl_element(element); } #endif // HAVE_BAGL // This function can be used to declare a callback to SEPROXYHAL_TAG_TICKER_EVENT in the application WEAK void app_ticker_event_callback(void) {} -WEAK uint8_t io_event(uint8_t channel) +WEAK unsigned char io_event(unsigned char channel) { - (void) channel; - + UNUSED(channel); switch (G_io_seproxyhal_spi_buffer[0]) { case SEPROXYHAL_TAG_BUTTON_PUSH_EVENT: UX_BUTTON_PUSH_EVENT(G_io_seproxyhal_spi_buffer); break; - case SEPROXYHAL_TAG_STATUS_EVENT: - if (G_io_apdu_media == IO_APDU_MEDIA_USB_HID && // - !(U4BE(G_io_seproxyhal_spi_buffer, 3) & // - SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED)) { - THROW(EXCEPTION_IO_RESET); - } - __attribute__((fallthrough)); - case SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT: -#ifdef HAVE_BAGL - UX_DISPLAYED_EVENT({}); -#endif // HAVE_BAGL -#ifdef HAVE_NBGL - UX_DEFAULT_EVENT(); -#endif // HAVE_NBGL - break; -#ifdef HAVE_NBGL +#ifdef HAVE_SE_TOUCH case SEPROXYHAL_TAG_FINGER_EVENT: UX_FINGER_EVENT(G_io_seproxyhal_spi_buffer); break; -#endif // HAVE_NBGL +#endif // HAVE_SE_TOUCH case SEPROXYHAL_TAG_TICKER_EVENT: app_ticker_event_callback(); UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer, {}); @@ -96,106 +86,77 @@ WEAK uint8_t io_event(uint8_t channel) io_nfc_process_events(); #endif // HAVE_NFC_READER break; +#ifdef HAVE_NFC_READER + case SEPROXYHAL_TAG_NFC_EVENT: + io_nfc_event(); + io_nfc_process_events(); + break; +#endif // HAVE_NFC_READER + default: UX_DEFAULT_EVENT(); break; } - if (!io_seproxyhal_spi_is_status_sent()) { - io_seproxyhal_general_status(); - } - return 1; } -WEAK uint16_t io_exchange_al(uint8_t channel, uint16_t tx_len) -{ - switch (channel & ~(IO_FLAGS)) { - case CHANNEL_KEYBOARD: - break; - case CHANNEL_SPI: - if (tx_len) { - io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len); - - if (channel & IO_RESET_AFTER_REPLIED) { - halt(); - } - - return 0; - } - else { - return io_seproxyhal_spi_recv(G_io_apdu_buffer, sizeof(G_io_apdu_buffer), 0); - } - default: - THROW(INVALID_PARAMETER); - } - - return 0; -} - WEAK void io_init() { - // Reset length of APDU response - G_output_len = 0; - G_io_state = READY; + io_seproxyhal_init(); + need_to_start_io = 1; } WEAK int io_recv_command() { - int ret = -1; + int status = 0; + + if (need_to_start_io) { + io_seproxyhal_io_heartbeat(); + io_seproxyhal_io_heartbeat(); + io_seproxyhal_io_heartbeat(); + os_io_start(); + need_to_start_io = 0; + } - switch (G_io_state) { - case READY: - ret = io_exchange(CHANNEL_APDU | IO_CONTINUE_RX, G_output_len); - G_io_state = RECEIVED; - break; - case RECEIVED: - G_io_state = WAITING; - ret = io_exchange(CHANNEL_APDU | IO_ASYNCH_REPLY, G_output_len); - G_io_state = RECEIVED; - break; - case WAITING: - G_io_state = READY; - ret = -1; - break; + while (status <= 0) { + status = io_legacy_apdu_rx(); } - return ret; + return status; } WEAK int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t sw) { - int ret = -1; + int status = 0; + size_t length = 0; - G_output_len = 0; if (rdatalist && count > 0) { for (size_t i = 0; i < count; i++) { const buffer_t *rdata = &rdatalist[i]; - if (!buffer_copy(rdata, - G_io_apdu_buffer + G_output_len, - sizeof(G_io_apdu_buffer) - G_output_len - 2)) { + if (!buffer_copy(rdata, G_io_tx_buffer + length, sizeof(G_io_tx_buffer) - length - 2)) { return io_send_sw(SW_WRONG_RESPONSE_LENGTH); } - G_output_len += rdata->size - rdata->offset; + length += rdata->size - rdata->offset; if (count > 1) { PRINTF("<= FRAG (%u/%u) RData=%.*H\n", i + 1, count, rdata->size, rdata->ptr); } } - PRINTF("<= SW=%04X | RData=%.*H\n", sw, G_output_len, G_io_apdu_buffer); + PRINTF("<= SW=%04X | RData=%.*H\n", sw, length, G_io_tx_buffer); } else { PRINTF("<= SW=%04X | RData=\n", sw); } - write_u16_be(G_io_apdu_buffer, G_output_len, sw); - G_output_len += 2; + write_u16_be(G_io_tx_buffer, length, sw); + length += 2; #ifdef HAVE_SWAP // If we are in swap mode and have validated a TX, we send it and immediately quit if (G_called_from_swap && G_swap_response_ready) { PRINTF("Swap answer is processed. Send it\n"); - if (io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, G_output_len) == 0) { + if (io_legacy_apdu_tx(G_io_tx_buffer, length) >= 0) { swap_finalize_exchange_sign_transaction(sw == SW_OK); } else { @@ -205,42 +166,20 @@ WEAK int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint1 } #endif // HAVE_SWAP - switch (G_io_state) { - case READY: - ret = -1; - break; - case RECEIVED: -#ifdef STANDARD_APP_SYNC_RAPDU - // Send synchronously the APDU response. - // This is needed to send the response before displaying synchronous - // status message on the screen. - // This is not always done to spare the RAM (stack) on LNS. - __attribute__((fallthrough)); -#else - G_io_state = READY; - ret = 0; - break; -#endif - case WAITING: - ret = io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, G_output_len); - G_output_len = 0; - G_io_state = READY; - break; + status = io_legacy_apdu_tx(G_io_tx_buffer, length); + + if (status < 0) { + status = -1; } - return ret; + return status; } #ifdef STANDARD_APP_SYNC_RAPDU WEAK bool io_recv_and_process_event(void) { - int apdu_state = G_io_app.apdu_state; - - os_io_seph_recv_and_process(0); - - // If an APDU was received in previous os_io_seph_recv_and_process call and - // is waiting to be processed, return true - if (apdu_state == APDU_IDLE && G_io_app.apdu_state != APDU_IDLE) { + int status = io_legacy_apdu_rx(); + if (status > 0) { return true; } diff --git a/lib_standard_app/io.h b/lib_standard_app/io.h index 287a5144b..a04a1930a 100644 --- a/lib_standard_app/io.h +++ b/lib_standard_app/io.h @@ -3,22 +3,16 @@ #include #include "ux.h" -#include "os_io_seproxyhal.h" +#include "os_io.h" +#include "os_io_legacy.h" #include "buffer.h" #include "macros.h" -/** - * Enumeration for the status of IO. - */ -typedef enum { - READY, /// ready for new event - RECEIVED, /// data received - WAITING /// waiting -} io_state_e; +#define G_io_apdu_buffer G_io_rx_buffer #ifdef HAVE_BAGL -void io_seproxyhal_display(const bagl_element_t *element); +WEAK void io_seproxyhal_display(const bagl_element_t *element); #endif // HAVE_BAGL /** @@ -27,7 +21,7 @@ void io_seproxyhal_display(const bagl_element_t *element); * * */ -void app_ticker_event_callback(void); +WEAK void app_ticker_event_callback(void); /** * IO callback called when an interrupt based channel has received @@ -37,16 +31,14 @@ void app_ticker_event_callback(void); * @return 1 if success, 0 otherwise. * */ -uint8_t io_event(uint8_t channel __attribute__((unused))); - -uint16_t io_exchange_al(uint8_t channel, uint16_t tx_len); +WEAK unsigned char io_event(unsigned char channel); /** * Initialize the APDU I/O state. * * This function must be called before calling any other I/O function. */ -void io_init(void); +WEAK void io_init(void); /** * Receive APDU command in G_io_apdu_buffer. @@ -54,7 +46,7 @@ void io_init(void); * @return zero or positive integer if success, -1 otherwise. * */ -int io_recv_command(void); +WEAK int io_recv_command(void); /** * Send APDU response (response data + status word) by filling @@ -70,7 +62,7 @@ int io_recv_command(void); * @return zero or positive integer if success, -1 otherwise. * */ -int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t sw); +WEAK int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t sw); /** * Send APDU response (response data + status word) by filling diff --git a/lib_standard_app/main.c b/lib_standard_app/main.c index fc0b0fbb5..a70fdcad2 100644 --- a/lib_standard_app/main.c +++ b/lib_standard_app/main.c @@ -23,11 +23,11 @@ #ifdef HAVE_SWAP #include "swap.h" +#endif // HAVE_SWAP #ifdef HAVE_NBGL #include "nbgl_use_case.h" #endif // HAVE_NBGL -#endif // HAVE_SWAP ux_state_t G_ux; bolos_ux_params_t G_ux_params; @@ -43,22 +43,11 @@ WEAK void __attribute__((noreturn)) app_exit(void) WEAK void common_app_init(void) { UX_INIT(); - - io_seproxyhal_init(); - -#ifdef HAVE_IO_USB - USB_power(0); - USB_power(1); -#endif - -#ifdef HAVE_BLE - BLE_power(0, NULL); - BLE_power(1, NULL); -#endif // HAVE_BLE } WEAK void standalone_app_main(void) { + PRINTF("standalone_app_main"); #ifdef HAVE_SWAP G_called_from_swap = false; G_swap_response_ready = false; @@ -85,12 +74,7 @@ WEAK void standalone_app_main(void) // - the NanoX goes on battery power and display the lock screen // - the user plug the NanoX instead of entering its pin // - the device is frozen, battery should be removed -#ifdef HAVE_IO_USB - USB_power(0); -#endif -#ifdef HAVE_BLE - BLE_power(0, NULL); -#endif + os_io_stop(); // Display crash info on screen for debug purpose assert_display_exit(); #else diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/sc_itf.h b/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/sc_itf.h deleted file mode 100644 index 8babdec31..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/sc_itf.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - ****************************************************************************** - * @file sc_itf.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-January-2014 - * @brief Evaluation board specific configuration file. - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __SC_ITF_H -#define __SC_ITF_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ccid_if.h" - -#ifdef HAVE_USB_CLASS_CCID - -#include "usbd_ccid_cmd.h" - - -/* Exported macro ------------------------------------------------------------*/ -#define MAX_EXTRA_GUARD_TIME (0xFF - DEFAULT_EXTRA_GUARDTIME) - - /* Following macros are used for SC_XferBlock command */ -#define XFER_BLK_SEND_DATA 1 /* Command is for issuing the data */ -#define XFER_BLK_RECEIVE_DATA 2 /* Command is for receiving the data */ -#define XFER_BLK_NO_DATA 3 /* Command type is No data exchange */ - -/* Exported functions ------------------------------------------------------- */ -/* APPLICATION LAYER ---------------------------------------------------------*/ -#define SC_VOLTAGE_1_8V 1 -#define SC_VOLTAGE_3V 2 -#define SC_VOLTAGE_5V 3 -uint8_t SC_AnswerToReset (uint8_t voltage, uint8_t* atr_buffer); -//uint8_t SC_GetState (void); -//void SC_SetState (uint8_t scState); -uint8_t SC_Detect(void); -void SC_Poweroff(void); -void SC_ConfigDetection (void); -void SC_SaveVoltage (uint8_t ); -void SC_UpdateParams (void); -void SC_InitParams (void); -uint8_t SC_SetParams (Protocol0_DataStructure_t* ); -uint8_t SC_ExecuteEscape (uint8_t* escapePtr, uint32_t escapeLen, - uint8_t* responseBuff, - uint16_t* responseLen); -uint8_t SC_SetClock (uint8_t bClockCommand); -uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen); -uint8_t SC_Request_GetClockFrequencies(uint8_t* pbuf, uint16_t* len); -uint8_t SC_Request_GetDataRates(uint8_t* pbuf, uint16_t* len); -uint8_t SC_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse, - uint8_t bClassEnvelope); -uint8_t SC_Mechanical(uint8_t bFunction); -uint8_t SC_SetDataRateAndClockFrequency(uint32_t dwClockFrequency, - uint32_t dwDataRate); -uint8_t SC_Secure(uint8_t* pbuf, uint32_t* returnLen); - -#endif // HAVE_USB_CLASS_CCID - -#endif /* __SC_ITF_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_cmd.h b/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_cmd.h deleted file mode 100644 index 04974e0ba..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_cmd.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ccid_cmd.h - * @author MCD Application Team - * @version V1.0.1 - * @date 31-January-2014 - * @brief CCID Commands handling prototype - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CCID_CMD_H -#define __USBD_CCID_CMD_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ccid_core.h" - -#ifdef HAVE_USB_CLASS_CCID - -/* Exported types ------------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ - -/******************************************************************************/ -/* ERROR CODES for USB Bulk In Messages : bError */ -/******************************************************************************/ - -#define SLOT_NO_ERROR 0x81 -#define SLOTERROR_UNKNOWN 0x82 - -/* Index of not supported / incorrect message parameter : 7Fh to 01h */ -/* These Values are used for Return Types between Firmware Layers */ -/* -Failure of a command -The CCID cannot parse one parameter or the ICC is not supporting one parameter. -Then the Slot Error register contains the index of the first bad parameter as a -positive number (1-127). For instance, if the CCID receives an ICC command to -an unimplemented slot, then the Slot Error register shall be set to -‘5’ (index of bSlot field). - */ - -#define SLOTERROR_BAD_LENTGH 0x01 -#define SLOTERROR_BAD_SLOT 0x05 -#define SLOTERROR_BAD_POWERSELECT 0x07 -#define SLOTERROR_BAD_PROTOCOLNUM 0x07 -#define SLOTERROR_BAD_CLOCKCOMMAND 0x07 -#define SLOTERROR_BAD_ABRFU_3B 0x07 -#define SLOTERROR_BAD_BMCHANGES 0x07 -#define SLOTERROR_BAD_BFUNCTION_MECHANICAL 0x07 -#define SLOTERROR_BAD_ABRFU_2B 0x08 -#define SLOTERROR_BAD_LEVELPARAMETER 0x08 -#define SLOTERROR_BAD_FIDI 0x0A -#define SLOTERROR_BAD_T01CONVCHECKSUM 0x0B -#define SLOTERROR_BAD_GUARDTIME 0x0C -#define SLOTERROR_BAD_WAITINGINTEGER 0x0D -#define SLOTERROR_BAD_CLOCKSTOP 0x0E -#define SLOTERROR_BAD_IFSC 0x0F -#define SLOTERROR_BAD_NAD 0x10 -#define SLOTERROR_BAD_DWLENGTH 0x08 /* Used in PC_to_RDR_XfrBlock*/ - -/*---------- Table 6.2-2 Slot error register when bmCommandStatus = 1 */ -#define SLOTERROR_CMD_ABORTED 0xFF -#define SLOTERROR_ICC_MUTE 0xFE -#define SLOTERROR_XFR_PARITY_ERROR 0xFD -#define SLOTERROR_XFR_OVERRUN 0xFC -#define SLOTERROR_HW_ERROR 0xFB -#define SLOTERROR_BAD_ATR_TS 0xF8 -#define SLOTERROR_BAD_ATR_TCK 0xF7 -#define SLOTERROR_ICC_PROTOCOL_NOT_SUPPORTED 0xF6 -#define SLOTERROR_ICC_CLASS_NOT_SUPPORTED 0xF5 -#define SLOTERROR_PROCEDURE_BYTE_CONFLICT 0xF4 -#define SLOTERROR_DEACTIVATED_PROTOCOL 0xF3 -#define SLOTERROR_BUSY_WITH_AUTO_SEQUENCE 0xF2 -#define SLOTERROR_PIN_TIMEOUT 0xF0 -#define SLOTERROR_PIN_CANCELLED 0xEF -#define SLOTERROR_CMD_SLOT_BUSY 0xE0 -#define SLOTERROR_CMD_NOT_SUPPORTED 0x00 - - -#define DEFAULT_FIDI 0x11 /* DEFAULT_FIDI_VALUE */ -#define DEFAULT_T01CONVCHECKSUM 0x00 -#define DEFAULT_EXTRA_GUARDTIME 0x00 -#define DEFAULT_WAITINGINTEGER 0x0A -#define DEFAULT_CLOCKSTOP 0x00 -#define DEFAULT_IFSC 0x20 -#define DEFAULT_NAD 0x00 - -#define DEFAULT_DATA_RATE 0x000025CD -#define DEFAULT_CLOCK_FREQ 0x00000E10 - - -/* -Offset=0 bmICCStatus 2 bit 0, 1, 2 - 0 - An ICC is present and active (power is on and stable, RST is inactive) - 1 - An ICC is present and inactive (not activated or shut down by hardware error) - 2 - No ICC is present - 3 - RFU -Offset=0 bmRFU 4 bits 0 RFU -Offset=6 bmCommandStatus 2 bits 0, 1, 2 - 0 - Processed without error - 1 - Failed (error code provided by the error register) - 2 - Time Extension is requested - 3 - RFU - */ - -#define BM_ICC_PRESENT_ACTIVE 0x00 -#define BM_ICC_PRESENT_INACTIVE 0x01 -#define BM_ICC_NO_ICC_PRESENT 0x02 - -#define BM_COMMAND_STATUS_OFFSET 0x06 -#define BM_COMMAND_STATUS_NO_ERROR 0x00 -#define BM_COMMAND_STATUS_FAILED (0x01 << BM_COMMAND_STATUS_OFFSET) -#define BM_COMMAND_STATUS_TIME_EXTN (0x02 << BM_COMMAND_STATUS_OFFSET) - -/* defines for the CCID_CMD Layers */ -#define SIZE_OF_ATR 33 -#define LEN_RDR_TO_PC_SLOTSTATUS 10 -#define LEN_PROTOCOL_STRUCT_T0 5 - -#define BPROTOCOL_NUM_T0 0 -#define BPROTOCOL_NUM_T1 1 - -/************************************************************************************/ -/* ERROR CODES for RDR_TO_PC_HARDWAREERROR Message : bHardwareErrorCode */ -/************************************************************************************/ - -#define HARDWAREERRORCODE_OVERCURRENT 0x01 -#define HARDWAREERRORCODE_VOLTAGEERROR 0x02 -#define HARDWAREERRORCODE_OVERCURRENT_IT 0x04 -#define HARDWAREERRORCODE_VOLTAGEERROR_IT 0x08 - -typedef enum -{ - CHK_PARAM_SLOT = 1, - CHK_PARAM_DWLENGTH = (1<<1), - CHK_PARAM_abRFU2 = (1<<2), - CHK_PARAM_abRFU3 = (1<<3), - CHK_PARAM_CARD_PRESENT = (1<<4), - CHK_PARAM_ABORT = (1<<5), - CHK_ACTIVE_STATE = (1<<6) -} ChkParam_t; - - -/* Exported functions ------------------------------------------------------- */ - -uint8_t PC_to_RDR_IccPowerOn(void); -uint8_t PC_to_RDR_IccPowerOff(void); -uint8_t PC_to_RDR_GetSlotStatus(void); -uint8_t PC_to_RDR_XfrBlock(void); -uint8_t PC_to_RDR_GetParameters(void); -uint8_t PC_to_RDR_ResetParameters(void); -uint8_t PC_to_RDR_SetParameters(void); -uint8_t PC_to_RDR_Escape(void); -uint8_t PC_to_RDR_IccClock(void); -uint8_t PC_to_RDR_Abort(void); -uint8_t PC_TO_RDR_T0Apdu(void); -uint8_t PC_TO_RDR_Mechanical(void); -uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(void); -uint8_t PC_TO_RDR_Secure(void); - -void RDR_to_PC_DataBlock(unsigned char ); -void RDR_to_PC_NotifySlotChange(void); -void RDR_to_PC_SlotStatus(unsigned char ); -void RDR_to_PC_Parameters(unsigned char ); -void RDR_to_PC_Escape(unsigned char ); -void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode); - - -void CCID_UpdSlotStatus (uint8_t ); -void CCID_UpdSlotChange (uint8_t ); -uint8_t CCID_IsSlotStatusChange (void); -uint8_t CCID_CmdAbort(uint8_t slot, uint8_t seq); - -#endif // HAVE_USB_CLASS_CCID - -#endif /* __USBD_CCID_CMD_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_core.h b/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_core.h deleted file mode 100644 index 5fb81ffa6..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_core.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ccid_core.h - * @author MCD Application Team - * @version V1.0.1 - * @date 31-January-2014 - * @brief This file provides all the CCID core functions. - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef _USB_CCID_CORE_H_ -#define _USB_CCID_CORE_H_ - -#include "os.h" -#include "os_io.h" -#include "os_io_seproxyhal.h" - -#ifdef HAVE_USB_CLASS_CCID - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" -#include "usbd_ccid_impl.h" -#include "sc_itf.h" - -/* Exported defines ----------------------------------------------------------*/ - -#define REQUEST_ABORT 0x01 -#define REQUEST_GET_CLOCK_FREQUENCIES 0x02 -#define REQUEST_GET_DATA_RATES 0x03 - - -/* Exported types ------------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported variables --------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -uint8_t USBD_CCID_Init (USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -uint8_t USBD_CCID_DeInit (USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -uint8_t USBD_CCID_Setup (USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - -uint8_t USBD_CCID_DataIn (USBD_HandleTypeDef *pdev, - uint8_t epnum); - -uint8_t USBD_CCID_DataOut (USBD_HandleTypeDef *pdev, - uint8_t epnum, uint8_t* buffer, - apdu_buffer_t * apdu_buffer); - -#endif // HAVE_USB_CLASS_CCID - -#endif /* _USB_CCID_CORE_H_ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_if.h b/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_if.h deleted file mode 100644 index 1e077a7c8..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_if.h +++ /dev/null @@ -1,240 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ccid_if.h - * @author MCD Application Team - * @version V1.0.1 - * @date 31-January-2014 - * @brief This file provides all the functions prototypes for USB CCID - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CCID_IF_H -#define __USBD_CCID_IF_H - -#include "usbd_core.h" - -#ifdef HAVE_USB_CLASS_CCID - - -/* Exported defines ----------------------------------------------------------*/ -/* Bulk-only Command Block Wrapper */ -//#define ABDATA_SIZE 261 -#define CCID_HEADER_SIZE 10 - - -#define CCID_INT_BUFF_SIZ 2 - -#define CARD_SLOT_FITTED 1 -#define CARD_SLOT_REMOVED 0 - -#define BULK_MAX_PACKET_SIZE 0x40 -#define CCID_IN_EP_SIZE 0x40 -#define INTR_MAX_PACKET_SIZE 8 -#define CCID_MESSAGE_HEADER_SIZE 10 -#define CCID_NUMBER_OF_SLOTS 1 - /* Number of SLOTS. For single card, this value is 1 */ - -/* Following Parameters used in PC_to_RDR_IccPowerOn */ -#define VOLTAGE_SELECTION_AUTOMATIC 0xFF -#define VOLTAGE_SELECTION_3V 0x02 -#define VOLTAGE_SELECTION_5V 0x01 -#define VOLTAGE_SELECTION_1V8 0x03 - -/* PC_to_RDR_Secure PIN operations */ -#define PIN_OPR_VERIFICATION 0x00 -#define PIN_OPR_MODIFICATION 0x01 -#define PIN_OPR_TRANSFER 0x02 -#define PIN_OPR_WAIT_ICC_RESP 0x03 -#define PIN_OPR_CANCEL 0x04 -#define PIN_OPR_APDU_CLA 0xEF - -#define PC_TO_RDR_ICCPOWERON 0x62 -#define PC_TO_RDR_ICCPOWEROFF 0x63 -#define PC_TO_RDR_GETSLOTSTATUS 0x65 -#define PC_TO_RDR_XFRBLOCK 0x6F -#define PC_TO_RDR_GETPARAMETERS 0x6C -#define PC_TO_RDR_RESETPARAMETERS 0x6D -#define PC_TO_RDR_SETPARAMETERS 0x61 -#define PC_TO_RDR_ESCAPE 0x6B -#define PC_TO_RDR_ICCCLOCK 0x6E -#define PC_TO_RDR_T0APDU 0x6A -#define PC_TO_RDR_SECURE 0x69 -#define PC_TO_RDR_MECHANICAL 0x71 -#define PC_TO_RDR_ABORT 0x72 -#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73 - -#define RDR_TO_PC_DATABLOCK 0x80 -#define RDR_TO_PC_SLOTSTATUS 0x81 -#define RDR_TO_PC_PARAMETERS 0x82 -#define RDR_TO_PC_ESCAPE 0x83 -#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84 - -#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50 -#define RDR_TO_PC_HARDWAREERROR 0x51 - -#define OFFSET_INT_BMESSAGETYPE 0 -#define OFFSET_INT_BMSLOTICCSTATE 1 -#define SLOT_ICC_PRESENT 0x01 - /* LSb : (0b = no ICC present, 1b = ICC present) */ - -#define SLOT_ICC_CHANGE 0x02 /* MSb : (0b = no change, 1b = change) */ -/*****************************************************************************/ -/*********************** CCID Bulk Transfer State machine ********************/ -/*****************************************************************************/ -#define CCID_STATE_IDLE 0 /* Idle state */ -#define CCID_STATE_DATA_OUT 1 /* Data Out state */ -#define CCID_STATE_RECEIVE_DATA 2 -#define CCID_STATE_SEND_RESP 3 -#define CCID_STATE_DATAIN 4 -#define CCID_STATE_UNCORRECT_LENGTH 5 - -#define DIR_IN 0 -#define DIR_OUT 1 -#define BOTH_DIR 2 - -/* Exported types ------------------------------------------------------------*/ -#pragma pack(1) -typedef union ccid_bulk_header_u { - #pragma pack(1) - struct { - uint8_t bMessageType; /* Offset = 0*/ - uint32_t dwLength; /* Offset = 1, The length field (dwLength) is the length - of the message not including the 10-byte header.*/ - uint8_t bSlot; /* Offset = 5*/ - uint8_t bSeq; /* Offset = 6*/ - uint8_t bSpecific_0; /* Offset = 7*/ - uint8_t bSpecific_1; /* Offset = 8*/ - uint8_t bSpecific_2; /* Offset = 9*/ - } bulkout; - #pragma pack(1) - struct { - uint8_t bMessageType; /* Offset = 0 Same as Bulk OUT*/ - uint32_t dwLength; /* Offset = 1 Same as Bulk OUT*/ - uint8_t bSlot; /* Offset = 5, Same as Bulk-OUT message */ - uint8_t bSeq; /* Offset = 6, Same as Bulk-OUT message */ - uint8_t bStatus; /* Offset = 7, Slot status as defined in § 6.2.6*/ - uint8_t bError; /* Offset = 8, Slot error as defined in § 6.2.6*/ - uint8_t bSpecific; /* Offset = 9*/ - } bulkin; -} ccid_bulk_header_t; - -#pragma pack(1) -typedef struct -{ - ccid_bulk_header_t header; -} Ccid_bulk_data_t; -#pragma pack() - - -#pragma pack() - -typedef struct -{ - __IO uint8_t SlotStatus; - __IO uint8_t SlotStatusChange; -} Ccid_SlotStatus_t; - - -typedef struct -{ - __IO uint8_t bAbortRequestFlag; - __IO uint8_t bSeq; - __IO uint8_t bSlot; -} usb_ccid_param_t; - - -#pragma pack(1) -typedef struct _Protocol0_DataStructure_t -{ - uint8_t bmFindexDindex; - uint8_t bmTCCKST0; - uint8_t bGuardTimeT0; - uint8_t bWaitingIntegerT0; - uint8_t bClockStop; -} Protocol0_DataStructure_t; -#pragma pack() - -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -typedef struct -{ - uint8_t voltage; /* Voltage for the Card Already Selected */ - uint8_t USART_GuardTime; - uint8_t SC_A2R_FiDi; - uint8_t SC_hostFiDi; - uint8_t USART_DefaultGuardTime; - uint32_t USART_BaudRate; -} SC_Param_t; - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ccid_core.h" - - -typedef struct usb_class_ccid_s { - uint8_t Ccid_BulkState; - uint8_t ccid_card_inserted; - #ifdef HAVE_CCID_INTERRUPT - uint8_t UsbIntMessageBuffer[INTR_MAX_PACKET_SIZE]; /* data buffer*/ - __IO uint8_t PrevXferComplete_IntrIn; - #endif // HAVE_CCID_INTERRUPT - usb_ccid_param_t usb_ccid_param; - - uint8_t* pUsbMessageBuffer; - uint32_t UsbMessageLength; - Ccid_SlotStatus_t Ccid_SlotStatus; - Protocol0_DataStructure_t Protocol0_DataStructure; - //Ccid_bulk_data_t Ccid_bulk_data; - ccid_bulk_header_t bulk_header; - - SC_Param_t SC_Param; -} usb_class_ccid_t; -extern usb_class_ccid_t G_io_ccid; - -/* Exported macros -----------------------------------------------------------*/ -/* Exported variables --------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -void CCID_BulkMessage_In (USBD_HandleTypeDef *pdev, - uint8_t epnum); - -void CCID_BulkMessage_Out (USBD_HandleTypeDef *pdev, - uint8_t epnum, uint8_t* buffer, uint16_t buflen); - -void CCID_ReceiveCmdHeader(uint8_t* pDst, uint8_t u8length); -void CCID_CmdDecode(USBD_HandleTypeDef *pdev); - -void CCID_IntMessage(USBD_HandleTypeDef *pdev); -void CCID_Init(USBD_HandleTypeDef *pdev); -void CCID_DeInit(USBD_HandleTypeDef *pdev); - -uint8_t CCID_IsIntrTransferComplete(void); -void CCID_SetIntrTransferStatus (uint8_t ); -void Transfer_Data_Request(void); -void Set_CSW (uint8_t CSW_Status, uint8_t Send_Permission); - -void io_usb_ccid_set_card_inserted(unsigned int inserted); - -void io_usb_ccid_configure_pinpad(uint8_t enabled); - -#endif // HAVE_USB_CLASS_CCID - -#endif /* __USBD_CCID_IF_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c b/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c deleted file mode 100644 index e75501c60..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c +++ /dev/null @@ -1,1047 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ccid_cmd.c - * @author MCD Application Team - * @version V1.0.1 - * @date 31-January-2014 - * @brief CCID Commands handling - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ccid_cmd.h" - -#ifdef HAVE_USB_CLASS_CCID - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -#define CCID_UpdateCommandStatus(cmd_status,icc_status)\ - G_io_ccid.bulk_header.bulkin.bStatus=(cmd_status|icc_status) - /* - The Above Macro can take any of following Values - #define BM_ICC_PRESENT_ACTIVE 0x00 - #define BM_ICC_PRESENT_INACTIVE 0x01 - #define BM_ICC_NO_ICC_PRESENT 0x02 - - #define BM_COMMAND_STATUS_OFFSET 0x06 - #define BM_COMMAND_STATUS_NO_ERROR 0x00 - #define BM_COMMAND_STATUS_FAILED (0x01 << BM_COMMAND_STATUS_OFFSET) - #define BM_COMMAND_STATUS_TIME_EXTN (0x02 << BM_COMMAND_STATUS_OFFSET) - */ - -/* Private function prototypes -----------------------------------------------*/ -static uint8_t CCID_CheckCommandParams (uint32_t param_type); - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief PC_to_RDR_IccPowerOn - * PC_TO_RDR_ICCPOWERON message execution, apply voltage and get ATR - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_IccPowerOn(void) -{ - /* Apply the ICC VCC - Fills the Response buffer with ICC ATR - This Command is returned with RDR_to_PC_DataBlock(); - */ - - uint8_t voltage; - uint8_t sc_voltage = 0; - uint8_t error; - - G_io_ccid.bulk_header.bulkin.dwLength = 0; /* Reset Number of Bytes in abData */ - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_DWLENGTH | \ - CHK_PARAM_abRFU2 |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_ABORT ); - if (error != 0) - { - return error; - } - - /* Voltage that is applied to the ICC - 00h � Automatic Voltage Selection - 01h � 5.0 volts - 02h � 3.0 volts - 03h � 1.8 volts - */ - /* G_io_ccid.bulk_header.bulkout.bSpecific_0 Contains bPowerSelect */ - voltage = G_io_ccid.bulk_header.bulkout.bSpecific_0; - if (voltage >= VOLTAGE_SELECTION_1V8) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_POWERSELECT; /* The Voltage specified is out of Spec */ - } - - /* Correct Voltage Requested by the Host */ - if ((voltage == VOLTAGE_SELECTION_AUTOMATIC) || - (voltage == VOLTAGE_SELECTION_3V)) - { - /* voltage == 00 Voltage Automatic - voltage == 01 Voltage Automatic = 5.0V - voltage == 02 Voltage Automatic = 3V - voltage == 03 Voltage Automatic = 1.8V - */ - sc_voltage = SC_VOLTAGE_3V; - } - else if (voltage == VOLTAGE_SELECTION_5V) - { - sc_voltage = SC_VOLTAGE_5V; - } - - G_io_ccid.bulk_header.bulkin.dwLength = SC_AnswerToReset(sc_voltage, G_io_ccid_data_buffer); - - /* Check if the Card has come to Active State*/ - error = CCID_CheckCommandParams(CHK_ACTIVE_STATE); - if (error != 0) - { - /* Check if Voltage is not Automatic */ - if (voltage != 0) - { /* If Specific Voltage requested by Host i.e 3V or 5V*/ - return error; - } - else - {/* Automatic Voltage selection requested by Host */ - - if (sc_voltage != SC_VOLTAGE_5V) - { /* If voltage selected was Automatic and 5V is not yet tried */ - sc_voltage = SC_VOLTAGE_5V; - G_io_ccid.bulk_header.bulkin.dwLength = SC_AnswerToReset(sc_voltage, G_io_ccid_data_buffer); - - /* Check again the State */ - error = CCID_CheckCommandParams(CHK_ACTIVE_STATE); - if (error != 0) - return error; - - } - else - { /* Voltage requested from Host was 5V already*/ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_INACTIVE); - return error; - } - } /* Voltage Selection was automatic */ - } /* If Active State */ - - /* ATR is received, No Error Condition Found */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - - return SLOT_NO_ERROR; -} - -/** - * @brief PC_to_RDR_IccPowerOff - * Icc VCC is switched Off - * @param None - * @retval uint8_t error: status of the command execution - */ -uint8_t PC_to_RDR_IccPowerOff(void) -{ - /* The response to this command message is the RDR_to_PC_SlotStatus - response message. */ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_abRFU3 |\ - CHK_PARAM_DWLENGTH ); - if (error != 0) - { - return error; - } - - /* Command is ok, Check for Card Presence */ - if (SC_Detect()) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR,BM_ICC_PRESENT_INACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR,BM_ICC_NO_ICC_PRESENT); - } - - /* Power OFF the card */ - SC_Poweroff(); - - return SLOT_NO_ERROR; -} - -/** - * @brief PC_to_RDR_GetSlotStatus - * Provides the Slot status to the host - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_GetSlotStatus(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_DWLENGTH |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 ); - if (error != 0) - { - return error; - } - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR,BM_ICC_PRESENT_ACTIVE); - return SLOT_NO_ERROR; -} - - -/** - * @brief PC_to_RDR_XfrBlock - * Handles the Block transfer from Host. - * Response to this command message is the RDR_to_PC_DataBlock - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_XfrBlock(void) -{ - uint16_t expectedLength, reqlen; - - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 |\ - CHK_PARAM_ABORT |\ - CHK_ACTIVE_STATE ); - if (error != 0) - return error; - - if (G_io_ccid.bulk_header.bulkout.dwLength > IO_CCID_DATA_BUFFER_SIZE) - { /* Check amount of Data Sent by Host is > than memory allocated ? */ - - return SLOTERROR_BAD_DWLENGTH; - } - - - /* wLevelParameter = Size of expected data to be returned by the - bulk-IN endpoint */ - expectedLength = (G_io_ccid.bulk_header.bulkout.bSpecific_2 << 8) | - G_io_ccid.bulk_header.bulkout.bSpecific_1; - - reqlen = G_io_ccid.bulk_header.bulkout.dwLength; - - G_io_ccid.bulk_header.bulkin.dwLength = (uint16_t)expectedLength; - - error = SC_XferBlock(&G_io_ccid_data_buffer[0], reqlen); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - error = SLOT_NO_ERROR; - } - - return error; -} - - -/** - * @brief PC_to_RDR_GetParameters - * Provides the ICC parameters to the host - * Response to this command message is the RDR_to_PC_Parameters - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_GetParameters(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_DWLENGTH |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 ); - if (error != 0) - return error; - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - - return SLOT_NO_ERROR; -} - - -/** - * @brief PC_to_RDR_ResetParameters - * Set the ICC parameters to the default - * Response to this command message is the RDR_to_PC_Parameters - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_ResetParameters(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_DWLENGTH |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 |\ - CHK_ACTIVE_STATE); - if (error != 0) - return error; - - /* This command resets the slot parameters to their default values */ - G_io_ccid.Protocol0_DataStructure.bmFindexDindex = DEFAULT_FIDI; - G_io_ccid.Protocol0_DataStructure.bmTCCKST0 = DEFAULT_T01CONVCHECKSUM; - G_io_ccid.Protocol0_DataStructure.bGuardTimeT0 = DEFAULT_EXTRA_GUARDTIME; - G_io_ccid.Protocol0_DataStructure.bWaitingIntegerT0 = DEFAULT_WAITINGINTEGER; - G_io_ccid.Protocol0_DataStructure.bClockStop = DEFAULT_CLOCKSTOP; - - error = SC_SetParams(&G_io_ccid.Protocol0_DataStructure); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - error = SLOT_NO_ERROR; - } - - return error; -} - - -/** - * @brief PC_to_RDR_SetParameters - * Set the ICC parameters to the host defined parameters - * Response to this command message is the RDR_to_PC_Parameters - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_SetParameters(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU2 |\ - CHK_ACTIVE_STATE); - if (error != 0) - return error; - - error = SLOT_NO_ERROR; - - /* for Protocol T=0 (bProtocolNum=0) (dwLength=00000005h) */ - if ( (G_io_ccid.bulk_header.bulkout.dwLength == 5) && - (G_io_ccid.bulk_header.bulkout.bSpecific_0 != 0)) - error = SLOTERROR_BAD_PROTOCOLNUM; - - /* for Protocol T=1 (bProtocolNum=1) (dwLength=00000007h) */ - if ( (G_io_ccid.bulk_header.bulkout.dwLength == 7) && - (G_io_ccid.bulk_header.bulkout.bSpecific_0 != 1)) - error = SLOTERROR_CMD_NOT_SUPPORTED; - - /* For T0, Waiting Integer 0 supported */ - if (G_io_ccid_data_buffer[3] != 0) - error = SLOTERROR_BAD_WAITINGINTEGER; - - if (G_io_ccid_data_buffer[4] != DEFAULT_CLOCKSTOP) - error = SLOTERROR_BAD_CLOCKSTOP; - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - - memcpy(&G_io_ccid.Protocol0_DataStructure, (Protocol0_DataStructure_t*)(&(G_io_ccid_data_buffer[0])), sizeof(Protocol0_DataStructure_t)); - error = SC_SetParams(&G_io_ccid.Protocol0_DataStructure); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - error = SLOT_NO_ERROR; - } - - return error; -} - - -/** - * @brief PC_to_RDR_Escape - * Execute the Escape command. This is user specific Implementation - * Response to this command message is the RDR_to_PC_Escape - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_Escape(void) -{ - uint8_t error; - uint16_t size; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 |\ - CHK_PARAM_ABORT |\ - CHK_ACTIVE_STATE); - - if (error != 0) - return error; - - error = SC_ExecuteEscape(&G_io_ccid_data_buffer[0], - G_io_ccid.bulk_header.bulkout.dwLength, - &G_io_ccid_data_buffer[0], - &size); - - G_io_ccid.bulk_header.bulkin.dwLength = size; - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - - -/** - * @brief PC_to_RDR_IccClock - * Execute the Clock specific command from host - * Response to this command message is the RDR_to_PC_SlotStatus - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_IccClock(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU2 |\ - CHK_PARAM_DWLENGTH|\ - CHK_ACTIVE_STATE); - if (error != 0) - return error; - - /* bClockCommand � 00h restarts Clock - � 01h Stops Clock in the state shown in the bClockStop - field of the PC_to_RDR_SetParameters command - and RDR_to_PC_Parameters message.*/ - if (G_io_ccid.bulk_header.bulkout.bSpecific_0 > 1) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_CLOCKCOMMAND; - } - - error = SC_SetClock(G_io_ccid.bulk_header.bulkout.bSpecific_0); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - - -/** - * @brief PC_to_RDR_Abort - * Execute the Abort command from host, This stops all Bulk transfers - * from host and ICC - * Response to this command message is the RDR_to_PC_SlotStatus - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_Abort(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_abRFU3 |\ - CHK_PARAM_DWLENGTH); - if (error != 0) - return error; - - CCID_CmdAbort (G_io_ccid.bulk_header.bulkout.bSlot, G_io_ccid.bulk_header.bulkout.bSeq); - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR,BM_ICC_PRESENT_ACTIVE); - return SLOT_NO_ERROR; -} - -/** - * @brief CCID_CmdAbort - * Execute the Abort command from Bulk EP or from Control EP, - * This stops all Bulk transfers from host and ICC - * @param uint8_t slot: slot number that host wants to abort - * @param uint8_t seq : Seq number for PC_to_RDR_Abort - * @retval uint8_t status of the command execution - */ -uint8_t CCID_CmdAbort(uint8_t slot, uint8_t seq) -{ - /* This function is called for REQUEST_ABORT & PC_to_RDR_Abort */ - - if (slot >= CCID_NUMBER_OF_SLOTS) - { /* This error condition is possible only from CLASS_REQUEST, otherwise - Slot is already checked in parameters from PC_to_RDR_Abort request */ - /* Slot requested is more than supported by Firmware */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_NO_ICC_PRESENT); - return SLOTERROR_BAD_SLOT; - } - - if ( G_io_ccid.usb_ccid_param.bAbortRequestFlag == 1) - { /* Abort Command was already received from ClassReq or PC_to_RDR */ - if (( G_io_ccid.usb_ccid_param.bSeq == seq) && (G_io_ccid.usb_ccid_param.bSlot == slot)) - { - /* CLASS Specific request is already Received, Reset the abort flag */ - G_io_ccid.usb_ccid_param.bAbortRequestFlag = 0; - } - } - else - { - /* Abort Command was NOT received from ClassReq or PC_to_RDR, - so save them for next ABORT command to verify */ - G_io_ccid.usb_ccid_param.bAbortRequestFlag = 1; - G_io_ccid.usb_ccid_param.bSeq = seq ; - G_io_ccid.usb_ccid_param.bSlot = slot; - } - - return 0; -} - -/** - * @brief PC_TO_RDR_T0Apdu - * Execute the PC_TO_RDR_T0APDU command from host - * Response to this command message is the RDR_to_PC_SlotStatus - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_TO_RDR_T0Apdu(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_DWLENGTH | - CHK_PARAM_ABORT ); - if (error != 0) - return error; - - if (G_io_ccid.bulk_header.bulkout.bSpecific_0 > 0x03) - {/* Bit 0 is associated with field bClassGetResponse - Bit 1 is associated with field bClassEnvelope - Other bits are RFU.*/ - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_BMCHANGES; - } - - error = SC_T0Apdu(G_io_ccid.bulk_header.bulkout.bSpecific_0, - G_io_ccid.bulk_header.bulkout.bSpecific_1, - G_io_ccid.bulk_header.bulkout.bSpecific_2); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - -/** - * @brief PC_TO_RDR_Mechanical - * Execute the PC_TO_RDR_MECHANICAL command from host - * Response to this command message is the RDR_to_PC_SlotStatus - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_TO_RDR_Mechanical(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU2 |\ - CHK_PARAM_DWLENGTH - ); - if (error != 0) - return error; - - if (G_io_ccid.bulk_header.bulkout.bSpecific_0 > 0x05) - {/* 01h � Accept Card - 02h � Eject Card - 03h � Capture Card - 04h � Lock Card - 05h � Unlock Card*/ - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_BFUNCTION_MECHANICAL; - } - - error = SC_Mechanical(G_io_ccid.bulk_header.bulkout.bSpecific_0); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - -/** - * @brief PC_TO_RDR_SetDataRateAndClockFrequency - * Set the required Card Frequency and Data rate from the host. - * Response to this command message is the - * RDR_to_PC_DataRateAndClockFrequency - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(void) -{ - uint8_t error; - uint32_t clockFrequency; - uint32_t dataRate; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3); - if (error != 0) - return error; - - if (G_io_ccid.bulk_header.bulkout.dwLength != 0x08) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_LENTGH; - } - - /* HERE we avoiding to an unaligned memory access*/ - clockFrequency = U4LE(G_io_ccid_data_buffer, 0); - dataRate = U4LE(G_io_ccid_data_buffer, 4); - - error = SC_SetDataRateAndClockFrequency(clockFrequency, dataRate); - G_io_ccid.bulk_header.bulkin.bError = error; - - if (error != SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - G_io_ccid.bulk_header.bulkin.dwLength = 8; - - (G_io_ccid_data_buffer[0]) = clockFrequency & 0x000000FF ; - (G_io_ccid_data_buffer[1]) = (clockFrequency & 0x0000FF00) >> 8; - (G_io_ccid_data_buffer[2]) = (clockFrequency & 0x00FF0000) >> 16; - (G_io_ccid_data_buffer[3]) = (clockFrequency & 0xFF000000) >> 24; - (G_io_ccid_data_buffer[4]) = dataRate & 0x000000FF ; - (G_io_ccid_data_buffer[5]) = (dataRate & 0x0000FF00) >> 8; - (G_io_ccid_data_buffer[6]) = (dataRate & 0x00FF0000) >> 16; - (G_io_ccid_data_buffer[7]) = (dataRate & 0xFF000000) >> 24; - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - -/** - * @brief PC_TO_RDR_Secure - * Execute the Secure Command from the host. - * Response to this command message is the RDR_to_PC_DataBlock - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_TO_RDR_Secure(void) -{ - uint8_t error; - uint16_t wLevelParameter; - uint32_t responseLen; - - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_ABORT ); - - if (error != 0) { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - return error; - } - - wLevelParameter = (G_io_ccid.bulk_header.bulkout.bSpecific_1 + ((uint16_t)G_io_ccid.bulk_header.bulkout.bSpecific_2<<8)); - - if ((EXCHANGE_LEVEL_FEATURE == TPDU_EXCHANGE) || - (EXCHANGE_LEVEL_FEATURE == SHORT_APDU_EXCHANGE)) - { - /* TPDU level & short APDU level, wLevelParameter is RFU, = 0000h */ - if (wLevelParameter != 0) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - error = SLOTERROR_BAD_LEVELPARAMETER; - return error; - } - } - - error = SC_Secure(&G_io_ccid_data_buffer[0], &responseLen); - - G_io_ccid.bulk_header.bulkin.dwLength = responseLen; - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - -/******************************************************************************/ -/* BULK IN ROUTINES */ -/******************************************************************************/ - -/** - * @brief RDR_to_PC_DataBlock - * Provide the data block response to the host - * Response for PC_to_RDR_IccPowerOn, PC_to_RDR_XfrBlock - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_DataBlock(uint8_t errorCode) -{ - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_DATABLOCK; - G_io_ccid.bulk_header.bulkin.bError = errorCode; - G_io_ccid.bulk_header.bulkin.bSpecific=0; /* bChainParameter */ - - /* void the Length Specified in Command */ - if(errorCode != SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - } - - Transfer_Data_Request(); - -} - - -/** - * @brief RDR_to_PC_SlotStatus - * Provide the Slot status response to the host - * Response for PC_to_RDR_IccPowerOff - * PC_to_RDR_GetSlotStatus - * PC_to_RDR_IccClock - * PC_to_RDR_T0APDU - * PC_to_RDR_Mechanical - * Also the device sends this response message when it has completed - * aborting a slot after receiving both the Class Specific ABORT request - * and PC_to_RDR_Abort command message. - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_SlotStatus(uint8_t errorCode) -{ - - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_SLOTSTATUS; - G_io_ccid.bulk_header.bulkin.dwLength =0; - G_io_ccid.bulk_header.bulkin.bError = errorCode; - G_io_ccid.bulk_header.bulkin.bSpecific=0; /* bClockStatus = 00h Clock running - 01h Clock stopped in state L - 02h Clock stopped in state H - 03h Clock stopped in an unknown state - All other values are RFU. */ - - Transfer_Data_Request(); - -} - -/** - * @brief RDR_to_PC_Parameters - * Provide the data block response to the host - * Response for PC_to_RDR_GetParameters, PC_to_RDR_ResetParameters - * PC_to_RDR_SetParameters - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_Parameters(uint8_t errorCode) -{ - - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_PARAMETERS; - G_io_ccid.bulk_header.bulkin.bError = errorCode; - - if(errorCode == SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = LEN_PROTOCOL_STRUCT_T0; - } - else - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - } - - memcpy(G_io_ccid_data_buffer, &G_io_ccid.Protocol0_DataStructure, sizeof(G_io_ccid.Protocol0_DataStructure)); - - /* bProtocolNum */ - G_io_ccid.bulk_header.bulkin.bSpecific = BPROTOCOL_NUM_T0; - - Transfer_Data_Request(); -} - -/** - * @brief RDR_to_PC_Escape - * Provide the Escaped data block response to the host - * Response for PC_to_RDR_Escape - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_Escape(uint8_t errorCode) -{ - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_ESCAPE; - - G_io_ccid.bulk_header.bulkin.bSpecific=0; /* Reserved for Future Use */ - G_io_ccid.bulk_header.bulkin.bError = errorCode; - - /* void the Length Specified in Command */ - if(errorCode != SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - } - - Transfer_Data_Request(); -} - - - -/** - * @brief RDR_to_PC_DataRateAndClockFrequency - * Provide the Clock and Data Rate information to host - * Response for PC_TO_RDR_SetDataRateAndClockFrequency - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode) -{ - /* - uint16_t length = CCID_RESPONSE_HEADER_SIZE; - */ - - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_DATARATEANDCLOCKFREQUENCY; - G_io_ccid.bulk_header.bulkin.bError = errorCode; - G_io_ccid.bulk_header.bulkin.bSpecific=0; /* Reserved for Future Use */ - - /* void the Length Specified in Command */ - if(errorCode != SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - } - - Transfer_Data_Request(); -} - -#ifdef HAVE_CCID_INTERRUPT -/** - * @brief RDR_to_PC_NotifySlotChange - * Interrupt message to be sent to the host, Checks the card presence - * status and update the buffer accordingly - * @param None - * @retval None - */ -void RDR_to_PC_NotifySlotChange(void) -{ - G_io_ccid.UsbIntMessageBuffer[OFFSET_INT_BMESSAGETYPE] = RDR_TO_PC_NOTIFYSLOTCHANGE; - - if (SC_Detect() ) - { - /* - SLOT_ICC_PRESENT 0x01 : LSb : (0b = no ICC present, 1b = ICC present) - SLOT_ICC_CHANGE 0x02 : MSb : (0b = no change, 1b = change). - */ - G_io_ccid.UsbIntMessageBuffer[OFFSET_INT_BMSLOTICCSTATE] = SLOT_ICC_PRESENT | - SLOT_ICC_CHANGE; - } - else - { - G_io_ccid.UsbIntMessageBuffer[OFFSET_INT_BMSLOTICCSTATE] = SLOT_ICC_CHANGE; - - /* Power OFF the card */ - SC_Poweroff(); - } -} -#endif // HAVE_CCID_INTERRUPT - - -/** - * @brief CCID_UpdSlotStatus - * Updates the variable for the slot status - * @param uint8_t slotStatus : slot status from the calling function - * @retval None - */ -void CCID_UpdSlotStatus (uint8_t slotStatus) -{ - G_io_ccid.Ccid_SlotStatus.SlotStatus = slotStatus; -} - -/** - * @brief CCID_UpdSlotChange - * Updates the variable for the slot change status - * @param uint8_t changeStatus : slot change status from the calling function - * @retval None - */ -void CCID_UpdSlotChange (uint8_t changeStatus) -{ - G_io_ccid.Ccid_SlotStatus.SlotStatusChange = changeStatus; -} - -/** - * @brief CCID_IsSlotStatusChange - * Provides the value of the variable for the slot change status - * @param None - * @retval uint8_t slot change status - */ -uint8_t CCID_IsSlotStatusChange (void) -{ - return G_io_ccid.Ccid_SlotStatus.SlotStatusChange; -} - -/** - * @brief CCID_CheckCommandParams - * Checks the specific parameters requested by the function and update - * status accordingly. This function is called from all - * PC_to_RDR functions - * @param uint32_t param_type : Parameter enum to be checked by calling function - * @retval uint8_t status - */ -static uint8_t CCID_CheckCommandParams (uint32_t param_type) -{ - uint32_t parameter; - - G_io_ccid.bulk_header.bulkin.bStatus = BM_ICC_PRESENT_ACTIVE | BM_COMMAND_STATUS_NO_ERROR ; - - parameter = (uint32_t)param_type; - - if (parameter & CHK_PARAM_SLOT) - { - /* - The slot number (bSlot) identifies which ICC slot is being addressed - by the message, if the CCID supports multiple slots. - The slot number is zero-relative, and is in the range of zero to FFh. - */ - - /* SLOT Number is 0 onwards, so always < CCID_NUMBER_OF_SLOTs */ - /* Error Condition !!! */ - if (G_io_ccid.bulk_header.bulkout.bSlot >= CCID_NUMBER_OF_SLOTS) - { /* Slot requested is more than supported by Firmware */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_NO_ICC_PRESENT); - return SLOTERROR_BAD_SLOT; - } - } - - if (parameter & CHK_PARAM_CARD_PRESENT) - { - /* Commands Parameters ok, Check the Card Status */ - if (SC_Detect() == 0) - { /* Card is Not detected */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_NO_ICC_PRESENT); - return SLOTERROR_ICC_MUTE; - } - } - - /* Check that DwLength is 0 */ - if (parameter & CHK_PARAM_DWLENGTH) - { - if (G_io_ccid.bulk_header.bulkout.dwLength != 0) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_LENTGH; - } - } - - /* abRFU 2 : Reserved for Future Use*/ - if (parameter & CHK_PARAM_abRFU2) - { - - if ((G_io_ccid.bulk_header.bulkout.bSpecific_1 != 0) || - (G_io_ccid.bulk_header.bulkout.bSpecific_2 != 0)) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_ABRFU_2B; /* bSpecific_1 */ - } - } - - if (parameter & CHK_PARAM_abRFU3) - { - /* abRFU 3 : Reserved for Future Use*/ - if ((G_io_ccid.bulk_header.bulkout.bSpecific_0 != 0) || - (G_io_ccid.bulk_header.bulkout.bSpecific_1 != 0) || - (G_io_ccid.bulk_header.bulkout.bSpecific_2 != 0)) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_ABRFU_3B; - } - } - - - if (parameter & CHK_PARAM_ABORT) - { - if( G_io_ccid.usb_ccid_param.bAbortRequestFlag ) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_INACTIVE); - return SLOTERROR_CMD_ABORTED; - } - } - - if (parameter & CHK_ACTIVE_STATE) - { - /* Commands Parameters ok, Check the Card Status */ - /* Card is detected */ - if (! SC_Detect()) - { - /* Check that from Lower Layers, the SmartCard come to known state */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_INACTIVE); - return SLOTERROR_HW_ERROR; - } - } - - return 0; -} - -#endif // HAVE_USB_CLASS_CCID - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_core.c b/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_core.c deleted file mode 100644 index e60a55243..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_core.c +++ /dev/null @@ -1,276 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ccid_core.c - * @author MCD Application Team - * @version V1.0.1 - * @date 31-January-2014 - * @brief This file provides all the CCID core functions. - * - * @verbatim - * - * =================================================================== - * CCID Class Description - * =================================================================== - * This module manages the Specification for Integrated Circuit(s) - * Cards Interface Revision 1.1 - * This driver implements the following aspects of the specification: - * - Bulk Transfers - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ccid_core.h" -#include "os_io.h" -#include - -#ifdef HAVE_USB_CLASS_CCID - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ - - - -/* Private function ----------------------------------------------------------*/ - -/** - * @brief USBD_CCID_Init - * Initialize the USB CCID Interface - * @param pdev: device instance - * @param cfgidx: configuration index - * @retval status - */ -uint8_t USBD_CCID_Init (USBD_HandleTypeDef *pdev, - uint8_t cfgidx) -{ - UNUSED(cfgidx); - /* Open EP IN */ - USBD_LL_OpenEP(pdev, - CCID_BULK_IN_EP, - USBD_EP_TYPE_BULK, - CCID_BULK_EPIN_SIZE); - - /* Open EP OUT */ - USBD_LL_OpenEP(pdev, - CCID_BULK_OUT_EP, - USBD_EP_TYPE_BULK, - CCID_BULK_EPOUT_SIZE); - -#ifdef HAVE_CCID_INTERRUPT - /* Open INTR EP IN */ - USBD_LL_OpenEP(pdev, - CCID_INTR_IN_EP, - USBD_EP_TYPE_INTR, - CCID_INTR_EPIN_SIZE); -#endif // HAVE_CCID_INTERRUPT - - /* Init the CCID layer */ - CCID_Init(pdev); - - return USBD_OK; -} - -/** - * @brief USBD_CCID_DeInit - * DeInitilaize the usb ccid configuration - * @param pdev: device instance - * @param cfgidx: configuration index - * @retval status - */ -uint8_t USBD_CCID_DeInit (USBD_HandleTypeDef *pdev, - uint8_t cfgidx) -{ - UNUSED(cfgidx); -// /* Close CCID EPs */ -// USBD_LL_CloseEP (pdev , CCID_BULK_IN_EP); -// USBD_LL_CloseEP (pdev , CCID_BULK_OUT_EP); -// #ifdef HAVE_CCID_INTERRUPT -// USBD_LL_CloseEP (pdev , CCID_INTR_IN_EP); -// #endif // HAVE_CCID_INTERRUPT - - /* Un Init the CCID layer */ - CCID_DeInit(pdev); - return USBD_OK; -} - -/** - * @brief USBD_CCID_Setup - * Handle the CCID specific requests - * @param pdev: device instance - * @param req: USB request - * @retval status - */ -uint8_t USBD_CCID_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) -{ - uint8_t slot_nb; - uint8_t seq_nb; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - /* Class request */ - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case REQUEST_ABORT : - - if ((req->wLength == 0) && - ((req->bmRequest & 0x80) != 0x80)) - { /* Check bmRequest : No Data-In stage. 0x80 is Data Direction */ - - /* The wValue field contains the slot number (bSlot) in the low byte - and the sequence number (bSeq) in the high byte.*/ - slot_nb = (uint8_t) ((req->wValue) & 0x00ff); - seq_nb = (uint8_t) (((req->wValue) & 0xff00)>>8); - - if ( CCID_CmdAbort(slot_nb, seq_nb) != 0 ) - { /* If error is returned by lower layer : - Generally Slot# may not have matched */ - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - case REQUEST_GET_CLOCK_FREQUENCIES : - if((req->wValue == 0) && - (req->wLength != 0) && - ((req->bmRequest & 0x80) == 0x80)) - { /* Check bmRequest : Data-In stage. 0x80 is Data Direction */ - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - case REQUEST_GET_DATA_RATES : - if((req->wValue == 0) && - (req->wLength != 0) && - ((req->bmRequest & 0x80) == 0x80)) - { /* Check bmRequest : Data-In stage. 0x80 is Data Direction */ - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - default: - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - /* Interface & Endpoint request */ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_INTERFACE : - break; - - case USB_REQ_SET_INTERFACE : - break; - - case USB_REQ_CLEAR_FEATURE: - - /* Re-activate the EP */ - USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex); - if((((uint8_t)req->wIndex) & 0x80) == 0x80) - { - USBD_LL_OpenEP(pdev, - ((uint8_t)req->wIndex), - USBD_EP_TYPE_BULK, - CCID_BULK_EPIN_SIZE); - } - else - { - USBD_LL_OpenEP(pdev, - ((uint8_t)req->wIndex), - USBD_EP_TYPE_BULK, - CCID_BULK_EPOUT_SIZE); - } - - break; - - } - break; - - default: - break; - } - return USBD_OK; -} - -/** - * @brief USBD_CCID_DataIn - * handle data IN Stage - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - */ -uint8_t USBD_CCID_DataIn (USBD_HandleTypeDef *pdev, - uint8_t epnum) -{ - CCID_BulkMessage_In(pdev , epnum); - return USBD_OK; -} - -/** - * @brief USBD_CCID_DataOut - * handle data OUT Stage - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - */ -uint8_t USBD_CCID_DataOut (USBD_HandleTypeDef *pdev, - uint8_t epnum, uint8_t* buffer, - apdu_buffer_t * apdu_buffer) -{ -#ifndef HAVE_LOCAL_APDU_BUFFER - UNUSED(apdu_buffer); -#endif - uint16_t rlen = io_seproxyhal_get_ep_rx_size(CCID_BULK_OUT_EP); - CCID_BulkMessage_Out(pdev , epnum, buffer, rlen); -#ifdef HAVE_LOCAL_APDU_BUFFER - memcpy(apdu_buffer->buf, G_io_apdu_buffer, rlen); -#endif - return USBD_OK; -} - -#endif // HAVE_USB_CLASS_CCID - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - - diff --git a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c b/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c deleted file mode 100644 index 777d4ebe5..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c +++ /dev/null @@ -1,631 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ccid_if.c - * @author MCD Application Team - * @version V1.0.1 - * @date 31-January-2014 - * @brief This file provides all the functions for USB Interface for CCID - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "os.h" -#include "usbd_ccid_if.h" -#include - -#ifdef HAVE_USB_CLASS_CCID - -#if CCID_BULK_EPIN_SIZE > USB_SEGMENT_SIZE - #error configuration error, the USB MAX SEGMENT SIZE does not support the CCID endpoint (CCID_BULK_EPIN_SIZE vs USB_SEGMENT_SIZE) -#endif - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -usb_class_ccid_t G_io_ccid; - -/* Private function prototypes -----------------------------------------------*/ -static void CCID_Response_SendData (USBD_HandleTypeDef *pdev, - uint8_t* pbuf, - uint16_t len); -/* Private function ----------------------------------------------------------*/ -/** - * @brief CCID_Init - * Initialize the CCID USB Layer - * @param pdev: device instance - * @retval None - */ -void CCID_Init (USBD_HandleTypeDef *pdev) -{ - memset(&G_io_ccid, 0, sizeof(G_io_ccid)); - - /* CCID Related Initialization */ -#ifdef HAVE_CCID_INTERRUPT - CCID_SetIntrTransferStatus(1); /* Transfer Complete Status */ -#endif // HAVE_CCID_INTERRUPT - CCID_UpdSlotChange(1); - SC_InitParams(); - - /* Prepare Out endpoint to receive 1st packet */ - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; - USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); - - // send the smartcard as inserted state at boot time - io_usb_ccid_set_card_inserted(1); -} - -/** - * @brief CCID_DeInit - * Uninitialize the CCID Machine - * @param pdev: device instance - * @retval None - */ -void CCID_DeInit (USBD_HandleTypeDef *pdev) -{ - UNUSED(pdev); - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; -} - -/** - * @brief CCID_Message_In - * Handle Bulk IN & Intr IN data stage - * @param pdev: device instance - * @param uint8_t epnum: endpoint index - * @retval None - */ -void CCID_BulkMessage_In (USBD_HandleTypeDef *pdev, - uint8_t epnum) -{ - if (epnum == (CCID_BULK_IN_EP & 0x7F)) - {/* Filter the epnum by masking with 0x7f (mask of IN Direction) */ - - /*************** Handle Bulk Transfer IN data completion *****************/ - - switch (G_io_ccid.Ccid_BulkState) - { - case CCID_STATE_SEND_RESP: { - unsigned int remLen = G_io_ccid.UsbMessageLength; - - // advance with acknowledged sent chunk - if (G_io_ccid.pUsbMessageBuffer == (uint8_t *)&G_io_ccid.bulk_header) { - // first part of the bulk in sent. - // advance in the data buffer to transmit. (mixed source leap) - G_io_ccid.pUsbMessageBuffer = G_io_ccid_data_buffer+MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength)-CCID_HEADER_SIZE; - } - else { - G_io_ccid.pUsbMessageBuffer += MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength); - } - G_io_ccid.UsbMessageLength -= MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength); - - // if remaining length is > EPIN_SIZE: send a filled bulk packet - if (G_io_ccid.UsbMessageLength >= CCID_BULK_EPIN_SIZE) { - CCID_Response_SendData(pdev, G_io_ccid.pUsbMessageBuffer, - // use the header declared size packet must be well formed - CCID_BULK_EPIN_SIZE); - } - - // if remaining length is 0; send an empty packet and prepare to receive a new command - else if (G_io_ccid.UsbMessageLength == 0 && remLen == CCID_BULK_EPIN_SIZE) { - CCID_Response_SendData(pdev, G_io_ccid.pUsbMessageBuffer, - // use the header declared size packet must be well formed - 0); - goto last_xfer; // won't wait ack to avoid missing a command - } - // else if no more data, then last packet sent, go back to idle (done on transfer ack) - else if (G_io_ccid.UsbMessageLength == 0) { // robustness only - last_xfer: - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; - - /* Prepare EP to Receive First Cmd */ - // not timeout compliant // USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); - - // mark transfer as completed - G_io_app.apdu_state = APDU_IDLE; - } - - // if remaining length is < EPIN_SIZE: send packet and prepare to receive a new command - else { - CCID_Response_SendData(pdev, G_io_ccid.pUsbMessageBuffer, - // use the header declared size packet must be well formed - G_io_ccid.UsbMessageLength); - goto last_xfer; // won't wait ack to avoid missing a command - } - - break; - } - - default: - break; - } - } -#ifdef HAVE_CCID_INTERRUPT - else if (epnum == (CCID_INTR_IN_EP & 0x7F)) - { - /* Filter the epnum by masking with 0x7f (mask of IN Direction) */ - CCID_SetIntrTransferStatus(1); /* Transfer Complete Status */ - } -#endif // HAVE_CCID_INTERRUPT -} - -void CCID_Send_Reply(USBD_HandleTypeDef *pdev) { - /********** Decide for all commands ***************/ - if (G_io_ccid.Ccid_BulkState == CCID_STATE_SEND_RESP) - { - G_io_ccid.UsbMessageLength = G_io_ccid.bulk_header.bulkin.dwLength+CCID_HEADER_SIZE; /* Store for future use */ - - /* Expected Data Length Packet Received */ - G_io_ccid.pUsbMessageBuffer = (uint8_t*) &G_io_ccid.bulk_header; - - // send bulk header and first pat of the message at once - memcpy(G_io_usb_ep_buffer, &G_io_ccid.bulk_header, CCID_HEADER_SIZE); - if (G_io_ccid.UsbMessageLength>CCID_HEADER_SIZE) { - // copy start of data if bigger size than a header - memmove(G_io_usb_ep_buffer+CCID_HEADER_SIZE, G_io_ccid_data_buffer, MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength)-CCID_HEADER_SIZE); - } - // send the first mixed source chunk - CCID_Response_SendData(pdev, G_io_usb_ep_buffer, - // use the header declared size packet must be well formed - MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength)); - } -} - -/** - * @brief CCID_BulkMessage_Out - * Proccess CCID OUT data - * @param pdev: device instance - * @param uint8_t epnum: endpoint index - * @retval None - */ -void CCID_BulkMessage_Out (USBD_HandleTypeDef *pdev, - uint8_t epnum, uint8_t* buffer, uint16_t dataLen) -{ - if (epnum == (CCID_BULK_OUT_EP & 0x7F)) { - switch (G_io_ccid.Ccid_BulkState) - { - - // after a timeout, could be in almost any state :) therefore, clean it and process the newly received command - default: - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; - // no break is intentional - - __attribute__((fallthrough)); - case CCID_STATE_IDLE: - // prepare to receive another packet later on (to avoid troubles with timeout due to other hid command timeouting the ccid endpoint reply) - USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); - - if (dataLen == 0x00) - { /* Zero Length Packet Received, end of transfer */ - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; - } - else if (dataLen >= CCID_HEADER_SIZE) - { - G_io_ccid.UsbMessageLength = dataLen; /* Store for future use */ - - /* Expected Data Length Packet Received */ - // endianness is little :) useful for our ARM convention - G_io_ccid.pUsbMessageBuffer = (uint8_t*) &G_io_ccid.bulk_header; - - // copy the ccid bulk header only - memcpy(G_io_ccid.pUsbMessageBuffer, buffer, CCID_HEADER_SIZE); - // copy remaining part in the data buffer (split from the ccid to allow for overlaying with another ressource buffer) - if (dataLen>CCID_HEADER_SIZE) { - memmove(G_io_ccid_data_buffer, buffer+CCID_HEADER_SIZE, dataLen-CCID_HEADER_SIZE); - // we're now receiving in the data buffer (all subsequent calls) - G_io_ccid.pUsbMessageBuffer = G_io_ccid_data_buffer; - } - - if (G_io_ccid.bulk_header.bulkout.dwLength > IO_CCID_DATA_BUFFER_SIZE) - { /* Check if length of data to be sent by host is > buffer size */ - - /* Too long data received.... Error ! */ - G_io_ccid.Ccid_BulkState = CCID_STATE_UNCORRECT_LENGTH; - } - else - // everything received in the first packet - if (G_io_ccid.UsbMessageLength == (G_io_ccid.bulk_header.bulkout.dwLength + CCID_HEADER_SIZE)) { - /* Short message, less than the EP Out Size, execute the command, - if parameter like dwLength is too big, the appropriate command will - give an error */ - CCID_CmdDecode(pdev); - } - else - { /* Long message, receive additional data with command */ - G_io_ccid.Ccid_BulkState = CCID_STATE_RECEIVE_DATA; - G_io_ccid.pUsbMessageBuffer += dataLen-CCID_HEADER_SIZE; /* Point to new offset */ - } - } - break; - - case CCID_STATE_RECEIVE_DATA: - - USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); - - G_io_ccid.UsbMessageLength += dataLen; - - if (dataLen < CCID_BULK_EPOUT_SIZE) - {/* Short message, less than the EP Out Size, execute the command, - if parameter like dwLength is too big, the appropriate command will - give an error */ - - /* Full command is received, process the Command */ - memcpy(G_io_ccid.pUsbMessageBuffer, buffer, dataLen); - CCID_CmdDecode(pdev); - } - else //if (dataLen == CCID_BULK_EPOUT_SIZE) - { - if (G_io_ccid.UsbMessageLength < (G_io_ccid.bulk_header.bulkout.dwLength + CCID_HEADER_SIZE)) - { - memmove(G_io_ccid.pUsbMessageBuffer, buffer, dataLen); - G_io_ccid.pUsbMessageBuffer += dataLen; - /* Increment the pointer to receive more data */ - - /* Prepare EP to Receive next Cmd */ - // not timeout compliant // USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); - } - else if (G_io_ccid.UsbMessageLength == (G_io_ccid.bulk_header.bulkout.dwLength + CCID_HEADER_SIZE)) - { - /* Full command is received, process the Command */ - memmove(G_io_ccid.pUsbMessageBuffer, buffer, dataLen); - CCID_CmdDecode(pdev); - } - else - { - /* Too long data received.... Error ! */ - G_io_ccid.Ccid_BulkState = CCID_STATE_UNCORRECT_LENGTH; - } - } - - break; - - /* - case CCID_STATE_UNCORRECT_LENGTH: - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; - break; - - default: - - break; - */ - } - } -} - -/** - * @brief CCID_CmdDecode - * Parse the commands and Proccess command - * @param pdev: device instance - * @retval None - */ -void CCID_CmdDecode(USBD_HandleTypeDef *pdev) -{ - uint8_t errorCode; - - switch (G_io_ccid.bulk_header.bulkout.bMessageType) - { - case PC_TO_RDR_ICCPOWERON: - errorCode = PC_to_RDR_IccPowerOn(); - RDR_to_PC_DataBlock(errorCode); - break; - case PC_TO_RDR_ICCPOWEROFF: - errorCode = PC_to_RDR_IccPowerOff(); - RDR_to_PC_SlotStatus(errorCode); - break; - case PC_TO_RDR_GETSLOTSTATUS: - errorCode = PC_to_RDR_GetSlotStatus(); - RDR_to_PC_SlotStatus(errorCode); - break; - case PC_TO_RDR_XFRBLOCK: - PC_to_RDR_XfrBlock(); - // asynchronous // RDR_to_PC_DataBlock(errorCode); - break; - case PC_TO_RDR_GETPARAMETERS: - errorCode = PC_to_RDR_GetParameters(); - RDR_to_PC_Parameters(errorCode); - break; - case PC_TO_RDR_RESETPARAMETERS: - errorCode = PC_to_RDR_ResetParameters(); - RDR_to_PC_Parameters(errorCode); - break; - case PC_TO_RDR_SETPARAMETERS: - errorCode = PC_to_RDR_SetParameters(); - RDR_to_PC_Parameters(errorCode); - break; - case PC_TO_RDR_ESCAPE: - errorCode = PC_to_RDR_Escape(); - RDR_to_PC_Escape(errorCode); - break; - case PC_TO_RDR_ICCCLOCK: - errorCode = PC_to_RDR_IccClock(); - RDR_to_PC_SlotStatus(errorCode); - break; - case PC_TO_RDR_ABORT: - errorCode = PC_to_RDR_Abort(); - RDR_to_PC_SlotStatus(errorCode); - break; - case PC_TO_RDR_T0APDU: - errorCode = PC_TO_RDR_T0Apdu(); - RDR_to_PC_SlotStatus(errorCode); - break; - case PC_TO_RDR_MECHANICAL: - errorCode = PC_TO_RDR_Mechanical(); - RDR_to_PC_SlotStatus(errorCode); - break; - case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY: - errorCode = PC_TO_RDR_SetDataRateAndClockFrequency(); - RDR_to_PC_DataRateAndClockFrequency(errorCode); - break; - case PC_TO_RDR_SECURE: - PC_TO_RDR_Secure(); - // asynchronous // RDR_to_PC_DataBlock(errorCode); - break; - default: - RDR_to_PC_SlotStatus(SLOTERROR_CMD_NOT_SUPPORTED); - break; - } - - CCID_Send_Reply(pdev); -} - -/** - * @brief Transfer_Data_Request - * Prepare the request response to be sent to the host - * @param uint8_t* dataPointer: Pointer to the data buffer to send - * @param uint16_t dataLen : number of bytes to send - * @retval None - */ -void Transfer_Data_Request(void) -{ - /********** Update Global Variables ***************/ - G_io_ccid.Ccid_BulkState = CCID_STATE_SEND_RESP; -} - - -/** - * @brief CCID_Response_SendData - * Send the data on bulk-in EP - * @param pdev: device instance - * @param uint8_t* buf: pointer to data buffer - * @param uint16_t len: Data Length - * @retval None - */ -static void CCID_Response_SendData(USBD_HandleTypeDef *pdev, - uint8_t* buf, - uint16_t len) -{ - UNUSED(pdev); - // don't ask the MCU to perform bulk split, we could quickly get into a buffer overflow - if (len > CCID_BULK_EPIN_SIZE) { - THROW(SWO_IOL_OFW_04); - } - - uint8_t spi_buffer[6]; - spi_buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; - spi_buffer[1] = (3+len)>>8; - spi_buffer[2] = (3+len); - spi_buffer[3] = CCID_BULK_IN_EP; - spi_buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN; - spi_buffer[5] = len; - io_seproxyhal_spi_send(spi_buffer, 6); - io_seproxyhal_spi_send(buf, len); -} - -#ifdef HAVE_CCID_INTERRUPT -/** - * @brief CCID_IntMessage - * Send the Interrupt-IN data to the host - * @param pdev: device instance - * @retval None - */ -void CCID_IntMessage(USBD_HandleTypeDef *pdev) -{ - UNUSED(pdev); - /* Check if there us change in Smartcard Slot status */ - if ( CCID_IsSlotStatusChange() && CCID_IsIntrTransferComplete() ) - { -#ifdef HAVE_CCID_INTERRUPT - /* Check Slot Status is changed. Card is Removed/ Fitted */ - RDR_to_PC_NotifySlotChange(); -#endif // HAVE_CCID_INTERRUPT - - CCID_SetIntrTransferStatus(0); /* Reset the Status */ - CCID_UpdSlotChange(0); /* Reset the Status of Slot Change */ - - uint8_t spi_buffer[6]; - spi_buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; - spi_buffer[1] = (3+2)>>8; - spi_buffer[2] = (3+2); - spi_buffer[3] = CCID_INTR_IN_EP; - spi_buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN; - spi_buffer[5] = 2; - io_seproxyhal_spi_send(spi_buffer, 6); - io_seproxyhal_spi_send(G_io_ccid.UsbIntMessageBuffer, 2); - } -} - -/** - * @brief CCID_IsIntrTransferComplete - * Provides the status of previous Interrupt transfer status - * @param None - * @retval uint8_t PrevXferComplete_IntrIn: Value of the previous transfer status - */ -uint8_t CCID_IsIntrTransferComplete (void) -{ - return G_io_ccid.PrevXferComplete_IntrIn; -} - -/** - * @brief CCID_IsIntrTransferComplete - * Set the value of the Interrupt transfer status - * @param uint8_t xfer_Status: Value of the Interrupt transfer status to set - * @retval None - */ -void CCID_SetIntrTransferStatus (uint8_t xfer_Status) -{ - G_io_ccid.PrevXferComplete_IntrIn = xfer_Status; -} -#endif // HAVE_CCID_INTERRUPT - - - - - - -uint8_t SC_Detect(void) { - return G_io_ccid.ccid_card_inserted; -} - -void SC_InitParams (void) { - // nothing to do -} - -uint8_t SC_SetParams (Protocol0_DataStructure_t* pt0) { - UNUSED(pt0); - return SLOT_NO_ERROR; -} - - -uint8_t SC_SetClock (uint8_t bClockCommand) { - UNUSED(bClockCommand); - return SLOT_NO_ERROR; -} - -uint8_t SC_Request_GetClockFrequencies(uint8_t* pbuf, uint16_t* len); -uint8_t SC_Request_GetDataRates(uint8_t* pbuf, uint16_t* len); -uint8_t SC_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse, - uint8_t bClassEnvelope) { - UNUSED(bmChanges); - UNUSED(bClassGetResponse); - UNUSED(bClassEnvelope); - return SLOTERROR_CMD_NOT_SUPPORTED; -} -uint8_t SC_Mechanical(uint8_t bFunction) { - UNUSED(bFunction); - return SLOTERROR_CMD_NOT_SUPPORTED; -} -uint8_t SC_SetDataRateAndClockFrequency(uint32_t dwClockFrequency, - uint32_t dwDataRate) { - UNUSED(dwClockFrequency); - UNUSED(dwDataRate); - return SLOT_NO_ERROR; -} -uint8_t SC_Secure(uint8_t* pbuf, uint32_t* returnLen) { - // Extract the APDU to send to the App - switch(pbuf[0]) { - case PIN_OPR_VERIFICATION: - // CCID Spec: APDU starts at offset 25, after the 10-Byte header - pbuf += 15; - break; - case PIN_OPR_MODIFICATION: - // CCID Spec: APDU starts at offset 28, 29 or 30 - // depending on the nb of messages to display - switch(pbuf[11]) { - case 0: - // CCID Spec: No message to display - // APDU starts at offset 28, after the 10-Byte header - pbuf += 18; - break; - case 1: - case 2: - // CCID Spec: 1 or 2 message(s) to display - // APDU starts at offset 29, after the 10-Byte header - pbuf += 19; - break; - case 3: - // CCID Spec: 3 messages to display - // APDU starts at offset 30, after the 10-Byte header - pbuf += 20; - break; - default: // unsupported - G_io_ccid.bulk_header.bulkin.dwLength = 0; - RDR_to_PC_DataBlock(SLOTERROR_CMD_NOT_SUPPORTED); - CCID_Send_Reply(&USBD_Device); - return SLOTERROR_CMD_NOT_SUPPORTED; - } - break; - default: // unsupported - G_io_ccid.bulk_header.bulkin.dwLength = 0; - RDR_to_PC_DataBlock(SLOTERROR_CMD_NOT_SUPPORTED); - CCID_Send_Reply(&USBD_Device); - return SLOTERROR_CMD_NOT_SUPPORTED; - } - // Change APDU CLA to be interpreted by the CCID compatible App (like OpenPGP) - pbuf[0] = PIN_OPR_APDU_CLA; - // The APDU has no data, only the header (size 5) - *returnLen = 5; - return SC_XferBlock(pbuf, *returnLen); -} - -// prepare the apdu to be processed by the application -uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen) { - // check for overflow - if (blockLen > IO_APDU_BUFFER_SIZE) { - return SLOTERROR_BAD_LENTGH; - } - - // copy received apdu // if G_io_ccid_data_buffer is the buffer apdu, then the memmove will do nothing - memmove(G_io_apdu_buffer, ptrBlock, blockLen); - G_io_app.apdu_length = blockLen; - G_io_app.apdu_media = IO_APDU_MEDIA_USB_CCID; // for application code - G_io_app.apdu_state = APDU_USB_CCID; // for next call to io_exchange - - return SLOT_NO_ERROR; -} - -void io_usb_ccid_reply(unsigned char* buffer, unsigned short length) { - // avoid memory overflow - if (length > IO_CCID_DATA_BUFFER_SIZE) { - THROW(SWO_IOL_OFW_05); - } - // copy the responde apdu - memmove(G_io_ccid_data_buffer, buffer, length); - G_io_ccid.bulk_header.bulkin.dwLength = length; - // forge reply - RDR_to_PC_DataBlock(SLOT_NO_ERROR); - - // start sending rpely - CCID_Send_Reply(&USBD_Device); -} - -void io_usb_ccid_reply_bare(unsigned short length) { - G_io_ccid.bulk_header.bulkin.dwLength = length; - // forge reply - RDR_to_PC_DataBlock(SLOT_NO_ERROR); - // start sending rpely - CCID_Send_Reply(&USBD_Device); -} - -// ask for power on -void io_usb_ccid_set_card_inserted(unsigned int inserted) { - G_io_ccid.ccid_card_inserted = inserted; - CCID_UpdSlotChange(1); -#ifdef HAVE_CCID_INTERRUPT - CCID_IntMessage(&USBD_Device); -#endif // HAVE_CCID_INTERRUPT -} - -void io_usb_ccid_configure_pinpad(uint8_t enabled) { - const volatile uint8_t *cfgDesc = USBD_GetPinPadOffset(); - nvm_write((void *)cfgDesc, &enabled, 1); -} - -#endif // HAVE_USB_CLASS_CCID - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h b/lib_stusb/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h deleted file mode 100644 index 908c7b355..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_customhid.h - * @author MCD Application Team - * @version V2.2.0 - * @date 13-June-2014 - * @brief header file for the usbd_customhid.c file. - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_HID_CORE_H_ -#define __USB_HID_CORE_H_ - -#include "usbd_ioreq.h" - -/** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_HID - * @brief This file is the Header file for USBD_HID.c - * @{ - */ - - - -//#define USB_HID_CONFIG_DESC_SIZ 75 -//#define USB_HID_DESC_SIZ 9 - -#define HID_DESCRIPTOR_TYPE 0x21 -#define HID_REPORT_DESC 0x22 - - -#define HID_REQ_SET_PROTOCOL 0x0B -#define HID_REQ_GET_PROTOCOL 0x03 - -#define HID_REQ_SET_IDLE 0x0A -#define HID_REQ_GET_IDLE 0x02 - -#define HID_REQ_SET_REPORT 0x09 -#define HID_REQ_GET_REPORT 0x01 -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -typedef enum -{ - HID_IDLE = 0, - HID_BUSY, -} -HID_StateTypeDef; - - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - - -uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req); - - -uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, - uint8_t cfgidx); - -uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, - uint8_t cfgidx); -/** - * @} - */ - - -uint8_t *USBD_HID_GetCfgDesc_impl (uint16_t *length); - -uint8_t *USBD_HID_GetDeviceQualifierDesc_impl (uint16_t *length); - - - -uint8_t *USBD_HID_GetHidDescriptor_impl(uint16_t *length); -uint8_t *USBD_HID_GetReportDescriptor_impl(uint16_t *length); - - -uint8_t USBD_HID_DataOut_impl (USBD_HandleTypeDef *pdev, - uint8_t epnum, uint8_t* buffer, apdu_buffer_t*); - -/** - * @} - */ - -#endif // __USB_HID_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c b/lib_stusb/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c deleted file mode 100644 index 50aa5ed67..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c +++ /dev/null @@ -1,242 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_customhid.c - * @author MCD Application Team - * @version V2.2.0 - * @date 13-June-2014 - * @brief This file provides the HID core functions. - * - * @verbatim - * - * =================================================================== - * HID Class Description - * =================================================================== - * This module manages the HID class V1.11 following the "Device Class Definition - * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". - * This driver implements the following aspects of the specification: - * - The Boot Interface Subclass - * - Usage Page : Generic Desktop - * - Usage : Vendor - * - Collection : Application - * - * @note In HS mode and when the DMA is used, all variables and data structures - * dealing with the DMA during the transaction process should be 32-bit aligned. - * - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ -#include "os_helpers.h" -#include "os_io_seproxyhal.h" - - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_hid.h" -#include "usbd_hid_impl.h" -#include "usbd_ctlreq.h" - -#include "usbd_core.h" -#include "usbd_conf.h" - - -/** - * @} - */ - - - -/** @defgroup USBD_HID_Private_Functions - * @{ - */ - -/** - * @brief USBD_HID_Setup - * Handle the HID specific requests - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) -{ - uint16_t len = 0; - uint8_t *pbuf = NULL; - - uint8_t val = 0; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - - case HID_REQ_SET_PROTOCOL: - //hhid->Protocol = (uint8_t)(req->wValue); - //USBD_CtlSendStatus(pdev); - break; - - case HID_REQ_GET_PROTOCOL: - //USBD_CtlReceiveStatus(pdev); - - USBD_CtlSendData (pdev, - (uint8_t *)&val, - 1); - break; - - case HID_REQ_SET_IDLE: - //hhid->IdleState = (uint8_t)(req->wValue >> 8); - //USBD_CtlSendStatus(pdev); - break; - - case HID_REQ_GET_IDLE: - //USBD_CtlReceiveStatus(pdev); - - USBD_CtlSendData (pdev, - (uint8_t *)&val, - 1); - break; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - } - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - // 0x22 - if( req->wValue >> 8 == HID_REPORT_DESC) - { - pbuf = USBD_HID_GetReportDescriptor_impl(&len); - len = MIN(len , req->wLength); - } - // 0x21 - else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) - { - pbuf = USBD_HID_GetHidDescriptor_impl(&len); - len = MIN(len, req->wLength); - } - - //USBD_CtlReceiveStatus(pdev); - - USBD_CtlSendData (pdev, - pbuf, - len); - break; - - case USB_REQ_SET_INTERFACE : - //hhid->AltSetting = (uint8_t)(req->wValue); - USBD_CtlSendStatus(pdev); - break; - - case USB_REQ_GET_INTERFACE : - //USBD_CtlReceiveStatus(pdev); - - USBD_CtlSendData (pdev, - (uint8_t *)&val, - 1); - - break; - - } - } - - return USBD_OK; -} - - -/** - * @brief USBD_HID_Init - * Initialize the HID interface - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, - uint8_t cfgidx) -{ - UNUSED(cfgidx); - - /* Open EP IN */ - USBD_LL_OpenEP(pdev, - HID_EPIN_ADDR, - USBD_EP_TYPE_INTR, - HID_EPIN_SIZE); - - /* Open EP OUT */ - USBD_LL_OpenEP(pdev, - HID_EPOUT_ADDR, - USBD_EP_TYPE_INTR, - HID_EPOUT_SIZE); - - /* Prepare Out endpoint to receive 1st packet */ - USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR, HID_EPOUT_SIZE); - - /* garbles the usb com visibly - // transmit a first empty reply on the IN endpoint - USBD_LL_Transmit (pdev, - HID_EPIN_ADDR, - NULL, - 0); - */ - return USBD_OK; -} - -/** - * @brief USBD_HID_Init - * DeInitialize the HID layer - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, - uint8_t cfgidx) -{ - UNUSED(pdev); - UNUSED(cfgidx); - // /* Close HID EP IN */ - // USBD_LL_CloseEP(pdev, - // HID_EPIN_ADDR); - - // /* Close HID EP OUT */ - // USBD_LL_CloseEP(pdev, - // HID_EPOUT_ADDR); - - return USBD_OK; -} - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h b/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h deleted file mode 100644 index 37937dfcb..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h +++ /dev/null @@ -1,169 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_conf_template.h - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief Header file for the usbd_conf_template.c file - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CONF_TEMPLATE_H -#define __USBD_CONF_TEMPLATE_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32fxxx.h" /* replace 'stm32xxx' with your HAL driver header filename, ex: stm32f4xx.h */ -#include -#include -#include - -/** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_CONF - * @brief USB device low level driver configuration file - * @{ - */ - -/** @defgroup USBD_CONF_Exported_Defines - * @{ - */ - -#define USBD_MAX_NUM_INTERFACES 1 -#define USBD_MAX_NUM_CONFIGURATION 1 -#define USBD_MAX_STR_DESC_SIZ 0x100 -#define USBD_SUPPORT_USER_STRING 0 -#define USBD_SELF_POWERED 1 -#define USBD_DEBUG_LEVEL 2 - -/* MSC Class Config */ -#define MSC_MEDIA_PACKET 8192 - -/* CDC Class Config */ -#define USBD_CDC_INTERVAL 2000 - - /* DFU Class Config */ -#define USBD_DFU_MAX_ITF_NUM 1 -#define USBD_DFU_XFERS_IZE 1024 - - /* AUDIO Class Config */ -#define USBD_AUDIO_FREQ 22100 - -/** @defgroup USBD_Exported_Macros - * @{ - */ - - /* Memory management macros */ -#define USBD_malloc malloc -#define USBD_free free -#define USBD_memset memset -#define USBD_memcpy memcpy - - /* DEBUG macros */ - - -#if (USBD_DEBUG_LEVEL > 0) -#define USBD_UsrLog(...) printf(__VA_ARGS__);\ - printf("\n"); -#else -#define USBD_UsrLog(...) -#endif - - -#if (USBD_DEBUG_LEVEL > 1) - -#define USBD_ErrLog(...) printf("ERROR: ") ;\ - printf(__VA_ARGS__);\ - printf("\n"); -#else -#define USBD_ErrLog(...) -#endif - - -#if (USBD_DEBUG_LEVEL > 2) -#define USBD_DbgLog(...) printf("DEBUG : ") ;\ - printf(__VA_ARGS__);\ - printf("\n"); -#else -#define USBD_DbgLog(...) -#endif - -/** - * @} - */ - - - -/** - * @} - */ - - -/** @defgroup USBD_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USBD_CONF_TEMPLATE_H */ - - -/** - * @} - */ - -/** - * @} - */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_core.h deleted file mode 100644 index a1c0f2bd1..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_core.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_core.h - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief Header file for usbd_core.c file - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CORE_H -#define __USBD_CORE_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_conf.h" -#include "usbd_def.h" -#include "usbd_ctlreq.h" - -/** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_CORE - * @brief This file is the Header file for usbd_core.c file - * @{ - */ - - -/** @defgroup USBD_CORE_Exported_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ -#define USBD_SOF USBD_LL_SOF - -// the USB device -extern USBD_HandleTypeDef USBD_Device; -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_FunctionsPrototype - * @{ - */ -USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); -USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); -/** - * @brief USBD_RegisterClassForInterface - * Link class driver to Device Core. - * @param interfaceidx: The interface index (starting 0) for which the class is registered - * @param pDevice : Device Handle - * @param pclass: Class handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_RegisterClassForInterface(uint8_t interfaceidx, USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); - -USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); -USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); - -USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); -USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata, apdu_buffer_t *); -USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata); - -USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); -USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); - -USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); -USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); - -USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); - -/* USBD Low Level Driver */ -USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev); -USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t ep_type, - uint16_t ep_mps); - -USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); -USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); -USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); -USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); -uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); -USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr); -USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t size); - -USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint16_t size); - -uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr); -void USBD_LL_Delay (uint32_t Delay); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USBD_CORE_H */ - -/** - * @} - */ - -/** -* @} -*/ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - - - diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h b/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h deleted file mode 100644 index 43988291d..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_req.h - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief Header file for the usbd_req.c file - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_REQUEST_H -#define __USB_REQUEST_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - - -/** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_REQ - * @brief header file for the usbd_req.c file - * @{ - */ - -/** @defgroup USBD_REQ_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Exported_Types - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_REQ_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_REQ_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_REQ_Exported_FunctionsPrototype - * @{ - */ - -USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); -USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); -USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); - - -unsigned int usbd_is_valid_intf(USBD_HandleTypeDef *pdev , unsigned int intf); - -// weak version to be overloaded -void USBD_CtlError (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); -void USBD_CtlStall( USBD_HandleTypeDef *pdev); - -void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata); - -void USBD_GetString (uint8_t *desc, uint8_t *unicode, uint16_t *len); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USB_REQUEST_H */ - -/** - * @} - */ - -/** -* @} -*/ - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_def.h deleted file mode 100644 index c559b60c5..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ /dev/null @@ -1,364 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_def.h - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief General defines for the usb device library - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_DEF_H -#define __USBD_DEF_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_conf.h" -#include "os_io.h" - -/** @addtogroup STM32_USBD_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USB_DEF - * @brief general defines for the usb device library file - * @{ - */ - -/** @defgroup USB_DEF_Exported_Defines - * @{ - */ - -#ifndef NULL -#define NULL 0 -#endif - - -#define USB_LEN_DEV_QUALIFIER_DESC 0x0A -#define USB_LEN_DEV_DESC 0x12 -#define USB_LEN_CFG_DESC 0x09 -#define USB_LEN_IF_DESC 0x09 -#define USB_LEN_EP_DESC 0x07 -#define USB_LEN_OTG_DESC 0x03 -#define USB_LEN_LANGID_STR_DESC 0x04 -#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09 - -#define USBD_IDX_LANGID_STR 0x00 -#define USBD_IDX_MFC_STR 0x01 -#define USBD_IDX_PRODUCT_STR 0x02 -#define USBD_IDX_SERIAL_STR 0x03 -#define USBD_IDX_CONFIG_STR 0x04 -#define USBD_IDX_INTERFACE_STR 0x05 - -#define USB_REQ_TYPE_STANDARD 0x00 -#define USB_REQ_TYPE_CLASS 0x20 -#define USB_REQ_TYPE_VENDOR 0x40 -#define USB_REQ_TYPE_MASK 0x60 - -#define USB_REQ_RECIPIENT_DEVICE 0x00 -#define USB_REQ_RECIPIENT_INTERFACE 0x01 -#define USB_REQ_RECIPIENT_ENDPOINT 0x02 -#define USB_REQ_RECIPIENT_MASK 0x03 - -#define USB_REQ_GET_STATUS 0x00 -#define USB_REQ_CLEAR_FEATURE 0x01 -#define USB_REQ_SET_FEATURE 0x03 -#define USB_REQ_SET_ADDRESS 0x05 -#define USB_REQ_GET_DESCRIPTOR 0x06 -#define USB_REQ_SET_DESCRIPTOR 0x07 -#define USB_REQ_GET_CONFIGURATION 0x08 -#define USB_REQ_SET_CONFIGURATION 0x09 -#define USB_REQ_GET_INTERFACE 0x0A -#define USB_REQ_SET_INTERFACE 0x0B -#define USB_REQ_SYNCH_FRAME 0x0C - -#define USB_DESC_TYPE_DEVICE 1 -#define USB_DESC_TYPE_CONFIGURATION 2 -#define USB_DESC_TYPE_STRING 3 -#define USB_DESC_TYPE_INTERFACE 4 -#define USB_DESC_TYPE_ENDPOINT 5 -#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 -#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 -#define USB_DESC_TYPE_BOS 0x0F - -#define USB_CONFIG_REMOTE_WAKEUP 2 -#define USB_CONFIG_SELF_POWERED 1 - -#define USB_FEATURE_EP_HALT 0 -#define USB_FEATURE_REMOTE_WAKEUP 1 -#define USB_FEATURE_TEST_MODE 2 - -#define USB_DEVICE_CAPABITY_TYPE 0x10 - -#define USB_HS_MAX_PACKET_SIZE 512 -#define USB_FS_MAX_PACKET_SIZE 64 -#define USB_MAX_EP0_SIZE 64 - -/* Device Status */ -#define USBD_STATE_DEFAULT 1 -#define USBD_STATE_ADDRESSED 2 -#define USBD_STATE_CONFIGURED 3 -#define USBD_STATE_SUSPENDED 4 - - -/* EP0 State */ -#define USBD_EP0_IDLE 0 -#define USBD_EP0_SETUP 1 -#define USBD_EP0_DATA_IN 2 -#define USBD_EP0_DATA_OUT 3 -#define USBD_EP0_STATUS_IN 4 -#define USBD_EP0_STATUS_OUT 5 -#define USBD_EP0_STALL 6 - -#define USBD_EP_TYPE_CTRL 0 -#define USBD_EP_TYPE_ISOC 1 -#define USBD_EP_TYPE_BULK 2 -#define USBD_EP_TYPE_INTR 3 - - -/** - * @} - */ - - -/** @defgroup USBD_DEF_Exported_TypesDefinitions - * @{ - */ - -typedef struct usb_setup_req -{ - - uint8_t bmRequest; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -}USBD_SetupReqTypedef; - -struct _USBD_HandleTypeDef; - -typedef uint8_t (*Init_t) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); -typedef uint8_t (*DeInit_t) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); -/* Control Endpoints*/ -typedef uint8_t (*Setup_t) (struct _USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req); -typedef uint8_t (*EP0_TxSent_t) (struct _USBD_HandleTypeDef *pdev ); -typedef uint8_t (*EP0_RxReady_t) (struct _USBD_HandleTypeDef *pdev ); -/* Class Specific Endpoints*/ -typedef uint8_t (*DataIn_t) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); -typedef uint8_t (*DataOut_t) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t* pData, apdu_buffer_t *); -typedef uint8_t (*SOF_t) (struct _USBD_HandleTypeDef *pdev); -typedef uint8_t (*IsoINIncomplete_t) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); -typedef uint8_t (*IsoOUTIncomplete_t) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); - -typedef uint8_t *(*GetHSConfigDescriptor_t)(uint16_t *length); -typedef uint8_t *(*GetFSConfigDescriptor_t)(uint16_t *length); -typedef uint8_t *(*GetOtherSpeedConfigDescriptor_t)(uint16_t *length); -typedef uint8_t *(*GetDeviceQualifierDescriptor_t)(uint16_t *length); -#if (USBD_SUPPORT_USER_STRING == 1) -typedef uint8_t *(*GetUsrStrDescriptor_t)(struct _USBD_HandleTypeDef *pdev ,uint8_t index, uint16_t *length); -#endif - -typedef struct _Device_cb -{ - Init_t Init; - DeInit_t DeInit; - /* Control Endpoints*/ - Setup_t Setup; - EP0_TxSent_t EP0_TxSent; - EP0_RxReady_t EP0_RxReady; - /* Class Specific Endpoints*/ - DataIn_t DataIn; - DataOut_t DataOut; - SOF_t SOF; - IsoINIncomplete_t IsoINIncomplete; - IsoOUTIncomplete_t IsoOUTIncomplete; - - GetHSConfigDescriptor_t GetHSConfigDescriptor; - GetFSConfigDescriptor_t GetFSConfigDescriptor; - GetOtherSpeedConfigDescriptor_t GetOtherSpeedConfigDescriptor; - GetDeviceQualifierDescriptor_t GetDeviceQualifierDescriptor; -#if (USBD_SUPPORT_USER_STRING == 1) - GetUsrStrDescriptor_t GetUsrStrDescriptor; -#endif - -} USBD_ClassTypeDef; - -/* Following USB Device Speed */ -typedef enum -{ - USBD_SPEED_HIGH = 0, - USBD_SPEED_FULL = 1, - USBD_SPEED_LOW = 2, -}USBD_SpeedTypeDef; - -/* Following USB Device status */ -typedef enum { - USBD_OK = 0, - USBD_BUSY, - USBD_FAIL, -}USBD_StatusTypeDef; - -typedef uint8_t *(*GetDeviceDescriptor_t)( USBD_SpeedTypeDef speed , uint16_t *length); -typedef uint8_t *(*GetLangIDStrDescriptor_t)( USBD_SpeedTypeDef speed , uint16_t *length); -typedef uint8_t *(*GetManufacturerStrDescriptor_t)( USBD_SpeedTypeDef speed , uint16_t *length); -typedef uint8_t *(*GetProductStrDescriptor_t)( USBD_SpeedTypeDef speed , uint16_t *length); -typedef uint8_t *(*GetSerialStrDescriptor_t)( USBD_SpeedTypeDef speed , uint16_t *length); -typedef uint8_t *(*GetConfigurationStrDescriptor_t)( USBD_SpeedTypeDef speed , uint16_t *length); -typedef uint8_t *(*GetInterfaceStrDescriptor_t)( USBD_SpeedTypeDef speed , uint16_t *length); -typedef uint8_t *(*GetBOSDescriptor_t)( USBD_SpeedTypeDef speed , uint16_t *length); - -/* USB Device descriptors structure */ -typedef struct -{ - GetDeviceDescriptor_t GetDeviceDescriptor; - GetLangIDStrDescriptor_t GetLangIDStrDescriptor; - GetManufacturerStrDescriptor_t GetManufacturerStrDescriptor; - GetProductStrDescriptor_t GetProductStrDescriptor; - GetSerialStrDescriptor_t GetSerialStrDescriptor; - GetConfigurationStrDescriptor_t GetConfigurationStrDescriptor; - GetInterfaceStrDescriptor_t GetInterfaceStrDescriptor; - GetBOSDescriptor_t GetBOSDescriptor; -} USBD_DescriptorsTypeDef; - -/* USB Device handle structure */ -typedef struct -{ - uint32_t status; - uint32_t total_length; - uint32_t rem_length; - uint32_t maxpacket; -} USBD_EndpointTypeDef; - -/* USB Device handle structure */ -typedef struct _USBD_HandleTypeDef -{ - uint8_t id; - uint32_t dev_config; - uint32_t dev_default_config; - uint32_t dev_config_status; - USBD_SpeedTypeDef dev_speed; - USBD_EndpointTypeDef ep_in[IO_USB_MAX_ENDPOINTS]; - USBD_EndpointTypeDef ep_out[IO_USB_MAX_ENDPOINTS]; - uint32_t ep0_state; - uint32_t ep0_data_len; - uint8_t dev_state; - uint8_t dev_old_state; - uint8_t dev_address; - uint8_t dev_connection_status; - uint8_t dev_test_mode; - uint32_t dev_remote_wakeup; - - USBD_SetupReqTypedef request; - USBD_DescriptorsTypeDef *pDesc; - struct { - USBD_ClassTypeDef *pClass; - void *pClassData; - } interfacesClass [USBD_MAX_NUM_INTERFACES]; - void *pUserData; - void *pData; -} USBD_HandleTypeDef; - -/** - * @} - */ - - - -/** @defgroup USBD_DEF_Exported_Macros - * @{ - */ -#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ - (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) - -#define LOBYTE(x) ((uint8_t)((x) & 0x00FF)) -#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00) >>8)) -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -#if defined ( __GNUC__ ) - #ifndef __weak - #define __weak __attribute__((weak)) - #endif /* __weak */ - #ifndef __packed - #define __packed __attribute__((__packed__)) - #endif /* __packed */ -#endif /* __GNUC__ */ - - -/* In HS mode and when the DMA is used, all variables and data structures dealing - with the DMA during the transaction process should be 4-bytes aligned */ - -#if defined (__GNUC__) /* GNU Compiler */ - #define __ALIGN_END __attribute__ ((aligned (4))) - #define __ALIGN_BEGIN -#else - #define __ALIGN_END - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #elif defined (__TASKING__) /* TASKING Compiler */ - #define __ALIGN_BEGIN __align(4) - #endif /* __CC_ARM */ -#endif /* __GNUC__ */ - - -/** - * @} - */ - -/** @defgroup USBD_DEF_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_DEF_Exported_FunctionsPrototype - * @{ - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USBD_DEF_H */ - -/** - * @} - */ - -/** -* @} -*/ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h b/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h deleted file mode 100644 index 787947966..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h +++ /dev/null @@ -1,128 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ioreq.h - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief Header file for the usbd_ioreq.c file - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_IOREQ_H -#define __USBD_IOREQ_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" -#include "usbd_core.h" - -/** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_IOREQ - * @brief header file for the usbd_ioreq.c file - * @{ - */ - -/** @defgroup USBD_IOREQ_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Exported_Types - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_IOREQ_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_IOREQ_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype - * @{ - */ - -USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, - uint8_t *buf, - uint16_t len); - -USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev); - -USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev); - -uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev , - uint8_t epnum); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __USBD_IOREQ_H */ - -/** - * @} - */ - -/** -* @} -*/ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c.no b/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c.no deleted file mode 100644 index 56aedb42e..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c.no +++ /dev/null @@ -1,212 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_conf_template.c - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief USB Device configuration and interface file - * This template should be copied to the user folder, renamed and customized - * following user needs. - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ -/** - * @brief Initializes the Low Level portion of the Device driver. - * @param pdev: Device handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) -{ - return USBD_OK; -} - -/** - * @brief De-Initializes the Low Level portion of the Device driver. - * @param pdev: Device handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) -{ - return USBD_OK; -} - -/** - * @brief Starts the Low Level portion of the Device driver. - * @param pdev: Device handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) -{ - return USBD_OK; -} - -/** - * @brief Stops the Low Level portion of the Device driver. - * @param pdev: Device handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) -{ - return USBD_OK; -} - -/** - * @brief Opens an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @param ep_type: Endpoint Type - * @param ep_mps: Endpoint Max Packet Size - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t ep_type, - uint16_t ep_mps) -{ - return USBD_OK; -} - -/** - * @brief Closes an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - return USBD_OK; -} - -/** - * @brief Flushes an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - return USBD_OK; -} - -/** - * @brief Sets a Stall condition on an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - return USBD_OK; -} - -/** - * @brief Clears a Stall condition on an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - return USBD_OK; -} - -/** - * @brief Returns Stall condition. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval Stall (1: Yes, 0: No) - */ -uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - return 0; -} - -/** - * @brief Assigns a USB address to the device. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) -{ - return USBD_OK; -} - -/** - * @brief Transmits data over an endpoint. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @param pbuf: Pointer to data to be sent - * @param size: Data size - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t size) -{ - return USBD_OK; -} - -/** - * @brief Prepares an endpoint for reception. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @param pbuf: Pointer to data to be received - * @param size: Data size - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t size) -{ - return USBD_OK; -} - -/** - * @brief Returns the last transferred packet size. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval Recived Data Size - */ -uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - return 0; -} - -/** - * @brief Delays routine for the USB Device Library. - * @param Delay: Delay in ms - * @retval None - */ -void USBD_LL_Delay(uint32_t Delay) -{ -} -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_core.c b/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_core.c deleted file mode 100644 index b958b038f..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_core.c +++ /dev/null @@ -1,573 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_core.c - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief This file provides all the USBD core functions. - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "os_helpers.h" -#include "os_io.h" -#include "os_pic.h" -#include "usbd_core.h" -#include "usbd_ioreq.h" -#include - -/** @addtogroup STM32_USBD_DEVICE_LIBRARY -* @{ -*/ - - -/** @defgroup USBD_CORE -* @brief usbd core module -* @{ -*/ - -USBD_HandleTypeDef USBD_Device; - - -/** @defgroup USBD_CORE_Private_Functions -* @{ -*/ - -/** -* @brief USBD_Init -* Initializes the device stack and load the class driver -* @param pdev: device instance -* @param pdesc: Descriptor structure address -* @param id: Low level core index -* @retval None -*/ -USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id) -{ - /* Check whether the USB Host handle is valid */ - if(pdev == NULL) - { - USBD_ErrLog("Invalid Device handle"); - return USBD_FAIL; - } - - memset(pdev, 0, sizeof(USBD_HandleTypeDef)); - - /* Assign USBD Descriptors */ - if(pdesc != NULL) - { - pdev->pDesc = pdesc; - } - - /* Set Device initial State */ - pdev->dev_state = USBD_STATE_DEFAULT; - pdev->id = id; - /* Initialize low level driver */ - USBD_LL_Init(pdev); - - return USBD_OK; -} - -/** -* @brief USBD_DeInit -* Re-Initialize th device library -* @param pdev: device instance -* @retval status: status -*/ -USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) -{ - /* Set Default State */ - pdev->dev_state = USBD_STATE_DEFAULT; - - /* Free Class Resources */ - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if(pdev->interfacesClass[intf].pClass != NULL) { - ((DeInit_t)PIC(pdev->interfacesClass[intf].pClass->DeInit))(pdev, pdev->dev_config); - } - } - - /* Stop the low level driver */ - USBD_LL_Stop(pdev); - - /* Initialize low level driver */ - USBD_LL_DeInit(pdev); - - return USBD_OK; -} - -USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass) { - return USBD_RegisterClassForInterface(0, pdev, pclass); -} - -/** - * @brief USBD_RegisterClass - * Link class driver to Device Core. - * @param pDevice : Device Handle - * @param pclass: Class handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_RegisterClassForInterface(uint8_t interfaceidx, USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass) -{ - USBD_StatusTypeDef status = USBD_OK; - if(pclass != 0) - { - if (interfaceidx < USBD_MAX_NUM_INTERFACES) { - /* link the class to the USB Device handle */ - pdev->interfacesClass[interfaceidx].pClass = pclass; - } - status = USBD_OK; - } - else - { - USBD_ErrLog("Invalid Class handle"); - status = USBD_FAIL; - } - - return status; -} - -/** - * @brief USBD_Start - * Start the USB Device Core. - * @param pdev: Device Handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev) -{ - - /* Start the low level driver */ - USBD_LL_Start(pdev); - - return USBD_OK; -} - -/** - * @brief USBD_Stop - * Stop the USB Device Core. - * @param pdev: Device Handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev) -{ - /* Free Class Resources */ - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if(usbd_is_valid_intf(pdev, intf)) { - ((DeInit_t)PIC(pdev->interfacesClass[intf].pClass->DeInit))(pdev, pdev->dev_config); - } - } - - /* Stop the low level driver */ - USBD_LL_Stop(pdev); - - return USBD_OK; -} - -/** -* @brief USBD_RunTestMode -* Launch test mode process -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev) -{ - UNUSED(pdev); - return USBD_OK; -} - - -/** -* @brief USBD_SetClassConfig -* Configure device and start the interface -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status -*/ - -USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) -{ - /* Set configuration and Start the Class*/ - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if(usbd_is_valid_intf(pdev, intf)) { - ((Init_t)PIC(pdev->interfacesClass[intf].pClass->Init))(pdev, cfgidx); - } - } - - return USBD_OK; -} - -/** -* @brief USBD_ClrClassConfig -* Clear current configuration -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status: USBD_StatusTypeDef -*/ -USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) -{ - /* Clear configuration and De-initialize the Class process*/ - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if(usbd_is_valid_intf(pdev, intf)) { - ((DeInit_t)PIC(pdev->interfacesClass[intf].pClass->DeInit))(pdev, cfgidx); - } - } - return USBD_OK; -} - - -/** -* @brief USBD_SetupStage -* Handle the setup stage -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) -{ - USBD_ParseSetupRequest(&pdev->request, psetup); - - pdev->ep0_state = USBD_EP0_SETUP; - pdev->ep0_data_len = pdev->request.wLength; - - switch (pdev->request.bmRequest & 0x1F) - { - case USB_REQ_RECIPIENT_DEVICE: - USBD_StdDevReq (pdev, &pdev->request); - break; - - case USB_REQ_RECIPIENT_INTERFACE: - USBD_StdItfReq(pdev, &pdev->request); - break; - - case USB_REQ_RECIPIENT_ENDPOINT: - USBD_StdEPReq(pdev, &pdev->request); - break; - - default: - USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80); - break; - } - return USBD_OK; -} - -/** -* @brief USBD_DataOutStage -* Handle data OUT stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata, apdu_buffer_t * apdu_buffer) -{ - USBD_EndpointTypeDef *pep; - - if(epnum == 0) - { - pep = &pdev->ep_out[0]; - - if ( pdev->ep0_state == USBD_EP0_DATA_OUT) - { - if(pep->rem_length > pep->maxpacket) - { - pep->rem_length -= pep->maxpacket; - - USBD_CtlContinueRx (pdev, - pdata, - MIN(pep->rem_length ,pep->maxpacket)); - } - else - { - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if(usbd_is_valid_intf(pdev, intf) && (pdev->interfacesClass[intf].pClass->EP0_RxReady != NULL)&& - (pdev->dev_state == USBD_STATE_CONFIGURED)) - { - ((EP0_RxReady_t)PIC(pdev->interfacesClass[intf].pClass->EP0_RxReady))(pdev); - } - } - USBD_CtlSendStatus(pdev); - } - } - } - else { - - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if( usbd_is_valid_intf(pdev, intf) && (pdev->interfacesClass[intf].pClass->DataOut != NULL)&& - (pdev->dev_state == USBD_STATE_CONFIGURED)) - { - ((DataOut_t)PIC(pdev->interfacesClass[intf].pClass->DataOut))(pdev, epnum, pdata, apdu_buffer); - } - } - } - return USBD_OK; -} - -/** -* @brief USBD_DataInStage -* Handle data in stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uint8_t *pdata) -{ - USBD_EndpointTypeDef *pep; - UNUSED(pdata); - - if(epnum == 0) - { - pep = &pdev->ep_in[0]; - - if ( pdev->ep0_state == USBD_EP0_DATA_IN) - { - if(pep->rem_length > pep->maxpacket) - { - pep->rem_length -= pep->maxpacket; - pdev->pData = (uint8_t *)pdev->pData + pep->maxpacket; - - /* Prepare endpoint for premature end of transfer */ - /* - USBD_LL_PrepareReceive (pdev, - 0, - 0); - */ - - USBD_CtlContinueSendData (pdev, - (uint8_t *)pdev->pData, - pep->rem_length); - - } - else - { /* last packet is MPS multiple, so send ZLP packet */ - if((pep->maxpacket != 0) && - (pep->total_length % pep->maxpacket == 0) && - (pep->total_length >= pep->maxpacket) && - (pep->total_length < pdev->ep0_data_len )) - { - - /* Prepare endpoint for premature end of transfer */ - /* - USBD_LL_PrepareReceive (pdev, - 0, - 0); - */ - - USBD_CtlContinueSendData(pdev , NULL, 0); - pdev->ep0_data_len = 0; - - } - else - { - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if(usbd_is_valid_intf(pdev, intf) && (pdev->interfacesClass[intf].pClass->EP0_TxSent != NULL)&& - (pdev->dev_state == USBD_STATE_CONFIGURED)) - { - ((EP0_RxReady_t)PIC(pdev->interfacesClass[intf].pClass->EP0_TxSent))(pdev); - } - } - USBD_CtlReceiveStatus(pdev); - } - } - } - if (pdev->dev_test_mode == 1) - { - USBD_RunTestMode(pdev); - pdev->dev_test_mode = 0; - } - } - else { - uint8_t intf; - for (intf = 0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if( usbd_is_valid_intf(pdev, intf) && (pdev->interfacesClass[intf].pClass->DataIn != NULL)&& - (pdev->dev_state == USBD_STATE_CONFIGURED)) - { - ((DataIn_t)PIC(pdev->interfacesClass[intf].pClass->DataIn))(pdev, epnum); - } - } - } - return USBD_OK; -} - -/** -* @brief USBD_LL_Reset -* Handle Reset event -* @param pdev: device instance -* @retval status -*/ - -USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) -{ - pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; - - - pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; - /* Upon Reset call user call back */ - pdev->dev_state = USBD_STATE_DEFAULT; - - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if( usbd_is_valid_intf(pdev, intf)) - { - ((DeInit_t)PIC(pdev->interfacesClass[intf].pClass->DeInit))(pdev, pdev->dev_config); - } - } - - return USBD_OK; -} - - - - -/** -* @brief USBD_LL_Reset -* Handle Reset event -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed) -{ - pdev->dev_speed = speed; - return USBD_OK; -} - -/** -* @brief USBD_Suspend -* Handle Suspend event -* @param pdev: device instance -* @retval status -*/ - -USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) -{ - UNUSED(pdev); - // Ignored, gently - //pdev->dev_old_state = pdev->dev_state; - //pdev->dev_state = USBD_STATE_SUSPENDED; - return USBD_OK; -} - -/** -* @brief USBD_Resume -* Handle Resume event -* @param pdev: device instance -* @retval status -*/ - -USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) -{ - UNUSED(pdev); - // Ignored, gently - //pdev->dev_state = pdev->dev_old_state; - return USBD_OK; -} - -/** -* @brief USBD_SOF -* Handle SOF event -* @param pdev: device instance -* @retval status -*/ - -USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) -{ - if(pdev->dev_state == USBD_STATE_CONFIGURED) - { - uint8_t intf; - for (intf =0; intf < USBD_MAX_NUM_INTERFACES; intf++) { - if( usbd_is_valid_intf(pdev, intf) && pdev->interfacesClass[intf].pClass->SOF != NULL) - { - ((SOF_t)PIC(pdev->interfacesClass[intf].pClass->SOF))(pdev); - } - } - } - return USBD_OK; -} - -/** -* @brief USBD_IsoINIncomplete -* Handle iso in incomplete event -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) -{ - UNUSED(pdev); - UNUSED(epnum); - return USBD_OK; -} - -/** -* @brief USBD_IsoOUTIncomplete -* Handle iso out incomplete event -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) -{ - UNUSED(pdev); - UNUSED(epnum); - return USBD_OK; -} - -/** -* @brief USBD_DevConnected -* Handle device connection event -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) -{ - UNUSED(pdev); - return USBD_OK; -} - -/** -* @brief USBD_DevDisconnected -* Handle device disconnection event -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) -{ - /* Free Class Resources */ - pdev->dev_state = USBD_STATE_DEFAULT; - // done upon reset // ((DeInit_t)PIC(pdev->pClass->DeInit))(pdev, pdev->dev_config); - - return USBD_OK; -} -/** -* @} -*/ - - -/** -* @} -*/ - - -/** -* @} -*/ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c deleted file mode 100644 index 4e0b85588..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c +++ /dev/null @@ -1,805 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_req.c - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief This file provides the standard USB requests following chapter 9. - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ -#include "os_helpers.h" -#include "os_io.h" -#include "os_pic.h" - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ctlreq.h" -#include "usbd_ioreq.h" - - -/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_REQ - * @brief USB standard requests module - * @{ - */ - -/** @defgroup USBD_REQ_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_FunctionPrototypes - * @{ - */ -void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req); - -void USBD_SetAddress(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req); - -void USBD_SetConfig(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req); - -void USBD_GetConfig(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req); - -void USBD_GetStatus(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req); - -void USBD_SetFeature(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req); - -void USBD_ClrFeature(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req); - -uint8_t USBD_GetLen(uint8_t *buf); - -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Functions - * @{ - */ - -unsigned int usbd_is_valid_intf(USBD_HandleTypeDef *pdev , unsigned int intf) { - return intf < USBD_MAX_NUM_INTERFACES && pdev->interfacesClass[intf].pClass != NULL; -} - -/** -* @brief USBD_StdDevReq -* Handle standard usb device requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) -{ - USBD_StatusTypeDef ret = USBD_OK; - - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - - USBD_GetDescriptor (pdev, req) ; - break; - - case USB_REQ_SET_ADDRESS: - USBD_SetAddress(pdev, req); - break; - - case USB_REQ_SET_CONFIGURATION: - USBD_SetConfig (pdev , req); - break; - - case USB_REQ_GET_CONFIGURATION: - USBD_GetConfig (pdev , req); - break; - - case USB_REQ_GET_STATUS: - USBD_GetStatus (pdev , req); - break; - - - case USB_REQ_SET_FEATURE: - USBD_SetFeature (pdev , req); - break; - - case USB_REQ_CLEAR_FEATURE: - USBD_ClrFeature (pdev , req); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - - return ret; -} - -/** -* @brief USBD_StdItfReq -* Handle standard usb interface requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) -{ - USBD_StatusTypeDef ret = USBD_OK; - - switch (pdev->dev_state) - { - case USBD_STATE_CONFIGURED: - - if (usbd_is_valid_intf(pdev, LOBYTE(req->wIndex))) - { - ((Setup_t)PIC(pdev->interfacesClass[LOBYTE(req->wIndex)].pClass->Setup)) (pdev, req); - - if((req->wLength == 0)&& (ret == USBD_OK)) - { - USBD_CtlSendStatus(pdev); - } - } - else - { - USBD_CtlError(pdev , req); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - return USBD_OK; -} - -/** -* @brief USBD_StdEPReq -* Handle standard usb endpoint requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) -{ - - uint8_t ep_addr; - USBD_StatusTypeDef ret = USBD_OK; - ep_addr = LOBYTE(req->wIndex); - - // avoid processing for out of bounds endpoints - if ((ep_addr & 0x7F) > IO_USB_MAX_ENDPOINTS) { - USBD_CtlError(pdev , req); - return ret; - } - - // Note: this function consider endpoints are assigned to interfaces as a bijection (endpoint - // 0x01 and 0x81 are assigend to interface 1). This is done to avoid a long endpoint lookup - // with the declared interfaces to handle the corresponding setup packet. - // Moreover, endpoint directed setup packet are really uncommon. - - /* Check if it is a class request */ - if ((req->bmRequest & 0x60) == 0x20 && usbd_is_valid_intf(pdev, LOBYTE(req->wIndex))) - { - ((Setup_t)PIC(pdev->interfacesClass[LOBYTE(req->wIndex)].pClass->Setup)) (pdev, req); - - return USBD_OK; - } - - - switch (req->bRequest) - { - - case USB_REQ_SET_FEATURE : - - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - USBD_LL_StallEP(pdev , ep_addr); - } - break; - - case USBD_STATE_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - USBD_LL_StallEP(pdev , ep_addr); - - } - } - if(usbd_is_valid_intf(pdev, LOBYTE(req->wIndex))) { - ((Setup_t)PIC(pdev->interfacesClass[LOBYTE(req->wIndex)].pClass->Setup)) (pdev, req); - } - USBD_CtlSendStatus(pdev); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - case USB_REQ_CLEAR_FEATURE : - - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - USBD_LL_StallEP(pdev , ep_addr); - } - break; - - case USBD_STATE_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr & 0x7F) != 0x00) - { - USBD_LL_ClearStallEP(pdev , ep_addr); - - if(usbd_is_valid_intf(pdev, LOBYTE(req->wIndex))) { - ((Setup_t)PIC(pdev->interfacesClass[LOBYTE(req->wIndex)].pClass->Setup)) (pdev, req); - } - } - USBD_CtlSendStatus(pdev); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - case USB_REQ_GET_STATUS: - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if ((ep_addr & 0x7F) != 0x00) - { - USBD_LL_StallEP(pdev , ep_addr); - } - break; - - case USBD_STATE_CONFIGURED: - { - unsigned short status = USBD_LL_IsStallEP(pdev, ep_addr)? 1 : 0; - USBD_CtlSendData (pdev, - (uint8_t *)&status, - 2); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - default: - break; - } - return ret; -} -/** -* @brief USBD_GetDescriptor -* Handle Get Descriptor requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req) -{ - uint16_t len = 0; - uint8_t *pbuf = NULL; - - - switch (req->wValue >> 8) - { -#if (USBD_LPM_ENABLED == 1) - case USB_DESC_TYPE_BOS: - if(pdev->pDesc->GetBOSDescriptor != NULL) { - pbuf = ((GetBOSDescriptor_t)PIC(pdev->pDesc->GetBOSDescriptor))(pdev->dev_speed, &len); - } - else { - goto default_error; - } - break; -#endif - case USB_DESC_TYPE_DEVICE: - pbuf = ((GetDeviceDescriptor_t)PIC(pdev->pDesc->GetDeviceDescriptor))(pdev->dev_speed, &len); - break; - - case USB_DESC_TYPE_CONFIGURATION: - if(pdev->interfacesClass[0].pClass != NULL) { - if(pdev->dev_speed == USBD_SPEED_HIGH ) - { - pbuf = (uint8_t *)((GetHSConfigDescriptor_t)PIC(pdev->interfacesClass[0].pClass->GetHSConfigDescriptor))(&len); - //pbuf[1] = USB_DESC_TYPE_CONFIGURATION; CONST BUFFER KTHX - } - else - { - pbuf = (uint8_t *)((GetFSConfigDescriptor_t)PIC(pdev->interfacesClass[0].pClass->GetFSConfigDescriptor))(&len); - //pbuf[1] = USB_DESC_TYPE_CONFIGURATION; CONST BUFFER KTHX - } - } - break; - - case USB_DESC_TYPE_STRING: - switch ((uint8_t)(req->wValue)) - { - case USBD_IDX_LANGID_STR: - pbuf = ((GetLangIDStrDescriptor_t)PIC(pdev->pDesc->GetLangIDStrDescriptor))(pdev->dev_speed, &len); - break; - - case USBD_IDX_MFC_STR: - pbuf = ((GetManufacturerStrDescriptor_t)PIC(pdev->pDesc->GetManufacturerStrDescriptor))(pdev->dev_speed, &len); - break; - - case USBD_IDX_PRODUCT_STR: - pbuf = ((GetProductStrDescriptor_t)PIC(pdev->pDesc->GetProductStrDescriptor))(pdev->dev_speed, &len); - break; - - case USBD_IDX_SERIAL_STR: - pbuf = ((GetSerialStrDescriptor_t)PIC(pdev->pDesc->GetSerialStrDescriptor))(pdev->dev_speed, &len); - break; - - case USBD_IDX_CONFIG_STR: - pbuf = ((GetConfigurationStrDescriptor_t)PIC(pdev->pDesc->GetConfigurationStrDescriptor))(pdev->dev_speed, &len); - break; - - case USBD_IDX_INTERFACE_STR: - pbuf = ((GetInterfaceStrDescriptor_t)PIC(pdev->pDesc->GetInterfaceStrDescriptor))(pdev->dev_speed, &len); - break; - - default: -#if (USBD_SUPPORT_USER_STRING == 1) - if(pdev->interfacesClass[0].pClass != NULL) { - pbuf = ((GetUsrStrDescriptor_t)PIC(pdev->interfacesClass[0].pClass->GetUsrStrDescriptor))(pdev, (req->wValue) , &len); - } - break; -#else - goto default_error; -#endif - } - break; - case USB_DESC_TYPE_DEVICE_QUALIFIER: - - if(pdev->dev_speed == USBD_SPEED_HIGH && pdev->interfacesClass[0].pClass != NULL ) - { - pbuf = (uint8_t *)((GetDeviceQualifierDescriptor_t)PIC(pdev->interfacesClass[0].pClass->GetDeviceQualifierDescriptor))(&len); - break; - } - else - { - goto default_error; - } - - case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: - if(pdev->dev_speed == USBD_SPEED_HIGH && pdev->interfacesClass[0].pClass != NULL) - { - pbuf = (uint8_t *)((GetOtherSpeedConfigDescriptor_t)PIC(pdev->interfacesClass[0].pClass->GetOtherSpeedConfigDescriptor))(&len); - // pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; CONST BUFFER KTHX - break; - } - else - { - goto default_error; - } - - default: - default_error: - USBD_CtlError(pdev , req); - return; - } - - if((len != 0)&& (req->wLength != 0)) - { - - len = MIN(len , req->wLength); - - // prepare abort if host does not read the whole data - //USBD_CtlReceiveStatus(pdev); - - // start transfer - USBD_CtlSendData (pdev, - pbuf, - len); - } - -} - -/** -* @brief USBD_SetAddress -* Set device address -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -void USBD_SetAddress(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req) -{ - uint8_t dev_addr; - - if ((req->wIndex == 0) && (req->wLength == 0)) - { - dev_addr = (uint8_t)(req->wValue) & 0x7F; - - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - USBD_CtlError(pdev , req); - } - else - { - pdev->dev_address = dev_addr; - USBD_LL_SetUSBAddress(pdev, dev_addr); - USBD_CtlSendStatus(pdev); - - if (dev_addr != 0) - { - pdev->dev_state = USBD_STATE_ADDRESSED; - } - else - { - pdev->dev_state = USBD_STATE_DEFAULT; - } - } - } - else - { - USBD_CtlError(pdev , req); - } -} - -/** -* @brief USBD_SetConfig -* Handle Set device configuration request -* @param pdev: device instanceUSBD_SetConfig -* @param req: usb request -* @retval status -*/ -void USBD_SetConfig(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req) -{ - - uint8_t cfgidx; - - cfgidx = (uint8_t)(req->wValue); - - if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) - { - USBD_CtlError(pdev , req); - } - else - { - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if (cfgidx) - { - pdev->dev_config = cfgidx; - pdev->dev_state = USBD_STATE_CONFIGURED; - if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) - { - USBD_CtlError(pdev , req); - return; - } - } - USBD_CtlSendStatus(pdev); - break; - - case USBD_STATE_CONFIGURED: - if (cfgidx == 0) - { - pdev->dev_state = USBD_STATE_ADDRESSED; - pdev->dev_config = cfgidx; - USBD_ClrClassConfig(pdev , cfgidx); - USBD_CtlSendStatus(pdev); - } - else if (cfgidx != pdev->dev_config) - { - /* Clear old configuration */ - USBD_ClrClassConfig(pdev , pdev->dev_config); - - /* set new configuration */ - pdev->dev_config = cfgidx; - if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) - { - USBD_CtlError(pdev , req); - return; - } - } - USBD_CtlSendStatus(pdev); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - } -} - -/** -* @brief USBD_GetConfig -* Handle Get device configuration request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -void USBD_GetConfig(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req) -{ - - if (req->wLength != 1) - { - USBD_CtlError(pdev , req); - } - else - { - switch (pdev->dev_state ) - { - case USBD_STATE_ADDRESSED: - pdev->dev_default_config = 0; - USBD_CtlSendData (pdev, - (uint8_t *)&pdev->dev_default_config, - 1); - break; - - case USBD_STATE_CONFIGURED: - USBD_CtlSendData (pdev, - (uint8_t *)&pdev->dev_config, - 1); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - } -} - -/** -* @brief USBD_GetStatus -* Handle Get Status request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -void USBD_GetStatus(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req) -{ - - - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - case USBD_STATE_CONFIGURED: - -#if ( USBD_SELF_POWERED == 1) - pdev->dev_config_status = USB_CONFIG_SELF_POWERED; -#else - pdev->dev_config_status = 0; -#endif - - if (pdev->dev_remote_wakeup) USBD_CtlReceiveStatus(pdev); - { - pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; - } - - USBD_CtlSendData (pdev, - (uint8_t *)& pdev->dev_config_status, - 2); - break; - - default : - USBD_CtlError(pdev , req); - break; - } -} - - -/** -* @brief USBD_SetFeature -* Handle Set device feature request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -void USBD_SetFeature(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req) -{ - - if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) - { - pdev->dev_remote_wakeup = 1; - if(usbd_is_valid_intf(pdev, LOBYTE(req->wIndex))) { - ((Setup_t)PIC(pdev->interfacesClass[LOBYTE(req->wIndex)].pClass->Setup)) (pdev, req); - } - USBD_CtlSendStatus(pdev); - } - -} - - -/** -* @brief USBD_ClrFeature -* Handle clear device feature request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -void USBD_ClrFeature(USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req) -{ - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - case USBD_STATE_CONFIGURED: - if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) - { - pdev->dev_remote_wakeup = 0; - if(usbd_is_valid_intf(pdev, LOBYTE(req->wIndex))) { - ((Setup_t)PIC(pdev->interfacesClass[LOBYTE(req->wIndex)].pClass->Setup)) (pdev, req); - } - USBD_CtlSendStatus(pdev); - } - break; - - default : - USBD_CtlError(pdev , req); - break; - } -} - -/** -* @brief USBD_ParseSetupRequest -* Copy buffer into setup structure -* @param pdev: device instance -* @param req: usb request -* @retval None -*/ - -void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) -{ - req->bmRequest = *(uint8_t *) (pdata); - req->bRequest = *(uint8_t *) (pdata + 1); - req->wValue = SWAPBYTE (pdata + 2); - req->wIndex = SWAPBYTE (pdata + 4); - req->wLength = SWAPBYTE (pdata + 6); - -} - -/** -* @brief USBD_CtlError -* Handle USB low level Error -* @param pdev: device instance -* @param req: usb request -* @retval None -*/ -void USBD_CtlStall( USBD_HandleTypeDef *pdev) -{ - USBD_LL_StallEP(pdev , 0x80); - USBD_LL_StallEP(pdev , 0); -} - -__weak void USBD_CtlError( USBD_HandleTypeDef *pdev , - USBD_SetupReqTypedef *req) -{ - UNUSED(req); - USBD_CtlStall(pdev); -} - - -/** - * @brief USBD_GetString - * Convert Ascii string into unicode one - * @param desc : descriptor buffer - * @param unicode : Formatted string buffer (unicode) - * @param len : descriptor length - * @retval None - */ -void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) -{ - uint8_t idx = 0; - - if (desc != NULL) - { - *len = USBD_GetLen(desc) * 2 + 2; - unicode[idx++] = *len; - unicode[idx++] = USB_DESC_TYPE_STRING; - - while (*desc != '\0') - { - unicode[idx++] = *desc++; - unicode[idx++] = 0x00; - } - } -} - -/** - * @brief USBD_GetLen - * return the string length - * @param buf : pointer to the ascii string buffer - * @retval string length - */ -uint8_t USBD_GetLen(uint8_t *buf) -{ - uint8_t len = 0; - - while (*buf != '\0') - { - len++; - buf++; - } - - return len; -} -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c b/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c deleted file mode 100644 index 6923b3fec..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c +++ /dev/null @@ -1,226 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ioreq.c - * @author MCD Application Team - * @version V2.4.1 - * @date 19-June-2015 - * @brief This file provides the IO requests APIs for control endpoints. - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2015 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "os_io.h" -#include "os_helpers.h" -#include "usbd_core.h" -#include "usbd_ioreq.h" - -/** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_IOREQ - * @brief control I/O requests module - * @{ - */ - -/** @defgroup USBD_IOREQ_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Variables - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Functions - * @{ - */ - -/** -* @brief USBD_CtlSendData -* send data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be sent -* @retval status -*/ -USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len) -{ - /* Set EP0 State */ - pdev->ep0_state = USBD_EP0_DATA_IN; - pdev->ep_in[0].total_length = len; - pdev->ep_in[0].rem_length = len; - // store the continuation data if needed - pdev->pData = pbuf; - /* Start the transfer */ - USBD_LL_Transmit (pdev, 0x00, pbuf, MIN(len, pdev->ep_in[0].maxpacket)); - - return USBD_OK; -} - -/** -* @brief USBD_CtlContinueSendData -* continue sending data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be sent -* @retval status -*/ -USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len) -{ - /* Start the next transfer */ - USBD_LL_Transmit (pdev, 0x00, pbuf, MIN(len, pdev->ep_in[0].maxpacket)); - return USBD_OK; -} - -/** -* @brief USBD_CtlPrepareRx -* receive data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be received -* @retval status -*/ -USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len) -{ - UNUSED(pbuf); - /* Set EP0 State */ - pdev->ep0_state = USBD_EP0_DATA_OUT; - pdev->ep_out[0].total_length = len; - pdev->ep_out[0].rem_length = len; - /* Start the transfer */ - USBD_LL_PrepareReceive (pdev, - 0, - len); - - return USBD_OK; -} - -/** -* @brief USBD_CtlContinueRx -* continue receive data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be received -* @retval status -*/ -USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, - uint8_t *pbuf, - uint16_t len) -{ - UNUSED(pbuf); - USBD_LL_PrepareReceive (pdev, - 0, - len); - return USBD_OK; -} -/** -* @brief USBD_CtlSendStatus -* send zero lzngth packet on the ctl pipe -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev) -{ - - /* Set EP0 State */ - pdev->ep0_state = USBD_EP0_STATUS_IN; - - /* Start the transfer */ - USBD_LL_Transmit (pdev, 0x00, NULL, 0); - - return USBD_OK; -} - -/** -* @brief USBD_CtlReceiveStatus -* receive zero lzngth packet on the ctl pipe -* @param pdev: device instance -* @retval status -*/ -USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev) -{ - /* Set EP0 State */ - pdev->ep0_state = USBD_EP0_STATUS_OUT; - - /* Start the transfer */ - USBD_LL_PrepareReceive ( pdev, - 0, - 0); - - return USBD_OK; -} - - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/STM32_USB_Device_Library/Release_Notes.html b/lib_stusb/STM32_USB_Device_Library/Release_Notes.html deleted file mode 100644 index f150dcd9e..000000000 --- a/lib_stusb/STM32_USB_Device_Library/Release_Notes.html +++ /dev/null @@ -1,1219 +0,0 @@ - - - - - - - - - - - - - - - - - -Release Notes for STM32 USB Device Library - - - - - - - - -
    - -

     

    - -
    - - - - - -
    - - - - - - - -
    -

    Back to Release page

    -
    -

    Release Notes for STM32 USB Device Library

    -

    Copyright - 2015 STMicroelectronics

    -

    -
    -

     

    - - - - -
    -

    Update History

    -

    V2.4.1 / 19-June-2015
    -

    - - - - - - - - - - - - - - - -

    Main -Changes

    - - - - - - - - - - - - - - - - - - - -
      -
    • CDC Class
    • -
        -
      • usbd_cdc.c: comments update
      • -
      -
    • MSC Class
    • -
        -
      • usbd_msc_bot.h: update to be C++ compliant
      • -
      -
    • AUDIO Class
    • -
        -
      • usbd_audio.c: fix issue when Host sends GetInterface command it gets a wrong value
      • -
      -
        -
      • usbd_audio.c: remove useless management of DMA half transfer
        -
      • -
      -
    - - - -

    V2.4.0 / 28-February-2015
    -

    - - - - - - - - - - - - - -

    Main -Changes

    - - - - - - - - - - - - - - - - - -
      -
    • Core Driver
    • -
        -
      • Add support of Link Power Management (LPM): add new API GetBOSDescriptor(), that is used only if USBD_LPM_ENABLED switch is enabled in usbd_conf.h file
      • usbd_core.c: -Fix bug of unsupported premature Host Out stage during data In stage -(ie. when endpoint 0 maximum data size is 8 and Host requests -GetDeviceDescriptor for the first time)
      • usbd_ctlreq.c: Fix bug of unsupported Endpoint Class requests (ie. Audio SetCurrent request for endpoint sampling rate setting)
      • -
      -
    • HID Class
    • -
        -
      • Updating Polling time API USBD_HID_GetPollingInterval() to query this period for HS and FS
      • usbd_hid.c: Fix USBD_LL_CloseEP() function call in USBD_HID_DeInit() replacing endpoint size by endpoint address.
      • -
    • CDC Class
      • usbd_cdc.c: 
        • Add missing GetInterface request management in USBD_CDC_Setup() function
        • Update -USBD_CDC_Setup() function to allow correct user implementation of -CDC_SET_CONTROL_LINE_STATE and similar no-data setup requests.
      -
    - -

    V2.3.0 / 04-November-2014
    -

    - - - - - - - - - - - -

    Main -Changes

    - - - - - - - - - - - - - - - -
      -
    • Update all drivers to be C++ compliant
      -
    • -
    • CDC Class
    • -
        -
      • usbd_cdc.c: fix clear flag issue in USBD_CDC_TransmitPacket() function
      • -
      -
        -
      • usbd_cdc_if_template.c: update TEMPLATE_Receive() function header comment
        -
      • -
      -
    • Miscellaneous source code comments update
    • -
    -

    V2.2.0 / 13-June-2014

    - - - - - - - - - -

    Main -Changes

    - - - - - - - - - - - - - -
      -
    • Source code comments review and update
    • -
    • HID class
    • -
        -
      • Remove unused API USBD_HID_DeviceQualifierDescriptor()
      • -
      • Add a new API in the HID class to query the poll time USBD_HID_GetPollingInterval()
        -
      • -
      - -
    • CDC class
    • -
        -
      • Bug fix: missing handling ZeroLength Setup request
      • -
      -
    • All classes
      -
    • - -
        -
      • Add alias for the class definition, it's defined as macro with capital letter
      • -
      -
    -
    ex. for the HID, the USBD_HID_CLASS macro is defined this way #define USBD_HID_CLASS  &USBD_HID
      and the application code can use the previous definition: &USBD_HID ex. USBD_RegisterClass(&USBD_Device, &USBD_HID) or the new USBD_HID_CLASS ex. USBD_RegisterClass(&USBD_Device, USBD_HID_CLASS)
    -

    V2.1.0 / 22-April-2014

    - - - - - - - - -

    Main -Changes

    - - - - - - - - - - - -
      -
    • usbd_conf_template.c: update file with the right content (it was using MSC memory management layer)
      -
    • -
    • usbd_conf_template.h: change include of stm32f4xx.h by stm32xxx.h and add comment to inform user to adapt it to the device used
    • -
    • Several enhancements in CustomHID class
    • -
        -
      • Update the Custom HID class driver to simplify the link with user processes
      • -
      • Optimize the Custom HID class driver and reduce footprint
      • -
      • Add USBD_CUSTOM_HID_RegisterInterface() API to link user process to custom HID class
      • -
      • Add Custom HID interface template file usbd_customhid_if_template.c/h
      • -
      -
    • Miscellaneous comments update
      -
    • - -
    - -

    V2.0.0 / 18-February-2014

    - - - - - -

    Main -Changes

    - - - - - - - - - -
      -
    • Major update -based on STM32Cube specification: Library Core, Classes architecture and APIs -modified vs. V1.1.0, and thus the 2 versions are not compatible.
      -
    • This version has to be used only with STM32Cube based development
    • -
    - - -

    V1.1.0 / 19-March-2012

    -

    Main -Changes

    - -
    • Official support of STM32F4xx devices
    • All source files: license disclaimer text update and add link to the License file on ST Internet.
    • Handle test mode in the set feature request
    • Handle dynamically the USB SELF POWERED feature
    • Handle correctly the USBD_CtlError process to take into account error during Control OUT stage
    • Miscellaneous bug fix

    V1.0.0 / 22-July-2011

    Main -Changes

    -
    • First official version for STM32F105/7xx and STM32F2xx devices

    -

    License

    -

    Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); You may not use this package except in compliance with the License. You may obtain a copy of the License at:


    Unless -required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See -the License for the specific language governing permissions and -limitations under the License.
    -
    -
    -
    -

    For - complete documentation on STM32 - Microcontrollers visit www.st.com/STM32

    -
    -

    -
    - -
    - -

     

    - -
    - - \ No newline at end of file diff --git a/lib_stusb/doc/mainpage.dox b/lib_stusb/doc/mainpage.dox deleted file mode 100644 index 74204fa68..000000000 --- a/lib_stusb/doc/mainpage.dox +++ /dev/null @@ -1,10 +0,0 @@ -/** @page usb_mainpage USB Core library - -@section usb_mainpage_intro Introduction - -This page describes the core part of the USB Stack (only available on \b NanoX and \b Stax products). -It also contains the mid-level API of the HID and CCID classes (see also @ref usb_impl_mainpage). - -@note TO BE COMPLETED - -*/ diff --git a/lib_stusb/include/usbd_conf.h b/lib_stusb/include/usbd_conf.h new file mode 100644 index 000000000..0ee3c7d21 --- /dev/null +++ b/lib_stusb/include/usbd_conf.h @@ -0,0 +1,29 @@ +/* @BANNER@ */ + +#ifndef USBD_CONF_H +#define USBD_CONF_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include + +#include "os.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ +#define USBD_MAX_NUM_INTERFACES (6) +#define USBD_MAX_NUM_CONFIGURATION (1) +#define USBD_MAX_STR_DESC_SIZ (48) + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ + +#endif // USBD_CONF_H diff --git a/lib_stusb/include/usbd_core.h b/lib_stusb/include/usbd_core.h new file mode 100644 index 000000000..664407588 --- /dev/null +++ b/lib_stusb/include/usbd_core.h @@ -0,0 +1,80 @@ +/* @BANNER@ */ + +#ifndef USBD_CORE_H +#define USBD_CORE_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" +#include "usbd_def.h" +#include "usbd_ioreq.h" +#include "usbd_ctlreq.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); + +USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); + +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); + +/* USBD Low Level Driver */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps); + +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr); + +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + const uint8_t *pbuf, + uint32_t size, + uint32_t timeout_ms); + +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint32_t size); + +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr); + +#endif // USBD_CORE_H diff --git a/lib_stusb/include/usbd_ctlreq.h b/lib_stusb/include/usbd_ctlreq.h new file mode 100644 index 000000000..61389e5e1 --- /dev/null +++ b/lib_stusb/include/usbd_ctlreq.h @@ -0,0 +1,32 @@ +/* @BANNER@ */ + +#ifndef USB_REQUEST_H +#define USB_REQUEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ +USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata); +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); + +#endif // USB_REQUEST_H diff --git a/lib_stusb/include/usbd_def.h b/lib_stusb/include/usbd_def.h new file mode 100644 index 000000000..bc8e3b791 --- /dev/null +++ b/lib_stusb/include/usbd_def.h @@ -0,0 +1,298 @@ +/* @BANNER@ */ + +#ifndef USBD_DEF_H +#define USBD_DEF_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/* Exported enumerations -----------------------------------------------------*/ +/* Following USB Device Speed */ +typedef enum { + USBD_SPEED_HIGH = 0U, + USBD_SPEED_FULL = 1U, + USBD_SPEED_LOW = 2U, +} USBD_SpeedTypeDef; + +/* Following USB Device status */ +typedef enum { + USBD_OK = 0U, + USBD_BUSY, + USBD_EMEM, + USBD_FAIL, + USBD_TIMEOUT, +} USBD_StatusTypeDef; + +/* Exported defines --------------------------------------------------------*/ +#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU +#define USB_LEN_DEV_DESC 0x12U +#define USB_LEN_CFG_DESC 0x09U +#define USB_LEN_IF_DESC 0x09U +#define USB_LEN_EP_DESC 0x07U +#define USB_LEN_OTG_DESC 0x03U +#define USB_LEN_LANGID_STR_DESC 0x04U +#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U + +#define USBD_IDX_LANGID_STR 0x00U +#define USBD_IDX_MFC_STR 0x01U +#define USBD_IDX_PRODUCT_STR 0x02U +#define USBD_IDX_SERIAL_STR 0x03U +#define USBD_IDX_CONFIG_STR 0x04U +#define USBD_IDX_INTERFACE_STR 0x05U +#define USBD_IDX_WINUSB_STR 0xEEU + +#define USB_REQ_TYPE_STANDARD 0x00U +#define USB_REQ_TYPE_CLASS 0x20U +#define USB_REQ_TYPE_VENDOR 0x40U +#define USB_REQ_TYPE_MASK 0x60U + +#define USB_REQ_RECIPIENT_DEVICE 0x00U +#define USB_REQ_RECIPIENT_INTERFACE 0x01U +#define USB_REQ_RECIPIENT_ENDPOINT 0x02U +#define USB_REQ_RECIPIENT_MASK 0x03U + +#define USB_REQ_GET_STATUS 0x00U +#define USB_REQ_CLEAR_FEATURE 0x01U +#define USB_REQ_SET_FEATURE 0x03U +#define USB_REQ_SET_ADDRESS 0x05U +#define USB_REQ_GET_DESCRIPTOR 0x06U +#define USB_REQ_SET_DESCRIPTOR 0x07U +#define USB_REQ_GET_CONFIGURATION 0x08U +#define USB_REQ_SET_CONFIGURATION 0x09U +#define USB_REQ_GET_INTERFACE 0x0AU +#define USB_REQ_SET_INTERFACE 0x0BU +#define USB_REQ_SYNCH_FRAME 0x0CU +#define USB_REQ_WEBUSB_VENDOR_CODE 0x1EU +#define USB_REQ_WINUSB_VENDOR_CODE 0x77U + +#define USB_DESC_TYPE_DEVICE 0x01U +#define USB_DESC_TYPE_CONFIGURATION 0x02U +#define USB_DESC_TYPE_STRING 0x03U +#define USB_DESC_TYPE_INTERFACE 0x04U +#define USB_DESC_TYPE_ENDPOINT 0x05U +#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U +#define USB_DESC_TYPE_IAD 0x0BU +#define USB_DESC_TYPE_BOS 0x0FU + +#define USB_CONFIG_REMOTE_WAKEUP 0x02U +#define USB_CONFIG_SELF_POWERED 0x01U + +#define USB_FEATURE_EP_HALT 0x00U +#define USB_FEATURE_REMOTE_WAKEUP 0x01U +#define USB_FEATURE_TEST_MODE 0x02U + +#define USB_DEVICE_CAPABITY_TYPE 0x10U + +#define USB_CONF_DESC_SIZE 0x09U +#define USB_IF_DESC_SIZE 0x09U +#define USB_EP_DESC_SIZE 0x07U +#define USB_IAD_DESC_SIZE 0x08U + +#define USB_HS_MAX_PACKET_SIZE 512U +#define USB_FS_MAX_PACKET_SIZE 64U +#define USB_MAX_EP0_SIZE 64U + +/* Device Status */ +#define USBD_STATE_DEFAULT 0x01U +#define USBD_STATE_ADDRESSED 0x02U +#define USBD_STATE_CONFIGURED 0x03U +#define USBD_STATE_SUSPENDED 0x04U + +/* EP0 State */ +#define USBD_EP0_IDLE 0x00U +#define USBD_EP0_SETUP 0x01U +#define USBD_EP0_DATA_IN 0x02U +#define USBD_EP0_DATA_OUT 0x03U +#define USBD_EP0_STATUS_IN 0x04U +#define USBD_EP0_STATUS_OUT 0x05U +#define USBD_EP0_STALL 0x06U + +#define USBD_EP_TYPE_CTRL 0x00U +#define USBD_EP_TYPE_ISOC 0x01U +#define USBD_EP_TYPE_BULK 0x02U +#define USBD_EP_TYPE_INTR 0x03U + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} USBD_SetupReqTypedef; + +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} USBD_ConfigDescTypedef; + +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; +} USBD_BosDescTypedef; + +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} USBD_EpDescTypedef; + +struct _USBD_HandleTypeDef; + +/* USB Device class structure */ +typedef uint8_t (*USB_Init_t)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); +typedef uint8_t (*USB_DeInit_t)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +typedef uint8_t (*USB_Setup_t)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +typedef uint8_t (*USB_EP0_TxSent_t)(struct _USBD_HandleTypeDef *pdev); +typedef uint8_t (*USB_EP0_RxReady_t)(struct _USBD_HandleTypeDef *pdev); + +typedef uint8_t (*USB_DataIn_t)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); +typedef uint8_t (*USB_DataOut_t)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); +typedef uint8_t (*USB_SOF_t)(struct _USBD_HandleTypeDef *pdev); +typedef uint8_t (*USB_IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); +typedef uint8_t (*USB_IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + +typedef uint8_t *(*USB_GetHSConfigDescriptor_t)(uint16_t *length); +typedef uint8_t *(*USB_GetFSConfigDescriptor_t)(uint16_t *length); +typedef uint8_t *(*USB_GetOtherSpeedConfigDescriptor_t)(uint16_t *length); +typedef uint8_t *(*USB_GetDeviceQualifierDescriptor_t)(uint16_t *length); + +typedef struct { + USB_Init_t Init; + USB_DeInit_t DeInit; + + USB_Setup_t Setup; + USB_EP0_TxSent_t EP0_TxSent; + USB_EP0_RxReady_t EP0_RxReady; + + USB_DataIn_t DataIn; + USB_DataOut_t DataOut; + USB_SOF_t SOF; + USB_IsoINIncomplete IsoINIncomplete; + USB_IsoOUTIncomplete IsoOUTIncomplete; + + USB_GetHSConfigDescriptor_t GetHSConfigDescriptor; + USB_GetFSConfigDescriptor_t GetFSConfigDescriptor; + USB_GetOtherSpeedConfigDescriptor_t GetOtherSpeedConfigDescriptor; + USB_GetDeviceQualifierDescriptor_t GetDeviceQualifierDescriptor; + +} USBD_ClassTypeDef; + +/* USB Device descriptors structure */ +typedef uint8_t *(*USB_GetDeviceDescriptor_t)(USBD_SpeedTypeDef speed, uint16_t *length); +typedef uint8_t *(*USB_GetLangIDStrDescriptor_t)(USBD_SpeedTypeDef speed, uint16_t *length); +typedef uint8_t *(*USB_GetManufacturerStrDescriptor_t)(USBD_SpeedTypeDef speed, uint16_t *length); +typedef uint8_t *(*USB_GetProductStrDescriptor_t)(USBD_SpeedTypeDef speed, uint16_t *length); +typedef uint8_t *(*USB_GetSerialStrDescriptor_t)(USBD_SpeedTypeDef speed, uint16_t *length); +typedef uint8_t *(*USB_GetConfigurationStrDescriptor_t)(USBD_SpeedTypeDef speed, uint16_t *length); +typedef uint8_t *(*USB_GetInterfaceStrDescriptor_t)(USBD_SpeedTypeDef speed, uint16_t *length); +typedef uint8_t *(*USB_GetBOSDescriptor_t)(USBD_SpeedTypeDef speed, uint16_t *length); + +typedef struct { + USB_GetDeviceDescriptor_t GetDeviceDescriptor; + USB_GetLangIDStrDescriptor_t GetLangIDStrDescriptor; + USB_GetManufacturerStrDescriptor_t GetManufacturerStrDescriptor; + USB_GetProductStrDescriptor_t GetProductStrDescriptor; + USB_GetSerialStrDescriptor_t GetSerialStrDescriptor; + USB_GetConfigurationStrDescriptor_t GetConfigurationStrDescriptor; + USB_GetInterfaceStrDescriptor_t GetInterfaceStrDescriptor; + USB_GetBOSDescriptor_t GetBOSDescriptor; +} USBD_DescriptorsTypeDef; + +/* USB Device end point structure */ +typedef struct { + uint32_t status; + uint32_t total_length; + uint32_t rem_length; + uint32_t maxpacket; + uint16_t is_used; + uint16_t bInterval; +} USBD_EndpointTypeDef; + +/* USB Device handle structure */ +typedef struct _USBD_HandleTypeDef { + uint8_t id; + uint32_t dev_config; + uint32_t dev_default_config; + uint32_t dev_config_status; + USBD_SpeedTypeDef dev_speed; + USBD_EndpointTypeDef ep_in[IO_USB_MAX_ENDPOINTS]; + USBD_EndpointTypeDef ep_out[IO_USB_MAX_ENDPOINTS]; + uint32_t ep0_state; + uint32_t ep0_data_len; + uint8_t dev_state; + uint8_t dev_old_state; + uint8_t dev_address; + uint8_t dev_connection_status; + uint32_t dev_remote_wakeup; + uint8_t ConfIdx; + + USBD_SetupReqTypedef request; + USBD_DescriptorsTypeDef *pDesc; + USBD_ClassTypeDef *pClass; + void *pClassData; + void *pUserData; + void *pData; + void *pBosDesc; + void *pConfDesc; +} USBD_HandleTypeDef; + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ + +static __inline uint16_t SWAPBYTE(uint8_t *addr) +{ + uint16_t _SwapVal, _Byte1, _Byte2; + uint8_t *_pbuff = addr; + + _Byte1 = *(uint8_t *) _pbuff; + _pbuff++; + _Byte2 = *(uint8_t *) _pbuff; + + _SwapVal = (_Byte2 << 8) | _Byte1; + + return _SwapVal; +} + +#ifndef LOBYTE +#define LOBYTE(x) ((uint8_t) ((x) &0x00FFU)) +#endif + +#ifndef HIBYTE +#define HIBYTE(x) ((uint8_t) (((x) &0xFF00U) >> 8U)) +#endif + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#if defined(__GNUC__) +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + +#endif // USBD_DEF_H diff --git a/lib_stusb/include/usbd_desc.h b/lib_stusb/include/usbd_desc.h new file mode 100644 index 000000000..72d620da4 --- /dev/null +++ b/lib_stusb/include/usbd_desc.h @@ -0,0 +1,37 @@ +/* @BANNER@ */ + +#ifndef USBD_DESC_H +#define USBD_DESC_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "usbd_def.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ +#define USBD_LEDGER_VID (0x2C97) + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern const USBD_DescriptorsTypeDef LEDGER_Desc; + +/* Exported functions prototypes--------------------------------------------- */ +uint8_t *USBD_get_descriptor_device(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_get_descriptor_lang_id(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_get_descriptor_manufacturer(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_get_descriptor_product(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_get_descriptor_serial(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_get_descriptor_BOS(USBD_SpeedTypeDef speed, uint16_t *length); + +void USBD_DESC_init(char *product_str, + uint16_t vid, + uint16_t pid, + uint8_t bcdusb, + uint8_t iad, + USB_GetBOSDescriptor_t bos_descriptor); + +#endif // USBD_DESC_H diff --git a/lib_stusb/include/usbd_ioreq.h b/lib_stusb/include/usbd_ioreq.h new file mode 100644 index 000000000..ab71199fe --- /dev/null +++ b/lib_stusb/include/usbd_ioreq.h @@ -0,0 +1,36 @@ +/* @BANNER@ */ + +#ifndef USBD_IOREQ_H +#define USBD_IOREQ_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_core.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len); + +USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len); + +USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len); + +USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len); + +USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev); + +uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); + +#endif // USBD_IOREQ_H diff --git a/lib_stusb/include/usbd_ledger.h b/lib_stusb/include/usbd_ledger.h new file mode 100644 index 000000000..41b7f9ef7 --- /dev/null +++ b/lib_stusb/include/usbd_ledger.h @@ -0,0 +1,77 @@ +/* @BANNER@ */ + +#ifndef USBD_LEDGER_H +#define USBD_LEDGER_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "os_io.h" + +#include "usbd_ledger_types.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + USBD_LEDGER_PRODUCT_BLUE = 0x0000, + USBD_LEDGER_PRODUCT_NANOS = 0x1000, + USBD_LEDGER_PRODUCT_HW2 = 0x3000, + USBD_LEDGER_PRODUCT_NANOX = 0x4000, + USBD_LEDGER_PRODUCT_NANOS_PLUS = 0x5000, + USBD_LEDGER_PRODUCT_STAX = 0x6000, + USBD_LEDGER_PRODUCT_FLEX = 0x7000, +} usbd_ledger_product_e; + +typedef enum { + USBD_LEDGER_CLASS_HID = 0x0001, + USBD_LEDGER_CLASS_HID_KBD = 0x0002, + USBD_LEDGER_CLASS_HID_U2F = 0x0004, + USBD_LEDGER_CLASS_CCID_BULK = 0x0008, + USBD_LEDGER_CLASS_WEBUSB = 0x0010, + USBD_LEDGER_CLASS_CDC_CONTROL = 0x0020, + USBD_LEDGER_CLASS_CDC_DATA = 0x0040, + USBD_LEDGER_CLASS_CDC = USBD_LEDGER_CLASS_CDC_CONTROL | USBD_LEDGER_CLASS_CDC_DATA, +} usbd_ledger_class_mask_e; + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern uint8_t USBD_LEDGER_io_buffer[OS_IO_BUFFER_SIZE + 1]; + +/* Exported functions prototypes--------------------------------------------- */ +void USBD_LEDGER_init(os_io_init_usb_t *init, uint8_t force_restart); +void USBD_LEDGER_start(void); +void USB_LEDGER_stop(void); + +void USBD_LEDGER_add_profile(const usbd_class_info_t *class_info, uint8_t bcdusb, uint8_t usbd_iad); + +// Rx +int USBD_LEDGER_rx_seph_evt(uint8_t *seph_buffer, + uint16_t seph_buffer_length, + uint8_t *apdu_buffer, + uint16_t apdu_buffer_max_length); + +void USBD_LEDGER_rx_evt_reset(void); +void USBD_LEDGER_rx_evt_sof(void); +void USBD_LEDGER_rx_evt_suspend(void); +void USBD_LEDGER_rx_evt_resume(void); +void USBD_LEDGER_rx_evt_setup(uint8_t *buffer); +void USBD_LEDGER_rx_evt_data_in(uint8_t ep_num, uint8_t *buffer); +void USBD_LEDGER_rx_evt_data_out(uint8_t ep_num, uint8_t *buffer, uint16_t length); + +// Tx +uint32_t USBD_LEDGER_send(uint8_t class_type, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms); + +// Check APDU +int32_t USBD_LEDGER_data_ready(uint8_t *buffer, uint16_t max_length); + +// Setting +void USBD_LEDGER_setting(uint32_t class_id, uint32_t setting_id, uint8_t *buffer, uint16_t length); + +#endif // USBD_LEDGER_H diff --git a/lib_stusb/include/usbd_ledger_ccid.h b/lib_stusb/include/usbd_ledger_ccid.h new file mode 100644 index 000000000..2f24bf777 --- /dev/null +++ b/lib_stusb/include/usbd_ledger_ccid.h @@ -0,0 +1,46 @@ +/* @BANNER@ */ + +#ifndef USBD_LEDGER_CCID_H +#define USBD_LEDGER_CCID_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "usbd_def.h" +#include "usbd_ledger_types.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern const usbd_class_info_t USBD_LEDGER_CCID_class_info; + +/* Exported functions prototypes--------------------------------------------- */ +uint8_t USBD_LEDGER_CCID_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_CCID_de_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_CCID_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req); +uint8_t USBD_LEDGER_CCID_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_CCID_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num); +uint8_t USBD_LEDGER_CCID_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length); + +uint8_t USBD_LEDGER_CCID_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms); + +int32_t USBD_LEDGER_CCID_data_ready(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length); + +#endif // USBD_LEDGER_CCID_H diff --git a/lib_stusb/include/usbd_ledger_cdc.h b/lib_stusb/include/usbd_ledger_cdc.h new file mode 100644 index 000000000..c516dcdba --- /dev/null +++ b/lib_stusb/include/usbd_ledger_cdc.h @@ -0,0 +1,45 @@ +/* @BANNER@ */ + +#ifndef USBD_LEDGER_CDC_H +#define USBD_LEDGER_CDC_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "usbd_def.h" +#include "usbd_ledger_types.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern const usbd_class_info_t USBD_LEDGER_CDC_Control_class_info; +extern const usbd_class_info_t USBD_LEDGER_CDC_Data_class_info; + +/* Exported functions prototypes--------------------------------------------- */ +uint8_t USBD_LEDGER_CDC_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_CDC_cmd_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_CDC_de_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_CDC_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req); +uint8_t USBD_LEDGER_CDC_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_CDC_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num); +uint8_t USBD_LEDGER_CDC_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length); + +uint8_t USBD_LEDGER_CDC_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms); + +uint8_t *USBD_LEDGER_CDC_get_bos_desc(USBD_SpeedTypeDef speed, uint16_t *length); + +#endif // USBD_LEDGER_CDC_H diff --git a/lib_stusb/include/usbd_ledger_hid.h b/lib_stusb/include/usbd_ledger_hid.h new file mode 100644 index 000000000..6aa0a8fd6 --- /dev/null +++ b/lib_stusb/include/usbd_ledger_hid.h @@ -0,0 +1,46 @@ +/* @BANNER@ */ + +#ifndef USBD_LEDGER_HID_H +#define USBD_LEDGER_HID_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "usbd_def.h" +#include "usbd_ledger_types.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern const usbd_class_info_t USBD_LEDGER_HID_class_info; + +/* Exported functions prototypes--------------------------------------------- */ +uint8_t USBD_LEDGER_HID_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_de_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req); +uint8_t USBD_LEDGER_HID_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num); +uint8_t USBD_LEDGER_HID_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length); + +uint8_t USBD_LEDGER_HID_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms); + +int32_t USBD_LEDGER_HID_data_ready(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length); + +#endif // USBD_LEDGER_HID_H diff --git a/lib_stusb/include/usbd_ledger_hid_kbd.h b/lib_stusb/include/usbd_ledger_hid_kbd.h new file mode 100644 index 000000000..95c18e15d --- /dev/null +++ b/lib_stusb/include/usbd_ledger_hid_kbd.h @@ -0,0 +1,43 @@ +/* @BANNER@ */ + +#ifndef USBD_LEDGER_HID_KBD_H +#define USBD_LEDGER_HID_KBD_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "usbd_def.h" +#include "usbd_ledger_types.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern const usbd_class_info_t USBD_LEDGER_HID_KBD_class_info; + +/* Exported functions prototypes--------------------------------------------- */ +uint8_t USBD_LEDGER_HID_KBD_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_KBD_de_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_KBD_setup(USBD_HandleTypeDef *pdev, + void *cookie, + USBD_SetupReqTypedef *req); +uint8_t USBD_LEDGER_HID_KBD_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_KBD_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num); +uint8_t USBD_LEDGER_HID_KBD_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length); + +uint8_t USBD_LEDGER_HID_KBD_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms); + +#endif // USBD_LEDGER_HID_KBD_H diff --git a/lib_stusb/include/usbd_ledger_hid_u2f.h b/lib_stusb/include/usbd_ledger_hid_u2f.h new file mode 100644 index 000000000..6e3b77bdb --- /dev/null +++ b/lib_stusb/include/usbd_ledger_hid_u2f.h @@ -0,0 +1,55 @@ +/* @BANNER@ */ + +#ifndef USBD_LEDGER_HID_U2F_H +#define USBD_LEDGER_HID_U2F_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "usbd_def.h" +#include "usbd_ledger_types.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + USBD_LEDGER_HID_U2F_SETTING_ID_VERSIONS = 0, + USBD_LEDGER_HID_U2F_SETTING_ID_CAPABILITIES_FLAG = 1, + USBD_LEDGER_HID_U2F_SETTING_ID_FREE_CID = 2, +} usdb_ledger_hid_u2f_setting_id_e; + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern const usbd_class_info_t USBD_LEDGER_HID_U2F_class_info; + +/* Exported functions prototypes--------------------------------------------- */ +uint8_t USBD_LEDGER_HID_U2F_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_U2F_de_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_U2F_setup(USBD_HandleTypeDef *pdev, + void *cookie, + USBD_SetupReqTypedef *req); +uint8_t USBD_LEDGER_HID_U2F_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_HID_U2F_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num); +uint8_t USBD_LEDGER_HID_U2F_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length); + +uint8_t USBD_LEDGER_HID_U2F_send_message(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *message, + uint16_t message_length, + uint32_t timeout_ms); + +int32_t USBD_LEDGER_HID_U2F_data_ready(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length); + +void USBD_LEDGER_HID_U2F_setting(uint32_t id, uint8_t *buffer, uint16_t length, void *cookie); + +#endif // USBD_LEDGER_HID_U2F_H diff --git a/lib_stusb/include/usbd_ledger_types.h b/lib_stusb/include/usbd_ledger_types.h new file mode 100644 index 000000000..c8b243bc6 --- /dev/null +++ b/lib_stusb/include/usbd_ledger_types.h @@ -0,0 +1,87 @@ +/* @BANNER@ */ + +#ifndef USBD_LEDGER_TYPES_H +#define USBD_LEDGER_TYPES_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "usbd_def.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ +#define MAX_DESCRIPTOR_SIZE (256) + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + uint8_t ep_in_addr; + uint16_t ep_in_size; + uint8_t ep_out_addr; + uint16_t ep_out_size; + uint8_t ep_type; +} usbd_end_point_info_t; + +typedef uint8_t (*usbd_class_init_t)(USBD_HandleTypeDef *pdev, void *cookie); +typedef uint8_t (*usbd_class_de_init_t)(USBD_HandleTypeDef *pdev, void *cookie); +typedef uint8_t (*usbd_class_setup_t)(USBD_HandleTypeDef *pdev, + void *cookie, + USBD_SetupReqTypedef *req); +typedef uint8_t (*usbd_ep0_rx_ready_t)(USBD_HandleTypeDef *pdev, void *cookie); +typedef uint8_t (*usbd_class_data_in_t)(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num); +typedef uint8_t (*usbd_class_data_out_t)(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length); + +typedef uint8_t (*usbd_send_packet_t)(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms); + +typedef int32_t (*usbd_data_ready_t)(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length); + +typedef void (*usbd_setting_t)(uint32_t class_id, uint8_t *buffer, uint16_t length, void *cookie); + +typedef struct usbd_class_info_t_ { + uint8_t type; // usbd_ledger_class_mask_e + + const usbd_end_point_info_t *end_point; + + usbd_class_init_t init; + usbd_class_de_init_t de_init; + usbd_class_setup_t setup; + usbd_ep0_rx_ready_t ep0_rx_ready; + usbd_class_data_in_t data_in; + usbd_class_data_out_t data_out; + + usbd_send_packet_t send_packet; + + usbd_data_ready_t data_ready; + + usbd_setting_t setting; + + uint8_t interface_descriptor_size; + const uint8_t *interface_descriptor; + + uint8_t interface_association_descriptor_size; + const uint8_t *interface_association_descriptor; + + uint8_t bos_descriptor_size; + const uint8_t *bos_descriptor; + + void *cookie; +} usbd_class_info_t; + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ + +#endif // USBD_LEDGER_TYPES_H diff --git a/lib_stusb/include/usbd_ledger_webusb.h b/lib_stusb/include/usbd_ledger_webusb.h new file mode 100644 index 000000000..3b8e78c49 --- /dev/null +++ b/lib_stusb/include/usbd_ledger_webusb.h @@ -0,0 +1,46 @@ +/* @BANNER@ */ + +#ifndef USBD_LEDGER_WEBUSB_H +#define USBD_LEDGER_WEBUSB_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "usbd_def.h" +#include "usbd_ledger_types.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +extern const usbd_class_info_t USBD_LEDGER_WEBUSB_class_info; + +/* Exported functions prototypes--------------------------------------------- */ +uint8_t USBD_LEDGER_WEBUSB_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_WEBUSB_de_init(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_WEBUSB_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req); +uint8_t USBD_LEDGER_WEBUSB_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie); +uint8_t USBD_LEDGER_WEBUSB_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num); +uint8_t USBD_LEDGER_WEBUSB_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length); + +uint8_t USBD_LEDGER_WEBUSB_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms); + +int32_t USBD_LEDGER_WEBUSB_data_ready(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length); + +#endif // USBD_LEDGER_WEBUSB_H diff --git a/lib_stusb/src/usbd_conf.c b/lib_stusb/src/usbd_conf.c new file mode 100644 index 000000000..a298dbc62 --- /dev/null +++ b/lib_stusb/src/usbd_conf.c @@ -0,0 +1,325 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "os.h" +#include "usbd_core.h" +#include "usbd_conf.h" +#include "seproxyhal_protocol.h" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static uint8_t ep_in_stall_status; +static uint8_t ep_out_stall_status; + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ + +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + ep_in_stall_status = 0; + ep_out_stall_status = 0; + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + uint8_t buffer[5]; + + UNUSED(pdev); + + buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; + buffer[1] = 0; + buffer[2] = 2; + buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_ADDR; + buffer[4] = 0; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 5, NULL); + + buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_CONNECT; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) +{ + uint8_t buffer[4]; + + UNUSED(pdev); + + buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; + buffer[1] = 0; + buffer[2] = 1; + buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_DISCONNECT; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 4, NULL); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps) +{ + uint8_t buffer[8]; + + UNUSED(pdev); + + if ((ep_addr & 0x7F) >= 8) { + return USBD_FAIL; + } + + ep_in_stall_status = 0; + ep_out_stall_status = 0; + + buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; + buffer[1] = 0; + buffer[2] = 5; + buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_ENDPOINTS; + buffer[4] = 1; + buffer[5] = ep_addr; + buffer[6] = 0; + + switch (ep_type) { + case USBD_EP_TYPE_CTRL: + buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_CONTROL; + break; + + case USBD_EP_TYPE_ISOC: + buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_ISOCHRONOUS; + break; + + case USBD_EP_TYPE_BULK: + buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_BULK; + break; + + case USBD_EP_TYPE_INTR: + buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_INTERRUPT; + break; + + default: + buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_INTERRUPT; + break; + } + + buffer[7] = ep_mps; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 8, NULL); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + uint8_t buffer[8]; + + UNUSED(pdev); + + if ((ep_addr & 0x7F) >= 8) { + return USBD_FAIL; + } + + buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; + buffer[1] = 0; + buffer[2] = 5; + buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_ENDPOINTS; + buffer[4] = 1; + buffer[5] = ep_addr; + buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_DISABLED; + buffer[7] = 0; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 8, NULL); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + UNUSED(pdev); + + if ((ep_addr & 0x7F) >= 8) { + return USBD_FAIL; + } + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + uint8_t buffer[6]; + + UNUSED(pdev); + + if ((ep_addr & 0x7F) >= 8) { + return USBD_FAIL; + } + + if (ep_addr & 0x80) { + ep_in_stall_status |= (1 << (ep_addr & 0x7F)); + } + else { + ep_out_stall_status |= (1 << (ep_addr & 0x7F)); + } + + buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; + buffer[1] = 0; + buffer[2] = 3; + buffer[3] = ep_addr; + buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_STALL; + buffer[5] = 0; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 6, NULL); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + uint8_t buffer[6]; + + UNUSED(pdev); + + if ((ep_addr & 0x7F) >= 8) { + return USBD_FAIL; + } + + if (ep_addr & 0x80) { + ep_in_stall_status &= ~(1 << (ep_addr & 0x7F)); + } + else { + ep_out_stall_status &= ~(1 << (ep_addr & 0x7F)); + } + + buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; + buffer[1] = 0; + buffer[2] = 3; + buffer[3] = ep_addr; + buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_UNSTALL; + buffer[5] = 0; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 6, NULL); + + return USBD_OK; +} + +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + UNUSED(pdev); + + if ((ep_addr & 0x7F) >= 8) { + return 0; + } + + if (ep_addr & 0x80) { + return ep_in_stall_status & (1 << (ep_addr & 0x7F)); + } + else { + return ep_out_stall_status & (1 << (ep_addr & 0x7F)); + } +} + +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + uint8_t buffer[5]; + + UNUSED(pdev); + + buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; + buffer[1] = 0; + buffer[2] = 2; + buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_ADDR; + buffer[4] = dev_addr; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 5, 0); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + const uint8_t *pbuf, + uint32_t size, + uint32_t timeout_ms) +{ + USBD_StatusTypeDef status = USBD_OK; + uint8_t buffer[6]; + + UNUSED(pdev); + + if ((ep_addr & 0x7F) >= 8) { + return USBD_FAIL; + } + + buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; + buffer[1] = (3 + size) >> 8; + buffer[2] = (3 + size) >> 0; + buffer[3] = ep_addr; + buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN; + buffer[5] = size; + if (timeout_ms) { + if (os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 6, (unsigned int *) &timeout_ms) + != TIMEOUT) { + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, pbuf, size, NULL); + } + else { + status = USBD_TIMEOUT; + } + } + else { + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 6, NULL); + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, pbuf, size, NULL); + } + + return status; +} + +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint32_t size) +{ + uint8_t buffer[6]; + + UNUSED(pdev); + UNUSED(pbuf); + + if ((ep_addr & 0x7F) >= 8) { + return USBD_FAIL; + } + + buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; + buffer[1] = 0; + buffer[2] = 3; + buffer[3] = ep_addr; + buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_OUT; + buffer[5] = size; + os_io_tx_cmd(OS_IO_PACKET_TYPE_SEPH, buffer, 6, NULL); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_BatteryCharging(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + return USBD_FAIL; +} diff --git a/lib_stusb/src/usbd_core.c b/lib_stusb/src/usbd_core.c new file mode 100644 index 000000000..39b4646f5 --- /dev/null +++ b/lib_stusb/src/usbd_core.c @@ -0,0 +1,369 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id) +{ + USBD_StatusTypeDef ret; + + // Check whether the USB Host handle is valid + if (pdev == NULL) { + return USBD_FAIL; + } + + // Unlink previous class resources + pdev->pClass = NULL; + pdev->pUserData = NULL; + pdev->pConfDesc = NULL; + + // Assign USBD Descriptors + if (pdesc != NULL) { + pdev->pDesc = pdesc; + } + + // Set Device initial State + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->id = id; + + // Initialize low level driver + ret = USBD_LL_Init(pdev); + + return ret; +} + +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) +{ + USBD_StatusTypeDef ret; + + // Disconnect the USB Device + (void) USBD_LL_Stop(pdev); + + // Set Default State + pdev->dev_state = USBD_STATE_DEFAULT; + + // Free Class Resources + if (pdev->pClass != NULL) { + ((USB_DeInit_t) PIC(pdev->pClass->DeInit))(pdev, (uint8_t) pdev->dev_config); + pdev->pClass = NULL; + pdev->pUserData = NULL; + } + + // Free Device descriptors resources + pdev->pDesc = NULL; + pdev->pConfDesc = NULL; + + // DeInitialize low level driver + ret = USBD_LL_DeInit(pdev); + + return ret; +} + +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass) +{ + uint16_t len = 0U; + + // Check whether the class handle is valid + if (pclass == NULL) { + return USBD_FAIL; + } + // link the class to the USB Device handle + pdev->pClass = pclass; + + // Get Device Configuration Descriptor + if (pdev->pClass->GetFSConfigDescriptor != NULL) { + pdev->pConfDesc + = ((USB_GetFSConfigDescriptor_t) PIC(pdev->pClass->GetFSConfigDescriptor))(&len); + } + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev) +{ + // Start the low level driver + return USBD_LL_Start(pdev); +} + +USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) +{ + // Disconnect USB Device + (void) USBD_LL_Stop(pdev); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + USBD_StatusTypeDef ret = USBD_FAIL; + + if (pdev->pClass != NULL) { + // Set configuration and Start the Class + ret = (USBD_StatusTypeDef) ((USB_Init_t) PIC(pdev->pClass->Init))(pdev, cfgidx); + } + + return ret; +} + +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + if (pdev->pClass != NULL) { + // Clear configuration and De-initialize the Class process + ((USB_DeInit_t) PIC(pdev->pClass->DeInit))(pdev, cfgidx); + } + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) +{ + USBD_StatusTypeDef ret = USBD_OK; + + USBD_ParseSetupRequest(&pdev->request, psetup); + + pdev->ep0_state = USBD_EP0_SETUP; + pdev->ep0_data_len = pdev->request.wLength; + + switch (pdev->request.bmRequest & 0x1FU) { + case USB_REQ_RECIPIENT_DEVICE: + ret = USBD_StdDevReq(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_INTERFACE: + ret = USBD_StdItfReq(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + ret = USBD_StdEPReq(pdev, &pdev->request); + break; + + default: + ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U)); + break; + } + + return ret; +} + +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep = NULL; + USBD_StatusTypeDef ret = USBD_OK; + + if (epnum == 0U) { + pep = &pdev->ep_out[0]; + + if (pdev->ep0_state == USBD_EP0_DATA_OUT) { + if (pep->rem_length > pep->maxpacket) { + pep->rem_length -= pep->maxpacket; + (void) USBD_CtlContinueRx(pdev, pdata, MIN(pep->rem_length, pep->maxpacket)); + } + else { + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (pdev->pClass->EP0_RxReady != NULL) { + ((USB_EP0_RxReady_t) PIC(pdev->pClass->EP0_RxReady))(pdev); + } + } + (void) USBD_CtlSendStatus(pdev); + } + } + } + else { + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (pdev->pClass->DataOut != NULL) { + ret = (USBD_StatusTypeDef) ((USB_DataOut_t) PIC(pdev->pClass->DataOut))(pdev, + epnum); + } + } + } + + return ret; +} + +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep = NULL; + USBD_StatusTypeDef ret = USBD_OK; + UNUSED(pdata); + + if (epnum == 0U) { + pep = &pdev->ep_in[0]; + + if (pdev->ep0_state == USBD_EP0_DATA_IN) { + if (pep->rem_length > pep->maxpacket) { + pep->rem_length -= pep->maxpacket; + pdev->pData = &((uint8_t *) pdev->pData)[pep->maxpacket]; + (void) USBD_CtlContinueSendData(pdev, pdev->pData, pep->rem_length); + // Prepare endpoint for premature end of transfer + (void) USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + } + else { + // last packet is MPS multiple, so send ZLP packet + if ((pep->maxpacket == pep->rem_length) && (pep->total_length >= pep->maxpacket) + && (pep->total_length < pdev->ep0_data_len)) { + (void) USBD_CtlContinueSendData(pdev, NULL, 0U); + pdev->ep0_data_len = 0U; + // Prepare endpoint for premature end of transfer + (void) USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + } + else { + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (pdev->pClass->EP0_TxSent != NULL) { + ((USB_EP0_TxSent_t) PIC(pdev->pClass->EP0_TxSent))(pdev); + } + } + //(void)USBD_LL_StallEP(pdev, 0x80U); + (void) USBD_CtlReceiveStatus(pdev); + } + } + } + } + else { + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (pdev->pClass->DataIn != NULL) { + ret = (USBD_StatusTypeDef) ((USB_DataIn_t) PIC(pdev->pClass->DataIn))(pdev, epnum); + } + } + } + + return ret; +} + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) +{ + // Upon Reset call user call back + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->ep0_state = USBD_EP0_IDLE; + pdev->dev_config = 0U; + pdev->dev_remote_wakeup = 0U; + + if (pdev->pClassData != NULL) { + if ((pdev->pClass != NULL) && (pdev->pClass->DeInit != NULL)) { + (void) ((USB_DeInit_t) PIC(pdev->pClass->DeInit))(pdev, (uint8_t) pdev->dev_config); + } + } + + // Open EP0 OUT + (void) USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); + pdev->ep_out[0x00U & 0xFU].is_used = 1U; + pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; + + // Open EP0 IN + (void) USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); + pdev->ep_in[0x80U & 0xFU].is_used = 1U; + pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed) +{ + pdev->dev_speed = speed; + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) +{ + pdev->dev_old_state = pdev->dev_state; + pdev->dev_state = USBD_STATE_SUSPENDED; + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) +{ + if (pdev->dev_state == USBD_STATE_SUSPENDED) { + pdev->dev_state = pdev->dev_old_state; + } + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) +{ + if (pdev->pClass == NULL) { + return USBD_FAIL; + } + + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (pdev->pClass->SOF != NULL) { + (void) ((USB_SOF_t) PIC(pdev->pClass->SOF))(pdev); + } + } + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + if (pdev->pClass == NULL) { + return USBD_FAIL; + } + + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (pdev->pClass->IsoINIncomplete != NULL) { + (void) ((USB_IsoINIncomplete) PIC(pdev->pClass->IsoINIncomplete))(pdev, epnum); + } + } + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + if (pdev->pClass == NULL) { + return USBD_FAIL; + } + + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (pdev->pClass->IsoOUTIncomplete != NULL) { + (void) ((USB_IsoOUTIncomplete) PIC(pdev->pClass->IsoOUTIncomplete))(pdev, epnum); + } + } + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) +{ + // Free Class Resources + pdev->dev_state = USBD_STATE_DEFAULT; + + if (pdev->pClass != NULL) { + (void) ((USB_DeInit_t) PIC(pdev->pClass->DeInit))(pdev, (uint8_t) pdev->dev_config); + } + + return USBD_OK; +} diff --git a/lib_stusb/src/usbd_ctlreq.c b/lib_stusb/src/usbd_ctlreq.c new file mode 100644 index 000000000..ad35cda3f --- /dev/null +++ b/lib_stusb/src/usbd_ctlreq.c @@ -0,0 +1,656 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ctlreq.h" +#include "usbd_ioreq.h" + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t USBD_GetLen(uint8_t *buf); + +/* Exported variables --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + ret = (USBD_StatusTypeDef) ((USB_Setup_t) PIC(pdev->pClass->Setup))(pdev, req); + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { + case USB_REQ_GET_DESCRIPTOR: + USBD_GetDescriptor(pdev, req); + break; + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; + + case USB_REQ_SET_CONFIGURATION: + ret = USBD_SetConfig(pdev, req); + break; + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig(pdev, req); + break; + + case USB_REQ_GET_STATUS: + USBD_GetStatus(pdev, req); + break; + + case USB_REQ_SET_FEATURE: + USBD_SetFeature(pdev, req); + break; + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature(pdev, req); + break; + + default: + ret = (USBD_StatusTypeDef) ((USB_Setup_t) PIC(pdev->pClass->Setup))(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return ret; +} + +USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + case USB_REQ_TYPE_STANDARD: + switch (pdev->dev_state) { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) { + ret = (USBD_StatusTypeDef) ((USB_Setup_t) PIC(pdev->pClass->Setup))(pdev, + req); + if ((req->wLength == 0U) && (ret == USBD_OK)) { + (void) USBD_CtlSendStatus(pdev); + } + } + else { + USBD_CtlError(pdev, req); + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return ret; +} + +USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + USBD_EndpointTypeDef *pep = NULL; + uint8_t ep_addr = LOBYTE(req->wIndex); + + switch (req->bmRequest & USB_REQ_TYPE_MASK) { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + ret = (USBD_StatusTypeDef) ((USB_Setup_t) PIC(pdev->pClass->Setup))(pdev, req); + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { + case USB_REQ_SET_FEATURE: + switch (pdev->dev_state) { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) { + (void) USBD_LL_StallEP(pdev, ep_addr); + (void) USBD_LL_StallEP(pdev, 0x80U); + } + else { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) { + if ((ep_addr != 0x00U) && (ep_addr != 0x80U) + && (req->wLength == 0x00U)) { + (void) USBD_LL_StallEP(pdev, ep_addr); + } + } + (void) USBD_CtlSendStatus(pdev); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + case USB_REQ_CLEAR_FEATURE: + switch (pdev->dev_state) { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) { + (void) USBD_LL_StallEP(pdev, ep_addr); + (void) USBD_LL_StallEP(pdev, 0x80U); + } + else { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) { + if ((ep_addr & 0x7FU) != 0x00U) { + (void) USBD_LL_ClearStallEP(pdev, ep_addr); + } + (void) USBD_CtlSendStatus(pdev); + ret = (USBD_StatusTypeDef) pdev->pClass->Setup(pdev, req); + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + case USB_REQ_GET_STATUS: + switch (pdev->dev_state) { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) { + USBD_CtlError(pdev, req); + break; + } + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] + : &pdev->ep_out[ep_addr & 0x7FU]; + + pep->status = 0x0000U; + + (void) USBD_CtlSendData(pdev, (uint8_t *) &pep->status, 2U); + break; + + case USBD_STATE_CONFIGURED: + if ((ep_addr & 0x80U) == 0x80U) { + if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) { + USBD_CtlError(pdev, req); + break; + } + } + else { + if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) { + USBD_CtlError(pdev, req); + break; + } + } + + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] + : &pdev->ep_out[ep_addr & 0x7FU]; + + if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) { + pep->status = 0x0000U; + } + else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U) { + pep->status = 0x0001U; + } + else { + pep->status = 0x0000U; + } + + (void) USBD_CtlSendData(pdev, (uint8_t *) &pep->status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return ret; +} + +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + uint16_t len = 0U; + uint8_t *pbuf = NULL; + uint8_t err = 0U; + + switch (req->wValue >> 8) { + case USB_DESC_TYPE_BOS: + if (pdev->pDesc->GetBOSDescriptor != NULL) { + pbuf = ((USB_GetBOSDescriptor_t) PIC(pdev->pDesc->GetBOSDescriptor))( + pdev->dev_speed, &len); + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USB_DESC_TYPE_DEVICE: + pbuf = ((USB_GetDeviceDescriptor_t) PIC(pdev->pDesc->GetDeviceDescriptor))( + pdev->dev_speed, &len); + break; + + case USB_DESC_TYPE_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) { + pbuf = ((USB_GetHSConfigDescriptor_t) PIC(pdev->pClass->GetHSConfigDescriptor))( + &len); + } + else { + pbuf = ((USB_GetFSConfigDescriptor_t) PIC(pdev->pClass->GetFSConfigDescriptor))( + &len); + } + break; + + case USB_DESC_TYPE_STRING: + switch ((uint8_t) (req->wValue)) { + case USBD_IDX_LANGID_STR: + if (pdev->pDesc->GetLangIDStrDescriptor != NULL) { + pbuf = ((USB_GetLangIDStrDescriptor_t) PIC( + pdev->pDesc->GetLangIDStrDescriptor))(pdev->dev_speed, &len); + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_MFC_STR: + if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) { + pbuf = ((USB_GetManufacturerStrDescriptor_t) PIC( + pdev->pDesc->GetManufacturerStrDescriptor))(pdev->dev_speed, &len); + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_PRODUCT_STR: + if (pdev->pDesc->GetProductStrDescriptor != NULL) { + pbuf = ((USB_GetProductStrDescriptor_t) PIC( + pdev->pDesc->GetProductStrDescriptor))(pdev->dev_speed, &len); + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_SERIAL_STR: + if (pdev->pDesc->GetSerialStrDescriptor != NULL) { + pbuf = ((USB_GetSerialStrDescriptor_t) PIC( + pdev->pDesc->GetSerialStrDescriptor))(pdev->dev_speed, &len); + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_CONFIG_STR: + if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) { + pbuf = ((USB_GetConfigurationStrDescriptor_t) PIC( + pdev->pDesc->GetConfigurationStrDescriptor))(pdev->dev_speed, &len); + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_INTERFACE_STR: + if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) { + pbuf = ((USB_GetInterfaceStrDescriptor_t) PIC( + pdev->pDesc->GetInterfaceStrDescriptor))(pdev->dev_speed, &len); + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_WINUSB_STR: + // TODO_IO : Could we process this? + break; + + default: + USBD_CtlError(pdev, req); + err++; + break; + } + break; + + case USB_DESC_TYPE_DEVICE_QUALIFIER: + if (pdev->dev_speed == USBD_SPEED_HIGH) { + pbuf = ((USB_GetDeviceQualifierDescriptor_t) PIC( + pdev->pClass->GetDeviceQualifierDescriptor))(&len); + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) { + pbuf = ((USB_GetOtherSpeedConfigDescriptor_t) PIC( + pdev->pClass->GetOtherSpeedConfigDescriptor))(&len); + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + } + else { + USBD_CtlError(pdev, req); + err++; + } + break; + + default: + USBD_CtlError(pdev, req); + err++; + break; + } + + if (err != 0U) { + return; + } + + if (req->wLength != 0U) { + if (len != 0U) { + len = MIN(len, req->wLength); + (void) USBD_CtlSendData(pdev, pbuf, len); + } + else { + USBD_CtlError(pdev, req); + } + } + else { + (void) USBD_CtlSendStatus(pdev); + } +} + +static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + uint8_t dev_addr; + + if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U)) { + dev_addr = (uint8_t) (req->wValue) & 0x7FU; + + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlError(pdev, req); + } + else { + pdev->dev_address = dev_addr; + (void) USBD_LL_SetUSBAddress(pdev, dev_addr); + (void) USBD_CtlSendStatus(pdev); + + if (dev_addr != 0U) { + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else { + pdev->dev_state = USBD_STATE_DEFAULT; + } + } + } + else { + USBD_CtlError(pdev, req); + } +} + +static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + static uint8_t cfgidx = 0; + + cfgidx = (uint8_t) (req->wValue); + + if (cfgidx > USBD_MAX_NUM_CONFIGURATION) { + USBD_CtlError(pdev, req); + return USBD_FAIL; + } + + switch (pdev->dev_state) { + case USBD_STATE_ADDRESSED: + if (cfgidx != 0U) { + pdev->dev_config = cfgidx; + ret = USBD_SetClassConfig(pdev, cfgidx); + if (ret != USBD_OK) { + USBD_CtlError(pdev, req); + } + else { + (void) USBD_CtlSendStatus(pdev); + pdev->dev_state = USBD_STATE_CONFIGURED; + } + } + else { + (void) USBD_CtlSendStatus(pdev); + } + break; + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0U) { + pdev->dev_state = USBD_STATE_ADDRESSED; + pdev->dev_config = cfgidx; + (void) USBD_ClrClassConfig(pdev, cfgidx); + (void) USBD_CtlSendStatus(pdev); + } + else if (cfgidx != pdev->dev_config) { + // Clear old configuration + (void) USBD_ClrClassConfig(pdev, (uint8_t) pdev->dev_config); + + // set new configuration + pdev->dev_config = cfgidx; + + ret = USBD_SetClassConfig(pdev, cfgidx); + if (ret != USBD_OK) { + USBD_CtlError(pdev, req); + (void) USBD_ClrClassConfig(pdev, (uint8_t) pdev->dev_config); + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else { + (void) USBD_CtlSendStatus(pdev); + } + } + else { + (void) USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev, req); + (void) USBD_ClrClassConfig(pdev, cfgidx); + ret = USBD_FAIL; + break; + } + + return ret; +} + +static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + if (req->wLength != 1U) { + USBD_CtlError(pdev, req); + } + else { + switch (pdev->dev_state) { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + pdev->dev_default_config = 0U; + (void) USBD_CtlSendData(pdev, (uint8_t *) &pdev->dev_default_config, 1U); + break; + + case USBD_STATE_CONFIGURED: + (void) USBD_CtlSendData(pdev, (uint8_t *) &pdev->dev_config, 1U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + } +} + +static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch (pdev->dev_state) { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wLength != 0x2U) { + USBD_CtlError(pdev, req); + break; + } + + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; + if (pdev->dev_remote_wakeup != 0U) { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + } + + (void) USBD_CtlSendData(pdev, (uint8_t *) &pdev->dev_config_status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } +} + +static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) { + pdev->dev_remote_wakeup = 1U; + (void) USBD_CtlSendStatus(pdev); + } +} + +/** + * @brief USBD_ClrFeature + * Handle clear device feature request + * @param pdev: device instance + * @param req: usb request + * @retval status + */ +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch (pdev->dev_state) { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) { + pdev->dev_remote_wakeup = 0U; + (void) USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } +} + +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) +{ + uint8_t *pbuff = pdata; + + req->bmRequest = *(uint8_t *) (pbuff); + pbuff += 1; + req->bRequest = *(uint8_t *) (pbuff); + pbuff += 1; + req->wValue = SWAPBYTE(pbuff); + pbuff += 2; + req->wIndex = SWAPBYTE(pbuff); + pbuff += 2; + req->wLength = SWAPBYTE(pbuff); +} + +void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + UNUSED(req); + + (void) USBD_LL_StallEP(pdev, 0x80U); + (void) USBD_LL_StallEP(pdev, 0U); +} + +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + uint8_t idx = 0U; + uint8_t *pdesc = NULL; + + if (desc == NULL) { + return; + } + + pdesc = desc; + *len = ((uint16_t) USBD_GetLen(pdesc) * 2U) + 2U; + + unicode[idx++] = *(uint8_t *) len; + unicode[idx++] = USB_DESC_TYPE_STRING; + + while (*pdesc != (uint8_t) '\0') { + unicode[idx++] = *pdesc; + unicode[idx++] = 0U; + pdesc++; + } +} + +static uint8_t USBD_GetLen(uint8_t *buf) +{ + uint8_t len = 0U; + uint8_t *pbuff = buf; + + while (*pbuff != (uint8_t) '\0') { + len++; + pbuff++; + } + + return len; +} diff --git a/lib_stusb/src/usbd_desc.c b/lib_stusb/src/usbd_desc.c new file mode 100644 index 000000000..455ac0625 --- /dev/null +++ b/lib_stusb/src/usbd_desc.c @@ -0,0 +1,180 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +#include "usbd_conf.h" +#include "usbd_desc.h" + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ +#define USBD_LANGID_STRING (0x409) +#define USBD_MANUFACTURER_STRING ("Ledger") + +#define USBD_SERIAL_STRING_SIZE (2 + 2 * (7 * 2)) + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +const USBD_DescriptorsTypeDef LEDGER_Desc = { + USBD_get_descriptor_device, + USBD_get_descriptor_lang_id, + USBD_get_descriptor_manufacturer, + USBD_get_descriptor_product, + USBD_get_descriptor_serial, + USBD_get_descriptor_product, + USBD_get_descriptor_product, + USBD_get_descriptor_BOS, +}; + +/* Private variables ---------------------------------------------------------*/ +static uint8_t usbd_bcdusb; +static uint16_t usbd_vid; +static uint16_t usbd_pid; +static char *usbd_desc_product_str; +static uint8_t usbd_iad; +static USB_GetBOSDescriptor_t usbd_bos_descriptor; + +/* USB Standard Device Descriptor */ +static const uint8_t USBD_desc_device_desc[USB_LEN_DEV_DESC] = { + 0x12, // bLength + USB_DESC_TYPE_DEVICE, // bDescriptorType + 0x00, // bcdUSB + 0x02, + 0x00, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + USB_MAX_EP0_SIZE, // bMaxPacketSize + LOBYTE(USBD_LEDGER_VID), // idVendor + HIBYTE(USBD_LEDGER_VID), // idVendor + 0x00, // idProduct + 0x00, // idProduct + 0x01, // bcdDevice rel. 2.00 + 0x02, + USBD_IDX_MFC_STR, // Index of manufacturer string + USBD_IDX_PRODUCT_STR, // Index of product string + USBD_IDX_SERIAL_STR, // Index of serial number string + 1 // bNumConfigurations +}; + +static uint8_t USBD_desc_device_desc_patched[USB_LEN_DEV_DESC]; + +/* USB Language ID descriptor */ +static const uint8_t USBD_desc_lang_id_desc[USB_LEN_LANGID_STR_DESC] = { + USB_LEN_LANGID_STR_DESC, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_LANGID_STRING), + HIBYTE(USBD_LANGID_STRING), +}; + +static uint8_t USBD_StringSerial[USBD_SERIAL_STRING_SIZE]; + +static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ]; + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +uint8_t *USBD_get_descriptor_device(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + + memcpy(USBD_desc_device_desc_patched, + USBD_desc_device_desc, + sizeof(USBD_desc_device_desc_patched)); + USBD_desc_device_desc_patched[2] = usbd_bcdusb; + if (usbd_iad) { + USBD_desc_device_desc_patched[4] = 0xEF; + USBD_desc_device_desc_patched[5] = 0x02; + USBD_desc_device_desc_patched[6] = 0x01; + } + else { + USBD_desc_device_desc_patched[4] = 0x00; + USBD_desc_device_desc_patched[5] = 0x00; + USBD_desc_device_desc_patched[6] = 0x00; + } + USBD_desc_device_desc_patched[8] = LOBYTE(usbd_vid); + USBD_desc_device_desc_patched[9] = HIBYTE(usbd_vid); + USBD_desc_device_desc_patched[10] = LOBYTE(usbd_pid); + USBD_desc_device_desc_patched[11] = HIBYTE(usbd_pid); + + *length = sizeof(USBD_desc_device_desc_patched); + return USBD_desc_device_desc_patched; +} + +uint8_t *USBD_get_descriptor_lang_id(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + + *length = sizeof(USBD_desc_lang_id_desc); + return (uint8_t *) USBD_desc_lang_id_desc; +} + +uint8_t *USBD_get_descriptor_manufacturer(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + + USBD_GetString((uint8_t *) USBD_MANUFACTURER_STRING, (uint8_t *) USBD_StrDesc, length); + + return (uint8_t *) USBD_StrDesc; +} + +uint8_t *USBD_get_descriptor_product(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + + USBD_GetString((uint8_t *) (usbd_desc_product_str), (uint8_t *) USBD_StrDesc, length); + + return (uint8_t *) USBD_StrDesc; +} + +uint8_t *USBD_get_descriptor_serial(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + + USBD_StringSerial[0] = 10; + USBD_StringSerial[1] = USB_DESC_TYPE_STRING; + USBD_StringSerial[2] = 0x30; + USBD_StringSerial[3] = 0x00; + USBD_StringSerial[4] = 0x30; + USBD_StringSerial[5] = 0x00; + USBD_StringSerial[6] = 0x30; + USBD_StringSerial[7] = 0x00; + USBD_StringSerial[8] = 0x31; + USBD_StringSerial[9] = 0x00; + + *length = USBD_StringSerial[0]; + + return (uint8_t *) USBD_StringSerial; +} + +uint8_t *USBD_get_descriptor_BOS(USBD_SpeedTypeDef speed, uint16_t *length) +{ + uint8_t *pbuf = NULL; + + if (usbd_bos_descriptor) { + pbuf = ((USB_GetBOSDescriptor_t) PIC(usbd_bos_descriptor))(speed, length); + } + + return pbuf; +} + +void USBD_DESC_init(char *product_str, + uint16_t vid, + uint16_t pid, + uint8_t bcdusb, + uint8_t iad, + USB_GetBOSDescriptor_t bos_descriptor) +{ + usbd_bcdusb = bcdusb; + usbd_vid = vid; + usbd_pid = pid; + usbd_desc_product_str = product_str; + usbd_iad = iad; + usbd_bos_descriptor = bos_descriptor; +} diff --git a/lib_stusb/src/usbd_ioreq.c b/lib_stusb/src/usbd_ioreq.c new file mode 100644 index 000000000..b86239825 --- /dev/null +++ b/lib_stusb/src/usbd_ioreq.c @@ -0,0 +1,90 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) +{ + // Set EP0 State + pdev->ep0_state = USBD_EP0_DATA_IN; + pdev->ep_in[0].total_length = len; + pdev->ep_in[0].rem_length = len; + pdev->pData = pbuf; + + // Start the transfer + (void) USBD_LL_Transmit(pdev, 0x00U, pbuf, MIN(len, pdev->ep_in[0].maxpacket), 0); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) +{ + // Start the next transfer + (void) USBD_LL_Transmit(pdev, 0x00U, pbuf, MIN(len, pdev->ep_in[0].maxpacket), 0); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) +{ + // Set EP0 State + pdev->ep0_state = USBD_EP0_DATA_OUT; + pdev->ep_out[0].total_length = len; + pdev->ep_out[0].rem_length = len; + + // Start the transfer + (void) USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) +{ + (void) USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev) +{ + // Set EP0 State + pdev->ep0_state = USBD_EP0_STATUS_IN; + + // Start the transfer + (void) USBD_LL_Transmit(pdev, 0x00U, NULL, 0U, 0); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev) +{ + // Set EP0 State + pdev->ep0_state = USBD_EP0_STATUS_OUT; + + // Start the transfer + (void) USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + + return USBD_OK; +} + +uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return USBD_LL_GetRxDataSize(pdev, ep_addr); +} diff --git a/lib_stusb/src/usbd_ledger.c b/lib_stusb/src/usbd_ledger.c new file mode 100644 index 000000000..1a9d9b68e --- /dev/null +++ b/lib_stusb/src/usbd_ledger.c @@ -0,0 +1,757 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" +#include "usbd_ledger.h" +#include "usbd_ledger_hid.h" +#include "usbd_ledger_hid_kbd.h" +#include "usbd_ledger_hid_u2f.h" +#include "usbd_ledger_webusb.h" +#include "usbd_ledger_cdc.h" +#include "lcx_rng.h" +#include "os_io_seph_cmd.h" +#include "seproxyhal_protocol.h" + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ +typedef enum { + USBD_LEDGER_STATE_INITIALIZED = 0xA0, + USBD_LEDGER_STATE_RUNNING, + USBD_LEDGER_STATE_STOPPED, +} usb_ledger_state_t; + +/* Private defines------------------------------------------------------------*/ +#define USBD_BLUE_PRODUCT_STRING ("Blue") +#define USBD_NANOS_PRODUCT_STRING ("Nano S") +#define USBD_NANOX_PRODUCT_STRING ("Nano X") +#define USBD_NANOS_PLUS_PRODUCT_STRING ("Nano S+") +#define USBD_STAX_PRODUCT_STRING ("Stax") +#define USBD_FLEX_PRODUCT_STRING ("Flex") + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + usb_ledger_state_t state; + + usbd_ledger_product_e product; + uint16_t vid; + uint16_t pid; + char name[20]; + uint8_t bcdusb; + uint8_t usbd_iad; + + uint8_t nb_of_class; + usbd_class_info_t *class[USBD_MAX_NUM_INTERFACES]; + uint16_t classes; + + USBD_HandleTypeDef usbd_handle; + + uint16_t usb_ep_xfer_len[IO_USB_MAX_ENDPOINTS]; + uint8_t *usb_ep_xfer_buffer[IO_USB_MAX_ENDPOINTS]; +} usbd_ledger_data_t; + +#ifdef HAVE_PRINTF +#define DEBUG PRINTF +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +static uint8_t init(USBD_HandleTypeDef *pdev, uint8_t cfg_idx); +static uint8_t de_init(USBD_HandleTypeDef *pdev, uint8_t cfg_idx); +static uint8_t setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t data_in(USBD_HandleTypeDef *pdev, uint8_t ep_num); +static uint8_t data_out(USBD_HandleTypeDef *pdev, uint8_t ep_num); +static uint8_t ep0_rx_ready(USBD_HandleTypeDef *pdev); + +static uint8_t *get_cfg_desc(uint16_t *length); +static uint8_t *get_dev_qualifier_desc(uint16_t *length); +static uint8_t *get_bos_desc(USBD_SpeedTypeDef speed, uint16_t *length); + +static void forge_configuration_descriptor(void); +static void forge_bos_descriptor(void); + +/* Exported variables --------------------------------------------------------*/ +uint8_t USBD_LEDGER_io_buffer[OS_IO_BUFFER_SIZE + 1]; + +/* Private variables ---------------------------------------------------------*/ +static const USBD_ClassTypeDef USBD_LEDGER_CLASS = { + init, // Init + de_init, // DeInit + setup, // Setup + NULL, // EP0_TxSent + ep0_rx_ready, // EP0_RxReady + data_in, // DataIn + data_out, // DataOut + NULL, // SOF + NULL, // IsoINIncomplete + NULL, // IsoOUTIncomplete + get_cfg_desc, // GetHSConfigDescriptor + get_cfg_desc, // GetFSConfigDescriptor + get_cfg_desc, // GetOtherSpeedConfigDescriptor + get_dev_qualifier_desc, // GetDeviceQualifierDescriptor +}; + +static const uint8_t interface_descriptor[USB_LEN_CFG_DESC] = { + USB_LEN_CFG_DESC, // bLength + USB_DESC_TYPE_CONFIGURATION, // bDescriptorType + 0x00, // wTotalLength (dynamic) + 0x00, // wTotalLength (dynamic) + 0x00, // bNumInterfaces (dynamic) + 0x01, // bConfigurationValue + USBD_IDX_PRODUCT_STR, // iConfiguration + 0xC0, // bmAttributes: self powered + 0x32, // bMaxPower: 100 mA +}; + +static const uint8_t device_qualifier_decriptor[USB_LEN_DEV_QUALIFIER_DESC] = { + USB_LEN_DEV_QUALIFIER_DESC, // bLength + USB_DESC_TYPE_DEVICE_QUALIFIER, // bDescriptorType + 0x00, // bcdUSB + 0x02, // bcdUSB + 0x00, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + 0x40, // bMaxPacketSize0 + 0x01, // bNumConfigurations + 0x00, // bReserved +}; + +static const uint8_t bos_descriptor[] = { + 0x05, // bLength + USB_DESC_TYPE_BOS, // bDescriptorType + 0x00, // wTotalLength (dynamic) + 0x00, // wTotalLength (dynamic) + 0x00, // bNumDeviceCaps (dynamic) +}; + +static usbd_ledger_data_t usbd_ledger_data; +static os_io_init_usb_t usbd_ledger_init_data; + +static uint8_t usbd_ledger_descriptor[MAX_DESCRIPTOR_SIZE]; +static uint16_t usbd_ledger_descriptor_size; + +/* Private functions ---------------------------------------------------------*/ +static uint8_t init(USBD_HandleTypeDef *pdev, uint8_t cfg_idx) +{ + uint8_t ret = USBD_OK; + uint8_t index = 0; + usbd_end_point_info_t *end_point_info = NULL; + + UNUSED(cfg_idx); + pdev->pClassData = &usbd_ledger_data; + + usbd_class_info_t *class_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + class_info = usbd_ledger_data.class[index]; + if (class_info) { + end_point_info = (usbd_end_point_info_t *) PIC(class_info->end_point); + + // Open EP IN + if (end_point_info->ep_in_addr != 0xFF) { + USBD_LL_OpenEP(pdev, + end_point_info->ep_in_addr, + end_point_info->ep_type, + end_point_info->ep_in_size); + pdev->ep_in[end_point_info->ep_in_addr & 0x0F].is_used = 1; + } + + // Open EP OUT + if (end_point_info->ep_out_addr != 0xFF) { + USBD_LL_OpenEP(pdev, + end_point_info->ep_out_addr, + end_point_info->ep_type, + end_point_info->ep_out_size); + pdev->ep_out[end_point_info->ep_out_addr & 0x0F].is_used = 1; + } + + if (class_info->init) { + ret = ((usbd_class_init_t) PIC(class_info->init))(pdev, class_info->cookie); + } + } + } + + return ret; +} + +static uint8_t de_init(USBD_HandleTypeDef *pdev, uint8_t cfg_idx) +{ + uint8_t ret = USBD_OK; + uint8_t index = 0; + usbd_end_point_info_t *end_point_info = NULL; + + UNUSED(cfg_idx); + + usbd_class_info_t *class_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + class_info = usbd_ledger_data.class[index]; + if (class_info) { + end_point_info = (usbd_end_point_info_t *) PIC(class_info->end_point); + + // Close EP IN + if (end_point_info->ep_in_addr != 0xFF) { + USBD_LL_CloseEP(pdev, end_point_info->ep_in_addr); + pdev->ep_in[end_point_info->ep_in_addr & 0x0F].is_used = 0; + } + + // Close EP OUT + if (end_point_info->ep_out_addr != 0xFF) { + USBD_LL_CloseEP(pdev, end_point_info->ep_out_addr); + pdev->ep_out[end_point_info->ep_out_addr & 0x0F].is_used = 0; + } + + if (class_info->de_init) { + ret = ((usbd_class_de_init_t) PIC(class_info->de_init))(pdev, class_info->cookie); + } + } + } + + pdev->pClassData = NULL; + + return ret; +} + +static uint8_t setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + uint8_t ret = USBD_FAIL; + uint16_t index = req->wIndex; + + if (index < usbd_ledger_data.nb_of_class) { + usbd_class_info_t *class_info = usbd_ledger_data.class[index]; + ret = ((usbd_class_setup_t) PIC(class_info->setup))(pdev, class_info->cookie, req); + } + else { + ret = USBD_FAIL; + USBD_CtlError(pdev, req); + } + + return ret; +} + +static uint8_t data_in(USBD_HandleTypeDef *pdev, uint8_t ep_num) +{ + uint8_t ret = USBD_OK; + uint8_t index = 0; + + usbd_class_info_t *class_info = NULL; + usbd_end_point_info_t *end_point_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + class_info = usbd_ledger_data.class[index]; + end_point_info = (usbd_end_point_info_t *) PIC(class_info->end_point); + if (((end_point_info->ep_in_addr & 0x7F) == (ep_num & 0x7F)) && (class_info->data_in)) { + ret = ((usbd_class_data_in_t) PIC(class_info->data_in))( + pdev, class_info->cookie, ep_num); + } + } + + return ret; +} + +static uint8_t data_out(USBD_HandleTypeDef *pdev, uint8_t ep_num) +{ + uint8_t ret = USBD_OK; + uint8_t index = 0; + + usbd_class_info_t *class_info = NULL; + usbd_end_point_info_t *end_point_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + class_info = usbd_ledger_data.class[index]; + end_point_info = (usbd_end_point_info_t *) PIC(class_info->end_point); + if (((end_point_info->ep_out_addr & 0x7F) == (ep_num & 0x7F)) && (class_info->data_out)) { + ret = ((usbd_class_data_out_t) PIC(class_info->data_out))( + pdev, + class_info->cookie, + ep_num, + usbd_ledger_data.usb_ep_xfer_buffer[ep_num & 0x7F], + usbd_ledger_data.usb_ep_xfer_len[ep_num & 0x7F]); + } + } + + return ret; +} + +static uint8_t ep0_rx_ready(USBD_HandleTypeDef *pdev) +{ + UNUSED(pdev); + + return USBD_OK; +} + +static uint8_t *get_cfg_desc(uint16_t *length) +{ + forge_configuration_descriptor(); + *length = usbd_ledger_descriptor_size; + return usbd_ledger_descriptor; +} + +static uint8_t *get_dev_qualifier_desc(uint16_t *length) +{ + *length = sizeof(device_qualifier_decriptor); + return (uint8_t *) PIC(device_qualifier_decriptor); +} + +static uint8_t *get_bos_desc(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + forge_bos_descriptor(); + *length = usbd_ledger_descriptor_size; + return usbd_ledger_descriptor; +} + +static void forge_configuration_descriptor(void) +{ + uint8_t offset = 0; + uint8_t index = 0; + + memset(usbd_ledger_descriptor, 0, sizeof(usbd_ledger_descriptor)); + + memcpy(&usbd_ledger_descriptor[offset], interface_descriptor, sizeof(interface_descriptor)); + offset += sizeof(interface_descriptor); + + usbd_class_info_t *class_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + if (usbd_ledger_data.class[index]) { + class_info = usbd_ledger_data.class[index]; + // Interface Association Descriptor + if (class_info->interface_association_descriptor) { + memcpy(&usbd_ledger_descriptor[offset], + PIC(class_info->interface_association_descriptor), + class_info->interface_association_descriptor_size); + usbd_ledger_descriptor[offset + 2] = index; + offset += class_info->interface_association_descriptor_size; + } + // Interface Descriptor + memcpy(&usbd_ledger_descriptor[offset], + PIC(class_info->interface_descriptor), + class_info->interface_descriptor_size); + usbd_ledger_descriptor[offset + 2] = index; + if (class_info->type == USBD_LEDGER_CLASS_CDC_CONTROL) { + usbd_ledger_descriptor[offset + 18] = index + 1; + usbd_ledger_descriptor[offset + 26] = index; + usbd_ledger_descriptor[offset + 27] = index + 1; + } + offset += class_info->interface_descriptor_size; + usbd_ledger_descriptor[4]++; + } + } + + usbd_ledger_descriptor[2] = (uint8_t) (offset >> 0); + usbd_ledger_descriptor[3] = (uint8_t) (offset >> 8); + usbd_ledger_descriptor_size = offset; +} + +static void forge_bos_descriptor(void) +{ + uint8_t offset = 0; + uint8_t index = 0; + + memset(usbd_ledger_descriptor, 0, sizeof(usbd_ledger_descriptor)); + + memcpy(&usbd_ledger_descriptor[offset], bos_descriptor, sizeof(bos_descriptor)); + offset += sizeof(bos_descriptor); + + usbd_class_info_t *class_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + class_info = usbd_ledger_data.class[index]; + if ((class_info) && (class_info->bos_descriptor)) { + memcpy(&usbd_ledger_descriptor[offset], + PIC(class_info->bos_descriptor), + class_info->bos_descriptor_size); + offset += class_info->bos_descriptor_size; + usbd_ledger_descriptor[4]++; + } + } + + usbd_ledger_descriptor[2] = (uint8_t) (offset >> 0); + usbd_ledger_descriptor[3] = (uint8_t) (offset >> 8); + usbd_ledger_descriptor[4] = 2; + usbd_ledger_descriptor_size = offset; +} + +/* Exported functions --------------------------------------------------------*/ +void USBD_LEDGER_init(os_io_init_usb_t *init, uint8_t force_restart) +{ + if (!init) { + return; + } + + if ((force_restart) || (usbd_ledger_data.state < USBD_LEDGER_STATE_INITIALIZED)) { + // First time USB is started or forced to restart + memset(&usbd_ledger_data, 0, sizeof(usbd_ledger_data)); + usbd_ledger_data.state = USBD_LEDGER_STATE_INITIALIZED; + DEBUG("USBD_LEDGER_init deep\n"); + } + else { + DEBUG("USBD_LEDGER_init\n"); + } + + memcpy(&usbd_ledger_init_data, init, sizeof(usbd_ledger_init_data)); +} + +void USBD_LEDGER_start(void) +{ + DEBUG("USBD_LEDGER_start %d %04X:%04X (%04X)", + usbd_ledger_data.state, + usbd_ledger_init_data.pid, + usbd_ledger_init_data.vid, + usbd_ledger_init_data.class_mask); + if (strlen(usbd_ledger_init_data.name)) { + DEBUG(" %s\n", usbd_ledger_init_data.name); + } + else { + DEBUG("\n"); + } + + if ((usbd_ledger_data.state == USBD_LEDGER_STATE_INITIALIZED) + || (usbd_ledger_data.classes != usbd_ledger_init_data.class_mask) + || (usbd_ledger_init_data.vid && (usbd_ledger_data.vid != usbd_ledger_init_data.vid))) { + // First time USD is started + // or wanted classes have changed + // or vendor ID has changed + + if (usbd_ledger_data.state == USBD_LEDGER_STATE_RUNNING) { + USB_LEDGER_stop(); + usbd_ledger_data.state = USBD_LEDGER_STATE_STOPPED; + } + + usbd_ledger_data.bcdusb = 0x00; + usbd_ledger_data.usbd_iad = 0; + + // Fill the name + if (!strlen(usbd_ledger_init_data.name)) { + strlcpy(usbd_ledger_init_data.name, + USBD_BLUE_PRODUCT_STRING, + sizeof(usbd_ledger_data.name)); +#if defined(TARGET_NANOS) + strlcpy(usbd_ledger_init_data.name, + USBD_NANOS_PRODUCT_STRING, + sizeof(usbd_ledger_data.name)); +#endif // TARGET_NANOS +#if defined(TARGET_NANOX) + strlcpy(usbd_ledger_init_data.name, + USBD_NANOX_PRODUCT_STRING, + sizeof(usbd_ledger_data.name)); +#endif // TARGET_NANOX +#if defined(TARGET_NANOS2) + strlcpy(usbd_ledger_init_data.name, + USBD_NANOS_PLUS_PRODUCT_STRING, + sizeof(usbd_ledger_data.name)); +#endif // TARGET_NANOS2 +#if defined(TARGET_FATSTACKS) || defined(TARGET_STAX) + strlcpy(usbd_ledger_init_data.name, + USBD_STAX_PRODUCT_STRING, + sizeof(usbd_ledger_data.name)); +#endif // TARGET_FATSTACKS || TARGET_STAX +#if defined(TARGET_FLEX) + strlcpy(usbd_ledger_init_data.name, + USBD_FLEX_PRODUCT_STRING, + sizeof(usbd_ledger_data.name)); +#endif // TARGET_FLEX + } + strlcpy(usbd_ledger_data.name, usbd_ledger_init_data.name, sizeof(usbd_ledger_data.name)); + + // Fill the product type + usbd_ledger_data.product = USBD_LEDGER_PRODUCT_BLUE; +#if defined(TARGET_NANOS) + usbd_ledger_data.product = USBD_LEDGER_PRODUCT_NANOS; +#endif // TARGET_NANOS +#if defined(TARGET_NANOX) + usbd_ledger_data.product = USBD_LEDGER_PRODUCT_NANOX; +#endif // TARGET_NANOX +#if defined(TARGET_NANOS2) + usbd_ledger_data.product = USBD_LEDGER_PRODUCT_NANOS_PLUS; +#endif // TARGET_NANOS2 +#if defined(TARGET_FATSTACKS) || defined(TARGET_STAX) + usbd_ledger_data.product = USBD_LEDGER_PRODUCT_STAX; +#endif // TARGET_FATSTACKS || TARGET_STAX +#if defined(TARGET_FLEX) + usbd_ledger_data.product = USBD_LEDGER_PRODUCT_FLEX; +#endif // TARGET_FLEX + + if (usbd_ledger_init_data.vid) { + usbd_ledger_data.vid = usbd_ledger_init_data.vid; + } + else { + usbd_ledger_data.vid = USBD_LEDGER_VID; + } + + if (usbd_ledger_init_data.pid) { + usbd_ledger_data.pid = usbd_ledger_init_data.pid; + } + else { + usbd_ledger_data.pid = usbd_ledger_data.product; + } + + if (usbd_ledger_init_data.class_mask & USBD_LEDGER_CLASS_HID) { + usbd_ledger_data.class[usbd_ledger_data.nb_of_class++] + = (usbd_class_info_t *) PIC(&USBD_LEDGER_HID_class_info); + } +#ifdef HAVE_USB_HIDKBD + else if (usbd_ledger_init_data.class_mask & USBD_LEDGER_CLASS_HID_KBD) { + usbd_ledger_data.class[usbd_ledger_data.nb_of_class++] + = (usbd_class_info_t *) PIC(&USBD_LEDGER_HID_KBD_class_info); + } +#endif // HAVE_USB_HIDKBD +#ifdef HAVE_IO_U2F + if (usbd_ledger_init_data.class_mask & USBD_LEDGER_CLASS_HID_U2F) { + usbd_ledger_data.class[usbd_ledger_data.nb_of_class++] + = (usbd_class_info_t *) PIC(&USBD_LEDGER_HID_U2F_class_info); + uint8_t buffer[4]; + buffer[0] = usbd_ledger_init_data.hid_u2f_settings.protocol_version; + buffer[1] = usbd_ledger_init_data.hid_u2f_settings.major_device_version_number; + buffer[2] = usbd_ledger_init_data.hid_u2f_settings.minor_device_version_number; + buffer[3] = usbd_ledger_init_data.hid_u2f_settings.build_device_version_number; + USBD_LEDGER_setting( + USBD_LEDGER_CLASS_HID_U2F, USBD_LEDGER_HID_U2F_SETTING_ID_VERSIONS, buffer, 4); + buffer[0] = usbd_ledger_init_data.hid_u2f_settings.capabilities_flag; + USBD_LEDGER_setting(USBD_LEDGER_CLASS_HID_U2F, + USBD_LEDGER_HID_U2F_SETTING_ID_CAPABILITIES_FLAG, + buffer, + 1); + cx_rng(buffer, 4); + USBD_LEDGER_setting( + USBD_LEDGER_CLASS_HID_U2F, USBD_LEDGER_HID_U2F_SETTING_ID_FREE_CID, buffer, 4); + } +#endif // HAVE_IO_U2F +#ifdef HAVE_USB_CLASS_CCID + if (usbd_ledger_init_data.class_mask & USBD_LEDGER_CLASS_CCID) { + // usbd_ledger_data.class[usbd_ledger_data.nb_of_class++] = NULL; + } +#endif // HAVE_USB_CLASS_CCID +#ifdef HAVE_WEBUSB + if (usbd_ledger_init_data.class_mask & USBD_LEDGER_CLASS_WEBUSB) { + usbd_ledger_data.bcdusb = 0x10; + usbd_ledger_data.class[usbd_ledger_data.nb_of_class++] + = (usbd_class_info_t *) PIC(&USBD_LEDGER_WEBUSB_class_info); + } +#endif // HAVE_WEBUSB +#ifdef HAVE_CDCUSB + if (usbd_ledger_init_data.class_mask & USBD_LEDGER_CLASS_CDC) { + usbd_ledger_data.class[usbd_ledger_data.nb_of_class++] + = (usbd_class_info_t *) PIC(&USBD_LEDGER_CDC_Control_class_info); + usbd_ledger_data.class[usbd_ledger_data.nb_of_class++] + = (usbd_class_info_t *) PIC(&USBD_LEDGER_CDC_Data_class_info); + usbd_ledger_data.usbd_iad = 1; + } +#endif // HAVE_CDCUSB + + usbd_ledger_data.classes = usbd_ledger_init_data.class_mask; + + USBD_DESC_init(usbd_ledger_data.name, + usbd_ledger_data.vid, + usbd_ledger_data.pid, + usbd_ledger_data.bcdusb, + usbd_ledger_data.usbd_iad, + get_bos_desc); + USBD_Init(&usbd_ledger_data.usbd_handle, (USBD_DescriptorsTypeDef *) &LEDGER_Desc, 0); + USBD_RegisterClass(&usbd_ledger_data.usbd_handle, (USBD_ClassTypeDef *) &USBD_LEDGER_CLASS); + } + if ((usbd_ledger_data.state == USBD_LEDGER_STATE_STOPPED) + || (usbd_ledger_data.state == USBD_LEDGER_STATE_INITIALIZED)) { + USBD_Start(&usbd_ledger_data.usbd_handle); + usbd_ledger_data.state = USBD_LEDGER_STATE_RUNNING; + } +} + +void USB_LEDGER_stop(void) +{ + USBD_Stop(&usbd_ledger_data.usbd_handle); + usbd_ledger_data.state = USBD_LEDGER_STATE_STOPPED; +} + +void USBD_LEDGER_add_profile(const usbd_class_info_t *class_info, uint8_t bcdusb, uint8_t usbd_iad) +{ + usbd_ledger_data.class[usbd_ledger_data.nb_of_class++] = (usbd_class_info_t *) PIC(class_info); + usbd_ledger_data.bcdusb |= bcdusb; + if (usbd_iad) { + usbd_ledger_data.usbd_iad = usbd_iad; + } + + USBD_DESC_init(usbd_ledger_data.name, + usbd_ledger_data.vid, + usbd_ledger_data.pid, + usbd_ledger_data.bcdusb, + usbd_ledger_data.usbd_iad, + get_bos_desc); +} + +void USBD_LEDGER_rx_evt_reset(void) +{ + USBD_LL_SetSpeed(&usbd_ledger_data.usbd_handle, USBD_SPEED_FULL); + USBD_LL_Reset(&usbd_ledger_data.usbd_handle); +} + +void USBD_LEDGER_rx_evt_sof(void) +{ + USBD_LL_SOF(&usbd_ledger_data.usbd_handle); +} + +void USBD_LEDGER_rx_evt_suspend(void) +{ + USBD_LL_Suspend(&usbd_ledger_data.usbd_handle); +} + +void USBD_LEDGER_rx_evt_resume(void) +{ + USBD_LL_Resume(&usbd_ledger_data.usbd_handle); +} + +void USBD_LEDGER_rx_evt_setup(uint8_t *buffer) +{ + USBD_LL_SetupStage(&usbd_ledger_data.usbd_handle, buffer); +} + +void USBD_LEDGER_rx_evt_data_in(uint8_t ep_num, uint8_t *buffer) +{ + USBD_LL_DataInStage(&usbd_ledger_data.usbd_handle, ep_num, buffer); +} + +void USBD_LEDGER_rx_evt_data_out(uint8_t ep_num, uint8_t *buffer, uint16_t length) +{ + usbd_ledger_data.usb_ep_xfer_len[ep_num & 0x7F] = length; + usbd_ledger_data.usb_ep_xfer_buffer[ep_num & 0x7F] = buffer; + USBD_LL_DataOutStage(&usbd_ledger_data.usbd_handle, ep_num, buffer); +} + +uint32_t USBD_LEDGER_send(uint8_t class_type, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms) +{ + uint32_t status = INVALID_PARAMETER; + uint8_t usb_status = USBD_OK; + uint8_t index = 0; + + usbd_class_info_t *class_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + class_info = usbd_ledger_data.class[index]; + if (class_info->type == class_type) { + usb_status + = ((usbd_send_packet_t) PIC(class_info->send_packet))(&usbd_ledger_data.usbd_handle, + class_info->cookie, + packet_type, + packet, + packet_length, + timeout_ms); + break; + } + } + + if (usb_status == USBD_OK) { + status = SWO_SUCCESS; + } + else if (usb_status == USBD_TIMEOUT) { + status = TIMEOUT; + } + + return status; +} + +int32_t USBD_LEDGER_data_ready(uint8_t *buffer, uint16_t max_length) +{ + uint8_t index = 0; + int32_t status = 0; + + usbd_class_info_t *class_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + class_info = usbd_ledger_data.class[index]; + if (class_info->data_ready) { + status = ((usbd_data_ready_t) PIC(class_info->data_ready))( + &usbd_ledger_data.usbd_handle, class_info->cookie, buffer, max_length); + if (status > 0) { + return status; + } + } + } + + return 0; +} + +void USBD_LEDGER_setting(uint32_t class_id, uint32_t setting_id, uint8_t *buffer, uint16_t length) +{ + uint8_t index = 0; + + usbd_class_info_t *class_info = NULL; + for (index = 0; index < usbd_ledger_data.nb_of_class; index++) { + class_info = usbd_ledger_data.class[index]; + if ((class_info->type == class_id) && (class_info->setting)) { + ((usbd_setting_t) PIC(class_info->setting))( + setting_id, buffer, length, class_info->cookie); + } + } +} + +int USBD_LEDGER_rx_seph_evt(uint8_t *seph_buffer, + uint16_t seph_buffer_length, + uint8_t *apdu_buffer, + uint16_t apdu_buffer_max_length) +{ + int status = 0; + + if (seph_buffer[1] == SEPROXYHAL_TAG_USB_EVENT) { + switch (seph_buffer[4]) { + case SEPROXYHAL_TAG_USB_EVENT_RESET: + USBD_LEDGER_rx_evt_reset(); + break; + + case SEPROXYHAL_TAG_USB_EVENT_SOF: + USBD_LEDGER_rx_evt_sof(); + break; + + case SEPROXYHAL_TAG_USB_EVENT_SUSPENDED: + USBD_LEDGER_rx_evt_suspend(); + break; + + case SEPROXYHAL_TAG_USB_EVENT_RESUMED: + USBD_LEDGER_rx_evt_resume(); + break; + + default: + status = -1; + break; + } + } + else if (seph_buffer[1] == SEPROXYHAL_TAG_USB_EP_XFER_EVENT) { + uint8_t epnum = seph_buffer[4] & 0x7F; + uint16_t length = MIN(seph_buffer[6], seph_buffer_length - 6); + + switch (seph_buffer[5]) { + case SEPROXYHAL_TAG_USB_EP_XFER_SETUP: + USBD_LEDGER_rx_evt_setup(&seph_buffer[7]); + break; + + case SEPROXYHAL_TAG_USB_EP_XFER_IN: + if (epnum < IO_USB_MAX_ENDPOINTS) { + USBD_LEDGER_rx_evt_data_in(epnum, &seph_buffer[7]); + } + else { + status = -1; + } + break; + + case SEPROXYHAL_TAG_USB_EP_XFER_OUT: + if (epnum < IO_USB_MAX_ENDPOINTS) { + USBD_LEDGER_rx_evt_data_out(epnum, &seph_buffer[7], length); + status = USBD_LEDGER_data_ready(apdu_buffer, apdu_buffer_max_length); + } + else { + status = -1; + } + break; + + default: + status = -1; + break; + } + } + else { + return -1; + } + + return status; +} diff --git a/lib_stusb/src/usbd_ledger_ccid.c b/lib_stusb/src/usbd_ledger_ccid.c new file mode 100644 index 000000000..d4cc07397 --- /dev/null +++ b/lib_stusb/src/usbd_ledger_ccid.c @@ -0,0 +1,321 @@ +/* @BANNER@ */ + +#ifdef HAVE_USB_CLASS_CCID +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" +#include "usbd_ledger.h" +#include "usbd_ledger_ccid.h" + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ +#define LEDGER_CCID_BULK_EPIN_ADDR (0x83) +#define LEDGER_CCID_BULK_EPIN_SIZE (0x40) +#define LEDGER_CCID_BULK_EPOUT_ADDR (0x03) +#define LEDGER_CCID_BULK_EPOUT_SIZE (0x40) + +#define CCID_FUNCTIONAL_DESCRIPTOR_TYPE (0x21) + +#define LEDGER_CCID_INTERRUPT_EPIN_ADDR (0x84) +#define LEDGER_CCID_INTERRUPT_EPIN_SIZE (0x10) + +// CCID Class-Specific Requests +#define REQ_ABORT (0x01) +#define REQ_GET_CLOCK_FREQUENCIES (0x02) +#define REQ_GET_DATA_RATES (0x03) + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + uint8_t alt_setting; +} ledger_ccid_handle_t; + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static ledger_ccid_handle_t ledger_ccid_handle; + +/* Exported variables --------------------------------------------------------*/ +const usbd_end_point_info_t LEDGER_CCID_Bulk_end_point_info = { + .ep_in_addr = LEDGER_CCID_BULK_EPIN_ADDR, + .ep_in_size = LEDGER_CCID_BULK_EPIN_SIZE, + .ep_out_addr = LEDGER_CCID_BULK_EPOUT_ADDR, + .ep_out_size = LEDGER_CCID_BULK_EPOUT_SIZE, + .ep_type = USBD_EP_TYPE_BULK, +}; + +// clang-format off +const uint8_t LEDGER_CCID_Bulk_descriptor[32] = { + /************** Interface descriptor ******************************/ + USB_LEN_IF_DESC, // bLength + USB_DESC_TYPE_INTERFACE, // bDescriptorType : interface + 0x00, // bInterfaceNumber : 0 (dynamic) + 0x00, // bAlternateSetting : 0 + 0x02, // bNumEndpoints : 2 + 0x0B, // bInterfaceClass : Smart Card Device Class + 0x00, // bInterfaceSubClass : none + 0x00, // bInterfaceProtocol : none + USBD_IDX_PRODUCT_STR, // iInterface : + + /************** Functional Descriptor *****************************/ + 0x36, // bLength + CCID_FUNCTIONAL_DESCRIPTOR_TYPE, // bDescriptorType : Functional + 0x10, 0x01, // bcdCCID : V1.10 + 0x00, // bMaxSlotIndex : 0 + 0x03, // bVoltageSupport : 3V or 5V + 0x01, 0x00, 0x00, 0x00, // dwProtocols : Protocol T=0 + 0x10, 0x0E, 0x00, 0x00, // dwDefaultClock : 3.6Mhz + 0x10, 0x0E, 0x00, 0x00, // dwMaximumClock : 3.6Mhz + 0x00, // bNumClockSupported : default and maximum clock + 0xCD, 0x25, 0x00, 0x00, // dwDataRate : 9677 bps + 0xCD, 0x25, 0x00, 0x00, // dwMaxDataRate : 9677 bps + 0x00, // bNumDataRatesSupported : between default & max data rate + 0x00, 0x00, 0x00, 0x00, // dwMaxIFSD : max IFSD for protocol T=1 + 0x00, 0x00, 0x00, 0x00, // dwSynchProtocols : None supported + 0x00, 0x00, 0x00, 0x00, // dwMechanical : No special characteristics + 0xBA, 0x06, 0x02, 0x00, // dwFeatures : - Short APDU level exchange with CCID + // - ... + 0x0F, 0x01, 0x00, 0x00, // dwMaxCCIDMessageLength : 261 + 10 + 0x00, // bClassGetResponse : default class value is 0x00 + 0x00, // bClassEnvelope : default class value is 0x00 + 0x00, 0x00, // wLcdLayout : No LCD + 0x00, // bPINSupport : Pin verification & modification not supported + 0x01, // bMaxCCIDBusySlots : Max is 1 + + /************** Endpoint descriptor *******************************/ + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_CCID_BULK_EPIN_ADDR, // bEndpointAddress + USBD_EP_TYPE_BULK, // bmAttributes + LEDGER_CCID_BULK_EPIN_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x00, // Ignored + + /************** Endpoint descriptor *******************************/ + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_CCID_BULK_EPOUT_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_CCID_BULK_EPOUT_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x00, // Ignored +}; +// clang-format on + +const usbd_class_info_t USBD_LEDGER_CCID_Bulk_class_info = { + .type = USBD_LEDGER_CLASS_CCID, + + .end_point = &LEDGER_CCID_end_point_info, + + .init = USBD_LEDGER_CCID_init, + .de_init = USBD_LEDGER_CCID_de_init, + .setup = USBD_LEDGER_CCID_setup, + .data_in = USBD_LEDGER_CCID_data_in, + .data_out = USBD_LEDGER_CCID_data_out, + + .send_packet = USBD_LEDGER_CCID_send_packet, + + .data_ready = USBD_LEDGER_CCID_data_ready, + + .interface_descriptor = LEDGER_CCID_Bulk_descriptor, + .interface_descriptor_size = sizeof(LEDGER_CCID_Bulk_descriptor), + + .interface_association_descriptor = NULL, + .interface_association_descriptor_size = 0, + + .bos_descriptor = NULL, + .bos_descriptor_size = 0, + + .cookie = &ledger_ccid_handle, +}; + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +uint8_t USBD_LEDGER_CCID_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + + ledger_ccid_handle_t *handle = (ledger_ccid_handle_t *) PIC(cookie); + + memset(handle, 0, sizeof(ledger_ccid_handle_t)); + + USBD_LL_PrepareReceive(pdev, LEDGER_CCID_BULK_EPOUT_ADDR, NULL, LEDGER_CCID_BULK_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CCID_de_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CCID_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req) +{ + if (!pdev || !cookie || !req) { + return USBD_FAIL; + } + + uint8_t ret = USBD_OK; + ledger_ccid_handle_t *handle = (ledger_ccid_handle_t *) PIC(cookie); + + uint8_t request = req->bmRequest & (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK); + + if (request == (USB_REQ_TYPE_STANDARD | USB_REQ_RECIPIENT_INTERFACE)) { + switch (req->bRequest) { + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlSendData(pdev, &handle->alt_setting, 1); + } + else { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + handle->alt_setting = (uint8_t) (req->wValue); + } + else { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + } + else if (request == (USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE)) { + switch (req->bRequest) { + case REQ_ABORT: + if ((req->bmRequest & 0x80U) == 0U) { + uint8_t bSlot = (uint8_t) req->wValue; + uint8_t bSeq = (uint8_t) (req->wValue >> 8); + // TODO_IO : handle the abort + } + else { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case REQ_GET_CLOCK_FREQUENCIES: + // Not supported : bNumClockSupported == 0 + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + + case REQ_GET_DATA_RATES: + // Not supported : bNumClockSupported == 0 + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +uint8_t USBD_LEDGER_CCID_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CCID_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + UNUSED(ep_num); + + ledger_ccid_handle_t *handle = (ledger_ccid_handle_t *) PIC(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CCID_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(ep_num); + + ledger_ccid_handle_t *handle = (ledger_ccid_handle_t *) PIC(cookie); + + USBD_LL_PrepareReceive(pdev, LEDGER_CCID_BULK_EPOUT_ADDR, NULL, LEDGER_CCID_BULK_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CCID_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(packet_type); + + uint8_t ret = USBD_OK; + ledger_ccid_handle_t *handle = (ledger_ccid_handle_t *) PIC(cookie); + + return ret; +} + +int32_t USBD_LEDGER_CCID_data_ready(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length) +{ + int32_t status = 0; + + UNUSED(pdev); + + if (!cookie || !buffer) { + return -1; + } + ledger_ccid_handle_t *handle = (ledger_ccid_handle_t *) PIC(cookie); + + return status; +} + +#endif // HAVE_USB_CLASS_CCID diff --git a/lib_stusb/src/usbd_ledger_cdc.c b/lib_stusb/src/usbd_ledger_cdc.c new file mode 100644 index 000000000..0064a425f --- /dev/null +++ b/lib_stusb/src/usbd_ledger_cdc.c @@ -0,0 +1,450 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" +#include "usbd_ledger.h" +#include "usbd_ledger_cdc.h" + +#ifdef HAVE_CDCUSB + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ +#define LEDGER_CDC_DATA_EPIN_ADDR (0x81) +#define LEDGER_CDC_DATA_EPIN_SIZE (0x40) +#define LEDGER_CDC_DATA_EPOUT_ADDR (0x01) +#define LEDGER_CDC_DATA_EPOUT_SIZE (0x40) + +#define LEDGER_CDC_CONTROL_EPIN_ADDR (0x84) +#define LEDGER_CDC_CONTROL_EPIN_SIZE (0x08) + +#define LEDGER_CDC_SET_LINE_CODING (0x20U) +#define LEDGER_CDC_GET_LINE_CODING (0x21U) + +#define MAX_PACKET_SIZE (0x40) + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +} line_coding_t; + +typedef struct { + uint8_t data[MAX_PACKET_SIZE]; + uint8_t cmd_op_code; + uint8_t cmd_length; + line_coding_t line_coding; + uint8_t alt_setting; + uint8_t tx_in_progress; +} ledger_cdc_handle_t; + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +static void control(ledger_cdc_handle_t *handle, + uint8_t cmd_opcode, + uint8_t *buffer, + uint16_t length); + +/* Private variables ---------------------------------------------------------*/ +static ledger_cdc_handle_t ledger_cdc_handle; + +/* Exported variables --------------------------------------------------------*/ + +const usbd_end_point_info_t LEDGER_CDC_Data_end_point_info = { + .ep_in_addr = LEDGER_CDC_DATA_EPIN_ADDR, + .ep_in_size = LEDGER_CDC_DATA_EPIN_SIZE, + .ep_out_addr = LEDGER_CDC_DATA_EPOUT_ADDR, + .ep_out_size = LEDGER_CDC_DATA_EPOUT_SIZE, + .ep_type = USBD_EP_TYPE_BULK, +}; + +const uint8_t LEDGER_CDC_Data_descriptors[23] = { + /************** Data interface descriptor *************************/ + USB_LEN_IF_DESC, // bLength + USB_DESC_TYPE_INTERFACE, // bDescriptorType : interface + 0x00, // bInterfaceNumber : 0 (dynamic) + 0x00, // bAlternateSetting : 0 + 0x02, // bNumEndpoints : 1 + 0x0A, // bInterfaceClass : CDC Data + 0x00, // bInterfaceSubClass : Unused + 0x00, // bInterfaceProtocol : None + 0x05, // iInterface : CDC ACM Data + + /************** Endpoint descriptor *******************************/ + 0x07, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_CDC_DATA_EPOUT_ADDR, // bEndpointAddress + USBD_EP_TYPE_BULK, // bmAttributes + MAX_PACKET_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x00, // bInterval + + /************** Endpoint descriptor *******************************/ + 0x07, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_CDC_DATA_EPIN_ADDR, // bEndpointAddress + USBD_EP_TYPE_BULK, // bmAttributes + MAX_PACKET_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x00, // bInterval +}; + +const usbd_class_info_t USBD_LEDGER_CDC_Data_class_info = { + .type = USBD_LEDGER_CLASS_CDC_DATA, + + .end_point = &LEDGER_CDC_Data_end_point_info, + + .init = USBD_LEDGER_CDC_init, + .de_init = USBD_LEDGER_CDC_de_init, + .setup = USBD_LEDGER_CDC_setup, + .data_in = USBD_LEDGER_CDC_data_in, + .data_out = USBD_LEDGER_CDC_data_out, + + .send_packet = USBD_LEDGER_CDC_send_packet, + + .data_ready = NULL, + + .setting = NULL, + + .interface_descriptor = LEDGER_CDC_Data_descriptors, + .interface_descriptor_size = sizeof(LEDGER_CDC_Data_descriptors), + + .interface_association_descriptor = NULL, + .interface_association_descriptor_size = 0, + + .bos_descriptor = NULL, + .bos_descriptor_size = 0, + + .cookie = &ledger_cdc_handle, +}; + +const usbd_end_point_info_t LEDGER_CDC_Control_end_point_info = { + .ep_in_addr = LEDGER_CDC_CONTROL_EPIN_ADDR, + .ep_in_size = LEDGER_CDC_CONTROL_EPIN_SIZE, + .ep_out_addr = 0xFF, + .ep_out_size = 0, + .ep_type = USBD_EP_TYPE_INTR, +}; + +const uint8_t LEDGER_CDC_Control_descriptors[35] = { + /************** Interface descriptor ******************************/ + USB_LEN_IF_DESC, // bLength + USB_DESC_TYPE_INTERFACE, // bDescriptorType : interface + 0x00, // bInterfaceNumber : 0 (dynamic) + 0x00, // bAlternateSetting : 0 + 0x01, // bNumEndpoints : 1 + 0x02, // bInterfaceClass : Communications + 0x02, // bInterfaceSubClass : Abstract (modem) + 0x00, // bInterfaceProtocol : None + 0x04, // iInterface : CDC Abstract Control Model (ACM) + + /************** CDC Header Functional Descriptor ******************/ + 0x05, // bLength + 0x24, // bDescriptorType : CDC + 0x01, // bDescriptorSubtype : Header + 0x01, // bcdCDC : Specification release number + 0x00, // bcdCDC : Specification release number + + /************** CDC Call Management Functional Descriptor *********/ + 0x05, // bLength + 0x24, // bDescriptorType : CDC + 0x01, // bDescriptorSubtype : Call Management + 0x00, // bmCapabilities : none + 0x00, // bDataInterface : 0 (dynamic) + + /************** CDC ACM Functional Descriptor *********************/ + 0x04, // bLength + 0x24, // bDescriptorType : CDC + 0x01, // bDescriptorSubtype : ACM + 0x02, // bmCapabilities : line coding and serial state + + /************** CDC Union Functional Descriptor *******************/ + 0x05, // bLength + 0x24, // bDescriptorType : CDC + 0x06, // bDescriptorSubtype : Union + 0x00, // bMasterInterface : 0 (dynamic) + 0x00, // bSlaveInterface : 0 (dynamic) + + /************** Endpoint descriptor *******************************/ + 0x07, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_CDC_CONTROL_EPIN_ADDR, // bEndpointAddress + 0x03, // bmAttributes : Interrupt/No Sync/Data + LEDGER_CDC_CONTROL_EPIN_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x10, // bInterval +}; + +const uint8_t LEDGER_CDC_Control_interface_association_descriptor[8] = { + /************** Interface Association descriptor ******************/ + 0x08, // bLength + 0x0B, // bDescriptorType : Interface Association + 0x00, // bFirstInterface : 0 (dynamic) + 0x02, // bInterfaceCount + 0x02, // bFunctionClass : Communications + 0x02, // bFunctionSubClass : Abstract (modem) + 0x00, // bFunctionProtocol : None + 0x04, // iFunction : +}; + +const usbd_class_info_t USBD_LEDGER_CDC_Control_class_info = { + .type = USBD_LEDGER_CLASS_CDC_CONTROL, + + .end_point = &LEDGER_CDC_Control_end_point_info, + + .init = USBD_LEDGER_CDC_cmd_init, + .de_init = USBD_LEDGER_CDC_de_init, + .setup = USBD_LEDGER_CDC_setup, + .data_in = USBD_LEDGER_CDC_data_in, + .data_out = USBD_LEDGER_CDC_data_out, + + .send_packet = USBD_LEDGER_CDC_send_packet, + + .data_ready = NULL, + + .setting = NULL, + + .interface_descriptor = LEDGER_CDC_Control_descriptors, + .interface_descriptor_size = sizeof(LEDGER_CDC_Control_descriptors), + + .interface_association_descriptor = LEDGER_CDC_Control_interface_association_descriptor, + .interface_association_descriptor_size + = sizeof(LEDGER_CDC_Control_interface_association_descriptor), + + .bos_descriptor = NULL, + .bos_descriptor_size = 0, + + .cookie = &ledger_cdc_handle, +}; + +/* Private functions ---------------------------------------------------------*/ +static void control(ledger_cdc_handle_t *handle, + uint8_t cmd_opcode, + uint8_t *buffer, + uint16_t length) +{ + UNUSED(length); + + switch (cmd_opcode) { + case LEDGER_CDC_SET_LINE_CODING: + handle->line_coding.bitrate = (uint32_t) ((buffer[0] << 0) | (buffer[1] << 8) + | (buffer[2] << 16) | (buffer[3] << 24)); + handle->line_coding.format = buffer[4]; + handle->line_coding.paritytype = buffer[5]; + handle->line_coding.datatype = buffer[6]; + break; + + case LEDGER_CDC_GET_LINE_CODING: + buffer[0] = (uint8_t) (handle->line_coding.bitrate >> 0); + buffer[1] = (uint8_t) (handle->line_coding.bitrate >> 8); + buffer[2] = (uint8_t) (handle->line_coding.bitrate >> 16); + buffer[3] = (uint8_t) (handle->line_coding.bitrate >> 24); + buffer[4] = handle->line_coding.format; + buffer[5] = handle->line_coding.paritytype; + buffer[6] = handle->line_coding.datatype; + break; + + default: + break; + } +} + +/* Exported functions --------------------------------------------------------*/ +uint8_t USBD_LEDGER_CDC_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + + ledger_cdc_handle_t *handle = (ledger_cdc_handle_t *) PIC(cookie); + + memset(handle, 0, sizeof(ledger_cdc_handle_t)); + + USBD_LL_PrepareReceive(pdev, LEDGER_CDC_DATA_EPOUT_ADDR, NULL, LEDGER_CDC_DATA_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CDC_cmd_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + pdev->ep_in[LEDGER_CDC_CONTROL_EPIN_ADDR & 0xFU].bInterval = 0x10; + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CDC_de_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CDC_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req) +{ + if (!pdev || !cookie || !req) { + return USBD_FAIL; + } + + uint8_t ret = USBD_OK; + ledger_cdc_handle_t *handle = (ledger_cdc_handle_t *) PIC(cookie); + uint16_t status_info = 0x0000; + uint16_t length = 0; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) { + case USB_REQ_TYPE_CLASS: + if ((req->bmRequest & 0x80U) != 0U) { + control(handle, req->bRequest, handle->data, req->wLength); + length = MIN(7, req->wLength); + (void) USBD_CtlSendData(pdev, handle->data, length); + } + else { + handle->cmd_op_code = req->bRequest; + handle->cmd_length = (uint8_t) req->wLength; + (void) USBD_CtlPrepareRx(pdev, handle->data, req->wLength); + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlSendData( + pdev, (uint8_t *) (void *) &status_info, sizeof(status_info)); + } + else { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlSendData(pdev, &handle->alt_setting, 1); + } + else { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + handle->alt_setting = (uint8_t) (req->wValue); + } + else { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + return ret; + + return ret; +} + +uint8_t USBD_LEDGER_CDC_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CDC_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num) +{ + if (!pdev || !cookie) { + return USBD_FAIL; + } + + ledger_cdc_handle_t *handle = (ledger_cdc_handle_t *) PIC(cookie); + + if ((pdev->ep_in[ep_num].total_length > 0) + && ((pdev->ep_in[ep_num].total_length % MAX_PACKET_SIZE) == 0)) { + pdev->ep_in[ep_num].total_length = 0; + (void) USBD_LL_Transmit(pdev, ep_num, NULL, 0, 0); + } + else { + handle->tx_in_progress = 0; + } + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CDC_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length) +{ + if (!pdev) { + return USBD_FAIL; + } + + UNUSED(cookie); + UNUSED(packet); + UNUSED(packet_length); + + if (ep_num == LEDGER_CDC_DATA_EPOUT_ADDR) { + USBD_LL_PrepareReceive(pdev, LEDGER_CDC_DATA_EPOUT_ADDR, NULL, LEDGER_CDC_DATA_EPOUT_SIZE); + } + + return USBD_OK; +} + +uint8_t USBD_LEDGER_CDC_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(packet_type); + + uint8_t ret = USBD_OK; + ledger_cdc_handle_t *handle = (ledger_cdc_handle_t *) PIC(cookie); + + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (handle->tx_in_progress == 0) { + handle->tx_in_progress = 1; + USBD_LL_Transmit(pdev, LEDGER_CDC_DATA_EPIN_ADDR, packet, packet_length, timeout_ms); + } + else { + return USBD_BUSY; + } + } + + return ret; +} + +#endif // HAVE_CDCUSB diff --git a/lib_stusb/src/usbd_ledger_hid.c b/lib_stusb/src/usbd_ledger_hid.c new file mode 100644 index 000000000..707cb859a --- /dev/null +++ b/lib_stusb/src/usbd_ledger_hid.c @@ -0,0 +1,418 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "ledger_protocol.h" +#include "usbd_ioreq.h" +#include "usbd_ledger.h" +#include "usbd_ledger_hid.h" + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ +enum ledger_hid_state_t { + LEDGER_HID_STATE_IDLE, + LEDGER_HID_STATE_BUSY, +}; + +/* Private defines------------------------------------------------------------*/ +#define LEDGER_HID_EPIN_ADDR (0x82) +#define LEDGER_HID_EPIN_SIZE (0x40) +#define LEDGER_HID_EPOUT_ADDR (0x02) +#define LEDGER_HID_EPOUT_SIZE (0x40) + +#define HID_DESCRIPTOR_TYPE (0x21) +#define HID_REPORT_DESCRIPTOR_TYPE (0x22) + +// HID Class-Specific Requests +#define REQ_SET_REPORT (0x09) +#define REQ_GET_REPORT (0x01) +#define REQ_SET_IDLE (0x0A) +#define REQ_GET_IDLE (0x02) +#define REQ_SET_PROTOCOL (0x0B) +#define REQ_GET_PROTOCOL (0x03) + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + uint8_t protocol; + uint8_t idle_state; + uint8_t alt_setting; + uint8_t state; // ledger_hid_state_t + ledger_protocol_t protocol_data; +} ledger_hid_handle_t; + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static ledger_hid_handle_t ledger_hid_handle; +static uint8_t ledger_protocol_chunk_buffer[LEDGER_HID_EPIN_SIZE]; + +/* Exported variables --------------------------------------------------------*/ +const usbd_end_point_info_t LEDGER_HID_end_point_info = { + .ep_in_addr = LEDGER_HID_EPIN_ADDR, + .ep_in_size = LEDGER_HID_EPIN_SIZE, + .ep_out_addr = LEDGER_HID_EPOUT_ADDR, + .ep_out_size = LEDGER_HID_EPOUT_SIZE, + .ep_type = USBD_EP_TYPE_INTR, +}; + +// clang-format off +const uint8_t LEDGER_HID_report_descriptor[34] = { + 0x06, 0xA0, 0xFF, // Usage page : vendor defined + 0x09, 0x01, // Usage ID : vendor defined + 0xA1, 0x01, // Collection : application + + // The Input report + 0x09, 0x03, // Usage ID : vendor defined + 0x15, 0x00, // Logical Minimum : 0 + 0x26, 0xFF, 0x00, // Logical Maximum : 255 + 0x75, 0x08, // Report Size : 8 bits + 0x95, LEDGER_HID_EPIN_SIZE, // Report Count : 64 fields + 0x81, 0x08, // Input : Data, Array, Absolute, Wrap + + // The Output report + 0x09, 0x04, // Usage ID : vendor defined + 0x15, 0x00, // Logical Minimum : 0 + 0x26, 0xFF, 0x00, // Logical Maximum : 255 + 0x75, 0x08, // Report Size : 8 bits + 0x95, LEDGER_HID_EPOUT_SIZE, // Report Count : 64 fields + 0x91, 0x08, // Output : Data, Array, Absolute, Wrap + + 0xC0 // Collection : end +}; + +const uint8_t LEDGER_HID_descriptors[32] = { + /************** Interface descriptor ******************************/ + USB_LEN_IF_DESC, // bLength + USB_DESC_TYPE_INTERFACE, // bDescriptorType : interface + 0x00, // bInterfaceNumber : 0 (dynamic) + 0x00, // bAlternateSetting : 0 + 0x02, // bNumEndpoints : 2 + 0x03, // bInterfaceClass : HID + 0x00, // bInterfaceSubClass : none + 0x00, // bInterfaceProtocol : none + USBD_IDX_PRODUCT_STR, // iInterface : + + /************** HID descriptor ************************************/ + 0x09, // bLength + HID_DESCRIPTOR_TYPE, // bDescriptorType : HID + 0x11, // bcdHID + 0x01, // bcdHID : V1.11 + 0x00, // bCountryCode : not supported + 0x01, // bNumDescriptors : 1 + HID_REPORT_DESCRIPTOR_TYPE, // bDescriptorType : report + sizeof(LEDGER_HID_report_descriptor), // wItemLength + 0x00, + + /************** Endpoint descriptor *******************************/ + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_HID_EPIN_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_HID_EPIN_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x01, // bInterval + + /************** Endpoint descriptor *******************************/ + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_HID_EPOUT_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_HID_EPOUT_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x01, // bInterval +}; +// clang-format on + +const usbd_class_info_t USBD_LEDGER_HID_class_info = { + .type = USBD_LEDGER_CLASS_HID, + + .end_point = &LEDGER_HID_end_point_info, + + .init = USBD_LEDGER_HID_init, + .de_init = USBD_LEDGER_HID_de_init, + .setup = USBD_LEDGER_HID_setup, + .data_in = USBD_LEDGER_HID_data_in, + .data_out = USBD_LEDGER_HID_data_out, + + .send_packet = USBD_LEDGER_HID_send_packet, + + .data_ready = USBD_LEDGER_HID_data_ready, + + .interface_descriptor = LEDGER_HID_descriptors, + .interface_descriptor_size = sizeof(LEDGER_HID_descriptors), + + .interface_association_descriptor = NULL, + .interface_association_descriptor_size = 0, + + .bos_descriptor = NULL, + .bos_descriptor_size = 0, + + .cookie = &ledger_hid_handle, +}; + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +uint8_t USBD_LEDGER_HID_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + + ledger_hid_handle_t *handle = (ledger_hid_handle_t *) PIC(cookie); + + memset(handle, 0, sizeof(ledger_hid_handle_t)); + + memset(&handle->protocol_data, 0, sizeof(handle->protocol_data)); + handle->protocol_data.rx_apdu_buffer = USBD_LEDGER_io_buffer; + handle->protocol_data.rx_apdu_buffer_size = sizeof(USBD_LEDGER_io_buffer); + handle->protocol_data.tx_chunk_buffer = ledger_protocol_chunk_buffer; + handle->protocol_data.tx_chunk_buffer_size = sizeof(ledger_protocol_chunk_buffer); + handle->protocol_data.mtu = sizeof(ledger_protocol_chunk_buffer); + + LEDGER_PROTOCOL_init(&handle->protocol_data, OS_IO_PACKET_TYPE_USB_HID_APDU); + + USBD_LL_PrepareReceive(pdev, LEDGER_HID_EPOUT_ADDR, NULL, LEDGER_HID_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_de_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req) +{ + if (!pdev || !cookie || !req) { + return USBD_FAIL; + } + + uint8_t ret = USBD_OK; + ledger_hid_handle_t *handle = (ledger_hid_handle_t *) PIC(cookie); + + uint8_t request = req->bmRequest & (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK); + + // HID Standard Requests + if (request == (USB_REQ_TYPE_STANDARD | USB_REQ_RECIPIENT_INTERFACE)) { + switch (req->bRequest) { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + uint16_t status_info = 0x0000; + USBD_CtlSendData(pdev, (uint8_t *) (void *) &status_info, sizeof(status_info)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_DESCRIPTOR: + if (req->wValue == ((uint16_t) (HID_DESCRIPTOR_TYPE << 8))) { + USBD_CtlSendData(pdev, + (uint8_t *) PIC(&LEDGER_HID_descriptors[USB_LEN_IF_DESC]), + MIN(LEDGER_HID_descriptors[USB_LEN_IF_DESC], req->wLength)); + } + else if (req->wValue == ((uint16_t) (HID_REPORT_DESCRIPTOR_TYPE << 8))) { + USBD_CtlSendData(pdev, + (uint8_t *) PIC(LEDGER_HID_report_descriptor), + MIN(sizeof(LEDGER_HID_report_descriptor), req->wLength)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlSendData(pdev, &handle->alt_setting, sizeof(handle->alt_setting)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + handle->alt_setting = (uint8_t) (req->wValue); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + ret = USBD_FAIL; + break; + } + } + // HID Class-Specific Requests + else if (request == (USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE)) { + switch (req->bRequest) { + case REQ_SET_PROTOCOL: + handle->protocol = (uint8_t) (req->wValue); + break; + + case REQ_GET_PROTOCOL: + USBD_CtlSendData(pdev, &handle->protocol, sizeof(handle->protocol)); + break; + + case REQ_SET_IDLE: + handle->idle_state = (uint8_t) (req->wValue >> 8); + break; + + case REQ_GET_IDLE: + USBD_CtlSendData(pdev, &handle->idle_state, sizeof(handle->idle_state)); + break; + + default: + ret = USBD_FAIL; + break; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +uint8_t USBD_LEDGER_HID_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + UNUSED(ep_num); + + ledger_hid_handle_t *handle = (ledger_hid_handle_t *) PIC(cookie); + + if (handle->protocol_data.tx_apdu_buffer) { + LEDGER_PROTOCOL_tx(&handle->protocol_data, NULL, 0); + if (handle->protocol_data.tx_chunk_length >= 2) { + handle->state = LEDGER_HID_STATE_BUSY; + USBD_LL_Transmit(pdev, + LEDGER_HID_EPIN_ADDR, + handle->protocol_data.tx_chunk_buffer, + LEDGER_HID_EPIN_SIZE, + 0); + } + } + if (!handle->protocol_data.tx_apdu_buffer) { + handle->protocol_data.tx_chunk_length = 0; + handle->state = LEDGER_HID_STATE_IDLE; + } + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(ep_num); + + ledger_hid_handle_t *handle = (ledger_hid_handle_t *) PIC(cookie); + + LEDGER_PROTOCOL_rx(&handle->protocol_data, packet, packet_length); + + USBD_LL_PrepareReceive(pdev, LEDGER_HID_EPOUT_ADDR, NULL, LEDGER_HID_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(packet_type); + + uint8_t ret = USBD_OK; + ledger_hid_handle_t *handle = (ledger_hid_handle_t *) PIC(cookie); + + LEDGER_PROTOCOL_tx(&handle->protocol_data, packet, packet_length); + + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (handle->state == LEDGER_HID_STATE_IDLE) { + if (handle->protocol_data.tx_chunk_length >= 2) { + handle->state = LEDGER_HID_STATE_BUSY; + ret = USBD_LL_Transmit(pdev, + LEDGER_HID_EPIN_ADDR, + handle->protocol_data.tx_chunk_buffer, + LEDGER_HID_EPIN_SIZE, + timeout_ms); + } + else { + ret = USBD_FAIL; + } + } + else { + ret = USBD_BUSY; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +int32_t USBD_LEDGER_HID_data_ready(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length) +{ + int32_t status = 0; + + UNUSED(pdev); + + if (!cookie || !buffer) { + return -1; + } + ledger_hid_handle_t *handle = (ledger_hid_handle_t *) PIC(cookie); + + if (handle->protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { + if (max_length < handle->protocol_data.rx_apdu_length) { + status = -1; + } + else { + memmove( + buffer, handle->protocol_data.rx_apdu_buffer, handle->protocol_data.rx_apdu_length); + status = handle->protocol_data.rx_apdu_length; + } + handle->protocol_data.rx_apdu_status = APDU_STATUS_WAITING; + } + + return status; +} diff --git a/lib_stusb/src/usbd_ledger_hid_kbd.c b/lib_stusb/src/usbd_ledger_hid_kbd.c new file mode 100644 index 000000000..bb8aa07b6 --- /dev/null +++ b/lib_stusb/src/usbd_ledger_hid_kbd.c @@ -0,0 +1,366 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" +#include "usbd_ledger.h" +#include "usbd_ledger_hid_kbd.h" + +#ifdef HAVE_USB_HIDKBD + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ +enum ledger_hid_kbd_state_t { + LEDGER_HID_KBD_STATE_IDLE, + LEDGER_HID_KBD_STATE_BUSY, +}; + +/* Private defines------------------------------------------------------------*/ +#define LEDGER_HID_KBD_EPIN_ADDR (0x82) +#define LEDGER_HID_KBD_EPIN_SIZE (0x08) +#define LEDGER_HID_KBD_EPOUT_ADDR (0x02) +#define LEDGER_HID_KBD_EPOUT_SIZE (0x08) + +#define HID_DESCRIPTOR_TYPE (0x21) +#define HID_REPORT_DESCRIPTOR_TYPE (0x22) + +// HID Class-Specific Requests +#define REQ_SET_REPORT (0x09) +#define REQ_GET_REPORT (0x01) +#define REQ_SET_IDLE (0x0A) +#define REQ_GET_IDLE (0x02) +#define REQ_SET_PROTOCOL (0x0B) +#define REQ_GET_PROTOCOL (0x03) + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + uint8_t protocol; + uint8_t idle_state; + uint8_t alt_setting; + uint8_t state; // ledger_hid_kbd_state_t +} ledger_hid_kbd_handle_t; + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static ledger_hid_kbd_handle_t ledger_hid_kbd_handle; + +/* Exported variables --------------------------------------------------------*/ +const usbd_end_point_info_t LEDGER_HID_KBD_end_point_info = { + .ep_in_addr = LEDGER_HID_KBD_EPIN_ADDR, + .ep_in_size = LEDGER_HID_KBD_EPIN_SIZE, + .ep_out_addr = LEDGER_HID_KBD_EPOUT_ADDR, + .ep_out_size = LEDGER_HID_KBD_EPOUT_SIZE, + .ep_type = USBD_EP_TYPE_INTR, +}; + +const uint8_t LEDGER_HID_KBD_report_descriptor[63] = { + 0x05, 0x01, // Usage page : Generic Desktop + 0x09, 0x06, // Usage ID : Keyboard + 0xA1, 0x01, // Collection : application + + 0x05, 0x07, // Usage page : Keyboard + 0x19, 0xE0, // Usage minimum : Keyboard LeftControl + 0x29, 0xE7, // Usage maximum : Keyboard Right GUI + 0x15, 0x00, // Logical minimum : 0 + 0x25, 0x01, // Logical maximum : 1 + 0x75, 0x01, // Report size : 1 bit + 0x95, 0x08, // Report count : 8 fields + 0x81, 0x02, // Input : Data, Variable, Absolute + 0x95, 0x01, // Report count : 1 fields + 0x75, 0x08, // Report size : 8 bit + 0x81, 0x01, // Input : onstant, Array, Absolute + 0x95, 0x05, // Report count : 5 fields + 0x75, 0x01, // Report size : 1 bit + + 0x05, 0x08, // Usage page : LEDs + 0x19, 0x01, // Usage minimum : Num Lock + 0x29, 0x05, // Usage maximum : Kana + 0x91, 0x02, // Output : Data, Variable, Absolute + 0x95, 0x01, // Report count : 1 fields + 0x75, 0x03, // Report size : 3 bit + 0x91, 0x01, // Output : Constant, Array, Absolute + 0x95, 0x06, // Report count : 6 fields + 0x75, 0x08, // Report size : 8 bit + 0x15, 0x00, // Logical minimum : 0 + 0x25, 0x65, // Logical maximum : 101 + + 0x05, 0x07, // Usage page : Keyboard + 0x19, 0x00, // Usage minimum : Reserved (no event indicated) + 0x29, 0x65, // Usage maximum : Keyboard application + 0x81, 0x00, // Input : Data, Array, Absolute + 0xC0 // Collection : end +}; + +const uint8_t LEDGER_HID_KBD_descriptors[32] = { + USB_LEN_IF_DESC, // bLength + USB_DESC_TYPE_INTERFACE, // bDescriptorType : interface + 0x00, // bInterfaceNumber : 0 + 0x00, // bAlternateSetting : 0 + 0x02, // bNumEndpoints : 2 + 0x03, // bInterfaceClass : HID + 0x01, // bInterfaceSubClass : boot + 0x01, // bInterfaceProtocol : keyboard + USBD_IDX_PRODUCT_STR, // iInterface : no string + + 0x09, // bLength: + 0x21, // bDescriptorType : HID + 0x11, // bcdHID + 0x01, // bcdHID : V1.11 + 0x21, // bCountryCode : US + 0x01, // bNumDescriptors : 1 + 0x22, // bDescriptorType : report + sizeof(LEDGER_HID_KBD_report_descriptor), // wItemLength + 0x00, + + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_HID_KBD_EPIN_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_HID_KBD_EPIN_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x01, // bInterval + + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_HID_KBD_EPOUT_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_HID_KBD_EPOUT_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x01, // bInterval +}; + +const usbd_class_info_t USBD_LEDGER_HID_KBD_class_info = { + .type = USBD_LEDGER_CLASS_HID_KBD, + + .end_point = &LEDGER_HID_KBD_end_point_info, + + .init = USBD_LEDGER_HID_KBD_init, + .de_init = USBD_LEDGER_HID_KBD_de_init, + .setup = USBD_LEDGER_HID_KBD_setup, + .data_in = USBD_LEDGER_HID_KBD_data_in, + .data_out = USBD_LEDGER_HID_KBD_data_out, + + .send_packet = USBD_LEDGER_HID_KBD_send_packet, + + .data_ready = NULL, + + .setting = NULL, + + .interface_descriptor = LEDGER_HID_KBD_descriptors, + .interface_descriptor_size = sizeof(LEDGER_HID_KBD_descriptors), + + .interface_association_descriptor = NULL, + .interface_association_descriptor_size = 0, + + .bos_descriptor = NULL, + .bos_descriptor_size = 0, + + .cookie = &ledger_hid_kbd_handle, +}; + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +uint8_t USBD_LEDGER_HID_KBD_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + if (!pdev || !cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + + ledger_hid_kbd_handle_t *handle = (ledger_hid_kbd_handle_t *) PIC(cookie); + + memset(handle, 0, sizeof(ledger_hid_kbd_handle_t)); + USBD_LL_PrepareReceive(pdev, LEDGER_HID_KBD_EPOUT_ADDR, NULL, LEDGER_HID_KBD_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_KBD_de_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_KBD_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req) +{ + if (!pdev || !cookie || !req) { + return USBD_FAIL; + } + + uint8_t ret = USBD_OK; + ledger_hid_kbd_handle_t *handle = (ledger_hid_kbd_handle_t *) PIC(cookie); + + uint8_t request = req->bmRequest & (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK); + + // HID Standard Requests + if (request == (USB_REQ_TYPE_STANDARD | USB_REQ_RECIPIENT_INTERFACE)) { + switch (req->bRequest) { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + uint16_t status_info = 0x0000; + USBD_CtlSendData(pdev, (uint8_t *) (void *) &status_info, sizeof(status_info)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_DESCRIPTOR: + if (req->wValue == ((uint16_t) (HID_DESCRIPTOR_TYPE << 8))) { + USBD_CtlSendData( + pdev, + (uint8_t *) PIC(&LEDGER_HID_KBD_descriptors[USB_LEN_IF_DESC]), + MIN(LEDGER_HID_KBD_descriptors[USB_LEN_IF_DESC], req->wLength)); + } + else if (req->wValue == ((uint16_t) (HID_REPORT_DESCRIPTOR_TYPE << 8))) { + USBD_CtlSendData(pdev, + (uint8_t *) PIC(LEDGER_HID_KBD_report_descriptor), + MIN(sizeof(LEDGER_HID_KBD_report_descriptor), req->wLength)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlSendData(pdev, &handle->alt_setting, sizeof(handle->alt_setting)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + handle->alt_setting = (uint8_t) (req->wValue); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + ret = USBD_FAIL; + break; + } + } + // HID Class-Specific Requests + else if (request == (USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE)) { + switch (req->bRequest) { + case REQ_SET_PROTOCOL: + handle->protocol = (uint8_t) (req->wValue); + break; + + case REQ_GET_PROTOCOL: + USBD_CtlSendData(pdev, &handle->protocol, sizeof(handle->protocol)); + break; + + case REQ_SET_IDLE: + handle->idle_state = (uint8_t) (req->wValue >> 8); + break; + + case REQ_GET_IDLE: + USBD_CtlSendData(pdev, &handle->idle_state, sizeof(handle->idle_state)); + break; + + default: + ret = USBD_FAIL; + break; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +uint8_t USBD_LEDGER_HID_KBD_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_KBD_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num) +{ + if (!pdev || !cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + UNUSED(ep_num); + + ledger_hid_kbd_handle_t *handle = (ledger_hid_kbd_handle_t *) PIC(cookie); + + handle->state = LEDGER_HID_KBD_STATE_IDLE; + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_KBD_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length) +{ + if (!pdev) { + return USBD_FAIL; + } + + UNUSED(cookie); + UNUSED(ep_num); + UNUSED(packet); + UNUSED(packet_length); + + USBD_LL_PrepareReceive(pdev, LEDGER_HID_KBD_EPOUT_ADDR, NULL, LEDGER_HID_KBD_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_KBD_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(packet_type); + UNUSED(packet_length); + + uint8_t ret = USBD_OK; + ledger_hid_kbd_handle_t *handle = (ledger_hid_kbd_handle_t *) PIC(cookie); + + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (handle->state == LEDGER_HID_KBD_STATE_IDLE) { + ret = USBD_LL_Transmit( + pdev, LEDGER_HID_KBD_EPIN_ADDR, packet, LEDGER_HID_KBD_EPIN_SIZE, timeout_ms); + } + else { + ret = USBD_BUSY; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +#endif // HAVE_USB_HIDKBD diff --git a/lib_stusb/src/usbd_ledger_hid_u2f.c b/lib_stusb/src/usbd_ledger_hid_u2f.c new file mode 100644 index 000000000..15b3bd308 --- /dev/null +++ b/lib_stusb/src/usbd_ledger_hid_u2f.c @@ -0,0 +1,642 @@ +/* @BANNER@ */ + +#ifdef HAVE_IO_U2F +/* Includes ------------------------------------------------------------------*/ +#include "lcx_crc.h" +#include "u2f_transport.h" +#include "usbd_ioreq.h" +#include "usbd_ledger.h" +#include "u2f_types.h" +#include "usbd_ledger_hid_u2f.h" + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ +enum ledger_hid_u2f_state_t { + LEDGER_HID_U2F_STATE_IDLE, + LEDGER_HID_U2F_STATE_BUSY, +}; + +enum ledger_hid_u2f_user_presence_t { + LEDGER_HID_U2F_USER_PRESENCE_IDLE, + LEDGER_HID_U2F_USER_PRESENCE_ASKING, + LEDGER_HID_U2F_USER_PRESENCE_CONFIRMED, +}; + +/* Private defines------------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ +#define LEDGER_HID_U2F_EPIN_ADDR (0x81) +#define LEDGER_HID_U2F_EPIN_SIZE (0x40) +#define LEDGER_HID_U2F_EPOUT_ADDR (0x01) +#define LEDGER_HID_U2F_EPOUT_SIZE (0x40) + +#define HID_DESCRIPTOR_TYPE (0x21) +#define HID_REPORT_DESCRIPTOR_TYPE (0x22) + +// HID Class-Specific Requests +#define REQ_SET_REPORT (0x09) +#define REQ_GET_REPORT (0x01) +#define REQ_SET_IDLE (0x0A) +#define REQ_GET_IDLE (0x02) +#define REQ_SET_PROTOCOL (0x0B) +#define REQ_GET_PROTOCOL (0x03) + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + // HID + uint8_t protocol; + uint8_t alt_setting; + uint8_t idle_state; + uint8_t state; // ledger_hid_u2f_state_t + + // Transport + u2f_transport_t transport_data; + + // User presence handling + uint16_t message_crc; + uint8_t user_presence; // ledger_hid_u2f_user_presence_t + uint8_t *backup_message; + uint16_t backup_message_length; + + // Context + uint8_t os_context; + +} ledger_hid_u2f_handle_t; + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static ledger_hid_u2f_handle_t ledger_hid_u2f_handle; +static uint8_t u2f_transport_packet_buffer[LEDGER_HID_U2F_EPIN_SIZE]; +static usdb_ledger_hid_u2f_settings_t ledger_hid_u2f_settings; +static uint32_t ledger_hid_free_cid; + +/* Exported variables --------------------------------------------------------*/ +const usbd_end_point_info_t LEDGER_HID_U2F_end_point_info = { + .ep_in_addr = LEDGER_HID_U2F_EPIN_ADDR, + .ep_in_size = LEDGER_HID_U2F_EPIN_SIZE, + .ep_out_addr = LEDGER_HID_U2F_EPOUT_ADDR, + .ep_out_size = LEDGER_HID_U2F_EPOUT_SIZE, + .ep_type = USBD_EP_TYPE_INTR, +}; + +// clang-format off +const uint8_t LEDGER_HID_U2F_report_descriptor[34] = { + 0x06, 0xD0, 0xF1, // Usage page : FIDO_USAGE_PAGE + 0x09, 0x01, // Usage ID : FIDO_USAGE_CTAPHID + 0xA1, 0x01, // Collection : HID_Application + + // The Input report + 0x09, 0x03, // Usage ID : FIDO_USAGE_DATA_IN + 0x15, 0x00, // Logical Minimum : 0 + 0x26, 0xFF, 0x00, // Logical Maximum : 255 + 0x75, 0x08, // Report Size : 8 bits + 0x95, LEDGER_HID_U2F_EPIN_SIZE, // Report Count : 64 fields + 0x81, 0x08, // Input : Data, Variable, Absolute, No Wrap + + // The Output report + 0x09, 0x04, // Usage ID : FIDO_USAGE_DATA_OUT + 0x15, 0x00, // Logical Minimum : 0 + 0x26, 0xFF, 0x00, // Logical Maximum : 255 + 0x75, 0x08, // Report Size : 8 bits + 0x95, LEDGER_HID_U2F_EPOUT_SIZE, // Report Count : 64 fields + 0x91, 0x08, // Output : Data, Variable, Absolute, No Wrap + + 0xC0 // Collection : end +}; + +const uint8_t LEDGER_HID_U2F_descriptors[32] = { + /************** Interface descriptor ******************************/ + USB_LEN_IF_DESC, // bLength + USB_DESC_TYPE_INTERFACE, // bDescriptorType : interface + 0x00, // bInterfaceNumber : 0 (dynamic) + 0x00, // bAlternateSetting : 0 + 0x02, // bNumEndpoints : 2 + 0x03, // bInterfaceClass : HID + 0x01, // bInterfaceSubClass : boot + 0x01, // bInterfaceProtocol : keyboard + USBD_IDX_PRODUCT_STR, // iInterface : + + /************** HID descriptor ************************************/ + 0x09, // bLength: + HID_DESCRIPTOR_TYPE, // bDescriptorType : HID + 0x11, // bcdHID + 0x01, // bcdHID : V1.11 + 0x21, // bCountryCode : US + 0x01, // bNumDescriptors : 1 + HID_REPORT_DESCRIPTOR_TYPE, // bDescriptorType : report + sizeof(LEDGER_HID_U2F_report_descriptor), // wItemLength + 0x00, + + /************** Endpoint descriptor *******************************/ + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_HID_U2F_EPIN_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_HID_U2F_EPIN_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x01, // bInterval + + /************** Endpoint descriptor *******************************/ + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_HID_U2F_EPOUT_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_HID_U2F_EPOUT_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x01, // bInterval +}; +// clang-format on + +const usbd_class_info_t USBD_LEDGER_HID_U2F_class_info = { + .type = USBD_LEDGER_CLASS_HID_U2F, + + .end_point = &LEDGER_HID_U2F_end_point_info, + + .init = USBD_LEDGER_HID_U2F_init, + .de_init = USBD_LEDGER_HID_U2F_de_init, + .setup = USBD_LEDGER_HID_U2F_setup, + .data_in = USBD_LEDGER_HID_U2F_data_in, + .data_out = USBD_LEDGER_HID_U2F_data_out, + + .send_packet = USBD_LEDGER_HID_U2F_send_message, + + .data_ready = USBD_LEDGER_HID_U2F_data_ready, + + .setting = USBD_LEDGER_HID_U2F_setting, + + .interface_descriptor = LEDGER_HID_U2F_descriptors, + .interface_descriptor_size = sizeof(LEDGER_HID_U2F_descriptors), + + .interface_association_descriptor = NULL, + .interface_association_descriptor_size = 0, + + .bos_descriptor = NULL, + .bos_descriptor_size = 0, + + .cookie = &ledger_hid_u2f_handle, +}; + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +uint8_t USBD_LEDGER_HID_U2F_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + + ledger_hid_u2f_handle_t *handle = (ledger_hid_u2f_handle_t *) PIC(cookie); + + memset(handle, 0, sizeof(ledger_hid_u2f_handle_t)); + + memset(&handle->transport_data, 0, sizeof(handle->transport_data)); + handle->transport_data.rx_message_buffer = USBD_LEDGER_io_buffer; + handle->transport_data.rx_message_buffer_size = sizeof(USBD_LEDGER_io_buffer); + handle->transport_data.tx_packet_buffer = u2f_transport_packet_buffer; + handle->transport_data.tx_packet_buffer_size = sizeof(u2f_transport_packet_buffer); + + handle->message_crc = 0; + handle->user_presence = LEDGER_HID_U2F_USER_PRESENCE_IDLE; + + handle->os_context = 0; + + U2F_TRANSPORT_init(&handle->transport_data, U2F_TRANSPORT_TYPE_USB_HID); + + USBD_LL_PrepareReceive(pdev, LEDGER_HID_U2F_EPOUT_ADDR, NULL, LEDGER_HID_U2F_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_U2F_de_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_U2F_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req) +{ + if (!pdev || !cookie || !req) { + return USBD_FAIL; + } + + uint8_t ret = USBD_OK; + ledger_hid_u2f_handle_t *handle = (ledger_hid_u2f_handle_t *) PIC(cookie); + + uint8_t request = req->bmRequest & (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK); + + // HID Standard Requests + if (request == (USB_REQ_TYPE_STANDARD | USB_REQ_RECIPIENT_INTERFACE)) { + switch (req->bRequest) { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + uint16_t status_info = 0x0000; + USBD_CtlSendData(pdev, (uint8_t *) (void *) &status_info, sizeof(status_info)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_DESCRIPTOR: + if (req->wValue == ((uint16_t) (HID_DESCRIPTOR_TYPE << 8))) { + USBD_CtlSendData( + pdev, + (uint8_t *) PIC(&LEDGER_HID_U2F_descriptors[USB_LEN_IF_DESC]), + MIN(LEDGER_HID_U2F_descriptors[USB_LEN_IF_DESC], req->wLength)); + } + else if (req->wValue == ((uint16_t) (HID_REPORT_DESCRIPTOR_TYPE << 8))) { + USBD_CtlSendData(pdev, + (uint8_t *) PIC(LEDGER_HID_U2F_report_descriptor), + MIN(sizeof(LEDGER_HID_U2F_report_descriptor), req->wLength)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlSendData(pdev, &handle->alt_setting, sizeof(handle->alt_setting)); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + handle->alt_setting = (uint8_t) (req->wValue); + } + else { + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + ret = USBD_FAIL; + break; + } + } + // HID Class-Specific Requests + else if (request == (USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE)) { + switch (req->bRequest) { + case REQ_SET_PROTOCOL: + handle->protocol = (uint8_t) (req->wValue); + break; + + case REQ_GET_PROTOCOL: + USBD_CtlSendData(pdev, &handle->protocol, sizeof(handle->protocol)); + break; + + case REQ_SET_IDLE: + handle->idle_state = (uint8_t) (req->wValue >> 8); + break; + + case REQ_GET_IDLE: + USBD_CtlSendData(pdev, &handle->idle_state, sizeof(handle->idle_state)); + break; + + default: + ret = USBD_FAIL; + break; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +uint8_t USBD_LEDGER_HID_U2F_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_U2F_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + UNUSED(ep_num); + + ledger_hid_u2f_handle_t *handle = (ledger_hid_u2f_handle_t *) PIC(cookie); + + if (handle->transport_data.tx_message_buffer) { + U2F_TRANSPORT_tx(&handle->transport_data, 0, NULL, 0); + if (handle->transport_data.tx_packet_length) { + handle->state = LEDGER_HID_U2F_STATE_BUSY; + USBD_LL_Transmit(pdev, + LEDGER_HID_U2F_EPIN_ADDR, + handle->transport_data.tx_packet_buffer, + LEDGER_HID_U2F_EPIN_SIZE, + 0); + } + } + if (!handle->transport_data.tx_message_buffer) { + handle->transport_data.tx_packet_length = 0; + handle->state = LEDGER_HID_U2F_STATE_IDLE; + if (handle->transport_data.state == U2F_STATE_CMD_PROCESSING) { + handle->transport_data.state = U2F_STATE_IDLE; + } + } + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_U2F_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(ep_num); + + ledger_hid_u2f_handle_t *handle = (ledger_hid_u2f_handle_t *) PIC(cookie); + + U2F_TRANSPORT_rx(&handle->transport_data, packet, packet_length); + + USBD_LL_PrepareReceive(pdev, LEDGER_HID_U2F_EPOUT_ADDR, NULL, LEDGER_HID_U2F_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_HID_U2F_send_message(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *message, + uint16_t message_length, + uint32_t timeout_ms) +{ + if (!pdev || !cookie || !message || !message_length) { + return USBD_FAIL; + } + + uint8_t ret = USBD_OK; + ledger_hid_u2f_handle_t *handle = (ledger_hid_u2f_handle_t *) PIC(cookie); + + uint8_t cmd = 0; + uint8_t *tx_buffer = (uint8_t *) message; + uint16_t tx_length = message_length; + + switch (packet_type) { + case OS_IO_PACKET_TYPE_USB_U2F_HID_APDU: + cmd = U2F_COMMAND_MSG; + if ((message_length == 2) && (message[0] == 0x69) && (message[1] == 0x85)) { + handle->user_presence = LEDGER_HID_U2F_USER_PRESENCE_ASKING; + } + else if (handle->user_presence == LEDGER_HID_U2F_USER_PRESENCE_ASKING) { + PRINTF("Confirmed"); + handle->user_presence = LEDGER_HID_U2F_USER_PRESENCE_CONFIRMED; + handle->backup_message = (uint8_t *) message; + handle->backup_message_length = message_length; + return USBD_OK; + } + break; + + case OS_IO_PACKET_TYPE_USB_U2F_HID_CBOR: + cmd = U2F_COMMAND_HID_CBOR; + break; + + case OS_IO_PACKET_TYPE_USB_U2F_HID_RAW: + cmd = message[0]; + tx_buffer = (uint8_t *) &message[1]; + tx_length = message_length - 1; + break; + + default: + return USBD_FAIL; + break; + } + + U2F_TRANSPORT_tx(&handle->transport_data, cmd, tx_buffer, tx_length); + + if (handle->transport_data.tx_packet_length) { + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (handle->state == LEDGER_HID_U2F_STATE_IDLE) { + handle->state = LEDGER_HID_U2F_STATE_BUSY; + ret = USBD_LL_Transmit(pdev, + LEDGER_HID_U2F_EPIN_ADDR, + handle->transport_data.tx_packet_buffer, + LEDGER_HID_U2F_EPIN_SIZE, + timeout_ms); + } + else { + ret = USBD_BUSY; + } + } + else { + ret = USBD_FAIL; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +int32_t USBD_LEDGER_HID_U2F_data_ready(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length) +{ + int32_t status = 0; + + UNUSED(pdev); + UNUSED(max_length); + + if (!cookie || !buffer) { + return -1; + } + ledger_hid_u2f_handle_t *handle = (ledger_hid_u2f_handle_t *) PIC(cookie); + + if (handle->transport_data.state != U2F_STATE_CMD_COMPLETE) { + return status; + } + + uint8_t error_msg[2] = {U2F_COMMAND_ERROR, CTAP1_ERR_SUCCESS}; + + switch (handle->transport_data.rx_message_buffer[0]) { + case U2F_COMMAND_HID_INIT: + // Mandatory command + if (handle->transport_data.rx_message_length != 11) { + error_msg[1] = CTAP1_ERR_INVALID_LENGTH; + USBD_LEDGER_HID_U2F_send_message( + pdev, cookie, OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, error_msg, 2, 0); + } + else { + uint8_t tx_packet_buffer[18]; + tx_packet_buffer[0] = U2F_COMMAND_HID_INIT; + // Nonce + memmove(&tx_packet_buffer[1], &handle->transport_data.rx_message_buffer[3], 8); + // CID + if (handle->transport_data.cid == U2F_BROADCAST_CID) { + U4BE_ENCODE(tx_packet_buffer, 9, ledger_hid_free_cid); + ledger_hid_free_cid++; + } + else { + U4BE_ENCODE(tx_packet_buffer, 9, handle->transport_data.cid); + } + // Versions & capabilities + tx_packet_buffer[13] = ledger_hid_u2f_settings.protocol_version; + tx_packet_buffer[14] = ledger_hid_u2f_settings.major_device_version_number; + tx_packet_buffer[15] = ledger_hid_u2f_settings.minor_device_version_number; + tx_packet_buffer[16] = ledger_hid_u2f_settings.build_device_version_number; + tx_packet_buffer[17] = ledger_hid_u2f_settings.capabilities_flag; + USBD_LEDGER_HID_U2F_send_message(pdev, + cookie, + OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, + tx_packet_buffer, + sizeof(tx_packet_buffer), + 0); + } + break; + + case U2F_COMMAND_MSG: + // Mandatory command in CTAP1 + // Optional command in CTAP2 by setting MSG not implemented capability flag or not + if ((ledger_hid_u2f_settings.protocol_version >= 2) + && (ledger_hid_u2f_settings.capabilities_flag & U2F_HID_CAPABILITY_NMSG)) { + error_msg[1] = CTAP1_ERR_INVALID_COMMAND; + USBD_LEDGER_HID_U2F_send_message( + pdev, cookie, OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, error_msg, 2, 0); + } + else { + uint16_t crc = cx_crc16_update(0, + handle->transport_data.rx_message_buffer, + handle->transport_data.rx_message_length); + if (handle->user_presence == LEDGER_HID_U2F_USER_PRESENCE_ASKING) { + if (handle->message_crc == crc) { + error_msg[0] = 0x69; + error_msg[1] = 0x85; + USBD_LEDGER_HID_U2F_send_message( + pdev, cookie, OS_IO_PACKET_TYPE_USB_U2F_HID_APDU, error_msg, 2, 0); + } + else { + error_msg[1] = CTAP1_ERR_CHANNEL_BUSY; + USBD_LEDGER_HID_U2F_send_message( + pdev, cookie, OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, error_msg, 2, 0); + } + } + else if ((handle->user_presence == LEDGER_HID_U2F_USER_PRESENCE_CONFIRMED) + && (handle->message_crc == crc)) { + // Send backup response + USBD_LEDGER_HID_U2F_send_message(pdev, + cookie, + OS_IO_PACKET_TYPE_USB_U2F_HID_APDU, + handle->backup_message, + handle->backup_message_length, + 0); + handle->user_presence = LEDGER_HID_U2F_USER_PRESENCE_IDLE; + } + else { + buffer[0] = OS_IO_PACKET_TYPE_USB_U2F_HID_APDU; + // TODO_IO : check max length + memmove(&buffer[1], + &handle->transport_data.rx_message_buffer[3], + handle->transport_data.rx_message_length - 3); + handle->transport_data.state = U2F_STATE_CMD_PROCESSING; + status = handle->transport_data.rx_message_length - 2; + handle->message_crc = crc; + handle->user_presence = LEDGER_HID_U2F_USER_PRESENCE_IDLE; + } + } + break; + + case U2F_COMMAND_HID_CBOR: + // Optional command available in CTAP2 only + if (!(ledger_hid_u2f_settings.capabilities_flag & U2F_HID_CAPABILITY_CBOR)) { + error_msg[1] = CTAP1_ERR_INVALID_COMMAND; + USBD_LEDGER_HID_U2F_send_message( + pdev, cookie, OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, error_msg, 2, 0); + } + else { + buffer[0] = OS_IO_PACKET_TYPE_USB_U2F_HID_CBOR; + // TODO_IO : check max length + memmove(&buffer[1], + &handle->transport_data.rx_message_buffer[3], + handle->transport_data.rx_message_length - 3); + handle->transport_data.state = U2F_STATE_CMD_PROCESSING; + status = handle->transport_data.rx_message_length - 2; + } + break; + + case U2F_COMMAND_HID_WINK: + // Optional command by setting WINK capability flag or not + if (!(ledger_hid_u2f_settings.capabilities_flag & U2F_HID_CAPABILITY_WINK)) { + error_msg[1] = CTAP1_ERR_INVALID_COMMAND; + USBD_LEDGER_HID_U2F_send_message( + pdev, cookie, OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, error_msg, 2, 0); + } + else { + // TODO_IO : process the wink command + handle->transport_data.state = U2F_STATE_IDLE; + } + break; + + case U2F_COMMAND_HID_CANCEL: + // Mandatory command in CTAP2 only + if (ledger_hid_u2f_settings.protocol_version < 2) { + error_msg[1] = CTAP1_ERR_INVALID_COMMAND; + USBD_LEDGER_HID_U2F_send_message( + pdev, cookie, OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, error_msg, 2, 0); + } + else { + // TODO_IO : process th cancel command + handle->transport_data.state = U2F_STATE_IDLE; + } + break; + + default: + error_msg[1] = CTAP1_ERR_INVALID_COMMAND; + USBD_LEDGER_HID_U2F_send_message( + pdev, cookie, OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, error_msg, 2, 0); + break; + } + + return status; +} + +void USBD_LEDGER_HID_U2F_setting(uint32_t id, uint8_t *buffer, uint16_t length, void *cookie) +{ + if (!cookie || !buffer) { + return; + } + + if ((id == USBD_LEDGER_HID_U2F_SETTING_ID_VERSIONS) && (buffer) && (length == 4)) { + ledger_hid_u2f_settings.protocol_version = buffer[0]; + ledger_hid_u2f_settings.major_device_version_number = buffer[1]; + ledger_hid_u2f_settings.minor_device_version_number = buffer[2]; + ledger_hid_u2f_settings.build_device_version_number = buffer[3]; + } + else if ((id == USBD_LEDGER_HID_U2F_SETTING_ID_CAPABILITIES_FLAG) && (buffer) + && (length == 1)) { + ledger_hid_u2f_settings.capabilities_flag = buffer[0]; + } + else if ((id == USBD_LEDGER_HID_U2F_SETTING_ID_FREE_CID) && (buffer) && (length == 4)) { + ledger_hid_free_cid = U4BE(buffer, 0); + } +} + +#endif // HAVE_IO_U2F diff --git a/lib_stusb/src/usbd_ledger_webusb.c b/lib_stusb/src/usbd_ledger_webusb.c new file mode 100644 index 000000000..dd1f33f27 --- /dev/null +++ b/lib_stusb/src/usbd_ledger_webusb.c @@ -0,0 +1,467 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include "ledger_protocol.h" +#include "usbd_ioreq.h" +#include "usbd_ledger.h" +#include "usbd_ledger_webusb.h" + +#ifdef HAVE_WEBUSB + +#pragma GCC diagnostic ignored "-Wcast-qual" + +/* Private enumerations ------------------------------------------------------*/ +enum ledger_webusb_state_t { + LEDGER_WEBUSB_STATE_IDLE, + LEDGER_WEBUSB_STATE_BUSY, +}; + +/* Private defines------------------------------------------------------------*/ +#define LEDGER_WEBUSB_EPIN_ADDR (0x83) +#define LEDGER_WEBUSB_EPIN_SIZE (0x40) +#define LEDGER_WEBUSB_EPOUT_ADDR (0x03) +#define LEDGER_WEBUSB_EPOUT_SIZE (0x40) + +#define WINUSB_GET_COMPATIBLE_ID_FEATURE (0x04) +#define WINUSB_GET_EXTENDED_PROPERTIES_OS_FEATURE (0x05) +#define MS_OS_20_DESCRIPTOR_INDEX (0x07) + +/* Private types, structures, unions -----------------------------------------*/ +typedef struct { + uint8_t state; // ledger_webusb_state_t + ledger_protocol_t protocol_data; +} ledger_webusb_handle_t; + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static ledger_webusb_handle_t ledger_webusb_handle; +static uint8_t ledger_protocol_chunk_buffer[LEDGER_WEBUSB_EPIN_SIZE]; + +/* Exported variables --------------------------------------------------------*/ + +const usbd_end_point_info_t LEDGER_WEBUSB_end_point_info = { + .ep_in_addr = LEDGER_WEBUSB_EPIN_ADDR, + .ep_in_size = LEDGER_WEBUSB_EPIN_SIZE, + .ep_out_addr = LEDGER_WEBUSB_EPOUT_ADDR, + .ep_out_size = LEDGER_WEBUSB_EPOUT_SIZE, + .ep_type = USBD_EP_TYPE_INTR, +}; + +// clang-format off +const uint8_t LEDGER_WEBUSB_bos_descriptor[] = { + // Webusb device capability descriptor + 0x18, // bLength + 0x10, // bDescriptorType : Device Capability + 0x05, // bDevCapabilityType : Platform + 0x00, // bReserved + 0x38, 0xB6, 0x08, 0x34, // PlatformCapablityUUID : WebUSB Platform Capability UUID (3408B638-09A9-47A0-8BFD-A0768815B665) + 0xA9, 0x09, 0xA0, 0x47, // PlatformCapablityUUID + 0x8B, 0xFD, 0xA0, 0x76, // PlatformCapablityUUID + 0x88, 0x15, 0xB6, 0x65, // PlatformCapablityUUID + 0x00, // bcdVersion : WebUSB version 1.0 + 0x01, // bcdVersion + USB_REQ_WEBUSB_VENDOR_CODE, // bVendorCode + 0x00, // iLandingPage + + // Microsoft OS 2.0 Platform Capability Descriptor + 0x1C, // bLength + 0x10, // bDescriptorType : Device Capability + 0x05, // bDevCapabilityType : Platform + 0x00, // bReserved + 0xDF, 0x60, 0xDD, 0xD8, // PlatformCapablityUUID : Microsoft OS 2.0 Platform Capability UUID (D8DD60DF-4589-4CC7-9CD2-659D9E648A9F) + 0x89, 0x45, 0xC7, 0x4C, // PlatformCapablityUUID + 0x9C, 0xD2, 0x65, 0x9D, // PlatformCapablityUUID + 0x9E, 0x64, 0x8A, 0x9F, // PlatformCapablityUUID + 0x00, 0x00, 0x03, 0x06, // dwWindowsVersion : minimum 8.1 (0x06030000) + 0xb2, // wMSOSDescriptorSetTotalLength : TODO_IO : should be processed at run time + 0x00, // wMSOSDescriptorSetTotalLength + USB_REQ_WINUSB_VENDOR_CODE, // bVendorCode + 0x00, // bAltEnumCode : alternate enumeration not supported +}; + +const uint8_t LEDGER_WEBUSB_descriptors[23] = { + /************** Interface descriptor ******************************/ + USB_LEN_IF_DESC, // bLength + USB_DESC_TYPE_INTERFACE, // bDescriptorType : interface + 0x00, // bInterfaceNumber : 0 (dynamic) + 0x00, // bAlternateSetting : 0 + 0x02, // bNumEndpoints : 2 + 0xFF, // bInterfaceClass : Vendor + 0xFF, // bInterfaceSubClass : Vendor + 0xFF, // bInterfaceProtocol : Vendor + USBD_IDX_PRODUCT_STR, // iInterface : no string + + /************** Endpoint descriptor *******************************/ + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_WEBUSB_EPIN_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_WEBUSB_EPIN_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x01, // bInterval + + /************** Endpoint descriptor *******************************/ + USB_LEN_EP_DESC, // bLength + USB_DESC_TYPE_ENDPOINT, // bDescriptorType + LEDGER_WEBUSB_EPOUT_ADDR, // bEndpointAddress + USBD_EP_TYPE_INTR, // bmAttributes + LEDGER_WEBUSB_EPOUT_SIZE, // wMaxPacketSize + 0x00, // wMaxPacketSize + 0x01, // bInterval +}; + +const uint8_t USBD_LEDGER_WINUSB_string_descriptor[] = { + 0x12, // bLength + USB_DESC_TYPE_STRING, // bDescriptorType + 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, // wData : MSFT100 + '1', 0x00, '0', 0x00, '0', 0x00, // + USB_REQ_WINUSB_VENDOR_CODE, 0x00 // +}; + +const uint8_t USBD_LEDGER_WINUSB_compat_id_feature_descriptor[] = { + 0x28, 0x00, 0x00, 0x00, // dwLength + 0x00, 0x01, // bcdVersion + 0x04, 0x00, // wIndex + 0x01, // bNumSections + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved + + 0x01, // bInterfaceNumber (dynamic) // TODO_IO + 0x01, // bReserved + 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // Compatible ID String + 0x00, 0x00, 0x00, 0x00, // Sub-compatible ID String + 0x00, 0x00, 0x00, 0x00, // + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved +}; + +const uint8_t USBD_LEDGER_WINUSB_extended_properties_feature_descriptor[] = { + 0x92, 0x00, 0x00, 0x00, // dwLength + 0x00, 0x01, // bcdVersion + 0x05, 0x00, // wIndex + 0x01, 0x00, // wNumFeatures + + 0x88, 0x00, 0x00, 0x00, // dwLength: + 0x07, 0x00, 0x00, 0x00, // dwPropertyDataType: Multiple NULL-terminated Unicode strings (REG_MULTI_SZ) + 0x2a, 0x00, // wPropertyNameLength + 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, // PropertyName 'DeviceInterfaceGUIDs' + 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, // + 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, // + 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, // + 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, // + 0x00, 0x00, // + 0x50, 0x00, // wPropertyDataLength + '{', 0x00, '1', 0x00, '3', 0x00, 'd', 0x00, // PropertyData : '{13d63400-2C97-0004-0000-4c6564676572}' + '6', 0x00, '3', 0x00, '4', 0x00, '0', 0x00, // + '0', 0x00, '-', 0x00, '2', 0x00, 'C', 0x00, // + '9', 0x00, '7', 0x00, '-', 0x00, '0', 0x00, // + '0', 0x00, '0', 0x00, '4', 0x00, '-', 0x00, // + '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, // + '-', 0x00, '4', 0x00, 'c', 0x00, '6', 0x00, // + '5', 0x00, '6', 0x00, '4', 0x00, '6', 0x00, // + '7', 0x00, '6', 0x00, '5', 0x00, '7', 0x00, // + '2', 0x00, '}', 0x00, // + 0x00, 0x00, 0x00, 0x00 // +}; + +const uint8_t USBD_LEDGER_WINUSB_ms_os_20_descriptor_set[] = { + // Microsoft OS 2.0 descriptor set header + 0x0a, 0x00, // wLength + 0x00, 0x00, // wDescriptorType : MSOS20_SET_HEADER_DESCRIPTOR + 0x00, 0x00, 0x03, 0x06, // dwWindowsVersion : minimum 8.1 (0x06030000) + 0xb2, 0x00, // wTotalLength : The size of entire MS OS 2.0 descriptor set + + // Microsoft OS 2.0 configuration subset header + 0x08, 0x00, // wLength + 0x01, 0x00, // wDescriptorType : MS_OS_20_SUBSET_HEADER_CONFIGURATION + 0x00, // bConfigurationValue + 0x00, // bReserved + 0xa8, 0x00, // wTotalLength + + // Microsoft OS 2.0 function subset header + 0x08, 0x00, // wLength + 0x02, 0x00, // wDescriptorType : MS_OS_20_SUBSET_HEADER_FUNCTION + 0x01, // bFirstInterface (dynamic) // TODO_IO + 0x00, // bReserved + 0xa0, 0x00, // wSubsetLength + + // Microsoft OS 2.0 compatible ID descriptor + 0x14, 0x00, // wLength + 0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID + 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // Compatible ID String + 0x00, 0x00, 0x00, 0x00, // Sub-compatible ID String + 0x00, 0x00, 0x00, 0x00, // + + // Microsoft OS 2.0 registry property descriptor + 0x84, 0x00, // wLength: + 0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY + 0x07, 0x00, // wPropertyDataType: Multiple NULL-terminated Unicode strings (REG_MULTI_SZ) + 0x2a, 0x00, // wPropertyNameLength + 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, // PropertyName 'DeviceInterfaceGUIDs' + 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, // + 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, // + 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, // + 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, // + 0x00, 0x00, // + 0x50, 0x00, // wPropertyDataLength + '{', 0x00, 'C', 0x00, 'E', 0x00, '8', 0x00, // PropertyData : '{CE809264-4B24-4E81-A8B2-57ED01D580E1}' + '0', 0x00, '9', 0x00, '2', 0x00, '6', 0x00, // + '4', 0x00, '-', 0x00, '4', 0x00, 'B', 0x00, // + '2', 0x00, '4', 0x00, '-', 0x00, '4', 0x00, // + 'E', 0x00, '8', 0x00, '1', 0x00, '-', 0x00, // + 'A', 0x00, '8', 0x00, 'B', 0x00, '2', 0x00, // + '-', 0x00, '5', 0x00, '7', 0x00, 'E', 0x00, // + 'D', 0x00, '0', 0x00, '1', 0x00, 'D', 0x00, // + '5', 0x00, '8', 0x00, '0', 0x00, 'E', 0x00, // + '1', 0x00, '}', 0x00, // + 0x00, 0x00, 0x00, 0x00 // +}; +// clang-format on + +const usbd_class_info_t USBD_LEDGER_WEBUSB_class_info = { + .type = USBD_LEDGER_CLASS_WEBUSB, + + .end_point = &LEDGER_WEBUSB_end_point_info, + + .init = USBD_LEDGER_WEBUSB_init, + .de_init = USBD_LEDGER_WEBUSB_de_init, + .setup = USBD_LEDGER_WEBUSB_setup, + .data_in = USBD_LEDGER_WEBUSB_data_in, + .data_out = USBD_LEDGER_WEBUSB_data_out, + + .send_packet = USBD_LEDGER_WEBUSB_send_packet, + + .data_ready = USBD_LEDGER_WEBUSB_data_ready, + + .setting = NULL, + + .interface_descriptor = LEDGER_WEBUSB_descriptors, + .interface_descriptor_size = sizeof(LEDGER_WEBUSB_descriptors), + + .interface_association_descriptor = NULL, + .interface_association_descriptor_size = 0, + + .bos_descriptor = LEDGER_WEBUSB_bos_descriptor, + .bos_descriptor_size = sizeof(LEDGER_WEBUSB_bos_descriptor), + + .cookie = &ledger_webusb_handle, +}; + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +uint8_t USBD_LEDGER_WEBUSB_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + + ledger_webusb_handle_t *handle = (ledger_webusb_handle_t *) PIC(cookie); + + memset(handle, 0, sizeof(ledger_webusb_handle_t)); + + memset(&handle->protocol_data, 0, sizeof(handle->protocol_data)); + handle->protocol_data.rx_apdu_buffer = USBD_LEDGER_io_buffer; + handle->protocol_data.rx_apdu_buffer_size = sizeof(USBD_LEDGER_io_buffer); + handle->protocol_data.tx_chunk_buffer = ledger_protocol_chunk_buffer; + handle->protocol_data.tx_chunk_buffer_size = sizeof(ledger_protocol_chunk_buffer); + handle->protocol_data.mtu = sizeof(ledger_protocol_chunk_buffer); + + LEDGER_PROTOCOL_init(&handle->protocol_data, OS_IO_PACKET_TYPE_USB_WEBUSB_APDU); + + USBD_LL_PrepareReceive(pdev, LEDGER_WEBUSB_EPOUT_ADDR, NULL, LEDGER_WEBUSB_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_WEBUSB_de_init(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_WEBUSB_setup(USBD_HandleTypeDef *pdev, void *cookie, USBD_SetupReqTypedef *req) +{ + if (!pdev || !req) { + return USBD_FAIL; + } + + UNUSED(cookie); + + uint8_t ret = USBD_OK; + + if ((req->bRequest == USB_REQ_GET_DESCRIPTOR) && ((req->wValue >> 8) == USB_DESC_TYPE_STRING) + && ((req->wValue & 0xFF) == USBD_IDX_WINUSB_STR)) { + USBD_CtlSendData(pdev, + (uint8_t *) PIC(USBD_LEDGER_WINUSB_string_descriptor), + sizeof(USBD_LEDGER_WINUSB_string_descriptor)); + } + else if (req->bRequest == USB_REQ_WINUSB_VENDOR_CODE) { + switch (req->wIndex) { + case WINUSB_GET_COMPATIBLE_ID_FEATURE: + USBD_CtlSendData(pdev, + (uint8_t *) PIC(USBD_LEDGER_WINUSB_compat_id_feature_descriptor), + sizeof(USBD_LEDGER_WINUSB_compat_id_feature_descriptor)); + break; + + case WINUSB_GET_EXTENDED_PROPERTIES_OS_FEATURE: + USBD_CtlSendData( + pdev, + (uint8_t *) PIC(USBD_LEDGER_WINUSB_extended_properties_feature_descriptor), + sizeof(USBD_LEDGER_WINUSB_extended_properties_feature_descriptor)); + break; + + case MS_OS_20_DESCRIPTOR_INDEX: + USBD_CtlSendData(pdev, + (uint8_t *) PIC(USBD_LEDGER_WINUSB_ms_os_20_descriptor_set), + sizeof(USBD_LEDGER_WINUSB_ms_os_20_descriptor_set)); + break; + + default: + ret = USBD_FAIL; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +uint8_t USBD_LEDGER_WEBUSB_ep0_rx_ready(USBD_HandleTypeDef *pdev, void *cookie) +{ + UNUSED(pdev); + UNUSED(cookie); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_WEBUSB_data_in(USBD_HandleTypeDef *pdev, void *cookie, uint8_t ep_num) +{ + if (!cookie) { + return USBD_FAIL; + } + + UNUSED(pdev); + UNUSED(ep_num); + + ledger_webusb_handle_t *handle = (ledger_webusb_handle_t *) PIC(cookie); + + if (handle->protocol_data.tx_apdu_buffer) { + LEDGER_PROTOCOL_tx(&handle->protocol_data, NULL, 0); + if (handle->protocol_data.tx_chunk_length >= 2) { + handle->state = LEDGER_WEBUSB_STATE_BUSY; + USBD_LL_Transmit(pdev, + LEDGER_WEBUSB_EPIN_ADDR, + handle->protocol_data.tx_chunk_buffer, + LEDGER_WEBUSB_EPIN_SIZE, + 0); + } + } + if (!handle->protocol_data.tx_apdu_buffer) { + handle->protocol_data.tx_chunk_length = 0; + handle->state = LEDGER_WEBUSB_STATE_IDLE; + } + + return USBD_OK; +} + +uint8_t USBD_LEDGER_WEBUSB_data_out(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t ep_num, + uint8_t *packet, + uint16_t packet_length) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(ep_num); + + ledger_webusb_handle_t *handle = (ledger_webusb_handle_t *) PIC(cookie); + + LEDGER_PROTOCOL_rx(&handle->protocol_data, packet, packet_length); + + USBD_LL_PrepareReceive(pdev, LEDGER_WEBUSB_EPOUT_ADDR, NULL, LEDGER_WEBUSB_EPOUT_SIZE); + + return USBD_OK; +} + +uint8_t USBD_LEDGER_WEBUSB_send_packet(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t packet_type, + const uint8_t *packet, + uint16_t packet_length, + uint32_t timeout_ms) +{ + if (!pdev || !cookie || !packet) { + return USBD_FAIL; + } + + UNUSED(packet_type); + + uint8_t ret = USBD_OK; + ledger_webusb_handle_t *handle = (ledger_webusb_handle_t *) PIC(cookie); + + LEDGER_PROTOCOL_tx(&handle->protocol_data, packet, packet_length); + + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (handle->state == LEDGER_WEBUSB_STATE_IDLE) { + if (handle->protocol_data.tx_chunk_length >= 2) { + handle->state = LEDGER_WEBUSB_STATE_BUSY; + ret = USBD_LL_Transmit(pdev, + LEDGER_WEBUSB_EPIN_ADDR, + handle->protocol_data.tx_chunk_buffer, + LEDGER_WEBUSB_EPIN_SIZE, + timeout_ms); + } + else { + ret = USBD_FAIL; + } + } + else { + ret = USBD_BUSY; + } + } + else { + ret = USBD_FAIL; + } + + return ret; +} + +int32_t USBD_LEDGER_WEBUSB_data_ready(USBD_HandleTypeDef *pdev, + void *cookie, + uint8_t *buffer, + uint16_t max_length) +{ + int32_t status = 0; + + UNUSED(pdev); + + if (!cookie || !buffer) { + return -1; + } + ledger_webusb_handle_t *handle = (ledger_webusb_handle_t *) PIC(cookie); + + if (handle->protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { + if (max_length < handle->protocol_data.rx_apdu_length) { + status = -1; + } + else { + memmove( + buffer, handle->protocol_data.rx_apdu_buffer, handle->protocol_data.rx_apdu_length); + status = handle->protocol_data.rx_apdu_length; + } + handle->protocol_data.rx_apdu_status = APDU_STATUS_WAITING; + } + + return status; +} + +#endif // HAVE_WEBUSB diff --git a/lib_stusb/usbd_conf.c b/lib_stusb/usbd_conf.c deleted file mode 100644 index fdc8afce4..000000000 --- a/lib_stusb/usbd_conf.c +++ /dev/null @@ -1,343 +0,0 @@ -/** - ****************************************************************************** - * @file : usbd_conf.c - * @brief : This file implements the board support package for the USB device library - ****************************************************************************** - * - * COPYRIGHT(c) 2015 STMicroelectronics - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** -*/ -#include "os_io_seproxyhal.h" -#include "os_helpers.h" -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" -#include "usbd_core.h" - - -/******************************************************************************* - LL Driver Interface (USB Device Library --> PCD) -*******************************************************************************/ -unsigned int ep_in_stall; -unsigned int ep_out_stall; -/** - * @brief Initializes the Low Level portion of the Device driver. - * @param pdev: Device handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev) -{ - UNUSED(pdev); - ep_in_stall = 0; - ep_out_stall = 0; - return USBD_OK; -} - -/** - * @brief De-Initializes the Low Level portion of the Device driver. - * @param pdev: Device handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev) -{ - uint8_t buffer[4]; - UNUSED(pdev); - - // usb off - buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; - buffer[1] = 0; - buffer[2] = 1; - buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_DISCONNECT; - io_seproxyhal_spi_send(buffer, 4); - - return USBD_OK; -} - -/** - * @brief Starts the Low Level portion of the Device driver. - * @param pdev: Device handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) -{ - uint8_t buffer[5]; - UNUSED(pdev); - - // reset address - buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; - buffer[1] = 0; - buffer[2] = 2; - buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_ADDR; - buffer[4] = 0; - io_seproxyhal_spi_send(buffer, 5); - - // start usb operation - buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; - buffer[1] = 0; - buffer[2] = 1; - buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_CONNECT; - io_seproxyhal_spi_send(buffer, 4); - return USBD_OK; -} - -/** - * @brief Stops the Low Level portion of the Device driver. - * @param pdev: Device handle - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev) -{ - UNUSED(pdev); - uint8_t buffer[4]; - buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; - buffer[1] = 0; - buffer[2] = 1; - buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_DISCONNECT; - io_seproxyhal_spi_send(buffer, 4); - return USBD_OK; -} - -/** - * @brief Opens an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @param ep_type: Endpoint Type - * @param ep_mps: Endpoint Max Packet Size - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t ep_type, - uint16_t ep_mps) -{ - uint8_t buffer[8]; - UNUSED(pdev); - - ep_in_stall = 0; - ep_out_stall = 0; - - buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; - buffer[1] = 0; - buffer[2] = 5; - buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_ENDPOINTS; - buffer[4] = 1; - buffer[5] = ep_addr; - buffer[6] = 0; - switch(ep_type) { - case USBD_EP_TYPE_CTRL: - buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_CONTROL; - break; - case USBD_EP_TYPE_ISOC: - buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_ISOCHRONOUS; - break; - case USBD_EP_TYPE_BULK: - buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_BULK; - break; - case USBD_EP_TYPE_INTR: - buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_INTERRUPT; - break; - } - buffer[7] = ep_mps; - io_seproxyhal_spi_send(buffer, 8); - return USBD_OK; -} - -/** - * @brief Closes an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - UNUSED(pdev); - uint8_t buffer[8]; - buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; - buffer[1] = 0; - buffer[2] = 5; - buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_ENDPOINTS; - buffer[4] = 1; - buffer[5] = ep_addr; - buffer[6] = SEPROXYHAL_TAG_USB_CONFIG_TYPE_DISABLED; - buffer[7] = 0; - io_seproxyhal_spi_send(buffer, 8); - return USBD_OK; -} - -/** - * @brief Flushes an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - UNUSED(pdev); - UNUSED(ep_addr); - //HAL_PCD_EP_Flush(pdev->pData, ep_addr); - return USBD_OK; -} - -/** - * @brief Sets a Stall condition on an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - UNUSED(pdev); - uint8_t buffer[6]; - buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; - buffer[1] = 0; - buffer[2] = 3; - buffer[3] = ep_addr; - buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_STALL; - buffer[5] = 0; - io_seproxyhal_spi_send(buffer, 6); - if (ep_addr & 0x80) { - ep_in_stall |= (1<<(ep_addr&0x7F)); - } - else { - ep_out_stall |= (1<<(ep_addr&0x7F)); - } - return USBD_OK; -} - -/** - * @brief Clears a Stall condition on an endpoint of the Low Level Driver. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - UNUSED(pdev); - uint8_t buffer[6]; - buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; - buffer[1] = 0; - buffer[2] = 3; - buffer[3] = ep_addr; - buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_UNSTALL; - buffer[5] = 0; - io_seproxyhal_spi_send(buffer, 6); - if (ep_addr & 0x80) { - ep_in_stall &= ~(1<<(ep_addr&0x7F)); - } - else { - ep_out_stall &= ~(1<<(ep_addr&0x7F)); - } - return USBD_OK; -} - -/** - * @brief Returns Stall condition. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval Stall (1: Yes, 0: No) - */ -uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr) -{ - UNUSED(pdev); - if((ep_addr & 0x80) == 0x80) - { - return ep_in_stall & (1<<(ep_addr&0x7F)); - } - else - { - return ep_out_stall & (1<<(ep_addr&0x7F)); - } -} -/** - * @brief Assigns a USB address to the device. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr) -{ - UNUSED(pdev); - uint8_t buffer[5]; - buffer[0] = SEPROXYHAL_TAG_USB_CONFIG; - buffer[1] = 0; - buffer[2] = 2; - buffer[3] = SEPROXYHAL_TAG_USB_CONFIG_ADDR; - buffer[4] = dev_addr; - io_seproxyhal_spi_send(buffer, 5); - return USBD_OK; -} - -/** - * @brief Transmits data over an endpoint. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @param pbuf: Pointer to data to be sent - * @param size: Data size - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t size) -{ - UNUSED(pdev); - uint8_t buffer[6]; - buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; - buffer[1] = (3+size)>>8; - buffer[2] = (3+size); - buffer[3] = ep_addr; - buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN; - buffer[5] = size; - io_seproxyhal_spi_send(buffer, 6); - io_seproxyhal_spi_send(pbuf, size); - return USBD_OK; -} - -/** - * @brief Prepares an endpoint for reception. - * @param pdev: Device handle - * @param ep_addr: Endpoint Number - * @param pbuf: Pointer to data to be received - * @param size: Data size - * @retval USBD Status - */ -USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, - uint8_t ep_addr, - uint16_t size) -{ - UNUSED(pdev); - uint8_t buffer[6]; - buffer[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; - buffer[1] = (3/*+size*/)>>8; - buffer[2] = (3/*+size*/); - buffer[3] = ep_addr; - buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_OUT; - buffer[5] = size; // expected size, not transmitted here ! - io_seproxyhal_spi_send(buffer, 6); - return USBD_OK; -} - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_stusb/usbd_conf.h b/lib_stusb/usbd_conf.h deleted file mode 100644 index 886496c86..000000000 --- a/lib_stusb/usbd_conf.h +++ /dev/null @@ -1,190 +0,0 @@ -/** - ****************************************************************************** - * @file : usbd_conf.h - * @brief : Header for usbd_conf file. - ****************************************************************************** - * COPYRIGHT(c) 2015 STMicroelectronics - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** -*/ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CONF__H__ -#define __USBD_CONF__H__ -#ifdef __cplusplus - extern "C" { -#endif - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wtypedef-redefinition" - -/* Includes ------------------------------------------------------------------*/ -#include -#include -#include -#include - -#ifndef _BITS_STDINT_INTN_H -typedef signed char int8_t; -typedef signed short int16_t; -#endif -#ifndef _BITS_STDINT_UINTN_H -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -#endif - -/** @addtogroup USBD_OTG_DRIVER - * @{ - */ - -/** @defgroup USBD_CONF - * @brief usb otg low level driver configuration file - * @{ - */ - -/** @defgroup USBD_CONF_Exported_Defines - * @{ - */ - -/*---------- -----------*/ -#define USBD_MAX_NUM_INTERFACES 3 -/*---------- -----------*/ -#define USBD_MAX_NUM_CONFIGURATION 1 -/*---------- -----------*/ -#define USBD_MAX_STR_DESC_SIZ 512 -/*---------- -----------*/ -#define USBD_SUPPORT_USER_STRING 0 -/*---------- -----------*/ -#define USBD_DEBUG_LEVEL 0 -/*---------- -----------*/ -#define USBD_LPM_ENABLED 1 -/*---------- -----------*/ -#define USBD_SELF_POWERED 1 - -/****************************************/ -/* #define for FS and HS identification */ -#define DEVICE_FS 0 - -/** @defgroup USBD_Exported_Macros - * @{ - */ - -/* Memory management macros */ -#define USBD_malloc (uint32_t *)USBD_static_malloc -#define USBD_free USBD_static_free -#define USBD_memset /* Not used */ -#define USBD_memcpy /* Not used */ - -#define USBD_Delay HAL_Delay - - /* DEBUG macros */ - -#if (USBD_DEBUG_LEVEL > 0) -#define USBD_UsrLog(...) printf(__VA_ARGS__);\ - printf("\n"); -#else -#define USBD_UsrLog(...) -#endif - - -#if (USBD_DEBUG_LEVEL > 1) - -#define USBD_ErrLog(...) printf("ERROR: ") ;\ - printf(__VA_ARGS__);\ - printf("\n"); -#else -#define USBD_ErrLog(...) -#endif - - -#if (USBD_DEBUG_LEVEL > 2) -#define USBD_DbgLog(...) printf("DEBUG : ") ;\ - printf(__VA_ARGS__);\ - printf("\n"); -#else -#define USBD_DbgLog(...) -#endif - -/** - * @} - */ - - - -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ -/* Exported functions ------------------------------------------------------- */ -void *USBD_static_malloc(uint32_t size); -void USBD_static_free(void *p); - -const volatile uint8_t *USBD_GetPinPadOffset(void); - -void USB_power(unsigned char enabled); - -#pragma clang diagnostic pop - -#ifdef __cplusplus -} -#endif - -#endif //__USBD_CONF__H__ - -/** - * @} - */ - -/** - * @} - */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/lib_stusb_impl/doc/mainpage.dox b/lib_stusb_impl/doc/mainpage.dox deleted file mode 100644 index b353bb2e6..000000000 --- a/lib_stusb_impl/doc/mainpage.dox +++ /dev/null @@ -1,10 +0,0 @@ -/** @page usb_impl_mainpage USB Classes library - -@section usb_impl_mainpage_intro Introduction - -This page describes the API of the HID and CCID classes (see also @ref usb_mainpage), and -the mid-level API of the U2F protocol offered on \b NanoX and \b Stax products. - -@note TO BE COMPLETED - -*/ diff --git a/lib_stusb_impl/include/usbd_ccid_if.h.h b/lib_stusb_impl/include/usbd_ccid_if.h.h new file mode 100644 index 000000000..b8e28b72d --- /dev/null +++ b/lib_stusb_impl/include/usbd_ccid_if.h.h @@ -0,0 +1,17 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ diff --git a/lib_stusb_impl/include/usbd_ccid_impl.h b/lib_stusb_impl/include/usbd_ccid_impl.h new file mode 100644 index 000000000..b8e28b72d --- /dev/null +++ b/lib_stusb_impl/include/usbd_ccid_impl.h @@ -0,0 +1,17 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ diff --git a/lib_stusb_impl/u2f_impl.c b/lib_stusb_impl/u2f_impl.c deleted file mode 100644 index 634ae9a5e..000000000 --- a/lib_stusb_impl/u2f_impl.c +++ /dev/null @@ -1,414 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include -#include - -#ifdef HAVE_IO_U2F - -#include "os.h" -#include "os_io_seproxyhal.h" -#include "u2f_service.h" -#include "u2f_transport.h" -#include "u2f_processing.h" - -#define INIT_U2F_VERSION 0x02 -#define INIT_DEVICE_VERSION_MAJOR 0 -#define INIT_DEVICE_VERSION_MINOR 1 -#define INIT_BUILD_VERSION 0 - -#ifdef HAVE_FIDO2 -#define INIT_CAPABILITIES 0x04 -#else -#define INIT_CAPABILITIES 0x00 -#endif - -#define OFFSET_CLA 0 -#define OFFSET_INS 1 -#define OFFSET_P1 2 -#define OFFSET_P2 3 -#define OFFSET_DATA 7 - -#define APDU_MIN_HEADER 4 -#define LC_FIRST_BYTE_OFFSET 4 -#define LONG_ENC_LC_SIZE 3 -#define LONG_ENC_LE_SIZE 2 // considering only scenarios where Lc is present - -#define FIDO_CLA 0x00 -#define FIDO_INS_ENROLL 0x01 -#define FIDO_INS_SIGN 0x02 -#define U2F_HANDLE_SIGN_HEADER_SIZE (32 + 32 + 1) -#define FIDO_INS_GET_VERSION 0x03 - -#define FIDO_INS_PROP_GET_COUNTER 0xC0 // U2F_VENDOR_FIRST -#define FIDO_INS_PROP_GET_INFO 0xC1 // grab the max message buffer size on 1 byte - -#define P1_SIGN_CHECK_ONLY 0x07 -#define P1_SIGN_SIGN 0x03 - -#define SIGN_USER_PRESENCE_MASK 0x01 - -#ifndef U2F_PROXY_MAGIC - -static const uint8_t SW_WRONG_LENGTH[] = {0x67, 0x00}; - -#else // U2F_PROXY_MAGIC - -static const uint8_t SW_BUSY[] = {0x90, 0x01}; -static const uint8_t SW_PROOF_OF_PRESENCE_REQUIRED[] = {0x69, 0x85}; -static const uint8_t SW_BAD_KEY_HANDLE[] = {0x6A, 0x80}; - -static const uint8_t SW_UNKNOWN_INSTRUCTION[] = {0x6d, 0x00}; -static const uint8_t SW_UNKNOWN_CLASS[] = {0x6e, 0x00}; -static const uint8_t SW_WRONG_LENGTH[] = {0x67, 0x00}; -static const uint8_t SW_INTERNAL[] = {0x6F, 0x00}; - -static const uint8_t U2F_VERSION[] = {'U', '2', 'F', '_', 'V', '2', 0x90, 0x00}; - -// take into account max header (u2f usb) -static const uint8_t INFO[] = {1 /*info format 1*/, - (char) (IO_APDU_BUFFER_SIZE - U2F_HANDLE_SIGN_HEADER_SIZE - 3 - 4), - 0x90, - 0x00}; - -// proxy mode enroll issue an error -void u2f_apdu_enroll(u2f_service_t *service, - uint8_t p1, - uint8_t p2, - uint8_t *buffer, - uint16_t length) -{ - UNUSED(p1); - UNUSED(p2); - UNUSED(buffer); - UNUSED(length); - - u2f_message_reply(service, U2F_CMD_MSG, (uint8_t *) SW_INTERNAL, sizeof(SW_INTERNAL)); -} - -void u2f_apdu_sign(u2f_service_t *service, uint8_t p1, uint8_t p2, uint8_t *buffer, uint16_t length) -{ - UNUSED(p2); - uint8_t keyHandleLength; - uint8_t i; - - // can't process the apdu if another one is already scheduled in - if (G_io_app.apdu_state != APDU_IDLE) { - u2f_message_reply(service, U2F_CMD_MSG, (uint8_t *) SW_BUSY, sizeof(SW_BUSY)); - return; - } - - if (length < U2F_HANDLE_SIGN_HEADER_SIZE + 5 /*at least an apdu header*/) { - u2f_message_reply( - service, U2F_CMD_MSG, (uint8_t *) SW_WRONG_LENGTH, sizeof(SW_WRONG_LENGTH)); - return; - } - - // Confirm immediately if it's just a validation call - if (p1 == P1_SIGN_CHECK_ONLY) { - u2f_message_reply(service, - U2F_CMD_MSG, - (uint8_t *) SW_PROOF_OF_PRESENCE_REQUIRED, - sizeof(SW_PROOF_OF_PRESENCE_REQUIRED)); - return; - } - - // Unwrap magic - keyHandleLength = buffer[U2F_HANDLE_SIGN_HEADER_SIZE - 1]; - if (U2F_HANDLE_SIGN_HEADER_SIZE + keyHandleLength != length) { - u2f_message_reply( - service, U2F_CMD_MSG, (uint8_t *) SW_WRONG_LENGTH, sizeof(SW_WRONG_LENGTH)); - return; - } - - // reply to the "get magic" question of the host - if (keyHandleLength == 5) { - // GET U2F PROXY PARAMETERS - // this apdu is not subject to proxy magic masking - // APDU is F1 D0 00 00 00 to get the magic proxy - // RAPDU: <> - if (memcmp(buffer + U2F_HANDLE_SIGN_HEADER_SIZE, "\xF1\xD0\x00\x00\x00", 5) == 0) { - // U2F_PROXY_MAGIC is given as a 0 terminated string - G_io_apdu_buffer[0] = sizeof(U2F_PROXY_MAGIC) - 1; - memcpy(G_io_apdu_buffer + 1, U2F_PROXY_MAGIC, sizeof(U2F_PROXY_MAGIC) - 1); - memcpy(G_io_apdu_buffer + 1 + sizeof(U2F_PROXY_MAGIC) - 1, "\x90\x00\x90\x00", 4); - u2f_message_reply(service, - U2F_CMD_MSG, - (uint8_t *) G_io_apdu_buffer, - G_io_apdu_buffer[0] + 1 + 2 + 2); - // processing finished. don't go further in the u2f msg processing - return; - } - } - - for (i = 0; i < keyHandleLength; i++) { - buffer[U2F_HANDLE_SIGN_HEADER_SIZE + i] - ^= U2F_PROXY_MAGIC[i % (sizeof(U2F_PROXY_MAGIC) - 1)]; - } - // Check that it looks like an APDU - if (length != U2F_HANDLE_SIGN_HEADER_SIZE + 5 + buffer[U2F_HANDLE_SIGN_HEADER_SIZE + 4]) { - u2f_message_reply( - service, U2F_CMD_MSG, (uint8_t *) SW_BAD_KEY_HANDLE, sizeof(SW_BAD_KEY_HANDLE)); - return; - } - - // make the apdu available to higher layers - memmove(G_io_apdu_buffer, buffer + U2F_HANDLE_SIGN_HEADER_SIZE, keyHandleLength); - G_io_app.apdu_length = keyHandleLength; - G_io_app.apdu_media = IO_APDU_MEDIA_U2F; // the effective transport is managed by the U2F layer - G_io_app.apdu_state = APDU_U2F; - - // prepare for asynch reply - u2f_message_set_autoreply_wait_user_presence(service, true); - - // don't reset the u2f processing command state, as we still await for the io_exchange caller to - // make the response call - /* - app_dispatch(); - if ((btchip_context_D.io_flags & IO_ASYNCH_REPLY) == 0) { - u2f_proxy_response(service, btchip_context_D.outLength); - } - */ -} - -void u2f_apdu_get_version(u2f_service_t *service, - uint8_t p1, - uint8_t p2, - uint8_t *buffer, - uint16_t length) -{ - // screen_printf("U2F version\n"); - UNUSED(p1); - UNUSED(p2); - UNUSED(buffer); - UNUSED(length); - u2f_message_reply(service, U2F_CMD_MSG, (uint8_t *) U2F_VERSION, sizeof(U2F_VERSION)); -} - -// Special command that returns the proxy -void u2f_apdu_get_info(u2f_service_t *service, - uint8_t p1, - uint8_t p2, - uint8_t *buffer, - uint16_t length) -{ - UNUSED(p1); - UNUSED(p2); - UNUSED(buffer); - UNUSED(length); - u2f_message_reply(service, U2F_CMD_MSG, (uint8_t *) INFO, sizeof(INFO)); -} - -#endif // U2F_PROXY_MAGIC - -void u2f_handle_cmd_init(u2f_service_t *service, - uint8_t *buffer, - uint16_t length, - uint8_t *channelInit) -{ - // screen_printf("U2F init\n"); - uint8_t channel[4]; - (void) length; - if (u2f_is_channel_broadcast(channelInit)) { - // cx_rng_no_throw(channel, 4); // not available within the IO task, just do without - service->next_channel += 1; - U4BE_ENCODE(channel, 0, service->next_channel); - } - else { - memcpy(channel, channelInit, 4); - } - memmove(G_io_apdu_buffer, buffer, 8); - memcpy(G_io_apdu_buffer + 8, channel, 4); - G_io_apdu_buffer[12] = INIT_U2F_VERSION; - G_io_apdu_buffer[13] = INIT_DEVICE_VERSION_MAJOR; - G_io_apdu_buffer[14] = INIT_DEVICE_VERSION_MINOR; - G_io_apdu_buffer[15] = INIT_BUILD_VERSION; - G_io_apdu_buffer[16] = INIT_CAPABILITIES; - - if (u2f_is_channel_broadcast(channelInit)) { - memset(service->channel, 0xff, 4); - } - else { - memcpy(service->channel, channel, 4); - } - u2f_message_reply(service, U2F_CMD_INIT, G_io_apdu_buffer, 17); -} - -void u2f_handle_cmd_ping(u2f_service_t *service, uint8_t *buffer, uint16_t length) -{ - // screen_printf("U2F ping\n"); - u2f_message_reply(service, U2F_CMD_PING, buffer, length); -} - -int u2f_get_cmd_msg_data_length(const uint8_t *buffer, uint16_t length) -{ - /* Parse buffer to retrieve the data length. - Only Extended encoding is supported */ - - if (length < APDU_MIN_HEADER) { - return -1; - } - - if (length == APDU_MIN_HEADER) { - // Either short or extended encoding with Lc and Le omitted - return 0; - } - - if (length == APDU_MIN_HEADER + 1) { - // Short encoding, with next byte either Le or Lc with the other one omitted - // There is no way to tell so no way to check the value - // but anyway the data length is 0 - - // Support this particular short encoding APDU as Fido Conformance Tool v1.7.0 - // is using it even though spec requires that short encoding should not be used - // over HID. - return 0; - } - - if (length < APDU_MIN_HEADER + 3) { - // Short encoding or bad length - // We don't support short encoding - return -1; - } - - if (length == APDU_MIN_HEADER + 3) { - if (buffer[4] != 0) { - // Short encoding or bad length - // We don't support short encoding - return -1; - } - // Can't be short encoding as Lc = 0x00 would lead to invalid length - // so extended encoding and either: - // - Lc = 0x00 0x00 0x00 and Le is omitted - // - Lc omitted and Le = 0x00 0xyy 0xzz - // so no way to check the value - // but anyway the data length is 0 - return 0; - } - - if (buffer[LC_FIRST_BYTE_OFFSET] != 0) { - // Short encoding or bad length - // We don't support short encoding - return -1; - } - - // Can't be short encoding as Lc = 0 would lead to invalid length - // so extended encoding with Lc field present, optionally Le (2B) is present too - uint32_t dataLength - = (buffer[LC_FIRST_BYTE_OFFSET + 1] << 8) | (buffer[LC_FIRST_BYTE_OFFSET + 2]); - - // Ensure that Lc value is consistent - if ((APDU_MIN_HEADER + LONG_ENC_LC_SIZE + dataLength != length) - && (APDU_MIN_HEADER + LONG_ENC_LC_SIZE + dataLength + LONG_ENC_LE_SIZE != length)) { - return -1; - } - - return dataLength; -} - -void u2f_handle_cmd_msg(u2f_service_t *service, uint8_t *buffer, uint16_t length) -{ - // screen_printf("U2F msg\n"); - -#ifdef U2F_PROXY_MAGIC - uint8_t cla = buffer[OFFSET_CLA]; - uint8_t ins = buffer[OFFSET_INS]; - uint8_t p1 = buffer[OFFSET_P1]; - uint8_t p2 = buffer[OFFSET_P2]; -#endif // U2F_PROXY_MAGIC - - int dataLength = u2f_get_cmd_msg_data_length(buffer, length); - if (dataLength < 0) { - // invalid size - u2f_message_reply( - service, U2F_CMD_MSG, (uint8_t *) SW_WRONG_LENGTH, sizeof(SW_WRONG_LENGTH)); - return; - } - -#ifndef U2F_PROXY_MAGIC - - // No proxy mode, just pass the APDU as it is to the upper layer - memmove(G_io_apdu_buffer, buffer, length); - G_io_app.apdu_length = length; - G_io_app.apdu_media = IO_APDU_MEDIA_U2F; // the effective transport is managed by the U2F layer - G_io_app.apdu_state = APDU_U2F; - -#else // U2F_PROXY_MAGIC - - if (cla != FIDO_CLA) { - u2f_message_reply( - service, U2F_CMD_MSG, (uint8_t *) SW_UNKNOWN_CLASS, sizeof(SW_UNKNOWN_CLASS)); - return; - } - switch (ins) { - case FIDO_INS_ENROLL: - // screen_printf("enroll\n"); - u2f_apdu_enroll(service, p1, p2, buffer + OFFSET_DATA, dataLength); - break; - case FIDO_INS_SIGN: - // screen_printf("sign\n"); - u2f_apdu_sign(service, p1, p2, buffer + OFFSET_DATA, dataLength); - break; - case FIDO_INS_GET_VERSION: - // screen_printf("version\n"); - u2f_apdu_get_version(service, p1, p2, buffer + OFFSET_DATA, dataLength); - break; - - // only support by - case FIDO_INS_PROP_GET_INFO: - u2f_apdu_get_info(service, p1, p2, buffer + OFFSET_DATA, dataLength); - break; - - default: - // screen_printf("unsupported\n"); - u2f_message_reply(service, - U2F_CMD_MSG, - (uint8_t *) SW_UNKNOWN_INSTRUCTION, - sizeof(SW_UNKNOWN_INSTRUCTION)); - return; - } - -#endif // U2F_PROXY_MAGIC -} - -void u2f_message_complete(u2f_service_t *service) -{ - uint8_t cmd = service->transportBuffer[0]; - uint16_t length = (service->transportBuffer[1] << 8) | (service->transportBuffer[2]); - switch (cmd) { - case U2F_CMD_INIT: - u2f_handle_cmd_init(service, service->transportBuffer + 3, length, service->channel); - break; - case U2F_CMD_PING: - u2f_handle_cmd_ping(service, service->transportBuffer + 3, length); - break; - case U2F_CMD_MSG: - u2f_handle_cmd_msg(service, service->transportBuffer + 3, length); - break; -#ifdef HAVE_FIDO2 - case CTAP2_CMD_CBOR: - ctap2_handle_cmd_cbor(service, service->transportBuffer + 3, length); - break; - case CTAP2_CMD_CANCEL: - ctap2_handle_cmd_cancel(service, service->transportBuffer + 3, length); - break; -#endif - } -} - -#endif diff --git a/lib_stusb_impl/u2f_impl.h b/lib_stusb_impl/u2f_impl.h deleted file mode 100644 index aadf92b64..000000000 --- a/lib_stusb_impl/u2f_impl.h +++ /dev/null @@ -1,26 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include "usbd_hid_impl.h" - -/** - * Parse the cmd msg header to retrieve the data length. - * Return -1 in case of parsing error. - * Else return the data length. - */ -int u2f_get_cmd_msg_data_length(const uint8_t *buffer, uint16_t length); diff --git a/lib_stusb_impl/u2f_io.c b/lib_stusb_impl/u2f_io.c deleted file mode 100644 index a621abbda..000000000 --- a/lib_stusb_impl/u2f_io.c +++ /dev/null @@ -1,60 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include -#include - -#ifdef HAVE_IO_U2F - -#include "os.h" -#include "u2f_service.h" -#include "u2f_transport.h" -#include "u2f_processing.h" -#include "u2f_impl.h" - -#include "os_io_seproxyhal.h" - -#ifdef HAVE_BLE -#include "ledger_ble.h" -#endif - -void u2f_io_send(uint8_t *buffer, uint16_t length, u2f_transport_media_t media) -{ - if (media == U2F_MEDIA_USB) { - memmove(G_io_usb_ep_buffer, buffer, length); - // wipe the remaining to avoid : - // 1/ data leaks - // 2/ invalid junk - memset(G_io_usb_ep_buffer + length, 0, sizeof(G_io_usb_ep_buffer) - length); - } - switch (media) { - case U2F_MEDIA_USB: - io_usb_send_ep(U2F_EPIN_ADDR, G_io_usb_ep_buffer, USB_SEGMENT_SIZE, 0); - break; -#ifdef HAVE_BLE - case U2F_MEDIA_BLE: - LEDGER_BLE_send(buffer, length); - break; -#endif - default: - PRINTF("Request to send on unsupported media %d\n", media); - break; - } -} - -#endif // HAVE_IO_U2F diff --git a/lib_stusb_impl/usbd_ccid_impl.h b/lib_stusb_impl/usbd_ccid_impl.h deleted file mode 100644 index 889aa639e..000000000 --- a/lib_stusb_impl/usbd_ccid_impl.h +++ /dev/null @@ -1,50 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#ifndef USBD_CCID_IMPL_H -#define USBD_CCID_IMPL_H - -#ifdef HAVE_USB_CLASS_CCID - -// ================================================ -// CCID - -#define TPDU_EXCHANGE 0x01 -#define SHORT_APDU_EXCHANGE 0x02 -#define EXTENDED_APDU_EXCHANGE 0x04 -#define CHARACTER_EXCHANGE 0x00 - -#define EXCHANGE_LEVEL_FEATURE SHORT_APDU_EXCHANGE - -#define CCID_INTF 2 -#define CCID_BULK_IN_EP 0x83 -#define CCID_BULK_EPIN_SIZE 64 -#define CCID_BULK_OUT_EP 0x03 -#define CCID_BULK_EPOUT_SIZE 64 - -#ifdef HAVE_CCID_INTERRUPT -#define CCID_INTR_IN_EP 0x84 -#define CCID_INTR_EPIN_SIZE 16 -#endif // HAVE_CCID_INTERRUPT - -#define IO_CCID_DATA_BUFFER_SIZE IO_APDU_BUFFER_SIZE -#define G_io_ccid_data_buffer G_io_apdu_buffer - -#endif // HAVE_USB_CLASS_CCID - -#endif // USBD_CCID_IMPL_H diff --git a/lib_stusb_impl/usbd_hid_impl.h b/lib_stusb_impl/usbd_hid_impl.h deleted file mode 100644 index 877cb873a..000000000 --- a/lib_stusb_impl/usbd_hid_impl.h +++ /dev/null @@ -1,64 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#ifndef USBD_HID_IMPL_H -#define USBD_HID_IMPL_H - -// ================================================ -// HIDGEN - -#define HID_INTF 0 - -#define HID_EPIN_ADDR 0x82 -#define HID_EPIN_SIZE 0x40 - -#define HID_EPOUT_ADDR 0x02 -#define HID_EPOUT_SIZE 0x40 - -#ifdef HAVE_IO_U2F -// ================================================ -// HID U2F - -#define U2F_INTF 1 - -#define U2F_EPIN_ADDR 0x81 -#define U2F_EPIN_SIZE 0x40 - -#define U2F_EPOUT_ADDR 0x01 -#define U2F_EPOUT_SIZE 0x40 -#endif // HAVE_IO_U2F - -#ifdef HAVE_WEBUSB - -#define WEBUSB_EPIN_ADDR 0x83 -#define WEBUSB_EPIN_SIZE 0x40 -#define WEBUSB_EPOUT_ADDR 0x03 -#define WEBUSB_EPOUT_SIZE 0x40 - -#ifdef HAVE_USB_CLASS_CCID -#error Unsupported CCID+WEBUSB, not enough endpoints -#endif // HAVE_USB_CLASS_CCID - -#ifdef HAVE_IO_U2F -#define WEBUSB_INTF 2 -#else // HAVE_IO_U2F -#define WEBUSB_INTF 1 -#endif // HAVE_IO_U2F -#endif // HAVE_WEBUSB - -#endif // USBD_HID_IMPL_H diff --git a/lib_stusb_impl/usbd_impl.c b/lib_stusb_impl/usbd_impl.c deleted file mode 100644 index d8b721506..000000000 --- a/lib_stusb_impl/usbd_impl.c +++ /dev/null @@ -1,1610 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_impl.c - * @author MCD Application Team - * @version V2.2.0 - * @date 13-June-2014 - * @brief This file provides the HID core functions. - * - * @verbatim - * - * =================================================================== - * HID Class Description - * =================================================================== - * This module manages the HID class V1.11 following the "Device Class Definition - * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". - * This driver implements the following aspects of the specification: - * - The Boot Interface Subclass - * - Usage Page : Generic Desktop - * - Usage : Vendor - * - Collection : Application - * - * @note In HS mode and when the DMA is used, all variables and data structures - * dealing with the DMA during the transaction process should be 32-bit aligned. - * - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - *

    © COPYRIGHT 2014 STMicroelectronics

    - * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -#include "os.h" -#include "os_io_usb.h" - -/* Includes ------------------------------------------------------------------*/ - -#include "usbd_hid.h" -#include "usbd_hid_impl.h" - -#include "usbd_ctlreq.h" - -#include "usbd_core.h" -#include "usbd_conf.h" - -#include "usbd_def.h" -#include "os_io_seproxyhal.h" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-qual" - -#ifdef HAVE_IO_U2F -#include "u2f_transport.h" -#include "u2f_impl.h" -#endif // HAVE_IO_U2F - -#ifdef HAVE_USB_CLASS_CCID -#include "usbd_ccid_core.h" -#endif // HAVE_USB_CLASS_CCID - -/** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_HID - * @brief usbd core module - * @{ - */ - -/** @defgroup USBD_HID_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_HID_Private_Defines - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_HID_Private_Macros - * @{ - */ -/** - * @} - */ -/** @defgroup USBD_HID_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_HID_Private_Variables - * @{ - */ - -#define USBD_LANGID_STRING 0x409 - -// clang-format off -#ifdef HAVE_VID_PID_PROBER -#define USBD_VID 0x2581 -#define USBD_PID 0xf1d1 -static uint8_t const USBD_PRODUCT_FS_STRING[] = { - 10*2+2, - USB_DESC_TYPE_STRING, - 'N', 0, - 'a', 0, - 'n', 0, - 'o', 0, - '-', 0, - 'U', 0, - '2', 0, - 'F', 0, - '-', 0, - 'P', 0, -}; -#else -#define USBD_VID 0x2C97 - -#if defined(TARGET_NANOS) -#ifndef HAVE_LEGACY_PID -#define USBD_PID 0x1000 -#else // HAVE_LEGACY_PID -#define USBD_PID 0x0001 -#endif // HAVE_LEGACY_PID -static uint8_t const USBD_PRODUCT_FS_STRING[] = { - 6*2+2, - USB_DESC_TYPE_STRING, - 'N', 0, - 'a', 0, - 'n', 0, - 'o', 0, - ' ', 0, - 'S', 0, -}; -#elif defined(TARGET_HW2) -#ifndef HAVE_LEGACY_PID -#define USBD_PID 0x3000 -#else // HAVE_LEGACY_PID -#define USBD_PID 0x0003 -#endif // HAVE_LEGACY_PID -static uint8_t const USBD_PRODUCT_FS_STRING[] = { - 3*2+2, - USB_DESC_TYPE_STRING, - 'H', 0, - 'W', 0, - '2', 0, -}; -#elif defined(TARGET_NANOX) -#ifndef HAVE_LEGACY_PID -#define USBD_PID 0x4000 -#else // HAVE_LEGACY_PID -#define USBD_PID 0x0004 -#endif // HAVE_LEGACY_PID -static uint8_t const USBD_PRODUCT_FS_STRING[] = { - 6*2+2, - USB_DESC_TYPE_STRING, - 'N', 0, - 'a', 0, - 'n', 0, - 'o', 0, - ' ', 0, - 'X', 0, -}; -#elif defined(TARGET_NANOS2) -#ifndef HAVE_LEGACY_PID -#define USBD_PID 0x5000 -#else // HAVE_LEGACY_PID -#define USBD_PID 0x0005 -#endif // HAVE_LEGACY_PID -static uint8_t const USBD_PRODUCT_FS_STRING[] = { - 11*2+2, - USB_DESC_TYPE_STRING, - 'N', 0, - 'a', 0, - 'n', 0, - 'o', 0, - ' ', 0, - 'S', 0, - ' ', 0, - 'P', 0, - 'l', 0, - 'u', 0, - 's', 0, -}; -#elif defined(TARGET_STAX) -#ifndef HAVE_LEGACY_PID -#define USBD_PID 0x6000 -#else // HAVE_LEGACY_PID -#define USBD_PID 0x0006 -#endif // HAVE_LEGACY_PID -static uint8_t const USBD_PRODUCT_FS_STRING[] = { - 11*2+2, - USB_DESC_TYPE_STRING, - 'L', 0, - 'e', 0, - 'd', 0, - 'g', 0, - 'e', 0, - 'r', 0, - ' ', 0, - 'S', 0, - 't', 0, - 'a', 0, - 'x', 0, -}; -#elif defined(TARGET_FLEX) -#ifndef HAVE_LEGACY_PID -#define USBD_PID 0x7000 -#else // HAVE_LEGACY_PID -#define USBD_PID 0x0007 -#endif // HAVE_LEGACY_PID -static uint8_t const USBD_PRODUCT_FS_STRING[] = { - 11*2+2, - USB_DESC_TYPE_STRING, - 'L', 0, - 'e', 0, - 'd', 0, - 'g', 0, - 'e', 0, - 'r', 0, - ' ', 0, - 'F', 0, - 'l', 0, - 'e', 0, - 'x', 0, -}; -#else -#error unknown TARGET_NAME -#endif -#endif - -/* USB Standard Device Descriptor */ -static uint8_t const USBD_LangIDDesc[]= -{ - USB_LEN_LANGID_STR_DESC, - USB_DESC_TYPE_STRING, - LOBYTE(USBD_LANGID_STRING), - HIBYTE(USBD_LANGID_STRING), -}; - -static uint8_t const USB_SERIAL_STRING[] = -{ - 4*2+2, - USB_DESC_TYPE_STRING, - '0', 0, - '0', 0, - '0', 0, - '1', 0, -}; - -static uint8_t const USBD_MANUFACTURER_STRING[] = { - 6*2+2, - USB_DESC_TYPE_STRING, - 'L', 0, - 'e', 0, - 'd', 0, - 'g', 0, - 'e', 0, - 'r', 0, -}; - -#define USBD_INTERFACE_FS_STRING USBD_PRODUCT_FS_STRING -#define USBD_CONFIGURATION_FS_STRING USBD_PRODUCT_FS_STRING - -#ifndef HAVE_USB_HIDKBD - -static uint8_t const HID_ReportDesc[] = { - 0x06, 0xA0, 0xFF, // Usage page (vendor defined) - 0x09, 0x01, // Usage ID (vendor defined) - 0xA1, 0x01, // Collection (application) - - // The Input report - 0x09, 0x03, // Usage ID - vendor defined - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8 bits) - 0x95, HID_EPIN_SIZE, // Report Count (64 fields) - 0x81, 0x08, // Input (Data, Variable, Absolute) - - // The Output report - 0x09, 0x04, // Usage ID - vendor defined - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8 bits) - 0x95, HID_EPOUT_SIZE, // Report Count (64 fields) - 0x91, 0x08, // Output (Data, Variable, Absolute) - 0xC0 -}; - -#else - -static uint8_t const HID_ReportDesc_kbd[] = { - 0x05, 0x01, - 0x09, 0x06, - 0xA1, 0x01, - 0x05, 0x07, - 0x19, 0xE0, - 0x29, 0xE7, - 0x15, 0x00, - 0x25, 0x01, - 0x75, 0x01, - 0x95, 0x08, - 0x81, 0x02, - 0x95, 0x01, - 0x75, 0x08, - 0x81, 0x01, - 0x95, 0x05, - 0x75, 0x01, - 0x05, 0x08, - 0x19, 0x01, - 0x29, 0x05, - 0x91, 0x02, - 0x95, 0x01, - 0x75, 0x03, - 0x91, 0x01, - 0x95, 0x06, - 0x75, 0x08, - 0x15, 0x00, - 0x25, 0x65, - 0x05, 0x07, - 0x19, 0x00, - 0x29, 0x65, - 0x81, 0x00, - 0xC0 -}; -#endif // HAVE_USB_HIDKBD - -#ifdef HAVE_IO_U2F -static uint8_t const HID_ReportDesc_fido[] = { - 0x06, 0xD0, 0xF1, // Usage page (vendor defined) - 0x09, 0x01, // Usage ID (vendor defined) - 0xA1, 0x01, // Collection (application) - - // The Input report - 0x09, 0x03, // Usage ID - vendor defined - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8 bits) - 0x95, U2F_EPIN_SIZE, // Report Count (64 fields) - 0x81, 0x08, // Input (Data, Variable, Absolute) - - // The Output report - 0x09, 0x04, // Usage ID - vendor defined - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8 bits) - 0x95, U2F_EPOUT_SIZE, // Report Count (64 fields) - 0x91, 0x08, // Output (Data, Variable, Absolute) - 0xC0 -}; -#endif // HAVE_IO_U2F - -#define ARRAY_U2LE(l) (l)&0xFF, (l)>>8 - -#define CFG_HDR_LEN (0x9) -#define CFG_HIDGEN_LEN (0x9+0x9+0x7+0x7) -#define CFG_IO_U2F_LEN (0x9+0x9+0x7+0x7) -#define CFG_USB_CCID_LEN (0x9+0x36+0x7+0x7) -#define CFG_WEBUSB_LEN (0x9+0x7+0x7) - -/* USB HID device Configuration Descriptor */ -#ifdef HAVE_USB_CLASS_CCID -// Note: keeping const qualifier to ensure the good section is used by the linker. -// This table is mapped in NVRAM section and therefore it is correctly initialized, -// normal Read is possible and Write can be done through nvm_write() calls. -static __ALIGN_BEGIN uint8_t const N_USBD_CfgDesc[] __ALIGN_END = -#else -static __ALIGN_BEGIN uint8_t const USBD_CfgDesc[] __ALIGN_END = -#endif // HAVE_USB_CLASS_CCID -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - ARRAY_U2LE(CFG_HDR_LEN /* wTotalLength: Bytes returned */ - +CFG_HIDGEN_LEN -#ifdef HAVE_IO_U2F - +CFG_IO_U2F_LEN -#endif // HAVE_IO_U2F -#ifdef HAVE_USB_CLASS_CCID - +CFG_USB_CCID_LEN -#endif // HAVE_USB_CLASS_CCID -#ifdef HAVE_WEBUSB - +CFG_WEBUSB_LEN -#endif // HAVE_WEBUSB - ), - 1 -#ifdef HAVE_IO_U2F - +1 -#endif // HAVE_IO_U2F -#ifdef HAVE_USB_CLASS_CCID - +1 -#endif // HAVE_USB_CLASS_CCID -#ifdef HAVE_WEBUSB - +1 -#endif // HAVE_WEBUSB - , /*bNumInterfaces */ - 0x01, /*bConfigurationValue: Configuration value*/ - USBD_IDX_PRODUCT_STR, /*iConfiguration: Index of string descriptor describing the configuration*/ - 0xC0, /*bmAttributes: bus powered */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ - -#ifndef HAVE_USB_HIDKBD - /* HIDGEN ################################################################################################ */ - - /************** Descriptor of KBD HID interface ****************/ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - HID_INTF, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: HID*/ - 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - USBD_IDX_PRODUCT_STR, /*iInterface: Index of string descriptor*/ - - /******************** Descriptor of HID *************************/ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc),/*wItemLength: Total length of Report descriptor*/ - 0x00, - - /******************** Descriptor of Custom HID endpoints ********************/ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ - HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */ - 0x00, - 0x01, /*bInterval: Polling Interval (20 ms)*/ - - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, - 0x01, /* bInterval: Polling Interval (20 ms) */ - -#else - /* HIDKBD ################################################################################################ */ - - /************** Descriptor of KBD HID interface ****************/ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - 0x00, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: HID*/ - 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x01, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - USBD_IDX_PRODUCT_STR, /*iInterface: Index of string descriptor*/ - - /******************** Descriptor of HID *************************/ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x21, /*bCountryCode: Hardware target country*/ // 0x21: US, 0x08: FR, 0x0D: ISO Intl - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc_kbd),/*wItemLength: Total length of Report descriptor*/ - 0x00, - /******************** Descriptor of Custom HID endpoints ********************/ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ - HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - 8, /*wMaxPacketSize: */ - 0x00, - 0x01, /*bInterval: Polling Interval */ - - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - 8, /* wMaxPacketSize: */ - 0x00, - 0x01, /* bInterval: Polling Interval */ -#endif // HAVE_USB_HIDKBD - -#ifdef HAVE_IO_U2F - /* HID FIDO ################################################################################################ */ - - /************** Descriptor of HID FIDO interface ****************/ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - U2F_INTF, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: HID*/ - 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x01, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - USBD_IDX_PRODUCT_STR, /*iInterface: Index of string descriptor*/ - - /******************** Descriptor of HID *************************/ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x21, /*bCountryCode: Hardware target country*/ // 0x21: US, 0x08: FR, 0x0D: ISO Intl - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc_fido),/*wItemLength: Total length of Report descriptor*/ - 0x00, - /******************** Descriptor of Custom HID endpoints ********************/ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ - U2F_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - U2F_EPIN_SIZE, /*wMaxPacketSize: */ - 0x00, - 0x01, /*bInterval: Polling Interval */ - - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - U2F_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - U2F_EPOUT_SIZE, /* wMaxPacketSize: */ - 0x00, - 0x01,/* bInterval: Polling Interval */ -#endif // HAVE_IO_U2F - -#ifdef HAVE_USB_CLASS_CCID - /* CCID ################################################################################################ */ - - /******************** CCID **** interface ********************/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - CCID_INTF, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: endpoints used */ - 0x0B, /* bInterfaceClass: user's interface for CCID */ - 0x00, /* bInterfaceSubClass : */ - 0x00, /* nInterfaceProtocol : None */ - 0x05, /* iInterface: */ - - /******************* CCID class descriptor ********************/ - 0x36, /* bLength: CCID Descriptor size */ - 0x21, /* bDescriptorType: Functional Descriptor type. */ - 0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.00) */ - 0x01, /* bcdCCID(MSB) */ - - 0x00, /* bMaxSlotIndex :highest available slot on this device */ - 0x03, /* bVoltageSupport: bit Wise OR for 01h-5.0V 02h-3.0V - 04h 1.8V*/ - - 0x01,0x00,0x00,0x00, /* dwProtocols: 0001h = Protocol T=0 */ - 0x10,0x0E,0x00,0x00, /* dwDefaultClock: 3.6Mhz = 3600kHz = 0x0E10, - for 4 Mhz the value is (0x00000FA0) : - This is used in ETU and waiting time calculations*/ - 0x10,0x0E,0x00,0x00, /* dwMaximumClock: Maximum supported ICC clock frequency - in KHz. So, 3.6Mhz = 3600kHz = 0x0E10, - 4 Mhz (0x00000FA0) : */ - 0x00, /* bNumClockSupported : no setting from PC - If the value is 00h, the - supported clock frequencies are assumed to be the - default clock frequency defined by dwDefaultClock - and the maximum clock frequency defined by - dwMaximumClock */ - - 0xCD,0x25,0x00,0x00, /* dwDataRate: Default ICC I/O data rate in bps - 9677 bps = 0x25CD - for example 10752 bps (0x00002A00) */ - - 0xCD,0x25,0x00,0x00, /* dwMaxDataRate: Maximum supported ICC I/O data - rate in bps */ - 0x00, /* bNumDataRatesSupported : - The number of data rates that are supported by the CCID - If the value is 00h, all data rates between the default - data rate dwDataRate and the maximum data rate - dwMaxDataRate are supported. - Dont support GET_CLOCK_FREQUENCIES - */ - //46 - 0x00,0x00,0x00,0x00, /* dwMaxIFSD: 0 (T=0 only) */ - 0x00,0x00,0x00,0x00, /* dwSynchProtocols */ - 0x00,0x00,0x00,0x00, /* dwMechanical: no special characteristics */ - - 0xBA, 0x06, 0x02, 0x00, - //0x38,0x00,EXCHANGE_LEVEL_FEATURE,0x00, - /* dwFeatures: clk, baud rate, voltage : automatic */ - /* 00000008h Automatic ICC voltage selection - 00000010h Automatic ICC clock frequency change - 00000020h Automatic baud rate change according to - active parameters provided by the Host or self - determined 00000100h CCID can set - ICC in clock stop mode - - Only one of the following values may be present to - select a level of exchange: - 00010000h TPDU level exchanges with CCID - 00020000h Short APDU level exchange with CCID - 00040000h Short and Extended APDU level exchange - If none of those values : character level of exchange*/ - 0x0F,0x01,0x00,0x00, /* dwMaxCCIDMessageLength: Maximum block size + header*/ - /* 261 + 10 */ - - 0x00, /* bClassGetResponse*/ - 0x00, /* bClassEnvelope */ - 0x00,0x00, /* wLcdLayout : 0000h no LCD. */ - 0x00, /* bPINSupport : no PIN verif and modif */ - 0x01, /* bMaxCCIDBusySlots */ - - /******************** CCID Endpoints ********************/ - 0x07, /*Endpoint descriptor length = 7*/ - 0x05, /*Endpoint descriptor type */ - CCID_BULK_IN_EP, /*Endpoint address (IN, address 1) */ - 0x02, /*Bulk endpoint type */ - LOBYTE(CCID_BULK_EPIN_SIZE), - HIBYTE(CCID_BULK_EPIN_SIZE), - 0x00, /*Polling interval in milliseconds */ - - 0x07, /*Endpoint descriptor length = 7 */ - 0x05, /*Endpoint descriptor type */ - CCID_BULK_OUT_EP, /*Endpoint address (OUT, address 1) */ - 0x02, /*Bulk endpoint type */ - LOBYTE(CCID_BULK_EPOUT_SIZE), - HIBYTE(CCID_BULK_EPOUT_SIZE), - 0x00, /*Polling interval in milliseconds*/ -#endif // HAVE_USB_CLASS_CCID - -#ifdef HAVE_WEBUSB - /* WEBUSB ################################################################################################ */ - - /************** Descriptor of WEBUSB interface ****************/ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - WEBUSB_INTF, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0xFF, /*bInterfaceClass: WINUSB*/ - 0xFF, /*bInterfaceSubClass : WINUSB*/ - 0xFF, /*nInterfaceProtocol : WINUSB*/ - USBD_IDX_PRODUCT_STR, /*iInterface: Index of string descriptor*/ - - /******************** Descriptor of endpoints ********************/ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ - WEBUSB_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - WEBUSB_EPIN_SIZE, /*wMaxPacketSize: */ - 0x00, - 0x01, /*bInterval: Polling Interval */ - - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - WEBUSB_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - WEBUSB_EPOUT_SIZE, /* wMaxPacketSize: */ - 0x00, - 0x01,/* bInterval: Polling Interval */ -#endif // HAVE_WEBUSB -} ; - -#ifdef HAVE_IO_U2F -/* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t const USBD_HID_Desc_fido[] __ALIGN_END = -{ - /******************** Descriptor of HID *************************/ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x21, /*bCountryCode: Hardware target country*/ // 0x21: US, 0x08: FR, 0x0D: ISO Intl - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc_fido),/*wItemLength: Total length of Report descriptor*/ - 0x00, -}; -#endif // HAVE_IO_U2F - -#ifndef HAVE_USB_HIDKBD -/* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t const USBD_HID_Desc[] __ALIGN_END = -{ - /* 18 */ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc),/*wItemLength: Total length of Report descriptor*/ - 0x00, -}; -#else -/* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t const USBD_HID_Desc_kbd[] __ALIGN_END = -{ - /******************** Descriptor of HID *************************/ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x21, /*bCountryCode: Hardware target country*/ // 0x21: US, 0x08: FR, 0x0D: ISO Intl - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc_kbd),/*wItemLength: Total length of Report descriptor*/ - 0x00, -}; -#endif // HAVE_USB_HIDKBD - -/* USB Standard Device Descriptor */ -static __ALIGN_BEGIN uint8_t const USBD_DeviceQualifierDesc[] __ALIGN_END = -{ - USB_LEN_DEV_QUALIFIER_DESC, - USB_DESC_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x01, - 0x00, -}; - -/* USB Standard Device Descriptor */ -static uint8_t const USBD_DeviceDesc[]= { - 0x12, /* bLength */ - USB_DESC_TYPE_DEVICE, /* bDescriptorType */ -#ifdef HAVE_WEBUSB - 0x10, /* bcdUSB */ -#else // HAVE_WEBUSB - 0x00, /* bcdUSB */ -#endif // HAVE_WEBUSB - 0x02, - 0x00, /* bDeviceClass */ - 0x00, /* bDeviceSubClass */ - 0x00, /* bDeviceProtocol */ - USB_MAX_EP0_SIZE, /* bMaxPacketSize */ - LOBYTE(USBD_VID), /* idVendor */ - HIBYTE(USBD_VID), /* idVendor */ - LOBYTE(USBD_PID), /* idProduct */ - HIBYTE(USBD_PID), /* idProduct */ - - // Change this ID to make windows WINUSB/WEBUSB reenumerate when the - // descriptor changes and the PID/VID are not changed. - 0x01, /* bcdDevice rel. 2.01 */ - 0x02, - USBD_IDX_MFC_STR, /* Index of manufacturer string */ - USBD_IDX_PRODUCT_STR, /* Index of product string */ - USBD_IDX_SERIAL_STR, /* Index of serial number string */ - 1 /* bNumConfigurations */ -}; /* USB_DeviceDescriptor */ -// clang-format on - -/** - * @brief Returns the device descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -static uint8_t *USBD_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_DeviceDesc); - return (uint8_t *) USBD_DeviceDesc; -} - -/** - * @brief Returns the LangID string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -static uint8_t *USBD_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_LangIDDesc); - return (uint8_t *) USBD_LangIDDesc; -} - -/** - * @brief Returns the product string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -static uint8_t *USBD_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_PRODUCT_FS_STRING); - return (uint8_t *) USBD_PRODUCT_FS_STRING; -} - -/** - * @brief Returns the manufacturer string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -static uint8_t *USBD_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_MANUFACTURER_STRING); - return (uint8_t *) USBD_MANUFACTURER_STRING; -} - -/** - * @brief Returns the serial number string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -static uint8_t *USBD_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USB_SERIAL_STRING); - return (uint8_t *) USB_SERIAL_STRING; -} - -/** - * @brief Returns the configuration string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -static uint8_t *USBD_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_CONFIGURATION_FS_STRING); - return (uint8_t *) USBD_CONFIGURATION_FS_STRING; -} - -/** - * @brief Returns the interface string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -static uint8_t *USBD_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_INTERFACE_FS_STRING); - return (uint8_t *) USBD_INTERFACE_FS_STRING; -} - -/** - * @brief DeviceQualifierDescriptor - * return Device Qualifier descriptor - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_GetDeviceQualifierDesc_impl(uint16_t *length) -{ - *length = sizeof(USBD_DeviceQualifierDesc); - return (uint8_t *) USBD_DeviceQualifierDesc; -} - -/** - * @brief USBD_CUSTOM_HID_GetCfgDesc - * return configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_GetCfgDesc_impl(uint16_t *length) -{ -#ifdef HAVE_USB_CLASS_CCID - *length = sizeof(N_USBD_CfgDesc); - return (uint8_t *) N_USBD_CfgDesc; -#else - *length = sizeof(USBD_CfgDesc); - return (uint8_t *) USBD_CfgDesc; -#endif -} - -uint8_t *USBD_HID_GetHidDescriptor_impl(uint16_t *len) -{ - switch (USBD_Device.request.wIndex & 0xFF) { -#ifdef HAVE_IO_U2F - case U2F_INTF: - *len = sizeof(USBD_HID_Desc_fido); - return (uint8_t *) USBD_HID_Desc_fido; -#endif // HAVE_IO_U2F -#ifndef HAVE_USB_HIDKBD - case HID_INTF: - *len = sizeof(USBD_HID_Desc); - return (uint8_t *) USBD_HID_Desc; -#else - case HID_INTF: - *len = sizeof(USBD_HID_Desc_kbd); - return (uint8_t *) USBD_HID_Desc_kbd; -#endif // HAVE_USB_HIDKBD - } - *len = 0; - return 0; -} - -uint8_t *USBD_HID_GetReportDescriptor_impl(uint16_t *len) -{ - switch (USBD_Device.request.wIndex & 0xFF) { -#ifdef HAVE_IO_U2F - case U2F_INTF: - *len = sizeof(HID_ReportDesc_fido); - return (uint8_t *) HID_ReportDesc_fido; -#endif // HAVE_IO_U2F -#ifndef HAVE_USB_HIDKBD - case HID_INTF: - *len = sizeof(HID_ReportDesc); - return (uint8_t *) HID_ReportDesc; -#else - case HID_INTF: - *len = sizeof(HID_ReportDesc_kbd); - return (uint8_t *) HID_ReportDesc_kbd; -#endif // HAVE_USB_HIDKBD - } - *len = 0; - return 0; -} - -#ifdef HAVE_USB_CLASS_CCID -/** - * @brief Returns the pinpad value offset in the descriptor. - * @retval Offset - */ -const volatile uint8_t *USBD_GetPinPadOffset(void) -{ - unsigned short length = 0; - uint8_t *cfgDesc = NULL; - unsigned short offset = 0; - - cfgDesc = USBD_GetCfgDesc_impl(&length); - - offset = CFG_HDR_LEN + CFG_HIDGEN_LEN; -#ifdef HAVE_IO_U2F - offset += CFG_IO_U2F_LEN; -#endif // HAVE_IO_U2F - // Offset of the parameter 'bPINSupport' inside the CCID interface structure in N_USBD_CfgDesc - offset += 61; - - // Returns a const volatile pointer allowing callers to do - // - write operations through nvram_write - // - read operation without potential compilation optimization issue thanks to the volatile - // qualifier. - return (const volatile uint8_t *) (cfgDesc + offset); -} -#endif // HAVE_USB_CLASS_CCID - -/** - * @} - */ - -/** - * @brief USBD_HID_DataOut - * handle data OUT Stage - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - * - * This function is the default behavior for our implementation when data are sent over the out hid - * endpoint - */ - -#ifdef HAVE_IO_U2F - -/** - * @brief USBD_HID_Init - * Initialize the HID interface - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -uint8_t USBD_U2F_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) -{ - UNUSED(cfgidx); - - /* Open EP IN */ - USBD_LL_OpenEP(pdev, U2F_EPIN_ADDR, USBD_EP_TYPE_INTR, U2F_EPIN_SIZE); - - /* Open EP OUT */ - USBD_LL_OpenEP(pdev, U2F_EPOUT_ADDR, USBD_EP_TYPE_INTR, U2F_EPOUT_SIZE); - - /* Prepare Out endpoint to receive 1st packet */ - USBD_LL_PrepareReceive(pdev, U2F_EPOUT_ADDR, U2F_EPOUT_SIZE); - - return USBD_OK; -} - -uint8_t USBD_U2F_DataIn_impl(USBD_HandleTypeDef *pdev, uint8_t epnum) -{ - UNUSED(pdev); - // only the data hid endpoint will receive data - switch (epnum) { - // FIDO endpoint - case (U2F_EPIN_ADDR & 0x7F): - // advance the u2f sending machine state - u2f_transport_sent(&G_io_u2f, U2F_MEDIA_USB); - break; - } - return USBD_OK; -} - -uint8_t USBD_U2F_DataOut_impl(USBD_HandleTypeDef *pdev, - uint8_t epnum, - uint8_t *buffer, - __attribute__((unused)) apdu_buffer_t *apdu_buf) -{ -#ifdef HAVE_LOCAL_APDU_BUFFER -#error "Feature not implemented" -#endif - - switch (epnum) { - // FIDO endpoint - case (U2F_EPOUT_ADDR & 0x7F): - USBD_LL_PrepareReceive(pdev, U2F_EPOUT_ADDR, U2F_EPOUT_SIZE); - u2f_transport_received( - &G_io_u2f, buffer, io_seproxyhal_get_ep_rx_size(U2F_EPOUT_ADDR), U2F_MEDIA_USB); - break; - } - - return USBD_OK; -} -#endif // HAVE_IO_U2F - -uint8_t USBD_HID_DataIn_impl(USBD_HandleTypeDef *pdev, uint8_t epnum) -{ - UNUSED(pdev); - switch (epnum) { - // HID gen endpoint - case (HID_EPIN_ADDR & 0x7F): - io_usb_hid_sent(io_usb_send_apdu_data); - break; - } - - return USBD_OK; -} - -uint8_t USBD_HID_DataOut_impl(USBD_HandleTypeDef *pdev, - uint8_t epnum, -#ifndef HAVE_USB_HIDKBD - uint8_t *buffer, - apdu_buffer_t *apdu_buf -#else - __attribute__((unused)) uint8_t *buffer, - __attribute__((unused)) apdu_buffer_t *apdu_buf -#endif // HAVE_USB_HIDKBD -) -{ - // only the data hid endpoint will receive data - switch (epnum) { - // HID gen endpoint - case (HID_EPOUT_ADDR & 0x7F): - // prepare receiving the next chunk (masked time) - USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR, HID_EPOUT_SIZE); - -#ifndef HAVE_USB_HIDKBD - // avoid troubles when an apdu has not been replied yet - if (G_io_app.apdu_media == IO_APDU_MEDIA_NONE) { - // add to the hid transport - switch (io_usb_hid_receive(io_usb_send_apdu_data, - buffer, - io_seproxyhal_get_ep_rx_size(HID_EPOUT_ADDR), - apdu_buf)) { - default: - break; - - case IO_USB_APDU_RECEIVED: - G_io_app.apdu_media = IO_APDU_MEDIA_USB_HID; // for application code - G_io_app.apdu_state = APDU_USB_HID; // for next call to io_exchange - G_io_app.apdu_length = G_io_usb_hid_total_length; - break; - } - } -#endif // HAVE_USB_HIDKBD - break; - } - - return USBD_OK; -} - -#ifdef HAVE_WEBUSB - -uint8_t USBD_WEBUSB_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) -{ - UNUSED(cfgidx); - - /* Open EP IN */ - USBD_LL_OpenEP(pdev, WEBUSB_EPIN_ADDR, USBD_EP_TYPE_INTR, WEBUSB_EPIN_SIZE); - - /* Open EP OUT */ - USBD_LL_OpenEP(pdev, WEBUSB_EPOUT_ADDR, USBD_EP_TYPE_INTR, WEBUSB_EPOUT_SIZE); - - /* Prepare Out endpoint to receive 1st packet */ - USBD_LL_PrepareReceive(pdev, WEBUSB_EPOUT_ADDR, WEBUSB_EPOUT_SIZE); - - return USBD_OK; -} - -uint8_t USBD_WEBUSB_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) -{ - UNUSED(pdev); - UNUSED(cfgidx); - return USBD_OK; -} - -uint8_t USBD_WEBUSB_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) -{ - UNUSED(pdev); - UNUSED(req); - return USBD_OK; -} - -uint8_t USBD_WEBUSB_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) -{ - UNUSED(pdev); - switch (epnum) { - // HID gen endpoint - case (WEBUSB_EPIN_ADDR & 0x7F): - io_usb_hid_sent(io_usb_send_apdu_data_ep0x83); - break; - } - return USBD_OK; -} - -uint8_t USBD_WEBUSB_DataOut(USBD_HandleTypeDef *pdev, - uint8_t epnum, - uint8_t *buffer, - apdu_buffer_t *apdu_buf) -{ - // only the data hid endpoint will receive data - switch (epnum) { - // HID gen endpoint - case (WEBUSB_EPOUT_ADDR & 0x7F): - // prepare receiving the next chunk (masked time) - USBD_LL_PrepareReceive(pdev, WEBUSB_EPOUT_ADDR, WEBUSB_EPOUT_SIZE); - - // avoid troubles when an apdu has not been replied yet - if (G_io_app.apdu_media == IO_APDU_MEDIA_NONE) { - // add to the hid transport - switch (io_usb_hid_receive(io_usb_send_apdu_data_ep0x83, - buffer, - io_seproxyhal_get_ep_rx_size(WEBUSB_EPOUT_ADDR), - apdu_buf)) { - default: - break; - - case IO_USB_APDU_RECEIVED: - G_io_app.apdu_media = IO_APDU_MEDIA_USB_WEBUSB; // for application code - G_io_app.apdu_state = APDU_USB_WEBUSB; // for next call to io_exchange - G_io_app.apdu_length = G_io_usb_hid_total_length; - break; - } - } - break; - } - - return USBD_OK; -} - -// arbitrary vendor chosen -#define WEBUSB_VENDOR_CODE 0x1E - -// from https://wicg.github.io/webusb/#webusb-platform-capability-descriptor -// see also this (for endianness explanation) -// https://github.com/WICG/webusb/issues/115#issuecomment-352206549 -#define WEBUSB_UUID \ - 0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65 - -#define WEBUSB_REQ_GET_URL 0x02 - -#define WEBUSB_DT_DESCRIPTOR_SET_HEADER 0 -#define WEBUSB_DT_CONFIGURATION_SUBSET_HEADER 1 -#define WEBUSB_DT_FUNCTION_SUBSET_HEADER 2 -#define WEBUSB_DT_URL 3 - -#define WEBUSB_URL_SCHEME_HTTP 0 -#define WEBUSB_URL_SCHEME_HTTPS 1 -#define WEBUSB_URL_SCHEME_CUSTOM 255 - -unsigned char const C_webusb_url_descriptor[] = { - // bLength - 3 + WEBUSB_URL_SIZE_B, - // bDescriptorType - WEBUSB_DT_URL, - // bScheme - WEBUSB_URL_SCHEME_HTTPS, - // URL - WEBUSB_URL}; - -/* USB 3.1 Descriptor Types - Table 9-6 */ -#define USB_DT_BOS 15 -#define USB_DT_DEVICE_CAPABILITY 16 - -#define USB_DT_BOS_SIZE 5 - -/* USB Device Capability Types - USB 3.1 Table 9-14 */ -#define USB_DC_PLATFORM 5 - -#define MS_OS_20_DESCRIPTOR_LENGTH (0xb2) - -#define WINUSB_VENDOR_CODE 0x77 - -// clang-format off -unsigned char const C_usb_bos[] = { - USB_DT_BOS_SIZE, // bLength (5) - USB_DT_BOS, // bDescriptorType - 0x39, 0x00, // wTotalLength - 2, //bNumberDeviceCapabilities - - // capability descriptor - 8+16, // bLength - USB_DT_DEVICE_CAPABILITY, // bDescriptorType - USB_DC_PLATFORM, // bDevCapability - 0, // bReserved - WEBUSB_UUID, // UUID[16] - 0x00, // bcdVersion - 0x01, - WEBUSB_VENDOR_CODE, // bVencordCode -#if WEBUSB_URL_SIZE_B > 0 - 1, // iLandingPage -#else // WEBUSB_URL_SIZE_B - 0, // iLandingPage, no url to retrieve -#endif // WEBUSB_URL_SIZE_B - - // Microsoft OS 2.0 Platform Capability Descriptor - 0x1C, // Descriptor size (28 bytes) - 0x10, // Descriptor type (Device Capability) - 0x05, // Capability type (Platform) - 0x00, // Reserved - - // MS OS 2.0 Platform Capability ID (D8DD60DF-4589-4CC7-9CD2-659D9E648A9F) - 0xDF, 0x60, 0xDD, 0xD8, - 0x89, 0x45, - 0xC7, 0x4C, - 0x9C, 0xD2, - 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F, - - 0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000) - MS_OS_20_DESCRIPTOR_LENGTH, 0x00, - WINUSB_VENDOR_CODE, // Vendor-assigned bMS_VendorCode - 0x00 // Doesn’t support alternate enumeration -}; -// clang-format on - -#endif // HAVE_WEBUSB - -static uint8_t *USBD_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); -#ifdef HAVE_WEBUSB - *length = sizeof(C_usb_bos); - return (uint8_t *) C_usb_bos; -#else - *length = 0; - return NULL; -#endif -} - -/** @defgroup USBD_HID_Private_Functions - * @{ - */ - -// note: how core lib usb calls the hid class -USBD_DescriptorsTypeDef const HID_Desc = { - USBD_DeviceDescriptor, - USBD_LangIDStrDescriptor, - USBD_ManufacturerStrDescriptor, - USBD_ProductStrDescriptor, - USBD_SerialStrDescriptor, - USBD_ConfigStrDescriptor, - USBD_InterfaceStrDescriptor, - USBD_BOSDescriptor, -}; - -#ifdef HAVE_IO_U2F -static USBD_ClassTypeDef const USBD_U2F = { - USBD_U2F_Init, - USBD_HID_DeInit, - USBD_HID_Setup, - NULL, /*EP0_TxSent*/ - NULL, - /*EP0_RxReady*/ /* STATUS STAGE IN */ - USBD_U2F_DataIn_impl, /*DataIn*/ - USBD_U2F_DataOut_impl, /*DataOut*/ - NULL, /*SOF */ - NULL, - NULL, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetDeviceQualifierDesc_impl, -}; -#endif // HAVE_IO_U2F - -static USBD_ClassTypeDef const USBD_HID = { - USBD_HID_Init, - USBD_HID_DeInit, - USBD_HID_Setup, - NULL, /*EP0_TxSent*/ - NULL, - /*EP0_RxReady*/ /* STATUS STAGE IN */ - USBD_HID_DataIn_impl, /*DataIn*/ - USBD_HID_DataOut_impl, /*DataOut*/ - NULL, /*SOF */ - NULL, - NULL, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetDeviceQualifierDesc_impl, -}; - -#ifdef HAVE_WEBUSB - -// clang-format off -static const unsigned char C_winusb_string_descriptor[] = { - // bLength - 0x12, - // bDescriptorType - USB_DESC_TYPE_STRING, - // wData - 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, '1', 0x00, '0', 0x00, '0', 0x00, WINUSB_VENDOR_CODE, 0x00, // MSFT100 -}; -// clang-format on - -// Microsoft OS 2.0 descriptor wIndex values -#define MS_OS_20_DESCRIPTOR_INDEX 0x07 - -// Microsoft OS 2.0 descriptor types -#define MS_OS_20_SUBSET_HEADER_CONFIGURATION 0x01 -#define MS_OS_20_SUBSET_HEADER_FUNCTION 0x02 -#define MS_OS_20_FEATURE_COMPATIBLE_ID 0x03 -#define MS_OS_20_FEATURE_REG_PROPERTY 0x04 - -// clang-format off -static const unsigned char C_winusb_request_descriptor[] = { - // Microsoft OS 2.0 descriptor set header (table 10) - 0x0A, - 0x00, // Descriptor size (10 bytes) - 0x00, - 0x00, // MS OS 2.0 descriptor set header - 0x00, - 0x00, - 0x03, - 0x06, // Windows version (8.1) (0x06030000) - MS_OS_20_DESCRIPTOR_LENGTH, - 0x00, // Size, MS OS 2.0 descriptor set - - // Microsoft OS 2.0 configuration subset header - 0x08, 0x00, // Descriptor size (8 bytes) - MS_OS_20_SUBSET_HEADER_CONFIGURATION, 0x00, // MS OS 2.0 configuration subset header - 0x00, // bConfigurationValue - 0x00, // Reserved - 0xA8, 0x00, // Size, MS OS 2.0 configuration subset - - // Microsoft OS 2.0 function subset header - 0x08, 0x00, // Descriptor size (8 bytes) - MS_OS_20_SUBSET_HEADER_FUNCTION, 0x00, // MS OS 2.0 function subset header - WEBUSB_INTF, // first Interface impacted by this function - - 0x00, // Reserved - 0xA0, 0x00, // Size, MS OS 2.0 function subset - - // Microsoft OS 2.0 compatible ID descriptor (table 13) - 0x14, 0x00, // wLength - MS_OS_20_FEATURE_COMPATIBLE_ID, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID - 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x84, 0x00, //wLength: - MS_OS_20_FEATURE_REG_PROPERTY, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9) - 0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15) - 0x2a, 0x00, //wPropertyNameLength: - //bPropertyName: “DeviceInterfaceGUID†- 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, - 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, - 0x00, 0x00, - 0x50, 0x00, // wPropertyDataLength - //bPropertyData: “{CE809264-4B24-4E81-A8B2-57ED01D580E1}â€. - '{', 0x00, 'C', 0x00, 'E', 0x00, '8', 0x00, '0', 0x00, '9', 0x00, '2', 0x00, '6', 0x00, '4', 0x00, '-', 0x00, - '4', 0x00, 'B', 0x00, '2', 0x00, '4', 0x00, '-', 0x00, '4', 0x00, 'E', 0x00, '8', 0x00, '1', 0x00, '-', 0x00, - 'A', 0x00, '8', 0x00, 'B', 0x00, '2', 0x00, '-', 0x00, '5', 0x00, '7', 0x00, 'E', 0x00, 'D', 0x00, '0', 0x00, - '1', 0x00, 'D', 0x00, '5', 0x00, '8', 0x00, '0', 0x00, 'E', 0x00, '1', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -#define WINUSB_GET_COMPATIBLE_ID_FEATURE 0x04 -static const unsigned char C_winusb_wcid[] = { - // header - 0x28, 0x00, 0x00, 0x00, // dwLength - 0x00, 0x01, // bcdVersion - 0x04, 0x00, // wIndex - 0x01, // bNumSections - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved - // functions - WEBUSB_INTF, // bInterfaceNumber - 0x01, // reserved - 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compatibleId - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, // subCompatibleId - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved -}; - -#define WINUSB_GET_EXTENDED_PROPERTIES_OS_FEATURE 0x05 -static const unsigned char C_winusb_guid[] = { - // header - 0x92, 0x00, 0x00, 0x00, // dwLength - 0x00, 0x01, // bcdVersion - 0x05, 0x00, // wIndex - 0x01, 0x00, // wNumFeatures - // features - 0x88, 0x00, 0x00, 0x00, // dwLength - 0x07, 0x00, 0x00, 0x00, // dwPropertyDataType - 0x2A, 0x00, // wNameLength - 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, - 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, - 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, - 'D', 0x00, 's', 0x00, 0x00, 0x00, // .name, unicode nul terminated - 0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength - // Same as BLE char: 13d63400-2C97-0004-0000-4c6564676572 - '{', 0x00, '1', 0x00, '3', 0x00, 'd', 0x00, '6', 0x00, '3', 0x00, - '4', 0x00, '0', 0x00, '0', 0x00, '-', 0x00, '2', 0x00, 'C', 0x00, - '9', 0x00, '7', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, - '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, '0', 0x00, - '-', 0x00, '4', 0x00, 'c', 0x00, '6', 0x00, '5', 0x00, '6', 0x00, - '4', 0x00, '6', 0x00, '7', 0x00, '6', 0x00, '5', 0x00, '7', 0x00, - '2', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 // propertyData, double unicode nul terminated -}; -// clang-format on - -// upon unsupported request, check for webusb request -void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) -{ -#if WEBUSB_URL_SIZE_B > 0 - if ((req->bmRequest & 0x80) && req->bRequest == WEBUSB_VENDOR_CODE - && req->wIndex == WEBUSB_REQ_GET_URL - // HTTPS url - && req->wValue == 1) { - // return the URL descriptor - USBD_CtlSendData(pdev, - (unsigned char *) C_webusb_url_descriptor, - MIN(req->wLength, sizeof(C_webusb_url_descriptor))); - } - else -#endif // WEBUSB_URL_SIZE_B - // SETUP (LE): 0x80 0x06 0x03 0x77 0x00 0x00 0xXX 0xXX - if ((req->bmRequest & 0x80) && req->bRequest == USB_REQ_GET_DESCRIPTOR - && (req->wValue >> 8) == USB_DESC_TYPE_STRING && (req->wValue & 0xFF) == 0xEE) { - USBD_CtlSendData(pdev, - (unsigned char *) C_winusb_string_descriptor, - MIN(req->wLength, sizeof(C_winusb_string_descriptor))); - } - // SETUP (LE): 0x80 0x77 0x04 0x00 0x00 0x00 0xXX 0xXX - else if ((req->bmRequest & 0x80) && req->bRequest == WINUSB_VENDOR_CODE - && req->wIndex == WINUSB_GET_COMPATIBLE_ID_FEATURE) { - USBD_CtlSendData( - pdev, (unsigned char *) C_winusb_wcid, MIN(req->wLength, sizeof(C_winusb_wcid))); - } - // SETUP (LE): 0x80 0x77 0x05 0x00 0x00 0x00 0xXX 0xXX - else if ((req->bmRequest & 0x80) && req->bRequest == WINUSB_VENDOR_CODE - && req->wIndex == WINUSB_GET_EXTENDED_PROPERTIES_OS_FEATURE) { - USBD_CtlSendData( - pdev, (unsigned char *) C_winusb_guid, MIN(req->wLength, sizeof(C_winusb_guid))); - } - // Microsoft OS 2.0 Descriptors for Windows 8.1 and Windows 10 - else if ((req->bmRequest & 0x80) && req->bRequest == WINUSB_VENDOR_CODE - && req->wIndex == MS_OS_20_DESCRIPTOR_INDEX) { - USBD_CtlSendData(pdev, - (unsigned char *) C_winusb_request_descriptor, - MIN(req->wLength, sizeof(C_winusb_request_descriptor))); - } - else { - USBD_CtlStall(pdev); - } -} - -static const USBD_ClassTypeDef USBD_WEBUSB = { - USBD_WEBUSB_Init, - USBD_WEBUSB_DeInit, - USBD_WEBUSB_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_WEBUSB_DataIn, - USBD_WEBUSB_DataOut, - NULL, /*SOF */ - NULL, /*ISOIn*/ - NULL, /*ISOOut*/ - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetDeviceQualifierDesc_impl, -}; - -#endif // HAVE_WEBUSB - -#ifdef HAVE_USB_CLASS_CCID -static const USBD_ClassTypeDef USBD_CCID = { - USBD_CCID_Init, - USBD_CCID_DeInit, - USBD_CCID_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_CCID_DataIn, - USBD_CCID_DataOut, - NULL, /*SOF */ - NULL, /*ISOIn*/ - NULL, /*ISOOut*/ - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetDeviceQualifierDesc_impl, -}; - -uint8_t SC_AnswerToReset(uint8_t voltage, uint8_t *atr_buffer) -{ - UNUSED(voltage); - // return the atr length - atr_buffer[0] = 0x3B; - atr_buffer[1] = 0; - return 2; -} - -void SC_Poweroff(void) -{ - // nothing to do ? -} - -uint8_t SC_ExecuteEscape(uint8_t *escapePtr, - uint32_t escapeLen, - uint8_t *responseBuff, - uint16_t *responseLen) -{ - UNUSED(escapePtr); - UNUSED(escapeLen); - UNUSED(responseBuff); - UNUSED(responseLen); - // nothing to do ? - return 0; -} -#endif // HAVE_USB_CLASS_CCID - -void USB_power(unsigned char enabled) -{ - memset(&USBD_Device, 0, sizeof(USBD_Device)); - - // init timeouts and other global fields - memset(G_io_app.usb_ep_xfer_len, 0, sizeof(G_io_app.usb_ep_xfer_len)); - memset(G_io_app.usb_ep_timeouts, 0, sizeof(G_io_app.usb_ep_timeouts)); - - if (enabled) { - memset(&USBD_Device, 0, sizeof(USBD_Device)); - /* Init Device Library */ - USBD_Init(&USBD_Device, (USBD_DescriptorsTypeDef *) &HID_Desc, 0); - - /* Register the HID class */ - USBD_RegisterClassForInterface(HID_INTF, &USBD_Device, (USBD_ClassTypeDef *) &USBD_HID); -#ifdef HAVE_IO_U2F - USBD_RegisterClassForInterface(U2F_INTF, &USBD_Device, (USBD_ClassTypeDef *) &USBD_U2F); - // initialize the U2F tunnel transport - u2f_transport_init(&G_io_u2f, G_io_apdu_buffer, IO_APDU_BUFFER_SIZE); -#endif // HAVE_IO_U2F -#ifdef HAVE_USB_CLASS_CCID - USBD_RegisterClassForInterface(CCID_INTF, &USBD_Device, (USBD_ClassTypeDef *) &USBD_CCID); -#endif // HAVE_USB_CLASS_CCID - -#ifdef HAVE_WEBUSB - USBD_RegisterClassForInterface( - WEBUSB_INTF, &USBD_Device, (USBD_ClassTypeDef *) &USBD_WEBUSB); -#endif // HAVE_WEBUSB - - /* Start Device Process */ - USBD_Start(&USBD_Device); - } - else { - USBD_DeInit(&USBD_Device); - } -} - -#pragma GCC diagnostic pop -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/lib_u2f/doc/mainpage.dox b/lib_u2f/doc/mainpage.dox deleted file mode 100644 index dbf4e0620..000000000 --- a/lib_u2f/doc/mainpage.dox +++ /dev/null @@ -1,9 +0,0 @@ -/** @page u2f_mainpage Universal 2nd Factor library - -@section u2f_mainpage_intro Introduction - -This page describes the API of U2F (Universal 2nd Factor), available on \b NanoX and \b Stax products. - -@note TO BE COMPLETED - -*/ diff --git a/lib_u2f/include/u2f_io.h b/lib_u2f/include/u2f_io.h deleted file mode 100644 index 2d3dd4ab8..000000000 --- a/lib_u2f/include/u2f_io.h +++ /dev/null @@ -1,37 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include -#include -#include - -#ifndef __U2F_IO_H__ - -#define __U2F_IO_H__ - -#include "u2f_service.h" -#include "os.h" - -#define EXCEPTION_DISCONNECT 0x80 - -/** - * Request an IO message to be dispatched in the required media. - */ -void u2f_io_send(uint8_t *buffer, uint16_t length, u2f_transport_media_t media); - -#endif diff --git a/lib_u2f/include/u2f_processing.h b/lib_u2f/include/u2f_processing.h deleted file mode 100644 index 0ece64c78..000000000 --- a/lib_u2f/include/u2f_processing.h +++ /dev/null @@ -1,51 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#ifndef __U2F_PROCESSING_H__ - -#define __U2F_PROCESSING_H__ - -#include "u2f_service.h" - -/** - * Function called when a complete message is received - */ -void u2f_message_complete(u2f_service_t *service); - -/** - * Function to be called upon timer event to notify the U2F library of potential - */ -void u2f_timeout(u2f_service_t *service); - -/** - * Auto reply user presence required until the real reply is ready to be replied - */ -void u2f_message_set_autoreply_wait_user_presence(u2f_service_t *service, bool enabled); - -/** - * Return true when a message can be replied using ::u2f_message_reply - */ -bool u2f_message_repliable(u2f_service_t *service); - -/** - * Function to be called by the user when the reply to a previously completed message is ready to be - * sent - */ -void u2f_message_reply(u2f_service_t *service, uint8_t cmd, uint8_t *buffer, uint16_t length); - -#endif diff --git a/lib_u2f/include/u2f_service.h b/lib_u2f/include/u2f_service.h deleted file mode 100644 index 11c3752c6..000000000 --- a/lib_u2f/include/u2f_service.h +++ /dev/null @@ -1,109 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include -#include -#include - -#ifndef __U2F_SERVICE_H__ - -#define __U2F_SERVICE_H__ - -#define U2F_CHANNEL_ID_SIZE 4 - -struct u2f_service_t; - -typedef void (*u2fHandle_t)(struct u2f_service_t *service, uint8_t *inputBuffer, uint8_t *channel); -typedef void (*u2fPromptUserPresence_t)(struct u2f_service_t *service, - bool enroll, - uint8_t *applicationParameter); -typedef void (*u2fTimer_t)(struct u2f_service_t *service); - -typedef enum { - U2F_IDLE, - U2F_HANDLE_SEGMENTED, - U2F_PROCESSING_COMMAND, - U2F_SENDING_RESPONSE, - U2F_SENDING_ERROR, - U2F_INTERNAL_ERROR, - U2F_FAKE_RECEIVED, -} u2f_transport_state_t; - -typedef enum { - U2F_MEDIA_NONE, - U2F_MEDIA_USB, - U2F_MEDIA_NFC, - U2F_MEDIA_BLE -} u2f_transport_media_t; - -typedef enum { - U2F_WAIT_ASYNCH_IDLE, - U2F_WAIT_ASYNCH_ON, - U2F_WAIT_ASYNCH_REPLY_READY, -} u2f_wait_asynch_state_t; - -typedef struct u2f_service_t { - // Internal - uint32_t next_channel; - - uint8_t channel[U2F_CHANNEL_ID_SIZE]; - u2f_transport_media_t media; - - // buffer reference used when transport layer is reset, to process and receive the next message - uint8_t *transportReceiveBuffer; - // length of the receive buffer to avoid overflows - uint16_t transportReceiveBufferLength; - - uint8_t transportChannel[4]; - uint16_t transportOffset; - uint16_t transportLength; - uint8_t transportPacketIndex; - uint8_t *transportBuffer; - u2f_transport_state_t transportState; - u2f_transport_media_t transportMedia; - - // handle fake channel state to simulate a USB keepalive - uint16_t fakeChannelTransportOffset; - uint8_t fakeChannelTransportPacketIndex; - u2f_transport_state_t fakeChannelTransportState; - uint16_t commandCrc; - uint16_t fakeChannelCrc; - - // mark that an asynchronous response is available - uint8_t waitAsynchronousResponse; - - // uint16_t responseLength; - bool sending; - - u2fTimer_t timeoutFunction; - uint32_t timerInterval; - uint32_t seqTimeout; - bool requireKeepalive; - uint32_t keepaliveTimeout; - - uint8_t sendCmd; -} u2f_service_t; - -void u2f_message_complete(u2f_service_t *service); - -// FIDO 2 compatible applications have to provide those implementations - -void ctap2_handle_cmd_cbor(u2f_service_t *service, uint8_t *buffer, uint16_t length); -void ctap2_handle_cmd_cancel(u2f_service_t *service, uint8_t *buffer, uint16_t length); - -#endif diff --git a/lib_u2f/include/u2f_timer.h b/lib_u2f/include/u2f_timer.h deleted file mode 100644 index 3bc2de45f..000000000 --- a/lib_u2f/include/u2f_timer.h +++ /dev/null @@ -1,33 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include -#include -#include - -#ifndef __U2F_TIMER_H__ - -#define __U2F_TIMER_H__ - -typedef void (*u2fTimer_t)(struct u2f_service_t *service); - -void u2f_timer_init(void); -void u2f_timer_register(uint32_t timerMs, u2fTimer_t timerCallback); -void u2f_timer_cancel(void); - -#endif diff --git a/lib_u2f/include/u2f_transport.h b/lib_u2f/include/u2f_transport.h index 6b88b6253..177158a84 100644 --- a/lib_u2f/include/u2f_transport.h +++ b/lib_u2f/include/u2f_transport.h @@ -1,144 +1,49 @@ +/* @BANNER@ */ -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ +#pragma once -#ifndef __U2F_TRANSPORT_H__ +/* Includes ------------------------------------------------------------------*/ +#include -#define __U2F_TRANSPORT_H__ +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + U2F_TRANSPORT_TYPE_USB_HID = 0x00, + U2F_TRANSPORT_TYPE_BLE = 0x01, +} u2f_transport_type_t; -#include "u2f_service.h" +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + u2f_transport_type_t type; -// Shared commands -#define U2F_CMD_PING 0x81 -#define U2F_CMD_MSG 0x83 -#define CTAP2_CMD_CBOR 0x90 // FIDO2 -#define CTAP2_CMD_CANCEL 0x91 // FIDO2 + uint32_t cid; + uint8_t state; -// USB only commands -#define U2F_CMD_INIT 0x86 -#define U2F_CMD_LOCK 0x84 -#define U2F_CMD_WINK 0x88 + const uint8_t *tx_message_buffer; + uint16_t tx_message_length; + uint16_t tx_message_sequence_number; + uint16_t tx_message_offset; -// BLE only commands -#define U2F_CMD_KEEPALIVE 0x82 -#define KEEPALIVE_REASON_PROCESSING 0x01 -#define KEEPALIVE_REASON_TUP_NEEDED 0x02 + uint8_t *tx_packet_buffer; + uint16_t tx_packet_buffer_size; + uint8_t tx_packet_length; -#define U2F_STATUS_ERROR 0xBF -#define CTAP2_STATUS_KEEPALIVE 0xBB // FIDO2 + uint8_t *rx_message_buffer; + uint16_t rx_message_buffer_size; + uint16_t rx_message_expected_sequence_number; + uint16_t rx_message_length; + uint16_t rx_message_offset; -// Shared errors -#define ERROR_NONE 0x00 -#define ERROR_INVALID_CMD 0x01 -#define ERROR_INVALID_PAR 0x02 -#define ERROR_INVALID_LEN 0x03 -#define ERROR_INVALID_SEQ 0x04 -#define ERROR_MSG_TIMEOUT 0x05 -#define ERROR_OTHER 0x7f -// USB only errors -#define ERROR_CHANNEL_BUSY 0x06 -#define ERROR_LOCK_REQUIRED 0x0a -#define ERROR_INVALID_CID 0x0b -// CTAP2 errors -#define ERROR_CBOR_UNEXPECTED_TYPE 0x11 -#define ERROR_INVALID_CBOR 0x12 -#define ERROR_MISSING_PARAMETER 0x14 -#define ERROR_LIMIT_EXCEEDED 0x15 -#define ERROR_UNSUPPORTED_EXTENSION 0x16 -#define ERROR_CREDENTIAL_EXCLUDED 0x19 -#define ERROR_PROCESSING 0x21 -#define ERROR_INVALID_CREDENTIAL 0x22 -#define ERROR_USER_ACTION_PENDING 0x23 -#define ERROR_OPERATION_PENDING 0x24 -#define ERROR_NO_OPERATIONS 0x25 -#define ERROR_UNSUPPORTED_ALGORITHM 0x26 -#define ERROR_OPERATION_DENIED 0x27 -#define ERROR_KEY_STORE_FULL 0x28 -#define ERROR_NO_OPERATION_PENDING 0x2A -#define ERROR_UNSUPPORTED_OPTION 0x2B -#define ERROR_INVALID_OPTION 0x2C -#define ERROR_KEEPALIVE_CANCEL 0x2D -#define ERROR_NO_CREDENTIALS 0x2E -#define ERROR_USER_ACTION_TIMEOUT 0x2F -#define ERROR_NOT_ALLOWED 0x30 -#define ERROR_PIN_INVALID 0x31 -#define ERROR_PIN_BLOCKED 0x32 -#define ERROR_PIN_AUTH_INVALID 0x33 -#define ERROR_PIN_AUTH_BLOCKED 0x34 -#define ERROR_PIN_NOT_SET 0x35 -#define ERROR_PIN_REQUIRED 0x36 -#define ERROR_PIN_POLICY_VIOLATION 0x37 -#define ERROR_PIN_TOKEN_EXPIRED 0x38 -#define ERROR_REQUEST_TOO_LARGE 0x39 -#define ERROR_ACTION_TIMEOUT 0x3A -#define ERROR_UP_REQUIRED 0x3B -// Proprietary errors -#define ERROR_PROP_UNKNOWN_COMMAND 0x80 -#define ERROR_PROP_COMMAND_TOO_LONG 0x81 -#define ERROR_PROP_INVALID_CONTINUATION 0x82 -#define ERROR_PROP_UNEXPECTED_CONTINUATION 0x83 -#define ERROR_PROP_CONTINUATION_OVERFLOW 0x84 -#define ERROR_PROP_MESSAGE_TOO_SHORT 0x85 -#define ERROR_PROP_UNCONSISTENT_MSG_LENGTH 0x86 -#define ERROR_PROP_UNSUPPORTED_MSG_APDU 0x87 -#define ERROR_PROP_INVALID_DATA_LENGTH_APDU 0x88 -#define ERROR_PROP_INTERNAL_ERROR_APDU 0x89 -#define ERROR_PROP_INVALID_PARAMETERS_APDU 0x8A -#define ERROR_PROP_INVALID_DATA_APDU 0x8B -#define ERROR_PROP_DEVICE_NOT_SETUP 0x8C -#define ERROR_PROP_MEDIA_MIXED 0x8D -#define ERROR_PROP_RPID_MEDIA_DENIED 0x8E +} u2f_transport_t; -/** - * Initialize the U2F transport library - * Incoming messages are store in the provided message buffer. It can be overlapped with io APDU - * buffer to save RAM (but won't allow for multiple IO model (no mutual exclusion in the buffer - * access)) - */ -void u2f_transport_init(u2f_service_t *service, - uint8_t *message_buffer, - uint16_t message_buffer_length); +/* Exported defines --------------------------------------------------------*/ +#define U2F_FORBIDDEN_CID (0x00000000) +#define U2F_BROADCAST_CID (0xFFFFFFFF) -/** - * Function to be called when an IO message has been sent. - */ -void u2f_transport_sent(u2f_service_t *service, u2f_transport_media_t media); +/* Exported macros------------------------------------------------------------*/ -/** - * Function to be called when an IO message has been received. - */ -void u2f_transport_received(u2f_service_t *service, - uint8_t *buffer, - uint16_t size, - u2f_transport_media_t media); +/* Exported variables --------------------------------------------------------*/ -/** - * Returns 0 if the provided channel buffer is not a broadcast channel - */ -bool u2f_is_channel_broadcast(uint8_t *channel); - -/** - * Returns 0 if the provided channel buffer is not a forbidden channel - */ -bool u2f_is_channel_forbidden(uint8_t *channel); - -/** - * Send a CTAP 2 KEEPALIVE command while processing a CBOR message - */ -void u2f_transport_ctap2_send_keepalive(u2f_service_t *service, uint8_t reason); - -#endif +/* Exported functions prototypes--------------------------------------------- */ +void U2F_TRANSPORT_init(u2f_transport_t *handle, uint8_t type); +void U2F_TRANSPORT_rx(u2f_transport_t *handle, uint8_t *buffer, uint16_t length); +void U2F_TRANSPORT_tx(u2f_transport_t *handle, uint8_t cmd, const uint8_t *buffer, uint16_t length); diff --git a/lib_u2f/include/u2f_types.h b/lib_u2f/include/u2f_types.h new file mode 100644 index 000000000..2ddeb7465 --- /dev/null +++ b/lib_u2f/include/u2f_types.h @@ -0,0 +1,196 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ +typedef enum { + U2F_STATE_IDLE = 0x00, + U2F_STATE_CMD_FRAMING = 0x01, + U2F_STATE_CMD_COMPLETE = 0x02, + U2F_STATE_CMD_PROCESSING = 0x03, +} u2f_state_t; + +typedef enum { + // Common + U2F_COMMAND_PING = 0x01, + U2F_COMMAND_MSG = 0x03, + U2F_COMMAND_ERROR = 0x3F, + + // USB HID + U2F_COMMAND_HID_LOCK = 0x04, + U2F_COMMAND_HID_INIT = 0x06, + U2F_COMMAND_HID_WINK = 0x08, + U2F_COMMAND_HID_CBOR = 0x10, + U2F_COMMAND_HID_CANCEL = 0x11, + U2F_COMMAND_HID_KEEP_ALIVE = 0x3B, + + // BLE + U2F_COMMAND_BLE_KEEP_ALIVE = 0x02, + U2F_COMMAND_BLE_CANCEL = 0x3E, + +} u2f_command_t; + +typedef enum { + U2F_KEEP_ALIVE_REASON_PROCESSING = 0x01, + U2F_KEEP_ALIVE_REASON_UP_NEEDED = 0x02, +} u2f_keep_alive_reason_t; + +typedef enum { + U2F_HID_CAPABILITY_WINK = 0x01, + U2F_HID_CAPABILITY_CBOR = 0x04, + U2F_HID_CAPABILITY_NMSG = 0x08, +} u2f_hid_capability_t; + +typedef enum { + // FIDO 1 + CTAP1_ERR_SUCCESS = 0x00, + CTAP1_ERR_INVALID_COMMAND = 0x01, + CTAP1_ERR_INVALID_PARAMETER = 0x02, + CTAP1_ERR_INVALID_LENGTH = 0x03, + CTAP1_ERR_INVALID_SEQ = 0x04, + CTAP1_ERR_TIMEOUT = 0x05, + CTAP1_ERR_CHANNEL_BUSY = 0x06, // HID only + CTAP1_ERR_LOCK_REQUIRED = 0x0A, // HID only + CTAP1_ERR_INVALID_CHANNEL = 0x0B, // HID only + CTAP1_ERR_OTHER = 0x7F, + + // FIDO2 + CTAP2_OK = 0x00, + CTAP2_ERR_CBOR_UNEXPECTED_TYPE = 0x11, + CTAP2_ERR_INVALID_CBOR = 0x12, + CTAP2_ERR_MISSING_PARAMETER = 0x14, + CTAP2_ERR_LIMIT_EXCEEDED = 0x15, + CTAP2_ERR_FP_DATABASE_FULL = 0x17, + CTAP2_ERR_LARGE_BLOB_STORAGE_FULL = 0x18, + CTAP2_ERR_CREDENTIAL_EXCLUDED = 0x19, + CTAP2_ERR_PROCESSING = 0x21, + CTAP2_ERR_INVALID_CREDENTIAL = 0x22, + CTAP2_ERR_USER_ACTION_PENDING = 0x23, + CTAP2_ERR_OPERATION_PENDING = 0x24, + CTAP2_ERR_NO_OPERATIONS = 0x25, + CTAP2_ERR_UNSUPPORTED_ALGORITHM = 0x26, + CTAP2_ERR_OPERATION_DENIED = 0x27, + CTAP2_ERR_KEY_STORE_FULL = 0x28, + CTAP2_ERR_UNSUPPORTED_OPTION = 0x2B, + CTAP2_ERR_INVALID_OPTION = 0x2C, + CTAP2_ERR_KEEPALIVE_CANCEL = 0x2D, + CTAP2_ERR_NO_CREDENTIALS = 0x2E, + CTAP2_ERR_USER_ACTION_TIMEOUT = 0x2F, + CTAP2_ERR_NOT_ALLOWED = 0x30, + CTAP2_ERR_PIN_INVALID = 0x31, + CTAP2_ERR_PIN_BLOCKED = 0x32, + CTAP2_ERR_PIN_AUTH_INVALID = 0x33, + CTAP2_ERR_PIN_AUTH_BLOCKED = 0x34, + CTAP2_ERR_PIN_NOT_SET = 0x35, + CTAP2_ERR_PUAT_REQUIRED = 0x36, + CTAP2_ERR_PIN_POLICY_VIOLATION = 0x37, + CTAP2_ERR_REQUEST_TOO_LARGE = 0x39, + CTAP2_ERR_ACTION_TIMEOUT = 0x3A, + CTAP2_ERR_UP_REQUIRED = 0x3B, + CTAP2_ERR_UV_BLOCKED = 0x3C, + CTAP2_ERR_INTEGRITY_FAILURE = 0x3D, + CTAP2_ERR_INVALID_SUBCOMMAND = 0x3E, + CTAP2_ERR_UV_INVALID = 0x3F, + CTAP2_ERR_UNAUTHORIZED_PERMISSION = 0x40, + CTAP2_ERR_SPEC_LAST = 0xDF, + CTAP2_ERR_EXTENSION_FIRST = 0xE0, + CTAP2_ERR_EXTENSION_LAST = 0xEF, + CTAP2_ERR_VENDOR_FIRST = 0xF0, + CTAP2_ERR_VENDOR_LAST = 0xFF, + + // Proprietary + PROP_ERR_UNKNOWN_COMMAND = 0x80, + PROP_ERR_COMMAND_TOO_LONG = 0x81, + PROP_ERR_INVALID_CONTINUATION = 0x82, + PROP_ERR_UNEXPECTED_CONTINUATION = 0x83, + PROP_ERR_CONTINUATION_OVERFLOW = 0x84, + PROP_ERR_MESSAGE_TOO_SHORT = 0x85, + PROP_ERR_UNCONSISTENT_MSG_LENGTH = 0x86, + PROP_ERR_UNSUPPORTED_MSG_APDU = 0x87, + PROP_ERR_INVALID_DATA_LENGTH_APDU = 0x88, + PROP_ERR_INTERNAL_ERROR_APDU = 0x89, + PROP_ERR_INVALID_PARAMETERS_APDU = 0x8A, + PROP_ERR_INVALID_DATA_APDU = 0x8B, + PROP_ERR_DEVICE_NOT_SETUP = 0x8C, + PROP_ERR_MEDIA_MIXED = 0x8D, + PROP_ERR_RPID_MEDIA_DENIED = 0x8E, +} u2f_error_t; + +/* Exported defines --------------------------------------------------------*/ +// LEGACY + +// Shared commands +#define CTAP2_CMD_CBOR U2F_COMMAND_HID_CBOR +#define CTAP2_CMD_CANCEL U2F_COMMAND_HID_CANCEL + +// BLE only commands +#define KEEPALIVE_REASON_PROCESSING U2F_KEEP_ALIVE_REASON_PROCESSING +#define KEEPALIVE_REASON_TUP_NEEDED U2F_KEEP_ALIVE_REASON_UP_NEEDED + +// Shared errors +#define ERROR_NONE CTAP1_ERR_SUCCESS +#define ERROR_INVALID_CMD CTAP1_ERR_INVALID_COMMAND +#define ERROR_INVALID_PAR CTAP1_ERR_INVALID_PARAMETER +#define ERROR_INVALID_LEN CTAP1_ERR_INVALID_LENGTH +#define ERROR_INVALID_SEQ CTAP1_ERR_INVALID_SEQ +#define ERROR_MSG_TIMEOUT CTAP1_ERR_TIMEOUT +#define ERROR_OTHER CTAP1_ERR_OTHER +// CTAP2 errors +#define ERROR_CBOR_UNEXPECTED_TYPE CTAP2_ERR_CBOR_UNEXPECTED_TYPE +#define ERROR_INVALID_CBOR CTAP2_ERR_INVALID_CBOR +#define ERROR_MISSING_PARAMETER CTAP2_ERR_MISSING_PARAMETER +#define ERROR_LIMIT_EXCEEDED CTAP2_ERR_LIMIT_EXCEEDED +#define ERROR_CREDENTIAL_EXCLUDED CTAP2_ERR_CREDENTIAL_EXCLUDED +#define ERROR_PROCESSING CTAP2_ERR_PROCESSING +#define ERROR_INVALID_CREDENTIAL CTAP2_ERR_INVALID_CREDENTIAL +#define ERROR_USER_ACTION_PENDING CTAP2_ERR_USER_ACTION_PENDING +#define ERROR_OPERATION_PENDING CTAP2_ERR_OPERATION_PENDING +#define ERROR_NO_OPERATIONS CTAP2_ERR_NO_OPERATIONS +#define ERROR_UNSUPPORTED_ALGORITHM CTAP2_ERR_UNSUPPORTED_ALGORITHM +#define ERROR_OPERATION_DENIED CTAP2_ERR_OPERATION_DENIED +#define ERROR_KEY_STORE_FULL CTAP2_ERR_KEY_STORE_FULL +#define ERROR_UNSUPPORTED_OPTION CTAP2_ERR_UNSUPPORTED_OPTION +#define ERROR_INVALID_OPTION CTAP2_ERR_INVALID_OPTION +#define ERROR_KEEPALIVE_CANCEL CTAP2_ERR_KEEPALIVE_CANCEL +#define ERROR_NO_CREDENTIALS CTAP2_ERR_NO_CREDENTIALS +#define ERROR_USER_ACTION_TIMEOUT CTAP2_ERR_USER_ACTION_TIMEOUT +#define ERROR_NOT_ALLOWED CTAP2_ERR_NOT_ALLOWED +#define ERROR_PIN_INVALID CTAP2_ERR_PIN_INVALID +#define ERROR_PIN_BLOCKED CTAP2_ERR_PIN_BLOCKED +#define ERROR_PIN_AUTH_INVALID CTAP2_ERR_PIN_AUTH_INVALID +#define ERROR_PIN_AUTH_BLOCKED CTAP2_ERR_PIN_AUTH_BLOCKED +#define ERROR_PIN_NOT_SET CTAP2_ERR_PIN_NOT_SET +#define ERROR_PIN_REQUIRED CTAP2_ERR_PUAT_REQUIRED +#define ERROR_PIN_POLICY_VIOLATION CTAP2_ERR_PIN_POLICY_VIOLATION +#define ERROR_REQUEST_TOO_LARGE CTAP2_ERR_REQUEST_TOO_LARGE +#define ERROR_ACTION_TIMEOUT CTAP2_ERR_ACTION_TIMEOUT +#define ERROR_UP_REQUIRED CTAP2_ERR_UP_REQUIRED +// Proprietary errors +#define ERROR_PROP_UNKNOWN_COMMAND PROP_ERR_UNKNOWN_COMMAND +#define ERROR_PROP_COMMAND_TOO_LONG PROP_ERR_COMMAND_TOO_LONG +#define ERROR_PROP_INVALID_CONTINUATION PROP_ERR_INVALID_CONTINUATION +#define ERROR_PROP_UNEXPECTED_CONTINUATION PROP_ERR_UNEXPECTED_CONTINUATION +#define ERROR_PROP_CONTINUATION_OVERFLOW PROP_ERR_CONTINUATION_OVERFLOW +#define ERROR_PROP_MESSAGE_TOO_SHORT PROP_ERR_MESSAGE_TOO_SHORT +#define ERROR_PROP_UNCONSISTENT_MSG_LENGTH PROP_ERR_UNCONSISTENT_MSG_LENGTH +#define ERROR_PROP_UNSUPPORTED_MSG_APDU PROP_ERR_UNSUPPORTED_MSG_APDU +#define ERROR_PROP_INVALID_DATA_LENGTH_APDU PROP_ERR_INVALID_DATA_LENGTH_APDU +#define ERROR_PROP_INTERNAL_ERROR_APDU PROP_ERR_INTERNAL_ERROR_APDU +#define ERROR_PROP_INVALID_PARAMETERS_APDU PROP_ERR_INVALID_PARAMETERS_APDU +#define ERROR_PROP_INVALID_DATA_APDU PROP_ERR_INVALID_DATA_APDU +#define ERROR_PROP_DEVICE_NOT_SETUP PROP_ERR_DEVICE_NOT_SETUP +#define ERROR_PROP_MEDIA_MIXED PROP_ERR_MEDIA_MIXED +#define ERROR_PROP_RPID_MEDIA_DENIED PROP_ERR_RPID_MEDIA_DENIED + +#define U2F_CMD_MSG U2F_COMMAND_MSG + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ diff --git a/lib_u2f/src/u2f_transport.c b/lib_u2f/src/u2f_transport.c index 4334fdd5c..194e4d2e2 100644 --- a/lib_u2f/src/u2f_transport.c +++ b/lib_u2f/src/u2f_transport.c @@ -1,572 +1,238 @@ +/* @BANNER@ */ -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#ifdef HAVE_IO_U2F - -#include +/* Includes ------------------------------------------------------------------*/ #include -#include "u2f_service.h" -#include "u2f_transport.h" -#include "u2f_processing.h" -#include "u2f_io.h" -#include "lcx_rng.h" -#include "lcx_crc.h" #include "os.h" -#include "os_io_seproxyhal.h" +#include "os_math.h" +#include "os_utils.h" +#include "os_io.h" -#define U2F_MASK_COMMAND 0x80 -#define U2F_COMMAND_HEADER_SIZE 3 +#include "u2f_types.h" +#include "u2f_transport.h" -static const uint8_t BROADCAST_CHANNEL[] = {0xff, 0xff, 0xff, 0xff}; -static const uint8_t FORBIDDEN_CHANNEL[] = {0x00, 0x00, 0x00, 0x00}; +/* Private enumerations ------------------------------------------------------*/ -/* TODO: take into account the INIT during SEGMENTED message correctly. - * Avoid erasing the first part of the apdu buffer when doing so) - */ +/* Private types, structures, unions -----------------------------------------*/ -// init -void u2f_transport_reset(u2f_service_t *service) -{ - service->transportState = U2F_IDLE; - service->transportOffset = 0; - service->transportMedia = 0; - service->transportPacketIndex = 0; - service->fakeChannelTransportState = U2F_IDLE; - service->fakeChannelTransportOffset = 0; - service->fakeChannelTransportPacketIndex = 0; - service->sending = false; - service->waitAsynchronousResponse = U2F_WAIT_ASYNCH_IDLE; - // reset the receive buffer to allow for a new message to be received again (in case - // transmission of a CODE buffer the previous reply) - service->transportBuffer = service->transportReceiveBuffer; - cx_rng(service->channel, U2F_CHANNEL_ID_SIZE); -} +/* Private defines------------------------------------------------------------*/ +#ifdef HAVE_PRINTF +// #define DEBUG PRINTF +#define DEBUG(...) +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF -/** - * Initialize the u2f transport and provide the buffer into which to store incoming message - */ -void u2f_transport_init(u2f_service_t *service, - uint8_t *message_buffer, - uint16_t message_buffer_length) -{ - service->next_channel = 1; - service->transportReceiveBuffer = message_buffer; - service->transportReceiveBufferLength = message_buffer_length; - u2f_transport_reset(service); -} +/* Private macros-------------------------------------------------------------*/ -/** - * Reply an error at the U2F transport level (take into account the FIDO U2F framing) - */ -static void u2f_transport_error(u2f_service_t *service, char errorCode) -{ - // u2f_transport_reset(service); // warning reset first to allow for U2F_io sent call to - // u2f_transport_sent internally on eventless platforms - G_io_usb_ep_buffer[8] = errorCode; - - // ensure the state is set to error sending to allow for special treatment in case reply is not - // read by the receiver - service->transportState = U2F_SENDING_ERROR; - service->transportPacketIndex = 0; - service->transportBuffer = G_io_usb_ep_buffer + 8; - service->transportOffset = 0; - service->transportLength = 1; - service->sendCmd = U2F_STATUS_ERROR; - // pump the first message, with the reception media - u2f_transport_sent(service, service->media); -} +/* Private functions prototypes ----------------------------------------------*/ +static u2f_error_t process_packet(u2f_transport_t *handle, uint8_t *buffer, uint16_t length); -/** - * Function called when the previously scheduled message to be sent on the media is effectively - * sent. And a new message can be scheduled. - */ -void u2f_transport_sent(u2f_service_t *service, u2f_transport_media_t media) -{ - // don't process when replying to anti timeout requests - if (!u2f_message_repliable(service)) { - // previous mark packet as sent - service->sending = false; - return; - } +/* Exported variables --------------------------------------------------------*/ - // previous mark packet as sent - service->sending = false; +/* Private variables ---------------------------------------------------------*/ - // if idle (possibly after an error), then only await for a transmission - if (service->transportState != U2F_SENDING_RESPONSE - && service->transportState != U2F_SENDING_ERROR) { - // absorb the error, transport is erroneous but that won't hurt in the end. - // also absorb the fake channel user presence check reply ack - // THROW(INVALID_STATE); - return; +/* Private functions ---------------------------------------------------------*/ +static u2f_error_t process_packet(u2f_transport_t *handle, uint8_t *buffer, uint16_t length) +{ + u2f_error_t error = CTAP1_ERR_SUCCESS; + + // Check CID for USB HID transport + if (handle->type == U2F_TRANSPORT_TYPE_USB_HID) { + if (length < 4) { + // CID not complete, answer with broadcast CID? + error = CTAP1_ERR_OTHER; + handle->cid = U2F_BROADCAST_CID; + goto end; + } + uint32_t message_cid = U4BE(buffer, 0); + if (message_cid == U2F_FORBIDDEN_CID) { + // Forbidden CID + error = CTAP1_ERR_INVALID_CHANNEL; + goto end; + } + else if ((message_cid == U2F_BROADCAST_CID) && (length >= 5) + && (buffer[4] != (U2F_COMMAND_HID_INIT | 0x80))) { + // Broadcast CID but not an init message + error = CTAP1_ERR_INVALID_CHANNEL; + goto end; + } + else if ((handle->cid != U2F_FORBIDDEN_CID) && (handle->cid != message_cid)) { + // CID is already set + error = CTAP1_ERR_CHANNEL_BUSY; + goto end; + } + else if (handle->state > U2F_STATE_CMD_FRAMING) { + // Good CID but a request is already in process + error = CTAP1_ERR_CHANNEL_BUSY; + goto end; + } + else if (handle->cid == U2F_FORBIDDEN_CID) { + // Set new CID + handle->cid = message_cid; + } + buffer += 4; + length -= 4; + } + + // Check header length + if (length < 1) { + error = CTAP1_ERR_OTHER; + goto end; + } + + if (buffer[0] & 0x80) { + // Initialization packet + if (length < 3) { + error = CTAP1_ERR_OTHER; + goto end; + } + + // Check if packet will fit in the rx buffer + handle->rx_message_length = (uint16_t) U2BE(buffer, 1) + 3; + if (handle->rx_message_length > handle->rx_message_buffer_size) { + error = CTAP1_ERR_OTHER; + goto end; + } + + handle->state = U2F_STATE_CMD_FRAMING; + handle->rx_message_offset = 0; + handle->rx_message_buffer[handle->rx_message_offset++] = buffer[0] & 0x7F; // CMD + handle->rx_message_buffer[handle->rx_message_offset++] = buffer[1]; // BCNTH + handle->rx_message_buffer[handle->rx_message_offset++] = buffer[2]; // BCNTL + handle->rx_message_expected_sequence_number = 0; + buffer += 3; + length -= 3; } - if (service->transportOffset < service->transportLength) { - uint16_t mtu = (media == U2F_MEDIA_USB) ? USB_SEGMENT_SIZE : BLE_SEGMENT_SIZE; - uint16_t channelHeader = (media == U2F_MEDIA_USB ? 4 : 0); - uint8_t headerSize - = (service->transportPacketIndex == 0 ? (channelHeader + 3) : (channelHeader + 1)); - uint16_t blockSize - = ((service->transportLength - service->transportOffset) > (mtu - headerSize) - ? (mtu - headerSize) - : service->transportLength - service->transportOffset); - uint16_t dataSize = blockSize + headerSize; - uint16_t offset = 0; - // Fragment - if (media == U2F_MEDIA_USB) { - memcpy(G_io_usb_ep_buffer, service->channel, U2F_CHANNEL_ID_SIZE); - offset += 4; - } - if (service->transportPacketIndex == 0) { - G_io_usb_ep_buffer[offset++] = service->sendCmd; - G_io_usb_ep_buffer[offset++] = (service->transportLength >> 8); - G_io_usb_ep_buffer[offset++] = (service->transportLength & 0xff); - } - else { - G_io_usb_ep_buffer[offset++] = (service->transportPacketIndex - 1); + else { + // Continuation packet + if (handle->state != U2F_STATE_CMD_FRAMING) { + error = CTAP1_ERR_OTHER; + goto end; } - if (service->transportBuffer != NULL) { - memmove(G_io_usb_ep_buffer + headerSize, - service->transportBuffer + service->transportOffset, - blockSize); + else if (buffer[0] != handle->rx_message_expected_sequence_number) { + error = CTAP1_ERR_INVALID_SEQ; + goto end; } - service->transportOffset += blockSize; - service->transportPacketIndex++; - u2f_io_send(G_io_usb_ep_buffer, dataSize, media); - } - // last part sent - else if (service->transportOffset == service->transportLength) { - u2f_transport_reset(service); - // we sent the whole response (even if we haven't yet received the ack for the last sent usb - // in packet) - G_io_app.apdu_state = APDU_IDLE; + handle->rx_message_expected_sequence_number++; + buffer += 1; + length -= 1; } -} -void u2f_transport_send_usb_user_presence_required(u2f_service_t *service) -{ - uint16_t offset = 0; - service->sending = true; - memcpy(G_io_usb_ep_buffer, service->channel, U2F_CHANNEL_ID_SIZE); - offset += 4; - G_io_usb_ep_buffer[offset++] = U2F_CMD_MSG; - G_io_usb_ep_buffer[offset++] = 0; - G_io_usb_ep_buffer[offset++] = 2; - G_io_usb_ep_buffer[offset++] = 0x69; - G_io_usb_ep_buffer[offset++] = 0x85; - u2f_io_send(G_io_usb_ep_buffer, offset, U2F_MEDIA_USB); -} + if ((handle->rx_message_offset + length) > handle->rx_message_length) { + length = handle->rx_message_length - handle->rx_message_offset; + } -void u2f_transport_send_wink(u2f_service_t *service) -{ - uint16_t offset = 0; - service->sending = true; - memcpy(G_io_usb_ep_buffer, service->channel, U2F_CHANNEL_ID_SIZE); - offset += 4; - G_io_usb_ep_buffer[offset++] = U2F_CMD_WINK; - G_io_usb_ep_buffer[offset++] = 0; - G_io_usb_ep_buffer[offset++] = 0; - u2f_io_send(G_io_usb_ep_buffer, offset, U2F_MEDIA_USB); -} + memcpy(&handle->rx_message_buffer[handle->rx_message_offset], buffer, length); + handle->rx_message_offset += length; -#ifdef HAVE_FIDO2 + if (handle->rx_message_offset == handle->rx_message_length) { + handle->state = U2F_STATE_CMD_COMPLETE; + } -void u2f_transport_ctap2_send_keepalive(u2f_service_t *service, uint8_t reason) -{ - uint16_t offset = 0; - service->sending = true; - memcpy(G_io_usb_ep_buffer, service->channel, U2F_CHANNEL_ID_SIZE); - offset += 4; - G_io_usb_ep_buffer[offset++] = CTAP2_STATUS_KEEPALIVE; - G_io_usb_ep_buffer[offset++] = 0; - G_io_usb_ep_buffer[offset++] = 1; - G_io_usb_ep_buffer[offset++] = reason; - u2f_io_send(G_io_usb_ep_buffer, offset, U2F_MEDIA_USB); +end: + return error; } -#endif - -bool u2f_transport_receive_fakeChannel(u2f_service_t *service, uint8_t *buffer, uint16_t size) +/* Exported functions --------------------------------------------------------*/ +void U2F_TRANSPORT_init(u2f_transport_t *handle, uint8_t type) { - if (service->fakeChannelTransportState == U2F_INTERNAL_ERROR) { - return false; - } - if (memcmp(service->channel, buffer, U2F_CHANNEL_ID_SIZE) != 0) { - goto error; + if (!handle) { + return; } - if (service->fakeChannelTransportOffset == 0) { - uint16_t commandLength = U2BE(buffer, 4 + 1) + U2F_COMMAND_HEADER_SIZE; - // Some buggy implementations can send a WINK here, reply it gently - if (buffer[4] == U2F_CMD_WINK) { - u2f_transport_send_wink(service); - return true; - } - if (commandLength != service->transportLength) { - goto error; - } - if (buffer[4] != U2F_CMD_MSG) { - goto error; - } - service->fakeChannelTransportOffset = MIN(size - 4, service->transportLength); - service->fakeChannelTransportPacketIndex = 0; - service->fakeChannelCrc - = cx_crc16_update(0, buffer + 4, service->fakeChannelTransportOffset); - } - else { - if (buffer[4] != service->fakeChannelTransportPacketIndex) { - goto error; - } - uint16_t xfer_len - = MIN(size - 5, service->transportLength - service->fakeChannelTransportOffset); - service->fakeChannelTransportPacketIndex++; - service->fakeChannelTransportOffset += xfer_len; - service->fakeChannelCrc = cx_crc16_update(service->fakeChannelCrc, buffer + 5, xfer_len); - } - if (service->fakeChannelTransportOffset >= service->transportLength) { - if (service->fakeChannelCrc != service->commandCrc) { - goto error; - } - service->fakeChannelTransportState = U2F_FAKE_RECEIVED; - service->fakeChannelTransportOffset = 0; - // reply immediately when the asynch response is not yet ready - if (service->waitAsynchronousResponse == U2F_WAIT_ASYNCH_ON) { - u2f_transport_send_usb_user_presence_required(service); - // response sent - service->fakeChannelTransportState = U2F_IDLE; - } - } - return true; -error: - service->fakeChannelTransportState = U2F_INTERNAL_ERROR; - // don't hesitate here, the user will have to exit/rerun the app otherwise. - THROW(EXCEPTION_IO_RESET); - return false; + handle->state = U2F_STATE_IDLE; + handle->cid = U2F_FORBIDDEN_CID; + handle->type = type; } -/** - * Function that process every message received on a media. - * Performs message concatenation when message is split. - */ -void u2f_transport_received(u2f_service_t *service, - uint8_t *buffer, - uint16_t size, - u2f_transport_media_t media) +void U2F_TRANSPORT_rx(u2f_transport_t *handle, uint8_t *buffer, uint16_t length) { - uint16_t channelHeader = (media == U2F_MEDIA_USB ? 4 : 0); - uint16_t xfer_len; - service->media = media; - - // PRINTF("recv %d %d %d %d %d\n", size, service->waitAsynchronousResponse, - // service->transportState, service->transportOffset, buffer[4]); - - // Handle a busy channel and avoid reentry - if (service->transportState == U2F_SENDING_RESPONSE) { - u2f_transport_error(service, ERROR_CHANNEL_BUSY); - goto error; - } - if (service->waitAsynchronousResponse != U2F_WAIT_ASYNCH_IDLE) { - // TODO : this is an error for FIDO 2 - if (!u2f_transport_receive_fakeChannel(service, buffer, size)) { - u2f_transport_error(service, ERROR_CHANNEL_BUSY); - goto error; - } + if (!handle || !buffer || length < 3) { return; } - // SENDING_ERROR is accepted, and triggers a reset => means the host hasn't consumed the error. - if (service->transportState == U2F_SENDING_ERROR) { - u2f_transport_reset(service); - } + uint8_t error = (uint8_t) process_packet(handle, buffer, length); - if (size < (1 + channelHeader)) { - // Message to short, abort - u2f_transport_error(service, ERROR_PROP_MESSAGE_TOO_SHORT); - goto error; - } - if (media == U2F_MEDIA_USB) { - // hold the current channel value to reply to, for example, INIT commands within flow of - // segments. - memcpy(service->channel, buffer, U2F_CHANNEL_ID_SIZE); + if (error != CTAP1_ERR_SUCCESS) { + U2F_TRANSPORT_tx(handle, U2F_COMMAND_ERROR, &error, 1); + return; } -#ifdef HAVE_FIDO2 + switch (handle->rx_message_buffer[0]) { + case U2F_COMMAND_PING: + U2F_TRANSPORT_tx(handle, + U2F_COMMAND_PING, + &handle->rx_message_buffer[3], + handle->rx_message_length - 3); + DEBUG("U2F_COMMAND_PING %d\n", handle->rx_message_length); + handle->state = U2F_STATE_CMD_PROCESSING; + break; - // Handle a cancel request if received + default: + break; + } +} - if ((buffer[channelHeader] == CTAP2_CMD_CANCEL) - && (((media == U2F_MEDIA_USB) - && (memcmp(service->transportChannel, service->channel, U2F_CHANNEL_ID_SIZE) == 0)) - || (media != U2F_MEDIA_USB))) { - // Drop the cancel request if there's no command to be processed, otherwise pass it to the - // upper layer immediately - if (service->transportState != U2F_PROCESSING_COMMAND) { - return; - } - uint16_t commandLength = U2BE(buffer, channelHeader + 1); - ctap2_handle_cmd_cancel(service, buffer + channelHeader + 1 + 2, commandLength); +void U2F_TRANSPORT_tx(u2f_transport_t *handle, uint8_t cmd, const uint8_t *buffer, uint16_t length) +{ + if (!handle || (!buffer && !handle->tx_message_buffer)) { return; } -#endif - - // no previous chunk processed for the current message - if (service->transportOffset == 0 - // on USB we could get an INIT within a flow of segments. - || (media == U2F_MEDIA_USB - && memcmp(service->transportChannel, service->channel, U2F_CHANNEL_ID_SIZE) != 0) - // CTAP2 transport test (HID-1) - || (buffer[channelHeader] == U2F_CMD_INIT)) { - if (size < (channelHeader + 3)) { - // Message to short, abort - u2f_transport_error(service, ERROR_PROP_MESSAGE_TOO_SHORT); - goto error; - } - // check this is a command, cannot accept continuation without previous command - if ((buffer[channelHeader + 0] & U2F_MASK_COMMAND) == 0) { - // Not a command packet, abort - // CTAP2 transport test : do not send back an error in this case (HID-1) - // u2f_transport_error(service, ERROR_INVALID_SEQ); - goto error; - } - - // If waiting for a continuation on a different channel, reply BUSY - // immediately - if (media == U2F_MEDIA_USB) { - if ((service->transportState == U2F_HANDLE_SEGMENTED) - && (memcmp(service->channel, service->transportChannel, U2F_CHANNEL_ID_SIZE) != 0) - && (buffer[channelHeader] != U2F_CMD_INIT)) { - // special error case, we reply but don't change the current state of the transport - // (ongoing message for example) - // u2f_transport_error_no_reset(service, ERROR_CHANNEL_BUSY); - uint16_t offset = 0; - // Fragment - if (media == U2F_MEDIA_USB) { - memcpy(G_io_usb_ep_buffer, service->channel, U2F_CHANNEL_ID_SIZE); - offset += 4; - } - G_io_usb_ep_buffer[offset++] = U2F_STATUS_ERROR; - G_io_usb_ep_buffer[offset++] = 0; - G_io_usb_ep_buffer[offset++] = 1; - G_io_usb_ep_buffer[offset++] = ERROR_CHANNEL_BUSY; - u2f_io_send(G_io_usb_ep_buffer, offset, media); - goto error; - } - } - // If a command was already sent, and we are not processing a INIT - // command, abort - if ((service->transportState == U2F_HANDLE_SEGMENTED) - && !((media == U2F_MEDIA_USB) && (buffer[channelHeader] == U2F_CMD_INIT))) { - // Unexpected continuation at this stage, abort - u2f_transport_error(service, ERROR_INVALID_SEQ); - goto error; - } - // Check the length - uint16_t commandLength = U2BE(buffer, channelHeader + 1); - if (commandLength > (service->transportReceiveBufferLength - 3)) { - // Overflow in message size, abort - u2f_transport_error(service, ERROR_INVALID_LEN); - goto error; - } - // Check if the command is supported - switch (buffer[channelHeader]) { - case U2F_CMD_PING: - case U2F_CMD_MSG: -#ifdef HAVE_FIDO2 - case CTAP2_CMD_CBOR: - case CTAP2_CMD_CANCEL: -#endif - if (media == U2F_MEDIA_USB) { - if (u2f_is_channel_broadcast(service->channel) - || u2f_is_channel_forbidden(service->channel)) { - u2f_transport_error(service, ERROR_INVALID_CID); - goto error; - } - } - // no channel for BLE - break; - case U2F_CMD_INIT: - if (media != U2F_MEDIA_USB) { - // Unknown command, abort - u2f_transport_error(service, ERROR_INVALID_CMD); - goto error; - } - - if (u2f_is_channel_forbidden(service->channel)) { - u2f_transport_error(service, ERROR_INVALID_CID); - goto error; - } - - break; - default: - // Unknown command, abort - u2f_transport_error(service, ERROR_INVALID_CMD); - goto error; - } - - // Ok, initialize the buffer - // if (buffer[channelHeader] != U2F_CMD_INIT) - { - xfer_len = MIN(size - (channelHeader), U2F_COMMAND_HEADER_SIZE + commandLength); - memmove(service->transportBuffer, buffer + channelHeader, xfer_len); - if (media == U2F_MEDIA_USB) { - service->commandCrc = cx_crc16_update(0, service->transportBuffer, xfer_len); - } - service->transportOffset = xfer_len; - service->transportLength = U2F_COMMAND_HEADER_SIZE + commandLength; - service->transportMedia = media; - // initialize the response - service->transportPacketIndex = 0; - memcpy(service->transportChannel, service->channel, U2F_CHANNEL_ID_SIZE); - } + if (buffer) { + DEBUG("INITIALIZATION PACKET\n"); + handle->tx_message_buffer = buffer; + handle->tx_message_length = length; + handle->tx_message_sequence_number = 0; + handle->tx_message_offset = 0; + handle->tx_packet_length = 0; + memset(handle->tx_packet_buffer, 0, handle->tx_packet_buffer_size); } else { - // Continuation - if (size < (channelHeader + 2)) { - // Message to short, abort - u2f_transport_error(service, ERROR_PROP_MESSAGE_TOO_SHORT); - goto error; - } - if (media != service->transportMedia) { - // Mixed media - u2f_transport_error(service, ERROR_PROP_MEDIA_MIXED); - goto error; - } - if (service->transportState != U2F_HANDLE_SEGMENTED) { - // Unexpected continuation at this stage, abort - // TODO : review the behavior is HID only - if (media == U2F_MEDIA_USB) { - u2f_transport_reset(service); - goto error; - } - else { - u2f_transport_error(service, ERROR_INVALID_SEQ); - goto error; - } - } - if (media == U2F_MEDIA_USB) { - // Check the channel - if (memcmp(buffer, service->channel, U2F_CHANNEL_ID_SIZE) != 0) { - u2f_transport_error(service, ERROR_CHANNEL_BUSY); - goto error; - } - } - // also discriminate invalid command sent instead of a continuation - if (buffer[channelHeader] != service->transportPacketIndex) { - // Bad continuation packet, abort - u2f_transport_error(service, ERROR_INVALID_SEQ); - goto error; - } - xfer_len - = MIN(size - (channelHeader + 1), service->transportLength - service->transportOffset); - memmove(service->transportBuffer + service->transportOffset, - buffer + channelHeader + 1, - xfer_len); - if (media == U2F_MEDIA_USB) { - service->commandCrc = cx_crc16_update( - service->commandCrc, service->transportBuffer + service->transportOffset, xfer_len); - } - service->transportOffset += xfer_len; - service->transportPacketIndex++; - } - // See if we can process the command - if ((media != U2F_MEDIA_USB) - && (service->transportOffset > (service->transportLength + U2F_COMMAND_HEADER_SIZE))) { - // Overflow, abort - u2f_transport_error(service, ERROR_INVALID_LEN); - goto error; - } - else if (service->transportOffset >= service->transportLength) { - // switch before the handler gets the opportunity to change it again - service->transportState = U2F_PROCESSING_COMMAND; - // internal notification of a complete message received - u2f_message_complete(service); + DEBUG("CONTINUATION PACKET\n"); } - else { - // new segment received, reset the timeout for the current piece - service->seqTimeout = 0; - service->transportState = U2F_HANDLE_SEGMENTED; - } -error: - return; -} -bool u2f_is_channel_broadcast(uint8_t *channel) -{ - return (memcmp(channel, BROADCAST_CHANNEL, 4) == 0); -} + uint16_t tx_packet_offset = 0; + memset(handle->tx_packet_buffer, 0, handle->tx_packet_buffer_size); -bool u2f_is_channel_forbidden(uint8_t *channel) -{ - return (memcmp(channel, FORBIDDEN_CHANNEL, 4) == 0); -} - -/** - * Auto reply hodl until the real reply is prepared and sent - */ -void u2f_message_set_autoreply_wait_user_presence(u2f_service_t *service, bool enabled) -{ - // TODO : this only works for U2F + // Add CID if necessary + if (handle->type == U2F_TRANSPORT_TYPE_USB_HID) { + U4BE_ENCODE(handle->tx_packet_buffer, 0, handle->cid); + tx_packet_offset += 4; + } - if (enabled) { - // start replying placeholder until user presence validated - if (service->waitAsynchronousResponse == U2F_WAIT_ASYNCH_IDLE) { - service->waitAsynchronousResponse = U2F_WAIT_ASYNCH_ON; - u2f_transport_send_usb_user_presence_required(service); - } + // Fill header + if (buffer) { + handle->tx_packet_buffer[tx_packet_offset++] = cmd | 0x80; // CMD + U2BE_ENCODE(handle->tx_packet_buffer, tx_packet_offset, length); // BCNT + tx_packet_offset += 2; } - // don't set to REPLY_READY when it has not been enabled beforehand - else if (service->waitAsynchronousResponse == U2F_WAIT_ASYNCH_ON) { - service->waitAsynchronousResponse = U2F_WAIT_ASYNCH_REPLY_READY; + else { + handle->tx_packet_buffer[tx_packet_offset++] = handle->tx_message_sequence_number++; // SEQ } -} - -bool u2f_message_repliable(u2f_service_t *service) -{ - // no more asynch replies - // finished receiving the command - // and not sending a user presence required status - return service->waitAsynchronousResponse == U2F_WAIT_ASYNCH_IDLE - || (service->waitAsynchronousResponse != U2F_WAIT_ASYNCH_ON - && service->fakeChannelTransportState == U2F_FAKE_RECEIVED - && service->sending == false); -} -void u2f_message_reply(u2f_service_t *service, uint8_t cmd, uint8_t *buffer, uint16_t len) -{ - // if U2F is not ready to reply, then gently avoid replying - if (u2f_message_repliable(service)) { - service->transportState = U2F_SENDING_RESPONSE; - service->transportPacketIndex = 0; - service->transportBuffer = buffer; - service->transportOffset = 0; - service->transportLength = len; - service->sendCmd = cmd; - if (service->transportMedia != U2F_MEDIA_BLE) { - // pump the first message - u2f_transport_sent(service, service->transportMedia); - } - else { - while (G_io_app.apdu_state != APDU_IDLE) { - u2f_transport_sent(service, service->transportMedia); - } - } + if ((handle->tx_message_length + tx_packet_offset) + >= (handle->tx_packet_buffer_size + handle->tx_message_offset)) { + // Remaining message length doesn't fit the max packet size + memcpy(&handle->tx_packet_buffer[tx_packet_offset], + &handle->tx_message_buffer[handle->tx_message_offset], + handle->tx_packet_buffer_size - tx_packet_offset); + handle->tx_message_offset += handle->tx_packet_buffer_size - tx_packet_offset; + tx_packet_offset = handle->tx_packet_buffer_size; } + else { + // Remaining message fits the max packet size + memcpy(&handle->tx_packet_buffer[tx_packet_offset], + &handle->tx_message_buffer[handle->tx_message_offset], + handle->tx_message_length - handle->tx_message_offset); + tx_packet_offset += (handle->tx_message_length - handle->tx_message_offset); + handle->tx_message_offset = handle->tx_message_length; + handle->tx_message_buffer = NULL; + handle->state = U2F_STATE_IDLE; + handle->cid = U2F_FORBIDDEN_CID; + } + + handle->tx_packet_length = tx_packet_offset; + DEBUG(" %d\n", handle->tx_packet_length); } - -#endif diff --git a/lib_u2f_legacy/include/u2f_impl.h b/lib_u2f_legacy/include/u2f_impl.h new file mode 100644 index 000000000..b8e28b72d --- /dev/null +++ b/lib_u2f_legacy/include/u2f_impl.h @@ -0,0 +1,17 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ diff --git a/lib_u2f_legacy/include/u2f_processing.h b/lib_u2f_legacy/include/u2f_processing.h new file mode 100644 index 000000000..592ba51ff --- /dev/null +++ b/lib_u2f_legacy/include/u2f_processing.h @@ -0,0 +1,22 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include +#include "u2f_service.h" + +/* Exported enumerations -----------------------------------------------------*/ + +/* Exported types, structures, unions ----------------------------------------*/ + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ +void u2f_message_set_autoreply_wait_user_presence(u2f_service_t *service, bool enabled); +void u2f_message_reply(u2f_service_t *service, uint8_t cmd, uint8_t *buffer, uint16_t len); +void u2f_transport_ctap2_send_keepalive(u2f_service_t *service, uint8_t reason); diff --git a/lib_u2f_legacy/include/u2f_service.h b/lib_u2f_legacy/include/u2f_service.h new file mode 100644 index 000000000..e737a1c59 --- /dev/null +++ b/lib_u2f_legacy/include/u2f_service.h @@ -0,0 +1,33 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include "u2f_types.h" + +/* Exported enumerations -----------------------------------------------------*/ +typedef enum { + U2F_MEDIA_NONE, + U2F_MEDIA_USB, + U2F_MEDIA_NFC, + U2F_MEDIA_BLE +} u2f_transport_media_t; + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct { + u2f_transport_media_t media; +} u2f_service_t; + +#include "os_io_legacy.h" + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ + +// FIDO 2 compatible applications have to provide those implementations +void ctap2_handle_cmd_cbor(u2f_service_t *service, uint8_t *buffer, uint16_t length); +void ctap2_handle_cmd_cancel(u2f_service_t *service, uint8_t *buffer, uint16_t length); diff --git a/lib_u2f_legacy/src/u2f_legacy.c b/lib_u2f_legacy/src/u2f_legacy.c new file mode 100644 index 000000000..74e42621b --- /dev/null +++ b/lib_u2f_legacy/src/u2f_legacy.c @@ -0,0 +1,55 @@ +/* @BANNER@ */ + +#ifdef HAVE_IO_U2F + +/* Includes ------------------------------------------------------------------*/ +#include +#include "u2f_impl.h" +#include "u2f_processing.h" +#include "u2f_service.h" +#include "os_io.h" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ +u2f_service_t G_io_u2f; + +/* Private variables ---------------------------------------------------------*/ + +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +void u2f_message_set_autoreply_wait_user_presence(u2f_service_t *service, bool enabled) +{ + (void) service; + (void) enabled; + uint8_t buffer[2] = {0x69, 0x85}; + os_io_tx_cmd(OS_IO_PACKET_TYPE_USB_U2F_HID_APDU, buffer, sizeof(buffer), 0); +} + +void u2f_message_reply(u2f_service_t *service, uint8_t cmd, uint8_t *buffer, uint16_t len) +{ + (void) service; + os_io_tx_cmd(cmd, buffer, len, 0); +} + +void u2f_transport_ctap2_send_keepalive(u2f_service_t *service, uint8_t reason) +{ + (void) service; + (void) reason; + uint8_t buffer[2]; + + buffer[0] = U2F_COMMAND_HID_KEEP_ALIVE; + buffer[1] = reason; + os_io_tx_cmd(OS_IO_PACKET_TYPE_USB_U2F_HID_RAW, buffer, sizeof(buffer), 0); +} + +#endif // HAVE_IO_U2F diff --git a/lib_ux/include/ux_bagl.h b/lib_ux/include/ux_bagl.h index b655eb322..062e9b927 100644 --- a/lib_ux/include/ux_bagl.h +++ b/lib_ux/include/ux_bagl.h @@ -171,7 +171,6 @@ void io_seproxyhal_display_default(const bagl_element_t *element); #endif // UX_STACK_SLOT_ARRAY_COUNT typedef unsigned int (*callback_int_t)(unsigned int); -typedef void (*asynchmodal_end_callback_t)(unsigned int ux_status); typedef struct ux_stack_slot_s ux_stack_slot_t; @@ -209,9 +208,7 @@ void ux_stack_al_display_next_element(unsigned int stack_slot); void ux_stack_redisplay(void); const bagl_element_t *ux_stack_display_element_callback(const bagl_element_t *element); -#ifdef HAVE_SE_SCREEN -void ux_stack_display_elements(ux_stack_slot_t *slot); -#endif // HAVE_SE_SCREEN +void ux_stack_display_elements(ux_stack_slot_t *slot); #ifdef HAVE_UX_LEGACY // a menu callback is called with a given userid provided within the menu entry to allow for fast @@ -300,10 +297,6 @@ struct ux_state_s { unsigned char stack_count; // initialized @0 by the bolos ux initialize bolos_task_status_t exit_code; -#ifdef HAVE_BLE - asynchmodal_end_callback_t asynchmodal_end_callback; -#endif // HAVE_BLE - #ifdef HAVE_UX_FLOW // global context, therefore, don't allow for multiple paging overlaid in a graphic stack ux_layout_paging_state_t layout_paging; @@ -370,7 +363,6 @@ extern bolos_ux_params_t G_ux_params; * Take into account if the next element is allowed/denied for display by the registered * preprocessor */ -#ifdef HAVE_SE_SCREEN #define UX_DISPLAY_NEXT_ELEMENT() \ if (G_ux.stack[0].element_arrays[0].element_array \ && G_ux.stack[0].element_index < G_ux.stack[0].element_arrays[0].element_array_count \ @@ -388,7 +380,7 @@ extern bolos_ux_params_t G_ux_params; .element_arrays[0] \ .element_array[G_ux.stack[0].element_index]; \ } \ - io_seproxyhal_display(element); \ + io_seph_ux_display_bagl_element(element); \ } \ G_ux.stack[0].element_index++; \ } \ @@ -396,86 +388,6 @@ extern bolos_ux_params_t G_ux_params; screen_update(); \ } \ } -#else // HAVE_SE_SCREEN -#define UX_DISPLAY_NEXT_ELEMENT() \ - while (G_ux.stack[0].element_arrays[0].element_array \ - && G_ux.stack[0].element_index < G_ux.stack[0].element_arrays[0].element_array_count \ - && !io_seproxyhal_spi_is_status_sent() \ - && (os_perso_isonboarded() != BOLOS_UX_OK \ - || os_global_pin_is_validated() == BOLOS_UX_OK)) { \ - const bagl_element_t *element \ - = &G_ux.stack[0].element_arrays[0].element_array[G_ux.stack[0].element_index]; \ - if (!G_ux.stack[0].screen_before_element_display_callback \ - || (element = G_ux.stack[0].screen_before_element_display_callback(element))) { \ - if ((unsigned int) element \ - == 1) { /*backward compat with coding to avoid smashing everything*/ \ - element \ - = &G_ux.stack[0].element_arrays[0].element_array[G_ux.stack[0].element_index]; \ - } \ - io_seproxyhal_display(element); \ - } \ - G_ux.stack[0].element_index++; \ - } -#endif // HAVE_SE_SCREEN - -#ifdef HAVE_BLE -/** - * internal bolos ux event processing with callback in case event is to be processed by the - * application - */ -#define UX_FORWARD_EVENT_REDRAWCB(bypasspincheck, \ - G_ux_params, \ - G_ux, \ - os_ux, \ - os_sched_last_status, \ - callback, \ - redraw_cb, \ - ignoring_app_if_ux_busy) \ - G_ux_params.ux_id = BOLOS_UX_EVENT; \ - G_ux_params.len = 0; \ - os_ux(&G_ux_params); \ - G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \ - if (G_ux.asynchmodal_end_callback \ - && os_ux_get_status(BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST) != 0) { \ - asynchmodal_end_callback_t cb = G_ux.asynchmodal_end_callback; \ - G_ux.asynchmodal_end_callback = NULL; \ - cb(os_ux_get_status(BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST)); \ - G_ux_params.len = BOLOS_UX_REDRAW; \ - } \ - if (G_ux_params.len == BOLOS_UX_REDRAW) { \ - redraw_cb; \ - } \ - else if (!ignoring_app_if_ux_busy \ - || (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE)) { \ - callback; \ - } - -#else // HAVE_BLE - -/** - * internal bolos ux event processing with callback in case event is to be processed by the - * application - */ -#define UX_FORWARD_EVENT_REDRAWCB(bypasspincheck, \ - G_ux_params, \ - G_ux, \ - os_ux, \ - os_sched_last_status, \ - callback, \ - redraw_cb, \ - ignoring_app_if_ux_busy) \ - G_ux_params.ux_id = BOLOS_UX_EVENT; \ - G_ux_params.len = 0; \ - os_ux(&G_ux_params); \ - G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \ - if (G_ux_params.len == BOLOS_UX_REDRAW) { \ - redraw_cb; \ - } \ - else if (!ignoring_app_if_ux_busy \ - || (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE)) { \ - callback; \ - } -#endif // HAVE_BLE /** * Request a wake up of the device (backlight, pin lock screen, ...) to display a new interface to @@ -491,23 +403,21 @@ extern bolos_ux_params_t G_ux_params; /** * Redisplay request (no immediate display status sent) */ -#define UX_REDISPLAY_REQUEST() \ - io_seproxyhal_init_ux(); \ - io_seproxyhal_init_button(); \ +#define UX_REDISPLAY_REQUEST() \ + io_seph_ux_init_button(); \ G_ux.stack[0].element_index = 0; /** * Force redisplay of the screen from the given index in the screen's element array */ -#define UX_REDISPLAY_IDX(index) \ - io_seproxyhal_init_ux(); \ - io_seproxyhal_init_button(); /*ensure to avoid release of a button from a nother screen to \ - mess up with the redisplayed screen */ \ - G_ux.stack[0].element_index = index; \ - /* REDRAW is redisplay already, use os_ux return value to check */ \ - G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \ - if (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE) { \ - UX_DISPLAY_NEXT_ELEMENT(); \ +#define UX_REDISPLAY_IDX(index) \ + io_seph_ux_init_button(); /*ensure to avoid release of a button from a nother screen to \ + mess up with the redisplayed screen */ \ + G_ux.stack[0].element_index = index; \ + /* REDRAW is redisplay already, use os_ux return value to check */ \ + G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \ + if (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE) { \ + UX_DISPLAY_NEXT_ELEMENT(); \ } /** @@ -546,22 +456,24 @@ extern bolos_ux_params_t G_ux_params; * internal bolos ux event processing with callback in case event is to be processed by the * application */ -#define UX_FORWARD_EVENT(callback, ignoring_app_if_ux_busy) \ - UX_FORWARD_EVENT_REDRAWCB(0, \ - G_ux_params, \ - G_io_asynch_ux_callback, \ - os_ux, \ - os_sched_last_status, \ - callback, \ - UX_REDISPLAY(), \ - ignoring_app_if_ux_busy); - -#define UX_CONTINUE_DISPLAY_APP(displayed_callback) \ - UX_DISPLAY_NEXT_ELEMENT(); \ - /* all items have been displayed */ \ - if (G_ux.stack[0].element_index >= G_ux.stack[0].element_arrays[0].element_array_count \ - && !io_seproxyhal_spi_is_status_sent()) { \ - displayed_callback \ +#define UX_FORWARD_EVENT(callback, ignoring_app_if_ux_busy) \ + G_ux_params.ux_id = BOLOS_UX_EVENT; \ + G_ux_params.len = 0; \ + os_ux(&G_ux_params); \ + G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \ + if (G_ux_params.len == BOLOS_UX_REDRAW) { \ + UX_REDISPLAY(); \ + } \ + else if (!ignoring_app_if_ux_busy \ + || (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE)) { \ + callback; \ + } + +#define UX_CONTINUE_DISPLAY_APP(displayed_callback) \ + UX_DISPLAY_NEXT_ELEMENT(); \ + /* all items have been displayed */ \ + if (G_ux.stack[0].element_index >= G_ux.stack[0].element_arrays[0].element_array_count) { \ + displayed_callback \ } /** @@ -580,27 +492,10 @@ extern bolos_ux_params_t G_ux_params; * Macro to process sequentially display a screen. The call finishes when the UX is completely * displayed, and the state of the MCU <-> SE exchanges is the same as before this macro call. */ -#ifdef HAVE_SE_SCREEN #define UX_WAIT_DISPLAYED() \ while (!UX_DISPLAYED()) { \ UX_DISPLAY_NEXT_ELEMENT(); \ } -#else -#define UX_WAIT_DISPLAYED() \ - while (!UX_DISPLAYED()) { \ - /* We wait for the MCU event (should indicate display processed for a bagl element) */ \ - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); \ - io_seproxyhal_handle_event(); \ - UX_DISPLAY_NEXT_ELEMENT(); \ - } \ - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); \ - io_seproxyhal_handle_event(); \ - /* We send a general status which indicates to the MCU that he can process any pending action \ - * (i.e. here, display the whole screen) */ \ - io_seproxyhal_general_status(); \ - /* We wait for an ack of the MCU. */ \ - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); -#endif /** * Process button push events. Application's button event handler is called only if the ux app does @@ -661,48 +556,6 @@ extern bolos_ux_params_t G_ux_params; os_ux(&G_ux_params); \ G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); -/** - * Setup the TICKER_EVENT interval. Application shall not use this entry point as it's the main - * ticking source. Use the ::UX_SET_INTERVAL_MS instead. - */ -void io_seproxyhal_setup_ticker(unsigned int interval_ms); - -void io_seproxyhal_request_mcu_status(void); - -/** - * Helper function to order the MCU to display the given bitmap with the given color index, a table - * of size: (1<> 0x04) & 0x0F; - } - - // We stop the processing when we reached the limit. - if (current_width_in_pixels > width_limit_in_pixels) { - break; - } - } - - return length; -} - -// This function is used to retrieve the width of a line of text. -STATIC_IF_NOT_INDEXED unsigned int se_compute_line_width_light(const char *text, - uint8_t text_length, - uint8_t text_format) -{ - unsigned char ch; - unsigned int line_width = 0; -#if defined(HAVE_INDEXED_STRINGS) - unsigned int width = 0; - unsigned char bold_toggle = 0; - - // Bold state at the beginning of the line: - if ((text_format & PAGING_FORMAT_NB) == PAGING_FORMAT_NB) { - bold_toggle = 1; - } -#endif // defined(HAVE_INDEXED_STRINGS) - - // We parse the characters of the input text on all the input length. - while (text_length--) { - ch = *(const unsigned char *) text; -#if defined(HAVE_INDEXED_STRINGS) - ++text; - width = 0; -#endif // defined(HAVE_INDEXED_STRINGS) - -#if defined(HAVE_UNICODE_SUPPORT) - unsigned int unicode; - - // Handle UTF-8 decoding (RFC3629): (https://www.ietf.org/rfc/rfc3629.txt - // Char. number range | UTF-8 octet sequence - // (hexadecimal) | (binary) - // --------------------+--------------------------------------------- - // 0000 0000-0000 007F | 0xxxxxxx - // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx - // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx - // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - - // 4 bytes UTF-8, Unicode 0x1000 to 0x1FFFF - if (ch >= 0xF0 && text_length >= 3) { - unicode = (ch & 0x07) << 18; - unicode |= (*((const unsigned char *) text + 0) & 0x3F) << 12; - unicode |= (*((const unsigned char *) text + 1) & 0x3F) << 6; - unicode |= (*((const unsigned char *) text + 2) & 0x3F); - text += 3; - text_length -= 3; - - // 3 bytes, from 0x800 to 0xFFFF - } - else if (ch >= 0xE0 && text_length >= 2) { - unicode = (ch & 0x0F) << 12; - unicode |= (*((const unsigned char *) text + 0) & 0x3F) << 6; - unicode |= (*((const unsigned char *) text + 1) & 0x3F); - text += 2; - text_length -= 2; - - // 2 bytes UTF-8, Unicode 0x80 to 0x7FF - // (0xC0 & 0xC1 are unused and can be used to store something else) - } - else if (ch >= 0xC2 && text_length >= 1) { - unicode = (ch & 0x1F) << 6; - unicode |= (*((const unsigned char *) text + 0) & 0x3F); - ++text; - text_length -= 1; - } - else { - unicode = 0; - } -#endif // defined(HAVE_UNICODE_SUPPORT) - - if (ch < NANOS_FIRST_CHAR || ch > NANOS_LAST_CHAR) { -#if defined(HAVE_INDEXED_STRINGS) - // Only proceed the first line width, not the whole paragraph - switch (ch) { - case '\n': - case '\f': - return line_width; - case '\b': // Bold toggle: turn Bold On/Off - bold_toggle ^= 1; - continue; - case '\e': // Escape character => ignore it and the extra byte. - if (text_length >= 1) { // Take care of \e without additional byte! - ++text; - text_length -= 1; - } - continue; - } -#else // defined(HAVE_INDEXED_STRINGS) - if (ch == '\n' || ch == '\r') { - break; - } -#endif // defined(HAVE_INDEXED_STRINGS) - -#if defined(HAVE_UNICODE_SUPPORT) - if (unicode) { - unsigned int i; - // Find the index of the unicode character we are dealing with. - // For the moment, let just parse the full array, but at the end let - // use binary search as data are sorted by unicode value ! - for (i = 0; i < NB_NANOS_UNICODE_CHARS; i++) { - if (nanos_unicode_index[i] == unicode) { - break; - } - } - // Did we find a corresponding unicode entry? - if (i < NB_NANOS_UNICODE_CHARS) { - width = nanos_unicode_width[i]; - } - else { - // No, use FFFD character width: - width = DEFAULT_NANOS_UNICODE_WIDTH; - } - } -#endif // defined(HAVE_UNICODE_SUPPORT) - } - else { -#if defined(HAVE_INDEXED_STRINGS) - ch -= NANOS_FIRST_CHAR; - width = nanos_characters_width[ch]; // 4 MSB = regular, 4 LSB = extrabold -#else // defined(HAVE_INDEXED_STRINGS) - // We retrieve the character width, and the paging format indicates whether we are - // processing bold characters or not. - if ((text_format & PAGING_FORMAT_NB) == PAGING_FORMAT_NB) { - // Bold. - line_width += nanos_characters_width[ch - NANOS_FIRST_CHAR] & 0x0F; - } - else { - // Regular. - line_width += (nanos_characters_width[ch - NANOS_FIRST_CHAR] >> 0x04) & 0x0F; - } -#endif // defined(HAVE_INDEXED_STRINGS) - } -#if defined(HAVE_INDEXED_STRINGS) - if (width) { - if (!bold_toggle) { - width >>= 4; // 4 LSB = regular, now - } - width &= 0x0F; // Keep only the 4 LSB - line_width += width; - } -#else // defined(HAVE_INDEXED_STRINGS) - text++; -#endif // defined(HAVE_INDEXED_STRINGS) - } - return line_width; -} - -#endif // !HAVE_SE_SCREEN - static bool is_word_delim(unsigned char c) { // return !((c >= 'a' && c <= 'z') diff --git a/lib_ux/src/ux_legacy.c b/lib_ux/src/ux_legacy.c index 27f74615e..6432ace80 100644 --- a/lib_ux/src/ux_legacy.c +++ b/lib_ux/src/ux_legacy.c @@ -20,7 +20,7 @@ #include "os_helpers.h" #include "os_pic.h" #include "os_pin.h" -#include "os_io_seproxyhal.h" +#include "os_io_seph_ux.h" #include #ifdef HAVE_UX_LEGACY @@ -435,50 +435,3 @@ const bagl_element_t printf_element = { 0}, .text = "Default printf" }; - -void debug_wait_displayed(void) -{ - // wait next event (probably a ticker, if not, too bad... this is debug !!) - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); -} - -#if defined(HAVE_DEBUG) || defined(BOLOS_DEBUG) -#include "string.h" - -void debug_printf(void *buffer) -{ -#ifdef TARGET_NANOS - io_seproxyhal_display_default(&clear_element); - debug_wait_displayed(); -#endif // TARGET_NANOS - memmove(&G_ux.tmp_element, &printf_element, sizeof(bagl_element_t)); - G_ux.tmp_element.text = buffer; - io_seproxyhal_display_default(&G_ux.tmp_element); - debug_wait_displayed(); - // // ask to replicate mcu buffer to the screen - // io_seproxyhal_general_status(); - // // wait up the display processed - // io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - // wait until a button event - while (G_io_seproxyhal_spi_buffer[0] != SEPROXYHAL_TAG_BUTTON_PUSH_EVENT - // not marked as released - || G_io_seproxyhal_spi_buffer[3] != 0) { - io_seproxyhal_general_status(); - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - } -} -#endif // defined(HAVE_DEBUG) || defined(BOLOS_DEBUG) - -#ifdef HAVE_DEBUG -#define L(x) debug_printf(x) -#else // HAVE_DEBUG -#define L(x) -#endif // HAVE_DEBUG - -// void ux_check_status_default(unsigned int status) { -// // nothing to be done here by default. -// UNUSED(status); -// } - -// void ux_check_status(unsigned int status) __attribute__ ((weak, alias -// ("ux_check_status_default"))); diff --git a/lib_ux/src/ux_stack.c b/lib_ux/src/ux_stack.c index 69f0bd52f..cbd509e2e 100644 --- a/lib_ux/src/ux_stack.c +++ b/lib_ux/src/ux_stack.c @@ -22,7 +22,7 @@ #include "os_screen.h" #include "os_types.h" #include "os_utils.h" -#include "os_io_seproxyhal.h" +#include "os_io_seph_ux.h" #include // return true (stack slot +1) if an element @@ -170,10 +170,6 @@ void ux_stack_remove(unsigned int stack_slot) // common code for all screens void ux_stack_init(unsigned int stack_slot) { - // reinit ux behavior (previous touched element, button push state) - io_seproxyhal_init_ux(); // glitch upon ux_stack_display for a button being pressed in a - // previous screen - /* // mismatch, the stack slot is not accessible !! if (G_ux.stack_count 0 && stack_slot + 1 == G_ux.stack_count) { - io_seproxyhal_init_ux(); // at worse a redisplay of the current screen has been requested, ensure to redraw it // correctly G_ux.stack[stack_slot].element_index = 0; -#ifdef HAVE_SE_SCREEN ux_stack_display_elements(&G_ux.stack[stack_slot]); // on balenos, no need to wait for the // display processed event -#else // HAVE_SE_SCREEN - ux_stack_al_display_next_element(stack_slot); -#endif // HAVE_SE_SCREEN } // asking to redraw below top screen (likely the app below the ux) else if (stack_slot == -1UL || G_ux.stack_count == 0) { diff --git a/lib_ux_nbgl/ux.c b/lib_ux_nbgl/ux.c index 985705fc4..abad37950 100644 --- a/lib_ux_nbgl/ux.c +++ b/lib_ux_nbgl/ux.c @@ -21,6 +21,7 @@ #include "nbgl_touch.h" #include "nbgl_buttons.h" #include "os_io.h" +#include "os_io_seph_ux.h" #ifndef HAVE_BOLOS // number of 100ms ticks since the start-up of the app static uint32_t nbTicks; diff --git a/lib_ux_nbgl/ux_nbgl.h b/lib_ux_nbgl/ux_nbgl.h index 3efc1f160..a9037f928 100644 --- a/lib_ux_nbgl/ux_nbgl.h +++ b/lib_ux_nbgl/ux_nbgl.h @@ -27,13 +27,12 @@ #include "os_task.h" #include "nbgl_screen.h" #include "nbgl_touch.h" +#include "seproxyhal_protocol.h" #include -#define BUTTON_LEFT 1 -#define BUTTON_RIGHT 2 - -typedef void (*asynchmodal_end_callback_t)(unsigned int ux_status); +#define BUTTON_LEFT SEPROXYHAL_TAG_BUTTON_PUSH_EVENT_LEFT +#define BUTTON_RIGHT SEPROXYHAL_TAG_BUTTON_PUSH_EVENT_RIGHT /** * Common structure for applications to perform asynchronous UX aside IO operations @@ -45,8 +44,6 @@ struct ux_state_s { bool validate_pin_from_dashboard; // set to true when BOLOS_UX_VALIDATE_PIN is received from // Dashboard task - asynchmodal_end_callback_t asynchmodal_end_callback; - char string_buffer[128]; }; @@ -65,28 +62,6 @@ extern void ux_process_default_event(void); */ #define UX_INIT() nbgl_objInit(); -#ifdef HAVE_BOLOS -// to be used only by hal_io.c in BOLOS, for compatibility -#define UX_FORWARD_EVENT_REDRAWCB(bypasspincheck, \ - ux_params, \ - ux, \ - os_ux, \ - os_sched_last_status, \ - callback, \ - redraw_cb, \ - ignoring_app_if_ux_busy) \ - ux_params.ux_id = BOLOS_UX_EVENT; \ - ux_params.len = 0; \ - os_ux(&ux_params); \ - ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \ - if (ux.asynchmodal_end_callback \ - && os_ux_get_status(BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST) != 0) { \ - asynchmodal_end_callback_t cb = ux.asynchmodal_end_callback; \ - ux.asynchmodal_end_callback = NULL; \ - cb(os_ux_get_status(BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST)); \ - } -#endif // HAVE_BOLOS - /** * Request a wake up of the device (pin lock screen, ...) to display a new interface to the user. * Wake up prevents power-off features. Therefore, security wise, this function shall only @@ -149,9 +124,6 @@ bolos_err_t delete_background_img(void); extern ux_seph_os_and_app_t G_ux_os; -void io_seproxyhal_request_mcu_status(void); -void io_seproxyhal_power_off(bool criticalBattery); - #if defined(HAVE_LANGUAGE_PACK) const char *get_ux_loc_string(UX_LOC_STRINGS_INDEX index); void bolos_ux_select_language(uint16_t language); diff --git a/protocol/include/ledger_protocol.h b/protocol/include/ledger_protocol.h new file mode 100644 index 000000000..045a8ee6b --- /dev/null +++ b/protocol/include/ledger_protocol.h @@ -0,0 +1,48 @@ +/* @BANNER@ */ + +#pragma once + +/* Includes ------------------------------------------------------------------*/ +#include + +/* Exported enumerations -----------------------------------------------------*/ +enum { + APDU_STATUS_WAITING, + APDU_STATUS_NEED_MORE_DATA, + APDU_STATUS_COMPLETE, +}; + +/* Exported types, structures, unions ----------------------------------------*/ +typedef struct ledger_protocol_s { + uint8_t type; + + const uint8_t *tx_apdu_buffer; + uint16_t tx_apdu_length; + uint16_t tx_apdu_sequence_number; + uint16_t tx_apdu_offset; + + uint8_t *tx_chunk_buffer; + uint8_t tx_chunk_buffer_size; + uint8_t tx_chunk_length; + + uint8_t *rx_apdu_buffer; + uint16_t rx_apdu_buffer_size; + uint8_t rx_apdu_status; + uint16_t rx_apdu_sequence_number; + uint16_t rx_apdu_length; + uint16_t rx_apdu_offset; + + uint16_t mtu; + uint8_t mtu_negotiated; +} ledger_protocol_t; + +/* Exported defines --------------------------------------------------------*/ + +/* Exported macros------------------------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/* Exported functions prototypes--------------------------------------------- */ +void LEDGER_PROTOCOL_init(ledger_protocol_t *data, uint8_t type); +void LEDGER_PROTOCOL_rx(ledger_protocol_t *data, uint8_t *buffer, uint16_t length); +void LEDGER_PROTOCOL_tx(ledger_protocol_t *data, const uint8_t *buffer, uint16_t length); diff --git a/protocol/src/ledger_protocol.c b/protocol/src/ledger_protocol.c new file mode 100644 index 000000000..9bbe1c734 --- /dev/null +++ b/protocol/src/ledger_protocol.c @@ -0,0 +1,212 @@ +/* @BANNER@ */ + +/* Includes ------------------------------------------------------------------*/ +#include + +#include "os.h" +#include "os_math.h" +#include "os_utils.h" + +#include "ledger_protocol.h" + +/* Private enumerations ------------------------------------------------------*/ + +/* Private types, structures, unions -----------------------------------------*/ + +/* Private defines------------------------------------------------------------*/ +#define TAG_GET_PROTOCOL_VERSION (0x00) +#define TAG_ALLOCATE_CHANNEL (0x01) +#define TAG_PING (0x02) +#define TAG_ABORT (0x03) +#define TAG_APDU (0x05) +#define TAG_MTU (0x08) + +#ifdef HAVE_PRINTF +// #define DEBUG PRINTF +#define DEBUG(...) +#else // !HAVE_PRINTF +#define DEBUG(...) +#endif // !HAVE_PRINTF + +/* Private macros-------------------------------------------------------------*/ + +/* Private functions prototypes ----------------------------------------------*/ +static void process_apdu_chunk(ledger_protocol_t *handle, uint8_t *buffer, uint16_t length); + +/* Exported variables --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static const uint8_t protocol_version[4] = {0x00, 0x00, 0x00, 0x00}; + +/* Private functions ---------------------------------------------------------*/ +static void process_apdu_chunk(ledger_protocol_t *handle, uint8_t *buffer, uint16_t length) +{ + // Check the sequence number + if ((length < 2) || ((uint16_t) U2BE(buffer, 0) != handle->rx_apdu_sequence_number)) { + handle->rx_apdu_status = APDU_STATUS_WAITING; + return; + } + // Check total length presence + if ((length < 4) && (handle->rx_apdu_sequence_number == 0)) { + handle->rx_apdu_status = APDU_STATUS_WAITING; + return; + } + + if (handle->rx_apdu_sequence_number == 0) { + // First chunk + handle->rx_apdu_buffer[0] = handle->type; + handle->rx_apdu_status = APDU_STATUS_NEED_MORE_DATA; + handle->rx_apdu_length = (uint16_t) U2BE(buffer, 2); + // Check if we have enough space to store the apdu + if (handle->rx_apdu_length > handle->rx_apdu_buffer_size) { + DEBUG("APDU WAITING - %d\n", handle->rx_apdu_length); + handle->rx_apdu_status = APDU_STATUS_WAITING; + handle->rx_apdu_length = handle->rx_apdu_buffer_size; + return; + } + handle->rx_apdu_offset = 0; + buffer = &buffer[4]; + length -= 4; + } + else { + // Next chunk + buffer = &buffer[2]; + length -= 2; + } + + if ((handle->rx_apdu_offset + length) > handle->rx_apdu_length) { + length = handle->rx_apdu_length - handle->rx_apdu_offset; + } + + memcpy(&handle->rx_apdu_buffer[1 + handle->rx_apdu_offset], buffer, length); + handle->rx_apdu_offset += length; + + if (handle->rx_apdu_offset == handle->rx_apdu_length) { + handle->rx_apdu_length++; // include the type + handle->rx_apdu_sequence_number = 0; + handle->rx_apdu_status = APDU_STATUS_COMPLETE; + DEBUG("APDU COMPLETE\n"); + } + else { + handle->rx_apdu_sequence_number++; + handle->rx_apdu_status = APDU_STATUS_NEED_MORE_DATA; + DEBUG("APDU NEED MORE DATA\n"); + } +} + +/* Exported functions --------------------------------------------------------*/ +void LEDGER_PROTOCOL_init(ledger_protocol_t *handle, uint8_t type) +{ + if (!handle) { + return; + } + + handle->rx_apdu_status = APDU_STATUS_WAITING; + handle->rx_apdu_sequence_number = 0; + handle->type = type; +} + +void LEDGER_PROTOCOL_rx(ledger_protocol_t *handle, uint8_t *buffer, uint16_t length) +{ + if (!handle || !buffer || length < 3) { + return; + } + + memset(handle->tx_chunk_buffer, 0, handle->tx_chunk_buffer_size); + memcpy(handle->tx_chunk_buffer, buffer, 2); // Copy channel ID + + switch (buffer[2]) { + case TAG_GET_PROTOCOL_VERSION: + DEBUG("TAG_GET_PROTOCOL_VERSION\n"); + handle->tx_chunk_buffer[2] = TAG_GET_PROTOCOL_VERSION; + handle->tx_chunk_length + = MIN((uint8_t) sizeof(protocol_version), (handle->tx_chunk_buffer_size - 3)); + memcpy(&handle->tx_chunk_buffer[3], protocol_version, handle->tx_chunk_length); + handle->tx_chunk_length += 3; + break; + + case TAG_ALLOCATE_CHANNEL: + DEBUG("TAG_ALLOCATE_CHANNEL\n"); + handle->tx_chunk_buffer[2] = TAG_ALLOCATE_CHANNEL; + handle->tx_chunk_length = 3; + break; + + case TAG_PING: + DEBUG("TAG_PING\n"); + handle->tx_chunk_length = MIN(handle->tx_chunk_buffer_size, length); + memcpy(handle->tx_chunk_buffer, buffer, handle->tx_chunk_length); + break; + + case TAG_APDU: + DEBUG("TAG_APDU\n"); + process_apdu_chunk(handle, &buffer[3], length - 3); + break; + + case TAG_MTU: + DEBUG("TAG_MTU\n"); + handle->tx_chunk_buffer[2] = TAG_MTU; + handle->tx_chunk_buffer[3] = 0x00; + handle->tx_chunk_buffer[4] = 0x00; + handle->tx_chunk_buffer[5] = 0x00; + handle->tx_chunk_buffer[6] = 0x01; + handle->tx_chunk_buffer[7] = handle->mtu - 2; + handle->tx_chunk_length = 8; + U2BE_ENCODE(handle->tx_chunk_buffer, 4, handle->mtu); + break; + + default: + // Unsupported command + break; + } +} + +void LEDGER_PROTOCOL_tx(ledger_protocol_t *handle, const uint8_t *buffer, uint16_t length) +{ + if (!handle || (!buffer && !handle->tx_apdu_buffer)) { + return; + } + if (buffer) { + DEBUG("FIRST CHUNK\n"); + handle->tx_apdu_buffer = buffer; + handle->tx_apdu_length = length; + handle->tx_apdu_sequence_number = 0; + handle->tx_apdu_offset = 0; + memset(&handle->tx_chunk_buffer[2], 0, handle->tx_chunk_buffer_size - 2); + } + else { + DEBUG("NEXT CHUNK\n"); + memset(&handle->tx_chunk_buffer[2], 0, handle->tx_chunk_buffer_size - 2); + } + + uint16_t tx_chunk_offset = 2; // Because channel id has been already filled beforehand + + handle->tx_chunk_buffer[tx_chunk_offset++] = TAG_APDU; + + U2BE_ENCODE(handle->tx_chunk_buffer, tx_chunk_offset, handle->tx_apdu_sequence_number); + tx_chunk_offset += 2; + + if (handle->tx_apdu_sequence_number == 0) { + U2BE_ENCODE(handle->tx_chunk_buffer, tx_chunk_offset, handle->tx_apdu_length); + tx_chunk_offset += 2; + } + if ((handle->tx_apdu_length + tx_chunk_offset) >= (handle->mtu + handle->tx_apdu_offset)) { + // Remaining buffer length doesn't fit the chunk + memcpy(&handle->tx_chunk_buffer[tx_chunk_offset], + &handle->tx_apdu_buffer[handle->tx_apdu_offset], + handle->mtu - tx_chunk_offset); + handle->tx_apdu_offset += handle->mtu - tx_chunk_offset; + handle->tx_apdu_sequence_number++; + tx_chunk_offset = handle->mtu; + } + else { + // Remaining buffer fits the chunk + memcpy(&handle->tx_chunk_buffer[tx_chunk_offset], + &handle->tx_apdu_buffer[handle->tx_apdu_offset], + handle->tx_apdu_length - handle->tx_apdu_offset); + tx_chunk_offset += (handle->tx_apdu_length - handle->tx_apdu_offset); + handle->tx_apdu_offset = handle->tx_apdu_length; + handle->tx_apdu_buffer = NULL; + } + handle->tx_chunk_length = tx_chunk_offset; + DEBUG(" %d\n", handle->tx_chunk_length); +} diff --git a/src/checks.c b/src/checks.c index f63f56d2a..abdc49ff2 100644 --- a/src/checks.c +++ b/src/checks.c @@ -22,8 +22,8 @@ #include "checks.h" #include "os_helpers.h" #include "os_pin.h" -#include "os_io_seproxyhal.h" #include "os_screen.h" +#include "os_io.h" #include "ux.h" // This label ultimately comes from the application link. @@ -126,8 +126,7 @@ void ui_audited_deinit(void) // for // further displays at the moment) and reinitialize the UX and buttons. ux_stack_pop(); - io_seproxyhal_init_ux(); - io_seproxyhal_init_button(); + io_seph_ux_init_button(); } #endif // HAVE_BAGL @@ -188,22 +187,12 @@ void check_audited_app(void) // to the expected one. if ((length) && (CHECK_NOT_AUDITED_TLV_VAL == data)) { ui_audited_init(); - io_seproxyhal_general_status(); - // We wait for the button callback pointer to be wiped, and we process the incoming MCU - // events in the meantime. This callback will be wiped within the actual - // 'ui_audited_elements_button' function, as soon as the user presses both buttons. do { - io_seproxyhal_spi_recv( - G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - io_seproxyhal_handle_event(); - io_seproxyhal_general_status(); + os_io_handle_ux_event_reject_apdu(); } while (!ui_audited_done()); ui_audited_deinit(); - - // Now we can wait for the next MCU status and exit. - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); } } diff --git a/src/ledger_assert.c b/src/ledger_assert.c index 3acb141c6..5ca975133 100644 --- a/src/ledger_assert.c +++ b/src/ledger_assert.c @@ -18,10 +18,10 @@ #include "ledger_assert.h" #include "os.h" +#include "os_io_legacy.h" #if defined(HAVE_BAGL) || defined(HAVE_NBGL) #include "ux.h" #endif -#include "os_io_seproxyhal.h" #ifdef HAVE_NBGL #include "nbgl_use_case.h" diff --git a/src/ledger_protocol.c b/src/ledger_protocol.c deleted file mode 100644 index 62c00fe3b..000000000 --- a/src/ledger_protocol.c +++ /dev/null @@ -1,222 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -/* Includes ------------------------------------------------------------------*/ -#include - -#include "os.h" -#include "os_math.h" -#include "os_utils.h" -#include "os_io_seproxyhal.h" - -#include "ledger_protocol.h" - -/* Private enumerations ------------------------------------------------------*/ - -/* Private types, structures, unions -----------------------------------------*/ - -/* Private defines------------------------------------------------------------*/ -#define TAG_GET_PROTOCOL_VERSION (0x00) -#define TAG_ALLOCATE_CHANNEL (0x01) -#define TAG_PING (0x02) -#define TAG_ABORT (0x03) -#define TAG_APDU (0x05) -#define TAG_MTU (0x08) - -#ifdef HAVE_PRINTF -#define LOG_BLE_PROTOCOL PRINTF -#else // !HAVE_PRINTF -#define LOG_BLE_PROTOCOL(...) -#endif // !HAVE_PRINTF - -/* Private macros-------------------------------------------------------------*/ - -/* Private functions prototypes ----------------------------------------------*/ -static void process_apdu_chunk(ledger_protocol_t *ctx, const uint8_t *buffer, uint16_t length); - -/* Exported variables --------------------------------------------------------*/ - -/* Private variables ---------------------------------------------------------*/ -static const uint8_t protocol_version[4] = {0x00, 0x00, 0x00, 0x00}; - -/* Private functions ---------------------------------------------------------*/ -static void process_apdu_chunk(ledger_protocol_t *ctx, const uint8_t *buffer, uint16_t length) -{ - // Check the sequence number - if ((length < 2) || ((uint16_t) U2BE(buffer, 0) != ctx->rx_apdu_sequence_number)) { - ctx->rx_apdu_status = APDU_STATUS_WAITING; - return; - } - // Check total length presence - if ((length < 4) && (ctx->rx_apdu_sequence_number == 0)) { - ctx->rx_apdu_status = APDU_STATUS_WAITING; - return; - } - - if (ctx->rx_apdu_sequence_number == 0) { - // First chunk - ctx->rx_apdu_status = APDU_STATUS_NEED_MORE_DATA; - ctx->rx_apdu_length = (uint16_t) U2BE(buffer, 2); - ctx->rx_apdu_offset = 0; - // Check if we have enough space to store the apdu - if (ctx->rx_apdu_length > ctx->rx_apdu_buffer_max_length) { - LOG_BLE_PROTOCOL("APDU WAITING - %d\n", ctx->rx_apdu_length); - ctx->rx_apdu_length = 0; - ctx->rx_apdu_status = APDU_STATUS_WAITING; - return; - } - buffer = &buffer[4]; - length -= 4; - } - else { - // Next chunk - buffer = &buffer[2]; - length -= 2; - } - - if ((ctx->rx_apdu_offset + length) > ctx->rx_apdu_length) { - length = ctx->rx_apdu_length - ctx->rx_apdu_offset; - } - - memcpy(&ctx->rx_apdu_buffer[ctx->rx_apdu_offset], buffer, length); - ctx->rx_apdu_offset += length; - - if (ctx->rx_apdu_offset == ctx->rx_apdu_length) { - ctx->rx_apdu_sequence_number = 0; - ctx->rx_apdu_status = APDU_STATUS_COMPLETE; - LOG_BLE_PROTOCOL("APDU COMPLETE\n"); - } - else { - ctx->rx_apdu_sequence_number++; - ctx->rx_apdu_status = APDU_STATUS_NEED_MORE_DATA; - LOG_BLE_PROTOCOL("APDU NEED MORE DATA\n"); - } -} - -/* Exported functions --------------------------------------------------------*/ -void LEDGER_PROTOCOL_init(ledger_protocol_t *ctx) -{ - ctx->rx_apdu_status = APDU_STATUS_WAITING; - ctx->rx_apdu_sequence_number = 0; -} - -void LEDGER_PROTOCOL_rx(ledger_protocol_t *ctx, const uint8_t *buffer, uint16_t length) -{ - if (!ctx || !buffer || length < 3) { - return; - } - - memset(ctx->tx_chunk, 0, sizeof(ctx->tx_chunk)); - - // For all calls to this function, the buffer was pre-initialized to the same constant - // In order for the input buffer to be 'const', this constant is forced directly here - ctx->tx_chunk[0] = 0xDE; - ctx->tx_chunk[1] = 0xF1; - - switch (buffer[2]) { - case TAG_GET_PROTOCOL_VERSION: - LOG_BLE_PROTOCOL("TAG_GET_PROTOCOL_VERSION\n"); - ctx->tx_chunk[2] = TAG_GET_PROTOCOL_VERSION; - ctx->tx_chunk_length = MIN(sizeof(protocol_version), (sizeof(ctx->tx_chunk) - 3)); - memcpy(&ctx->tx_chunk[3], protocol_version, ctx->tx_chunk_length); - ctx->tx_chunk_length += 3; - break; - - case TAG_ALLOCATE_CHANNEL: - LOG_BLE_PROTOCOL("TAG_ALLOCATE_CHANNEL\n"); - ctx->tx_chunk[2] = TAG_ALLOCATE_CHANNEL; - ctx->tx_chunk_length = 3; - break; - - case TAG_PING: - LOG_BLE_PROTOCOL("TAG_PING\n"); - ctx->tx_chunk_length = MIN(sizeof(ctx->tx_chunk), length); - memcpy(ctx->tx_chunk, buffer, ctx->tx_chunk_length); - break; - - case TAG_APDU: - LOG_BLE_PROTOCOL("TAG_APDU\n"); - process_apdu_chunk(ctx, &buffer[3], length - 3); - break; - - case TAG_MTU: - LOG_BLE_PROTOCOL("TAG_MTU\n"); - ctx->tx_chunk[2] = TAG_MTU; - ctx->tx_chunk[3] = 0x00; - ctx->tx_chunk[4] = 0x00; - ctx->tx_chunk[5] = 0x00; - ctx->tx_chunk[6] = 0x01; - ctx->tx_chunk[7] = ctx->mtu - 2; - ctx->tx_chunk_length = 8; - break; - - default: - // Unsupported command - break; - } -} - -void LEDGER_PROTOCOL_tx(ledger_protocol_t *ctx, const uint8_t *buffer, uint16_t length) -{ - if (!ctx || (!buffer && !ctx->tx_apdu_buffer)) { - return; - } - if (buffer) { - LOG_BLE_PROTOCOL("FIRST CHUNK"); - ctx->tx_apdu_buffer = buffer; - ctx->tx_apdu_length = length; - ctx->tx_apdu_sequence_number = 0; - ctx->tx_apdu_offset = 0; - memset(ctx->tx_chunk, 0, sizeof(ctx->tx_chunk)); - } - else { - LOG_BLE_PROTOCOL("NEXT CHUNK"); - } - - uint16_t tx_chunk_offset = 2; // Because channel id has been already filled beforehand - - ctx->tx_chunk[tx_chunk_offset++] = TAG_APDU; - - U2BE_ENCODE(ctx->tx_chunk, tx_chunk_offset, ctx->tx_apdu_sequence_number); - tx_chunk_offset += 2; - - if (ctx->tx_apdu_sequence_number == 0) { - U2BE_ENCODE(ctx->tx_chunk, tx_chunk_offset, ctx->tx_apdu_length); - tx_chunk_offset += 2; - } - if ((ctx->tx_apdu_length + tx_chunk_offset) >= (ctx->mtu + ctx->tx_apdu_offset)) { - // Remaining buffer length doesn't fit the chunk - memcpy(&ctx->tx_chunk[tx_chunk_offset], - &ctx->tx_apdu_buffer[ctx->tx_apdu_offset], - ctx->mtu - tx_chunk_offset); - ctx->tx_apdu_offset += ctx->mtu - tx_chunk_offset; - ctx->tx_apdu_sequence_number++; - tx_chunk_offset = ctx->mtu; - } - else { - // Remaining buffer fits the chunk TODO pad for usb - memcpy(&ctx->tx_chunk[tx_chunk_offset], - &ctx->tx_apdu_buffer[ctx->tx_apdu_offset], - ctx->tx_apdu_length - ctx->tx_apdu_offset); - tx_chunk_offset += (ctx->tx_apdu_length - ctx->tx_apdu_offset); - ctx->tx_apdu_offset = ctx->tx_apdu_length; - ctx->tx_apdu_buffer = NULL; - } - ctx->tx_chunk_length = tx_chunk_offset; - LOG_BLE_PROTOCOL(" %d\n", ctx->tx_chunk_length); -} diff --git a/src/os.c b/src/os.c index fbaaaf3a1..56977d399 100644 --- a/src/os.c +++ b/src/os.c @@ -25,11 +25,6 @@ #include "os.h" #include -#ifndef HAVE_LOCAL_APDU_BUFFER -// apdu buffer must hold a complete apdu to avoid troubles -unsigned char G_io_apdu_buffer[IO_APDU_BUFFER_SIZE]; -#endif - #ifndef BOLOS_OS_UPGRADER_APP void os_boot(void) { diff --git a/src/os_io_nfc.c b/src/os_io_nfc.c deleted file mode 100644 index 55955bd18..000000000 --- a/src/os_io_nfc.c +++ /dev/null @@ -1,252 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include "os.h" -#include "os_settings.h" -#include "os_io_seproxyhal.h" - -#include "errors.h" -#include "exceptions.h" -#ifdef HAVE_NFC - -#if defined(DEBUG_OS_STACK_CONSUMPTION) -#include "os_debug.h" -#endif // DEBUG_OS_STACK_CONSUMPTION - -#include "os_io.h" -#include "os_io_nfc.h" -#include "os_utils.h" -#include "os_io_seproxyhal.h" -#include - -#include "ledger_protocol.h" - -static uint8_t rx_apdu_buffer[IO_APDU_BUFFER_SIZE]; -static ledger_protocol_t ledger_protocol_data; - -void io_nfc_init(void) -{ - memset(&rx_apdu_buffer, 0, sizeof(rx_apdu_buffer)); - memset(&ledger_protocol_data, 0, sizeof(ledger_protocol_data)); - ledger_protocol_data.rx_apdu_buffer = rx_apdu_buffer; - ledger_protocol_data.rx_apdu_buffer_max_length = sizeof(rx_apdu_buffer); - ledger_protocol_data.mtu - = MIN(sizeof(ledger_protocol_data.tx_chunk), sizeof(G_io_seproxyhal_spi_buffer) - 3); -#ifdef HAVE_LOCAL_APDU_BUFFER - ledger_protocol_data.rx_dst_buffer = NULL; -#else - ledger_protocol_data.rx_dst_buffer = G_io_apdu_buffer; -#endif - LEDGER_PROTOCOL_init(&ledger_protocol_data); -#ifdef HAVE_NFC_READER - memset((void *) &G_io_reader_ctx, 0, sizeof(G_io_reader_ctx)); - G_io_reader_ctx.apdu_rx = rx_apdu_buffer; - G_io_reader_ctx.apdu_rx_max_size = sizeof(rx_apdu_buffer); -#endif // HAVE_NFC_READER -} - -void io_nfc_recv_event(void) -{ - size_t size = U2BE(G_io_seproxyhal_spi_buffer, 1); - - LEDGER_PROTOCOL_rx(&ledger_protocol_data, G_io_seproxyhal_spi_buffer + 3, size); - - // Full apdu is received, copy it to global apdu buffer - if (ledger_protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { -#ifdef HAVE_NFC_READER - if (G_io_reader_ctx.reader_mode) { - G_io_reader_ctx.response_received = true; - G_io_reader_ctx.apdu_rx_len = ledger_protocol_data.rx_apdu_length; - return; - } -#endif // HAVE_NFC_READER - - memcpy(ledger_protocol_data.rx_dst_buffer, - ledger_protocol_data.rx_apdu_buffer, - ledger_protocol_data.rx_apdu_length); - G_io_app.apdu_length = ledger_protocol_data.rx_apdu_length; - G_io_app.apdu_state = APDU_NFC; - G_io_app.apdu_media = IO_APDU_MEDIA_NFC; - ledger_protocol_data.rx_apdu_length = 0; - ledger_protocol_data.rx_apdu_status = APDU_STATUS_WAITING; - } -} - -static void nfc_send_rapdu(const uint8_t *packet, uint16_t packet_length) -{ - if ((size_t) (packet_length + 3) > sizeof(G_io_seproxyhal_spi_buffer)) { - return; - } - - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_NFC_RAPDU; - G_io_seproxyhal_spi_buffer[1] = (packet_length & 0xff00) >> 8; - G_io_seproxyhal_spi_buffer[2] = packet_length & 0xff; - memcpy(G_io_seproxyhal_spi_buffer + 3, packet, packet_length); - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 3 + packet_length); -} - -void io_nfc_send_response(const uint8_t *packet, uint16_t packet_length) -{ - LEDGER_PROTOCOL_tx(&ledger_protocol_data, packet, packet_length); - if (ledger_protocol_data.tx_chunk_length >= 2) { - // send the NFC APDU chunk - nfc_send_rapdu(ledger_protocol_data.tx_chunk, ledger_protocol_data.tx_chunk_length); - } - - while (ledger_protocol_data.tx_apdu_buffer) { - LEDGER_PROTOCOL_tx(&ledger_protocol_data, NULL, 0); - if (ledger_protocol_data.tx_chunk_length >= 2) { - // send the NFC APDU chunk - nfc_send_rapdu(ledger_protocol_data.tx_chunk, ledger_protocol_data.tx_chunk_length); - } - } -} - -#ifdef HAVE_NFC_READER - -void io_nfc_event(void) -{ - size_t size = U2BE(G_io_seproxyhal_spi_buffer, 1); - - if (size >= 1) { - switch (G_io_seproxyhal_spi_buffer[3]) { - case SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED: { - G_io_reader_ctx.event_happened = true; - G_io_reader_ctx.last_event = CARD_DETECTED; - G_io_reader_ctx.card.tech - = (G_io_seproxyhal_spi_buffer[4] == SEPROXYHAL_TAG_NFC_EVENT_CARD_DETECTED_A) - ? NFC_A - : NFC_B; - G_io_reader_ctx.card.nfcid_len = MIN(size - 2, sizeof(G_io_reader_ctx.card.nfcid)); - memcpy((void *) G_io_reader_ctx.card.nfcid, - G_io_seproxyhal_spi_buffer + 5, - G_io_reader_ctx.card.nfcid_len); - } break; - - case SEPROXYHAL_TAG_NFC_EVENT_CARD_LOST: - if (G_io_reader_ctx.evt_callback != NULL) { - G_io_reader_ctx.event_happened = true; - G_io_reader_ctx.last_event = CARD_REMOVED; - } - break; - } - } -} - -void io_nfc_process_events(void) -{ - if (G_io_reader_ctx.response_received) { - G_io_reader_ctx.response_received = false; - if (G_io_reader_ctx.resp_callback != NULL) { - nfc_resp_callback_t resp_cb = G_io_reader_ctx.resp_callback; - G_io_reader_ctx.resp_callback = NULL; - resp_cb(false, false, G_io_reader_ctx.apdu_rx, G_io_reader_ctx.apdu_rx_len); - } - } - - if (G_io_reader_ctx.resp_callback != NULL && G_io_reader_ctx.remaining_ms == 0) { - nfc_resp_callback_t resp_cb = G_io_reader_ctx.resp_callback; - G_io_reader_ctx.resp_callback = NULL; - resp_cb(false, true, NULL, 0); - } - - if (G_io_reader_ctx.event_happened) { - G_io_reader_ctx.event_happened = 0; - - // If card is removed during an APDU processing, call the resp_callback with an error - if (G_io_reader_ctx.resp_callback != NULL && G_io_reader_ctx.last_event == CARD_REMOVED) { - nfc_resp_callback_t resp_cb = G_io_reader_ctx.resp_callback; - G_io_reader_ctx.resp_callback = NULL; - resp_cb(true, false, NULL, 0); - } - - if (G_io_reader_ctx.evt_callback != NULL) { - G_io_reader_ctx.evt_callback(G_io_reader_ctx.last_event, - (struct card_info *) &G_io_reader_ctx.card); - } - if (G_io_reader_ctx.last_event == CARD_REMOVED) { - memset((void *) &G_io_reader_ctx.card, 0, sizeof(G_io_reader_ctx.card)); - } - } -} - -void io_nfc_ticker(void) -{ - if (G_io_reader_ctx.resp_callback != NULL) { - if (G_io_reader_ctx.remaining_ms <= 100) { - G_io_reader_ctx.remaining_ms = 0; - } - else { - G_io_reader_ctx.remaining_ms -= 100; - } - } -} - -bool io_nfc_reader_send(const uint8_t *cmd_data, - size_t cmd_len, - nfc_resp_callback_t callback, - int timeout_ms) -{ - G_io_reader_ctx.resp_callback = PIC(callback); - io_nfc_send_response(PIC(cmd_data), cmd_len); - - G_io_reader_ctx.response_received = false; - G_io_reader_ctx.remaining_ms = timeout_ms; - - return true; -} - -void io_nfc_reader_power(void) -{ - uint8_t buffer[4]; - buffer[0] = SEPROXYHAL_TAG_NFC_POWER; - buffer[1] = 0; - buffer[2] = 1; - buffer[3] = SEPROXYHAL_TAG_NFC_POWER_ON_READER; - io_seproxyhal_spi_send(buffer, 4); -} - -bool io_nfc_reader_start(nfc_evt_callback_t callback) -{ - G_io_reader_ctx.evt_callback = PIC(callback); - G_io_reader_ctx.reader_mode = true; - G_io_reader_ctx.event_happened = false; - G_io_reader_ctx.resp_callback = NULL; - G_io_reader_ctx.response_received = false; - io_nfc_reader_power(); - return true; -} - -void io_nfc_reader_stop() -{ - G_io_reader_ctx.evt_callback = NULL; - G_io_reader_ctx.reader_mode = false; - G_io_reader_ctx.event_happened = false; - G_io_reader_ctx.resp_callback = NULL; - G_io_reader_ctx.response_received = false; - io_seproxyhal_nfc_power(false); -} - -bool io_nfc_is_reader(void) -{ - return G_io_reader_ctx.reader_mode; -} - -#endif // HAVE_NFC_READER - -#endif // HAVE_NFC diff --git a/src/os_io_seproxyhal.c b/src/os_io_seproxyhal.c deleted file mode 100644 index 4feefebc1..000000000 --- a/src/os_io_seproxyhal.c +++ /dev/null @@ -1,1706 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ -#include "bolos_target.h" - -#ifdef TARGET_NANOX -#ifndef HAVE_SEPROXYHAL_MCU -#define HAVE_SEPROXYHAL_MCU -#endif // HAVE_SEPROXYHAL_MCU -#ifndef HAVE_MCU_PROTECT -#define HAVE_MCU_PROTECT -#endif // HAVE_MCU_PROTECT -#endif // TARGET_NANOX - -#include "errors.h" -#include "exceptions.h" -#include "os_apdu.h" -#include "os_apilevel.h" - -#if defined(DEBUG_OS_STACK_CONSUMPTION) -#include "os_debug.h" -#endif // DEBUG_OS_STACK_CONSUMPTION - -#include "os_id.h" -#include "os_io.h" -#include "os_io_usb.h" -#include "os_pic.h" -#include "os_pin.h" -#include "os_registry.h" -#include "os_seed.h" -#include "os_utils.h" -#include - -#ifdef OS_IO_SEPROXYHAL - -#include "os_io_seproxyhal.h" - -#ifdef HAVE_BLE -#include "ledger_ble.h" -#endif // HAVE_BLE - -#if defined(HAVE_BAGL) || defined(HAVE_NBGL) -#include "ux.h" -#endif -#include "checks.h" -#include "lcx_sha512.h" - -#ifndef IO_RAPDU_TRANSMIT_TIMEOUT_MS -#define IO_RAPDU_TRANSMIT_TIMEOUT_MS 2000UL -#endif // IO_RAPDU_TRANSMIT_TIMEOUT_MS - -#ifdef HAVE_IO_U2F -#include "u2f_processing.h" -#include "u2f_transport.h" -#endif - -#ifndef VERSION -#define VERSION "dummy" -#endif // VERSION - -#ifdef DEBUG -#define LOG printf -#else -#define LOG(...) -#endif - -#ifdef HAVE_IO_USB -#ifdef HAVE_L4_USBLIB -#include "usbd_def.h" -#include "usbd_core.h" -extern USBD_HandleTypeDef USBD_Device; -#endif -#endif -#include "os.h" - -#ifdef HAVE_NFC -#include "os_io_nfc.h" -#endif - -#ifdef HAVE_SERIALIZED_NBGL -#include "nbgl_serialize.h" -#endif - -#if !defined(HAVE_BOLOS_NO_DEFAULT_APDU) -#include "sdk_apdu_commands.h" -#endif // !HAVE_BOLOS_NO_DEFAULT_APDU - -#if defined(HAVE_LEDGER_PKI) -#include "os_pki.h" -#endif // HAVE_LEDGER_PKI - -void io_seproxyhal_handle_ble_event(void); - -unsigned int os_io_seph_recv_and_process(unsigned int dont_process_ux_events); - -#ifndef HAVE_BOLOS -io_seph_app_t G_io_app; -#endif // ! HAVE_BOLOS - -#if defined(HAVE_BAGL) || defined(HAVE_NBGL) -ux_seph_os_and_app_t G_ux_os; -#endif - -static const unsigned char seph_io_general_status[] = { - SEPROXYHAL_TAG_GENERAL_STATUS, - 0, - 2, - SEPROXYHAL_TAG_GENERAL_STATUS_LAST_COMMAND >> 8, - SEPROXYHAL_TAG_GENERAL_STATUS_LAST_COMMAND, -}; -void io_seproxyhal_general_status(void) -{ - // send the general status - io_seproxyhal_spi_send(seph_io_general_status, sizeof(seph_io_general_status)); -} - -static const unsigned char seph_io_request_status[] = { - SEPROXYHAL_TAG_REQUEST_STATUS, - 0, - 0, -}; -void io_seproxyhal_request_mcu_status(void) -{ - // send the general status - io_seproxyhal_spi_send(seph_io_request_status, sizeof(seph_io_request_status)); -} - -#ifdef HAVE_IO_USB -#ifdef HAVE_L4_USBLIB - -void io_seproxyhal_handle_usb_event(void) -{ - switch (G_io_seproxyhal_spi_buffer[3]) { - case SEPROXYHAL_TAG_USB_EVENT_RESET: - USBD_LL_SetSpeed(&USBD_Device, USBD_SPEED_FULL); - USBD_LL_Reset(&USBD_Device); - // ongoing APDU detected, throw a reset, even if not the media. to avoid potential - // troubles. - if (G_io_app.apdu_media != IO_APDU_MEDIA_NONE) { - THROW(EXCEPTION_IO_RESET); - } - memset(G_io_app.usb_ep_xfer_len, 0, sizeof(G_io_app.usb_ep_xfer_len)); - memset(G_io_app.usb_ep_timeouts, 0, sizeof(G_io_app.usb_ep_timeouts)); - break; - case SEPROXYHAL_TAG_USB_EVENT_SOF: - USBD_LL_SOF(&USBD_Device); - break; - case SEPROXYHAL_TAG_USB_EVENT_SUSPENDED: - USBD_LL_Suspend(&USBD_Device); - break; - case SEPROXYHAL_TAG_USB_EVENT_RESUMED: - USBD_LL_Resume(&USBD_Device); - break; - } -} - -void io_seproxyhal_handle_usb_ep_xfer_event(void) -{ - uint8_t epnum; - - epnum = G_io_seproxyhal_spi_buffer[3] & 0x7F; - - switch (G_io_seproxyhal_spi_buffer[4]) { - /* This event is received when a new SETUP token had been received on a control endpoint */ - case SEPROXYHAL_TAG_USB_EP_XFER_SETUP: - // assume length of setup packet, and that it is on endpoint 0 - USBD_LL_SetupStage(&USBD_Device, &G_io_seproxyhal_spi_buffer[6]); - break; - - /* This event is received after the prepare data packet has been flushed to the usb host */ - case SEPROXYHAL_TAG_USB_EP_XFER_IN: - if (epnum < IO_USB_MAX_ENDPOINTS) { - // discard ep timeout as we received the sent packet confirmation - G_io_app.usb_ep_timeouts[epnum].timeout = 0; - // propagate sending ack of the data - USBD_LL_DataInStage(&USBD_Device, epnum, &G_io_seproxyhal_spi_buffer[6]); - } - break; - - /* This event is received when a new DATA token is received on an endpoint */ - case SEPROXYHAL_TAG_USB_EP_XFER_OUT: - if (epnum < IO_USB_MAX_ENDPOINTS) { - // saved just in case it is needed ... -#if IO_SEPROXYHAL_BUFFER_SIZE_B - 6 >= 256 - G_io_app.usb_ep_xfer_len[epnum] = G_io_seproxyhal_spi_buffer[5]; -#else - G_io_app.usb_ep_xfer_len[epnum] - = MIN(G_io_seproxyhal_spi_buffer[5], IO_SEPROXYHAL_BUFFER_SIZE_B - 6); -#endif - // prepare reception - USBD_LL_DataOutStage(&USBD_Device, epnum, &G_io_seproxyhal_spi_buffer[6], NULL); - } - break; - } -} - -#else -// no usb lib: X86 for example - -void io_seproxyhal_handle_usb_event(void) {} -void io_seproxyhal_handle_usb_ep_xfer_event(void) {} - -#endif // HAVE_L4_USBLIB - -#ifdef HAVE_WEBUSB -void io_usb_send_apdu_data_ep0x83(unsigned char *buffer, unsigned short length) -{ - // wait for 20 events before hanging up and timeout (~2 seconds of timeout) - io_usb_send_ep(0x83, buffer, length, 20); -} -#endif // HAVE_WEBUSB - -#endif // HAVE_IO_USB - -void io_seproxyhal_handle_capdu_event(void) -{ - if (G_io_app.apdu_state == APDU_IDLE) { - size_t max = MIN(sizeof(G_io_apdu_buffer) - 3, sizeof(G_io_seproxyhal_spi_buffer) - 3); - size_t size = U2BE(G_io_seproxyhal_spi_buffer, 1); - - G_io_app.apdu_media = IO_APDU_MEDIA_RAW; // for application code - G_io_app.apdu_state = APDU_RAW; // for next call to io_exchange - G_io_app.apdu_length = MIN(size, max); - // copy apdu to apdu buffer - memcpy(G_io_apdu_buffer, G_io_seproxyhal_spi_buffer + 3, G_io_app.apdu_length); - } -} - -unsigned int io_seproxyhal_handle_event(void) -{ -#ifdef HAVE_IO_USB - unsigned int rx_len = U2BE(G_io_seproxyhal_spi_buffer, 1); -#endif - - switch (G_io_seproxyhal_spi_buffer[0]) { -#ifdef HAVE_IO_USB - case SEPROXYHAL_TAG_USB_EVENT: - if (rx_len != 1) { - return 0; - } - io_seproxyhal_handle_usb_event(); - return 1; - - case SEPROXYHAL_TAG_USB_EP_XFER_EVENT: - if (rx_len < 3) { - // error ! - return 0; - } - io_seproxyhal_handle_usb_ep_xfer_event(); - return 1; -#endif // HAVE_IO_USB - -#ifdef HAVE_BLE - case SEPROXYHAL_TAG_BLE_RECV_EVENT: - LEDGER_BLE_receive(G_io_seproxyhal_spi_buffer); - return 1; -#endif // HAVE_BLE - -#ifdef HAVE_NFC - case SEPROXYHAL_TAG_NFC_APDU_EVENT: - io_nfc_recv_event(); -#if defined(HAVE_NFC_READER) && !defined(HAVE_BOLOS) - io_nfc_process_events(); -#endif // HAVE_NFC_READER && !HAVE_BOLOS - return 1; -#ifdef HAVE_NFC_READER - case SEPROXYHAL_TAG_NFC_EVENT: - io_nfc_event(); -#ifndef HAVE_BOLOS - io_nfc_process_events(); -#endif // !HAVE_BOLOS - return 1; -#endif // HAVE_NFC_READER -#endif // HAVE_NFC - - case SEPROXYHAL_TAG_UX_EVENT: - switch (G_io_seproxyhal_spi_buffer[3]) { -#ifdef HAVE_BLE - case SEPROXYHAL_TAG_UX_CMD_BLE_DISABLE_ADV: - LEDGER_BLE_enable_advertising(0); - return 1; - break; - - case SEPROXYHAL_TAG_UX_CMD_BLE_ENABLE_ADV: - LEDGER_BLE_enable_advertising(1); - return 1; - break; - - case SEPROXYHAL_TAG_UX_CMD_BLE_RESET_PAIRINGS: - LEDGER_BLE_reset_pairings(); - return 1; - break; - - case SEPROXYHAL_TAG_UX_CMD_BLE_NAME_CHANGED: - // Restart advertising - G_io_app.name_changed = 1; - io_seph_ble_enable(0); - break; - - case SEPROXYHAL_TAG_UX_CMD_ACCEPT_PAIRING: - LEDGER_BLE_accept_pairing(G_io_seproxyhal_spi_buffer[4]); - return 1; - break; -#endif // HAVE_BLE - -#if !defined(HAVE_BOLOS) && defined(HAVE_BAGL) - case SEPROXYHAL_TAG_UX_CMD_REDISPLAY: - ux_stack_redisplay(); - return 1; - break; -#endif // HAVE_BOLOS && HAVE_BAGL - -#if !defined(HAVE_BOLOS) && defined(HAVE_NBGL) - case SEPROXYHAL_TAG_UX_CMD_REDISPLAY: - nbgl_objAllowDrawing(true); - nbgl_screenRedraw(); - nbgl_refresh(); - return 1; - break; -#endif // HAVE_BOLOS && HAVE_NBGL - - default: - return io_event(CHANNEL_SPI); - break; - } - break; - - case SEPROXYHAL_TAG_CAPDU_EVENT: - io_seproxyhal_handle_capdu_event(); - return 1; - - // ask the user if not processed here - case SEPROXYHAL_TAG_TICKER_EVENT: - // process ticker events to timeout the IO transfers, and forward to the user io_event - // function too - G_io_app.ms += 100; // value is by default, don't change the ticker configuration -#ifdef HAVE_IO_USB - { - unsigned int i = IO_USB_MAX_ENDPOINTS; - while (i--) { - if (G_io_app.usb_ep_timeouts[i].timeout) { - G_io_app.usb_ep_timeouts[i].timeout - -= MIN(G_io_app.usb_ep_timeouts[i].timeout, 100); - if (!G_io_app.usb_ep_timeouts[i].timeout) { - // timeout ! - G_io_app.apdu_state = APDU_IDLE; - THROW(EXCEPTION_IO_RESET); - } - } - } - } -#endif // HAVE_IO_USB -#ifdef HAVE_BLE_APDU - { - if (G_io_app.ble_xfer_timeout) { - G_io_app.ble_xfer_timeout -= MIN(G_io_app.ble_xfer_timeout, 100); - if (!G_io_app.ble_xfer_timeout) { - G_io_app.apdu_state = APDU_IDLE; - THROW(EXCEPTION_IO_RESET); - } - } - } -#endif // HAVE_BLE_APDU - FALL_THROUGH; - // no break is intentional - default: - return io_event(CHANNEL_SPI); - } - // defaultly return as not processed - return 0; -} - -// #define DEBUG_APDU -#ifdef DEBUG_APDU -volatile unsigned int debug_apdus_offset; -const char debug_apdus[] = { - 5, - 0xE0, - 0x40, - 0x00, - 0x00, - 0x00, - // 9, 0xe0, 0x22, 0x00, 0x00, 0x04, 0x31, 0x32, 0x33, 0x34, -}; -#endif // DEBUG_APDU - -#ifdef HAVE_BOLOS_APP_STACK_CANARY -#define APP_STACK_CANARY_MAGIC 0xDEAD0031 -extern unsigned int app_stack_canary; -#endif // HAVE_BOLOS_APP_STACK_CANARY - -#if (!defined(HAVE_BOLOS) && defined(HAVE_MCU_PROTECT)) -static const unsigned char seph_io_mcu_protect[] = { - SEPROXYHAL_TAG_MCU, - 0, - 1, - SEPROXYHAL_TAG_MCU_TYPE_PROTECT, -}; -#endif // (!defined(HAVE_BOLOS) && defined(HAVE_MCU_PROTECT)) - -void io_seproxyhal_init(void) -{ -#ifndef HAVE_BOLOS -#ifdef HAVE_MCU_PROTECT - // engage RDP2 on MCU - io_seproxyhal_spi_send(seph_io_mcu_protect, sizeof(seph_io_mcu_protect)); -#endif // HAVE_MCU_PROTECT -#endif // HAVE_BOLOS - -#ifdef HAVE_BOLOS_APP_STACK_CANARY - app_stack_canary = APP_STACK_CANARY_MAGIC; -#endif // HAVE_BOLOS_APP_STACK_CANARY - -#if !defined(HAVE_BOLOS) && !defined(BOLOS_OS_UPGRADER_APP) - // Warn UX layer of io reset to avoid unwanted pin lock - memset(&G_ux_params, 0, sizeof(G_ux_params)); - G_ux_params.ux_id = BOLOS_UX_IO_RESET; - - // If the app has just been booted from the UX, multiple os_ux calls may be necessary - // to ensure UX layer has take the BOLOS_UX_IO_RESET instruction into account. - for (uint8_t i = 0; i < 2; i++) { - os_ux(&G_ux_params); - if (os_sched_last_status(TASK_BOLOS_UX) == BOLOS_UX_OK) { - break; - } - } -#endif - - // wipe the io structure before it's used -#ifdef HAVE_BLE - unsigned int plane = G_io_app.plane_mode; -#endif // HAVE_BLE - memset(&G_io_app, 0, sizeof(G_io_app)); -#ifdef HAVE_BLE - G_io_app.plane_mode = plane; -#endif // HAVE_BLE - - G_io_app.apdu_state = APDU_IDLE; - G_io_app.apdu_length = 0; - G_io_app.apdu_media = IO_APDU_MEDIA_NONE; - - G_io_app.ms = 0; - -#ifdef DEBUG_APDU - debug_apdus_offset = 0; -#endif // DEBUG_APDU - -#ifdef HAVE_USB_APDU - io_usb_hid_init(); -#endif // HAVE_USB_APDU - -#ifdef HAVE_NFC - io_nfc_init(); -#endif // HAVE_NFC - -#ifdef HAVE_BAGL - - io_seproxyhal_init_ux(); - io_seproxyhal_init_button(); -#endif - -#if !defined(HAVE_BOLOS) && defined(HAVE_PENDING_REVIEW_SCREEN) - check_audited_app(); -#endif // !defined(HAVE_BOLOS) && defined(HAVE_PENDING_REVIEW_SCREEN) -} - -#ifdef HAVE_PIEZO_SOUND -void io_seproxyhal_play_tune(tune_index_e tune_index) -{ - uint8_t buffer[4]; - if (tune_index >= NB_TUNES) { - return; - } - - uint32_t sound_setting = os_setting_get(OS_SETTING_PIEZO_SOUND, NULL, 0); - - if ((!IS_NOTIF_ENABLED(sound_setting)) && (tune_index < TUNE_TAP_CASUAL)) { - return; - } - - if ((!IS_TAP_ENABLED(sound_setting)) && (tune_index >= TUNE_TAP_CASUAL)) { - return; - } - - if (io_seproxyhal_spi_is_status_sent()) { - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - } - - buffer[0] = SEPROXYHAL_TAG_PLAY_TUNE; - buffer[1] = 0; - buffer[2] = 1; - buffer[3] = (uint8_t) tune_index; - io_seproxyhal_spi_send(buffer, 4); -} -#endif // HAVE_PIEZO_SOUND - -#ifdef HAVE_NFC -void io_seproxyhal_nfc_power(bool forceInit) -{ - uint8_t buffer[4]; - uint8_t power - = (forceInit - || (os_setting_get(OS_SETTING_FEATURES, NULL, 0) & OS_SETTING_FEATURES_NFC_ENABLED)) - ? SEPROXYHAL_TAG_NFC_POWER_ON_CE - : SEPROXYHAL_TAG_NFC_POWER_OFF; - buffer[0] = SEPROXYHAL_TAG_NFC_POWER; - buffer[1] = 0; - buffer[2] = 1; - buffer[3] = power; - io_seproxyhal_spi_send(buffer, 4); -} -#endif // HAVE_NFC - -#ifdef HAVE_SE_TOUCH -#ifdef HAVE_TOUCH_READ_DEBUG_DATA_SYSCALL -#ifdef HAVE_GT1151_TOUCH -/** - * @brief Set touch in read raw data mode and read raw data - * - * @param sensi_data Pointer to the buffer to store sensi data - * @return BOLOS_TRUE/BOLOS_FALSE - */ -bolos_bool_t io_seproxyhal_touch_debug_read_sensi(uint8_t *sensi_data) -{ - return touch_switch_debug_mode_and_read(TOUCH_DEBUG_READ_RAW_DATA, 0, sensi_data); -} - -/** - * @brief Set touch in read diff data mode and read diff data - * - * @param diff_data Pointer to the buffer to store diff data - * @return BOLOS_TRUE/BOLOS_FALSE - */ -bolos_bool_t io_seproxyhal_touch_debug_read_diff_data(uint8_t *diff_data) -{ - return touch_switch_debug_mode_and_read(TOUCH_DEBUG_READ_DIFF_DATA, 0, diff_data); -} - -/** - * @brief Set touch in read coordinates mode - * - * @param None - * @return BOLOS_TRUE/BOLOS_FALSE - */ -bolos_bool_t io_seproxyhal_touch_debug_end(void) -{ - return touch_switch_debug_mode_and_read(TOUCH_DEBUG_END, 0, NULL); -} -#endif -#ifdef HAVE_EWD_720_TOUCH -/** - * @brief Read ewd720 touch offset data - * - * @param diff_data Pointer to the buffer to store diff data - * @return BOLOS_TRUE/BOLOS_FALSE - */ -bolos_bool_t io_seproxyhal_touch_debug_read_sensor_buffer(uint8_t buffer_type, - uint8_t *sensor_buffer) -{ - return touch_switch_debug_mode_and_read( - TOUCH_DEBUG_READ_SENSOR_BUFFER, buffer_type, sensor_buffer); -} -#endif -#endif -#endif - -#ifdef HAVE_BAGL - -void io_seproxyhal_init_ux(void) {} - -void io_seproxyhal_init_button(void) -{ - // no button push so far - G_ux_os.button_mask = 0; - G_ux_os.button_same_mask_counter = 0; -} - -void io_seproxyhal_display_bitmap(int x, - int y, - unsigned int w, - unsigned int h, - unsigned int *color_index, - unsigned int bit_per_pixel, - unsigned char *bitmap) -{ - // component type = ICON - // component icon id = 0 - // => bitmap transmitted - if (w && h) { - bagl_component_t c; - bagl_icon_details_t d; - memset(&c, 0, sizeof(c)); - c.type = BAGL_ICON; - c.x = x; - c.y = y; - c.width = w; - c.height = h; - // done by memset // c.icon_id = 0; - d.width = w; - d.height = h; - d.bpp = bit_per_pixel; - d.colors = color_index; - d.bitmap = bitmap; - - io_seproxyhal_display_icon(&c, &d); - /* - // color index size - h = ((1<>8; - G_io_seproxyhal_spi_buffer[2] = length; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 3); - io_seproxyhal_spi_send((unsigned char*)&c, sizeof(bagl_component_t)); - G_io_seproxyhal_spi_buffer[0] = bit_per_pixel; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 1); - io_seproxyhal_spi_send((unsigned char*)color_index, h); - io_seproxyhal_spi_send(bitmap, w); - */ - } -} - -#ifdef SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS -unsigned int io_seproxyhal_display_icon_header_and_colors(const bagl_component_t *icon_component, - const bagl_icon_details_t *icon_details, - unsigned int *icon_len) -{ - unsigned int len; - - struct display_raw_s { - struct { - struct { - unsigned char tag; - unsigned char len[2]; - } seph; - unsigned char type; - } header; - union { - short val; - char b[2]; - } x; - union { - short val; - char b[2]; - } y; - union { - unsigned short val; - char b[2]; - } w; - union { - unsigned short val; - char b[2]; - } h; - unsigned char bpp; - } __attribute__((packed)) raw; - - raw.header.seph.tag = SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS; - raw.header.type = SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS_START; - raw.x.val = icon_component->x; - raw.y.val = icon_component->y; - raw.w.val = icon_component->width; - raw.h.val = icon_component->height; - raw.bpp = icon_details->bpp; - - *icon_len - = raw.w.val * raw.h.val * raw.bpp / 8 + (((raw.w.val * raw.h.val * raw.bpp) % 8) ? 1 : 0); - - // optional, don't send too much on a single packet for MCU to receive it. when stream mode will - // be on, this will be useless min of remaining space in the packet vs. total icon size + color - // index size - len = MIN(sizeof(G_io_seproxyhal_spi_buffer) - sizeof(raw), *icon_len + (1 << raw.bpp) * 4); - - // sizeof packet - raw.header.seph.len[0] = (len + sizeof(raw) - sizeof(raw.header.seph)) >> 8; - raw.header.seph.len[1] = (len + sizeof(raw) - sizeof(raw.header.seph)); - - // swap endianness of coordinates (make it big endian) - SWAP(raw.x.b[0], raw.x.b[1]); - SWAP(raw.y.b[0], raw.y.b[1]); - SWAP(raw.w.b[0], raw.w.b[1]); - SWAP(raw.h.b[0], raw.h.b[1]); - - io_seproxyhal_spi_send((unsigned char *) &raw, sizeof(raw)); - io_seproxyhal_spi_send((const uint8_t *) PIC(icon_details->colors), (1 << raw.bpp) * 4); - len -= (1 << raw.bpp) * 4; - - // remaining length of bitmap bits to be displayed - return len; -} -#endif // SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS - -void io_seproxyhal_display_icon(const bagl_component_t *icon_component, - const bagl_icon_details_t *icon_det) -{ - bagl_component_t icon_component_mod; - const bagl_icon_details_t *icon_details = (const bagl_icon_details_t *) PIC(icon_det); - - if (icon_details && icon_details->bitmap) { - // ensure not being out of bounds in the icon component against the declared icon real size - memcpy(&icon_component_mod, PIC(icon_component), sizeof(bagl_component_t)); - icon_component_mod.width = icon_details->width; - icon_component_mod.height = icon_details->height; - icon_component = &icon_component_mod; - -#ifdef SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS - unsigned int len; - unsigned int icon_len; - unsigned int icon_off = 0; - - len = io_seproxyhal_display_icon_header_and_colors(icon_component, icon_details, &icon_len); - io_seproxyhal_spi_send(PIC(icon_details->bitmap), len); - // advance in the bitmap to be transmitted - icon_len -= len; - icon_off += len; - - // still some bitmap data to transmit - while (icon_len) { - // wait displayed event - io_seproxyhal_spi_recv( - G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS; - G_io_seproxyhal_spi_buffer[3] = SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS_CONT; - - len = MIN((sizeof(G_io_seproxyhal_spi_buffer) - 4), icon_len); - G_io_seproxyhal_spi_buffer[1] = (len + 1) >> 8; - G_io_seproxyhal_spi_buffer[2] = (len + 1); - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 4); - io_seproxyhal_spi_send(PIC(icon_details->bitmap) + icon_off, len); - - icon_len -= len; - icon_off += len; - } -#else // !SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS -#ifdef HAVE_SE_SCREEN - bagl_draw_glyph(&icon_component_mod, icon_details); -#endif // HAVE_SE_SCREEN -#if !defined(HAVE_SE_SCREEN) || (defined(HAVE_SE_SCREEN) && defined(HAVE_PRINTF)) - if (io_seproxyhal_spi_is_status_sent()) { - return; - } - // color index size - unsigned int h = (1 << (icon_details->bpp)) * sizeof(unsigned int); - // bitmap size - unsigned int w - = ((icon_component->width * icon_component->height * icon_details->bpp) / 8) - + ((icon_component->width * icon_component->height * icon_details->bpp) % 8 ? 1 : 0); - unsigned short length = sizeof(bagl_component_t) + 1 /* bpp */ - + h /* color index */ - + w; /* image bitmap size */ - if (length > (sizeof(G_io_seproxyhal_spi_buffer) - 4)) { -#if defined(HAVE_PRINTF) - PRINTF( - "ERROR: Inside io_seproxyhal_display_icon, icon size (%d) is too big for the " - "buffer (%d-4)! (bitmap=0x%x, width=%d, height=%d, bpp=%d)\n", - length, - sizeof(G_io_seproxyhal_spi_buffer), - icon_details->bitmap, - icon_details->width, - icon_details->height, - icon_details->bpp); -#endif // defined(HAVE_PRINTF) - return; - } - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_SCREEN_DISPLAY_STATUS; -#if defined(HAVE_SE_SCREEN) && defined(HAVE_PRINTF) - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_DBG_SCREEN_DISPLAY_STATUS; -#endif // HAVE_SE_SCREEN && HAVE_PRINTF - G_io_seproxyhal_spi_buffer[1] = length >> 8; - G_io_seproxyhal_spi_buffer[2] = length; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 3); - io_seproxyhal_spi_send((const uint8_t *) icon_component, sizeof(bagl_component_t)); - G_io_seproxyhal_spi_buffer[0] = icon_details->bpp; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 1); - io_seproxyhal_spi_send((const uint8_t *) PIC(icon_details->colors), h); - io_seproxyhal_spi_send((const uint8_t *) PIC(icon_details->bitmap), w); -#else // !HAVE_SE_SCREEN || (HAVE_SE_SCREEN && HAVE_PRINTF) - (void) icon_component; -#endif // !HAVE_SE_SCREEN || (HAVE_SE_SCREEN && HAVE_PRINTF) -#endif // !SEPROXYHAL_TAG_SCREEN_DISPLAY_RAW_STATUS - } -} - -void io_seproxyhal_display_default(const bagl_element_t *element) -{ - const bagl_element_t *el = (const bagl_element_t *) PIC(element); - const char *txt; - // process automagically address from rom and from ram - unsigned int type = (el->component.type & ~(BAGL_FLAG_TOUCHABLE)); - -#if defined(HAVE_INDEXED_STRINGS) - if (type == BAGL_LABELINE_LOC) { - txt = (const char *) PIC(get_ux_loc_string(el->index)); - } - else -#endif // defined(HAVE_INDEXED_STRINGS) - { - txt = (const char *) PIC(el->text); - } - - if (type != BAGL_NONE) { - if (txt != NULL) { - // consider an icon details descriptor is pointed by the context - if (type == BAGL_ICON && el->component.icon_id == 0) { - // SECURITY: due to this wild cast, the code MUST be executed on the application - // side instead of in - // the syscall sides to avoid buffer overflows and a real hard way of - // checking buffer belonging in the syscall dispatch - io_seproxyhal_display_icon(&el->component, (const bagl_icon_details_t *) txt); - } - else { -#ifdef HAVE_SE_SCREEN - bagl_draw_with_context(&el->component, txt, strlen(txt), BAGL_ENCODING_DEFAULT); -#endif // HAVE_SE_SCREEN -#if !defined(HAVE_SE_SCREEN) || (defined(HAVE_SE_SCREEN) && defined(HAVE_PRINTF)) - if (io_seproxyhal_spi_is_status_sent()) { - return; - } - // io_seph_send crash when using txt from language packs... - // ...let's use an intermediate buffer to store txt -#ifdef HAVE_LANGUAGE_PACK - char buffer[128]; - strlcpy(buffer, txt, sizeof(buffer)); -#else // HAVE_LANGUAGE_PACK - const char *buffer = txt; -#endif // HAVE_LANGUAGE_PACK - unsigned short length = sizeof(bagl_component_t) + strlen(buffer); - if (length > (sizeof(G_io_seproxyhal_spi_buffer) - 3)) { -#if defined(HAVE_PRINTF) - PRINTF( - "ERROR: Inside io_seproxyhal_display_default, length (%d) is too big for " - "G_io_seproxyhal_spi_buffer(%d)!\n", - length + 3, - sizeof(G_io_seproxyhal_spi_buffer)); -#endif // defined(HAVE_PRINTF) - return; - } - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_SCREEN_DISPLAY_STATUS; -#if defined(HAVE_SE_SCREEN) && defined(HAVE_PRINTF) - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_DBG_SCREEN_DISPLAY_STATUS; -#endif // HAVE_SE_SCREEN && HAVE_PRINTF - G_io_seproxyhal_spi_buffer[1] = length >> 8; - G_io_seproxyhal_spi_buffer[2] = length; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 3); - io_seproxyhal_spi_send((const uint8_t *) &el->component, sizeof(bagl_component_t)); - io_seproxyhal_spi_send((const uint8_t *) buffer, strlen(buffer)); -#endif // !HAVE_SE_SCREEN || (HAVE_SE_SCREEN && HAVE_PRINTF) - } - } - else { -#ifdef HAVE_SE_SCREEN - bagl_draw_with_context(&el->component, NULL, 0, 0); -#endif // HAVE_SE_SCREEN -#if !defined(HAVE_SE_SCREEN) || (defined(HAVE_SE_SCREEN) && defined(HAVE_PRINTF)) - if (io_seproxyhal_spi_is_status_sent()) { - return; - } - unsigned short length = sizeof(bagl_component_t); - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_SCREEN_DISPLAY_STATUS; -#if defined(HAVE_SE_SCREEN) && defined(HAVE_PRINTF) - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_DBG_SCREEN_DISPLAY_STATUS; -#endif // HAVE_SE_SCREEN && HAVE_PRINTF - G_io_seproxyhal_spi_buffer[1] = length >> 8; - G_io_seproxyhal_spi_buffer[2] = length; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 3); - io_seproxyhal_spi_send((const uint8_t *) &el->component, sizeof(bagl_component_t)); -#endif // !HAVE_SE_SCREEN || (HAVE_SE_SCREEN && HAVE_PRINTF) - } - } -} - -unsigned int bagl_label_roundtrip_duration_ms(const bagl_element_t *e, - unsigned int average_char_width) -{ - return bagl_label_roundtrip_duration_ms_buf(e, e->text, average_char_width); -} - -unsigned int bagl_label_roundtrip_duration_ms_buf(const bagl_element_t *e, - const char *str, - unsigned int average_char_width) -{ - // not a scrollable label - if (e == NULL || (e->component.type != BAGL_LABEL && e->component.type != BAGL_LABELINE)) { - return 0; - } - - const char *text_adr = (const char *) PIC(str); - unsigned int textlen = 0; - - // no delay, no text to display - if (!text_adr) { - return 0; - } - textlen = strlen(text_adr); - - // no delay, all text fits - textlen = textlen * average_char_width; - if (textlen <= e->component.width) { - return 0; - } - - // compute scrolled text length - return 2 * (textlen - e->component.width) * 1000 / e->component.icon_id - + 2 * (e->component.stroke & ~(0x80)) * 100; -} - -void io_seproxyhal_button_push(button_push_callback_t button_callback, unsigned int new_button_mask) -{ - if (button_callback) { - unsigned int button_mask; - unsigned int button_same_mask_counter; - // enable speeded up long push - if (new_button_mask == G_ux_os.button_mask) { - // each 100ms ~ - G_ux_os.button_same_mask_counter++; - } - - // when new_button_mask is 0 and - - // append the button mask - button_mask = G_ux_os.button_mask | new_button_mask; - - // pre reset variable due to os_sched_exit - button_same_mask_counter = G_ux_os.button_same_mask_counter; - - // reset button mask - if (new_button_mask == 0) { - // reset next state when button are released - G_ux_os.button_mask = 0; - G_ux_os.button_same_mask_counter = 0; - - // notify button released event - button_mask |= BUTTON_EVT_RELEASED; - } - else { - G_ux_os.button_mask = button_mask; - } - - // reset counter when button mask changes - if (new_button_mask != G_ux_os.button_mask) { - G_ux_os.button_same_mask_counter = 0; - } - - if (button_same_mask_counter >= BUTTON_FAST_THRESHOLD_CS) { - // fast bit when pressing and timing is right - if ((button_same_mask_counter % BUTTON_FAST_ACTION_CS) == 0) { - button_mask |= BUTTON_EVT_FAST; - } - - /* - // fast bit when releasing and threshold has been exceeded - if ((button_mask & BUTTON_EVT_RELEASED)) { - button_mask |= BUTTON_EVT_FAST; - } - */ - - // discard the release event after a fastskip has been detected, to avoid strange at - // release behavior and also to enable user to cancel an operation by starting - // triggering the fast skip - button_mask &= ~BUTTON_EVT_RELEASED; - } - - // indicate if button have been released - button_callback(button_mask, button_same_mask_counter); - } -} - -#endif // HAVE_BAGL - -void io_seproxyhal_setup_ticker(unsigned int interval_ms) -{ - uint8_t buffer[5]; - buffer[0] = SEPROXYHAL_TAG_SET_TICKER_INTERVAL; - buffer[1] = 0; - buffer[2] = 2; - buffer[3] = (interval_ms >> 8) & 0xff; - buffer[4] = (interval_ms) &0xff; - io_seproxyhal_spi_send(buffer, 5); -} - -void io_seproxyhal_power_off(bool criticalBattery) -{ - unsigned char seph_io_device_off[4] = { - SEPROXYHAL_TAG_DEVICE_OFF, - 0, - 1, - (char) criticalBattery, - }; - io_seproxyhal_spi_send(seph_io_device_off, sizeof(seph_io_device_off)); - for (;;) - ; -} - -static const unsigned char seph_io_se_reset[] = { - SEPROXYHAL_TAG_SE_POWER_OFF, - 0, - 0, -}; -void io_seproxyhal_se_reset(void) -{ - io_seproxyhal_spi_send(seph_io_se_reset, sizeof(seph_io_se_reset)); - for (;;) - ; -} - -#ifdef HAVE_SERIALIZED_NBGL - -#define SERIALIZED_NBGL_MAX_LEN 200 - -static uint8_t nbgl_serialize_buffer[SERIALIZED_NBGL_MAX_LEN]; - -void io_seproxyhal_send_nbgl_serialized(nbgl_serialized_event_type_e event, nbgl_obj_t *obj) -{ - // Serialize object - size_t len = 0; - size_t max_len = sizeof(nbgl_serialize_buffer) - 3; - uint8_t status = nbgl_serializeNbglEvent(event, obj, nbgl_serialize_buffer + 3, &len, max_len); - - // Encode and send - if (status == NBGL_SERIALIZE_OK) { - nbgl_serialize_buffer[0] = SEPROXYHAL_TAG_NBGL_SERIALIZED; - U2BE_ENCODE(nbgl_serialize_buffer, 1, len); - io_seproxyhal_spi_send(nbgl_serialize_buffer, len + 3); - } -} -#endif - -#ifdef HAVE_BLE -void io_seph_ble_enable(unsigned char enable) -{ - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_UX_CMD; - G_io_seproxyhal_spi_buffer[1] = 0; - G_io_seproxyhal_spi_buffer[2] = 1; - G_io_seproxyhal_spi_buffer[3] - = (enable ? SEPROXYHAL_TAG_UX_CMD_BLE_ENABLE_ADV : SEPROXYHAL_TAG_UX_CMD_BLE_DISABLE_ADV); - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 4); -} - -void io_seph_ble_clear_bond_db(void) -{ - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_UX_CMD; - G_io_seproxyhal_spi_buffer[1] = 0; - G_io_seproxyhal_spi_buffer[2] = 1; - G_io_seproxyhal_spi_buffer[3] = SEPROXYHAL_TAG_UX_CMD_BLE_RESET_PAIRINGS; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 4); -} - -void io_seph_ble_name_changed(void) -{ - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_UX_CMD; - G_io_seproxyhal_spi_buffer[1] = 0; - G_io_seproxyhal_spi_buffer[2] = 1; - G_io_seproxyhal_spi_buffer[3] = SEPROXYHAL_TAG_UX_CMD_BLE_NAME_CHANGED; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 4); -} -#endif // HAVE_BLE - -void io_seph_ux_redisplay(void) -{ - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_UX_CMD; - G_io_seproxyhal_spi_buffer[1] = 0; - G_io_seproxyhal_spi_buffer[2] = 1; - G_io_seproxyhal_spi_buffer[3] = SEPROXYHAL_TAG_UX_CMD_REDISPLAY; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 4); -} - -void io_seph_ux_accept_pairing(unsigned char status) -{ - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_UX_CMD; - G_io_seproxyhal_spi_buffer[1] = 0; - G_io_seproxyhal_spi_buffer[2] = 2; - G_io_seproxyhal_spi_buffer[3] = SEPROXYHAL_TAG_UX_CMD_ACCEPT_PAIRING; - G_io_seproxyhal_spi_buffer[4] = status; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 5); -} - -static const unsigned char seph_io_usb_disconnect[] = { - SEPROXYHAL_TAG_USB_CONFIG, - 0, - 1, - SEPROXYHAL_TAG_USB_CONFIG_DISCONNECT, -}; - -void io_seproxyhal_disable_io(void) -{ - // usb off - io_seproxyhal_spi_send(seph_io_usb_disconnect, sizeof(seph_io_usb_disconnect)); -} - -static const unsigned char seph_io_usb_connect[] = { - SEPROXYHAL_TAG_USB_CONFIG, - 0, - 1, - SEPROXYHAL_TAG_USB_CONFIG_CONNECT, -}; - -void io_seproxyhal_enable_io(void) -{ - // usb on - io_seproxyhal_spi_send(seph_io_usb_connect, sizeof(seph_io_usb_connect)); -} - -void io_seproxyhal_backlight(unsigned int flags, unsigned int backlight_percentage) -{ - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_SET_SCREEN_CONFIG; - G_io_seproxyhal_spi_buffer[1] = 0; - G_io_seproxyhal_spi_buffer[2] = 2; - G_io_seproxyhal_spi_buffer[3] = (backlight_percentage ? 0x80 : 0) | (flags & 0x7F); // power on - G_io_seproxyhal_spi_buffer[4] = backlight_percentage; - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 5); -} - -#ifdef HAVE_IO_U2F -u2f_service_t G_io_u2f; -#endif // HAVE_IO_U2F - -unsigned int os_io_seproxyhal_get_app_name_and_version(void) __attribute__((weak)); -unsigned int os_io_seproxyhal_get_app_name_and_version(void) -{ - unsigned int tx_len, len; - // build the get app name and version reply - tx_len = 0; - G_io_apdu_buffer[tx_len++] = 1; // format ID - -#ifndef HAVE_BOLOS - // append app name - len = os_registry_get_current_app_tag( - BOLOS_TAG_APPNAME, G_io_apdu_buffer + tx_len + 1, sizeof(G_io_apdu_buffer) - tx_len - 1); - G_io_apdu_buffer[tx_len++] = len; - tx_len += len; - // append app version - len = os_registry_get_current_app_tag( - BOLOS_TAG_APPVERSION, G_io_apdu_buffer + tx_len + 1, sizeof(G_io_apdu_buffer) - tx_len - 1); - G_io_apdu_buffer[tx_len++] = len; - tx_len += len; -#else // HAVE_BOLOS - // append app name - len = strlen("BOLOS"); - G_io_apdu_buffer[tx_len++] = len; - strcpy((char *) (G_io_apdu_buffer + tx_len), "BOLOS"); - tx_len += len; - // append app version - len = strlen(VERSION); - G_io_apdu_buffer[tx_len++] = len; - strcpy((char *) (G_io_apdu_buffer + tx_len), VERSION); - tx_len += len; -#endif // HAVE_BOLOS - -#if !defined(HAVE_IO_TASK) || !defined(HAVE_BOLOS) - // to be fixed within io tasks - // return OS flags to notify of platform's global state (pin lock etc) - G_io_apdu_buffer[tx_len++] = 1; // flags length - G_io_apdu_buffer[tx_len++] = os_flags(); -#endif // !defined(HAVE_IO_TASK) || !defined(HAVE_BOLOS) - - // status words - G_io_apdu_buffer[tx_len++] = 0x90; - G_io_apdu_buffer[tx_len++] = 0x00; - return tx_len; -} - -#if defined(HAVE_LEDGER_PKI) -unsigned int os_io_seproxyhal_pki_load_certificate(uint8_t *buffer, - size_t buffer_len, - uint8_t key_usage) -{ - uint32_t sw; - cx_ecfp_384_public_key_t public_key; - - sw = os_pki_load_certificate(key_usage, buffer, buffer_len, NULL, NULL, &public_key); - if (0 == sw) { - sw = SWO_SUCCESS; - } - explicit_bzero(&public_key, sizeof(cx_ecfp_384_public_key_t)); - U2BE_ENCODE(G_io_apdu_buffer, 0, sw); - return 2; -} -#endif // HAVE_LEDGER_PKI - -#if !defined(HAVE_BOLOS_NO_DEFAULT_APDU) -// This function is used to process the default APDU commands. -static bolos_bool_t io_process_default_apdus(unsigned char *channel, unsigned short *tx_len) -{ - // Indicates whether a command has been processed and need to send an answer. - bolos_bool_t processed = BOLOS_FALSE; - - // We handle the default apdus when the CLA byte is correct. - if (DEFAULT_APDU_CLA == G_io_apdu_buffer[APDU_OFF_CLA]) { - // We have several possible commands. - switch (G_io_apdu_buffer[APDU_OFF_INS]) { - // get name and version - case DEFAULT_APDU_INS_GET_VERSION: - // P1 and P2 shall be set to '00'. - if (!G_io_apdu_buffer[APDU_OFF_P1] && !G_io_apdu_buffer[APDU_OFF_P2]) { - *tx_len = os_io_seproxyhal_get_app_name_and_version(); - // disable 'return after tx' and 'asynch reply' flags - *channel &= ~IO_FLAGS; - processed = BOLOS_TRUE; - } - break; - - // exit app after replied - case DEFAULT_APDU_INS_APP_EXIT: - // P1 and P2 shall be set to '00'. - if (!G_io_apdu_buffer[APDU_OFF_P1] && !G_io_apdu_buffer[APDU_OFF_P2]) { - *tx_len = 0; - G_io_apdu_buffer[(*tx_len)++] = 0x90; - G_io_apdu_buffer[(*tx_len)++] = 0x00; - // disable 'return after tx' and 'asynch reply' flags - *channel &= ~IO_FLAGS; - // If this APDU has been received from the dashboard, we don't do - // anything except resetting the IO flags. -#if !defined(HAVE_BOLOS) - // We exit the application after having replied. - *channel |= IO_RESET_AFTER_REPLIED; -#endif - processed = BOLOS_TRUE; - } - break; - - // seed cookie - // host: - // device: 9000 | - // 6985 -#if defined(HAVE_SEED_COOKIE) - case DEFAULT_APDU_INS_GET_SEED_COOKIE: - // P1 and P2 shall be set to '00'. - if (!G_io_apdu_buffer[APDU_OFF_P1] && !G_io_apdu_buffer[APDU_OFF_P2]) { - *tx_len = 0; - if (os_global_pin_is_validated() == BOLOS_UX_OK) { - // format - G_io_apdu_buffer[(*tx_len)++] = 0x01; - - _Static_assert(sizeof(G_io_apdu_buffer) - 1 - 1 - 2 >= CX_SHA512_SIZE, - "structure size required 64 bytes"); - bolos_bool_t seed_generated - = os_perso_seed_cookie(G_io_apdu_buffer + 1 + 1); - if (seed_generated == BOLOS_TRUE) { - G_io_apdu_buffer[(*tx_len)++] = CX_SHA512_SIZE; - *tx_len += CX_SHA512_SIZE; - } - else { - G_io_apdu_buffer[(*tx_len)++] = 0; - } - - G_io_apdu_buffer[(*tx_len)++] = 0x90; - G_io_apdu_buffer[(*tx_len)++] = 0x00; - } - else { - G_io_apdu_buffer[(*tx_len)++] = 0x69; - G_io_apdu_buffer[(*tx_len)++] = 0x85; - } - *channel &= ~IO_FLAGS; - processed = BOLOS_TRUE; - } - break; -#endif // HAVE_SEED_COOKIE - -#if defined(DEBUG_OS_STACK_CONSUMPTION) - // OS stack consumption. - case DEFAULT_APDU_INS_STACK_CONSUMPTION: - // Initialization. - *tx_len = 2; - U2BE_ENCODE(G_io_apdu_buffer, 0x00, SWO_APD_HDR_0D); - - // P2 and Lc shall be set to '00'. - if (!G_io_apdu_buffer[APDU_OFF_P2] && !G_io_apdu_buffer[APDU_OFF_LC]) { - int s = os_stack_operations(G_io_apdu_buffer[APDU_OFF_P1]); - if (-1 != s) { - u4be_encode(G_io_apdu_buffer, 0x00, s); - *tx_len = sizeof(int); - G_io_apdu_buffer[(*tx_len)++] = 0x90; - G_io_apdu_buffer[(*tx_len)++] = 0x00; - } - } - *channel &= ~IO_FLAGS; - processed = BOLOS_TRUE; - break; -#endif // DEBUG_OS_STACK_CONSUMPTION - -#if defined(HAVE_LEDGER_PKI) - case DEFAULT_APDU_INS_LOAD_CERTIFICATE: - *tx_len = os_io_seproxyhal_pki_load_certificate(G_io_apdu_buffer + APDU_OFF_LC + 1, - G_io_apdu_buffer[APDU_OFF_LC], - G_io_apdu_buffer[APDU_OFF_P1]); - *channel &= ~IO_FLAGS; - processed = BOLOS_TRUE; - break; -#endif // HAVE_LEDGER_PKI - - default: - // 'processed' is already initialized. - break; - } - } - - return processed; -} - -#endif // HAVE_BOLOS_NO_DEFAULT_APDU - -unsigned short io_exchange(unsigned char channel, unsigned short tx_len) -{ - unsigned short rx_len; - unsigned int timeout_ms; - -#ifdef HAVE_BOLOS_APP_STACK_CANARY - // behavior upon detected stack overflow is to reset the SE - if (app_stack_canary != APP_STACK_CANARY_MAGIC) { - io_seproxyhal_se_reset(); - } -#endif // HAVE_BOLOS_APP_STACK_CANARY - -#ifdef DEBUG_APDU - if ((channel & ~(IO_FLAGS)) == CHANNEL_APDU) { - // ignore tx len - - // already received the data of the apdu when received the whole apdu - if ((channel & (CHANNEL_APDU | IO_RECEIVE_DATA)) == (CHANNEL_APDU | IO_RECEIVE_DATA)) { - // return apdu data - header - return G_io_apdu_length - 5; - } - - // fetch next apdu - if (debug_apdus_offset < sizeof(debug_apdus)) { - G_io_apdu_length = debug_apdus[debug_apdus_offset] & 0xFF; - memcpy(G_io_apdu_buffer, &debug_apdus[debug_apdus_offset + 1], G_io_apdu_length); - debug_apdus_offset += G_io_apdu_length + 1; - return G_io_apdu_length; - } - } -#endif // DEBUG_APDU - -reply_apdu: - switch (channel & ~(IO_FLAGS)) { - case CHANNEL_APDU: - // TODO work up the spi state machine over the HAL proxy until an APDU is available - - if (tx_len && !(channel & IO_ASYNCH_REPLY)) { - // ensure it's our turn to send a command/status, could lag a bit before sending the - // reply - while (io_seproxyhal_spi_is_status_sent()) { - io_seproxyhal_spi_recv( - G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - // process without sending status on tickers etc, to ensure keeping the hand - os_io_seph_recv_and_process(1); - } - - // reinit sending timeout for APDU replied within io_exchange - timeout_ms = G_io_app.ms + IO_RAPDU_TRANSMIT_TIMEOUT_MS; - - // until the whole RAPDU is transmitted, send chunks using the current mode for - // communication - for (;;) { - switch (G_io_app.apdu_state) { - default: - // delegate to the hal in case of not generic transport mode (or asynch) - if (io_exchange_al(channel, tx_len) == 0) { - goto break_send; - } - FALL_THROUGH; - case APDU_IDLE: - LOG("invalid state for APDU reply\n"); - THROW(INVALID_STATE); - break; -#ifdef HAVE_NFC - case APDU_NFC: - if ((tx_len > sizeof(G_io_apdu_buffer)) - || (tx_len > NFC_APDU_MAX_SIZE)) { - THROW(INVALID_PARAMETER); - } - io_nfc_send_response(G_io_apdu_buffer, tx_len); - G_io_app.apdu_state = APDU_IDLE; - G_io_app.apdu_media = IO_APDU_MEDIA_NONE; - goto break_send; -#endif - - case APDU_RAW: - if (tx_len > sizeof(G_io_apdu_buffer)) { - THROW(INVALID_PARAMETER); - } - // reply the RAW APDU over SEPROXYHAL protocol - G_io_seproxyhal_spi_buffer[0] = SEPROXYHAL_TAG_RAPDU; - G_io_seproxyhal_spi_buffer[1] = (tx_len) >> 8; - G_io_seproxyhal_spi_buffer[2] = (tx_len); - io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 3); - io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len); - - // isngle packet reply, mark immediate idle - G_io_app.apdu_state = APDU_IDLE; - // finished, no chunking - goto break_send; - -#ifdef HAVE_USB_APDU - case APDU_USB_HID: - // only send, don't perform synchronous reception of the next command - // (will be done later by the seproxyhal packet processing) - io_usb_hid_send(io_usb_send_apdu_data, tx_len, G_io_apdu_buffer); - goto break_send; -#ifdef HAVE_USB_CLASS_CCID - case APDU_USB_CCID: - io_usb_ccid_reply(G_io_apdu_buffer, tx_len); - goto break_send; -#endif // HAVE_USB_CLASS_CCID -#ifdef HAVE_WEBUSB - case APDU_USB_WEBUSB: - io_usb_hid_send(io_usb_send_apdu_data_ep0x83, tx_len, G_io_apdu_buffer); - goto break_send; -#endif // HAVE_WEBUSB -#endif // HAVE_USB_APDU - -#ifdef HAVE_BLE_APDU // versus U2F BLE - case APDU_BLE: - LEDGER_BLE_send(G_io_apdu_buffer, tx_len); - goto break_send; -#endif // HAVE_BLE_APDU - -#ifdef HAVE_IO_U2F - // case to handle U2F channels. u2f apdu to be dispatched in the upper - // layers - case APDU_U2F: - // prepare reply, the remaining segments will be pumped during USB/BLE - // events handling while waiting for the next APDU - - // the reply has been prepared by the application, stop sending anti - // timeouts - u2f_message_set_autoreply_wait_user_presence(&G_io_u2f, false); - - // continue processing currently received command until completely - // received. - while (!u2f_message_repliable(&G_io_u2f)) { - io_seproxyhal_general_status(); - do { - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, - sizeof(G_io_seproxyhal_spi_buffer), - 0); - // check for reply timeout - if (G_io_app.ms >= timeout_ms) { - THROW(EXCEPTION_IO_RESET); - } - // avoid a general status to be replied - io_seproxyhal_handle_event(); - } while (io_seproxyhal_spi_is_status_sent()); - } -#ifdef U2F_PROXY_MAGIC - - // user presence + counter + rapdu + sw must fit the apdu buffer - if (1U + 4U + tx_len + 2U > sizeof(G_io_apdu_buffer)) { - THROW(INVALID_PARAMETER); - } - - // u2F tunnel needs the status words to be included in the signature - // response BLOB, do it now. always return 9000 in the signature to - // avoid error @ transport level in u2f layers. - G_io_apdu_buffer[tx_len] = 0x90; // G_io_apdu_buffer[tx_len-2]; - G_io_apdu_buffer[tx_len + 1] = 0x00; // G_io_apdu_buffer[tx_len-1]; - tx_len += 2; - memmove(G_io_apdu_buffer + APDU_OFF_DATA, G_io_apdu_buffer, tx_len); - // zeroize user presence and counter - memset(G_io_apdu_buffer, 0, APDU_OFF_DATA); - u2f_message_reply(&G_io_u2f, U2F_CMD_MSG, G_io_apdu_buffer, tx_len + 5); - -#else // U2F_PROXY_MAGIC - u2f_message_reply(&G_io_u2f, U2F_CMD_MSG, G_io_apdu_buffer, tx_len); -#endif // U2F_PROXY_MAGIC - goto break_send; -#endif // HAVE_IO_U2F - } - continue; - - break_send: - - // wait end of reply transmission - // TODO: add timeout here to avoid spending too much time when host has - // disconnected - while (G_io_app.apdu_state != APDU_IDLE) { - io_seproxyhal_general_status(); - do { - io_seproxyhal_spi_recv( - G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - // check for reply timeout (when asynch reply (over hid or u2f for - // example)) this case shall be covered by usb_ep_timeout but is not, - // investigate that - if (G_io_app.ms >= timeout_ms) { - THROW(EXCEPTION_IO_RESET); - } - // avoid a general status to be replied - io_seproxyhal_handle_event(); - } while (io_seproxyhal_spi_is_status_sent()); - } - // reset apdu state - G_io_app.apdu_state = APDU_IDLE; - G_io_app.apdu_media = IO_APDU_MEDIA_NONE; - - G_io_app.apdu_length = 0; - - // continue sending commands, don't issue status yet - if (channel & IO_RETURN_AFTER_TX) { - return 0; - } - // acknowledge the write request (general status OK) and no more command to - // follow (wait until another APDU container is received to continue unwrapping) - io_seproxyhal_general_status(); - break; - } - - // perform reset after io exchange - if (channel & IO_RESET_AFTER_REPLIED) { - // The error cast is retrocompatible with the previous value. - os_sched_exit((bolos_task_status_t) EXCEPTION_IO_RESET); - // reset(); - } - } - - // When IO_CONTINUE_RX is used we don't reset potentially already received APDU. - // Instead we directly process them. - // Use case is: - // - First APDU received (call to io_exchange()) - // - UX waiting for user approval - // - First APDU response sent (call to io_exchange() with flag IO_RETURN_AFTER_TX) - // - UX with transient message like ("Transaction signed") - // This need to loop on os_io_seph_recv_and_process() to process tick and UX - // events, but a second APDU can be received here too. - // - Then a call to io_exchange() with flag IO_CONTINUE_RX will allow processing - // the APDU now that the app is ready. - // - // Note that a received APDU will be cleared out (reset of G_io_app.apdu_state / - // G_io_app.apdu_media / G_io_app.apdu_length) during the APDU response sending. - // Therefore there is no risk to process an APDU twice. - if (!(channel & IO_CONTINUE_RX)) { - if (!(channel & IO_ASYNCH_REPLY)) { - // already received the data of the apdu when received the whole apdu - if ((channel & (CHANNEL_APDU | IO_RECEIVE_DATA)) - == (CHANNEL_APDU | IO_RECEIVE_DATA)) { - // return apdu data - header - return G_io_app.apdu_length - 5; - } - - // reply has ended, proceed to next apdu reception (reset status only after - // asynch reply) - G_io_app.apdu_state = APDU_IDLE; - G_io_app.apdu_media = IO_APDU_MEDIA_NONE; - } - - // reset the received apdu length - G_io_app.apdu_length = 0; - } - - // ensure ready to receive an event (after an apdu processing with asynch flag, it may - // occur if the channel is not correctly managed) - - // until a new whole CAPDU is received - for (;;) { - // An apdu has been received asynchronously. - if (G_io_app.apdu_state != APDU_IDLE && G_io_app.apdu_length > 0) { - // for Bolos UX and apps, answer SWO_SEC_PIN_15 as soon as PIN has been set and - // PIN is not validated - if (os_perso_is_pin_set() == BOLOS_TRUE - && os_global_pin_is_validated() != BOLOS_TRUE) { - tx_len = 0; - G_io_apdu_buffer[(tx_len)++] = (SWO_SEC_PIN_15 >> 8) & 0xFF; - G_io_apdu_buffer[(tx_len)++] = (SWO_SEC_PIN_15) &0xFF; - channel &= ~IO_FLAGS; - goto reply_apdu; - } -#if !defined(HAVE_BOLOS_NO_DEFAULT_APDU) - // If a default command is received and processed within this call, - // then we send the answer. - if (io_process_default_apdus(&channel, &tx_len) == BOLOS_TRUE) { - goto reply_apdu; - } -#endif // ! HAVE_BOLOS_NO_DEFAULT_APDU - - return G_io_app.apdu_length; - } - - io_seproxyhal_general_status(); - // wait until a SPI packet is available - // NOTE: on ST31, dual wait ISO & RF (ISO instead of SPI) - rx_len = io_seproxyhal_spi_recv( - G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - - // can't process split TLV, continue - if (rx_len < 3 - || rx_len - != U2(G_io_seproxyhal_spi_buffer[1], G_io_seproxyhal_spi_buffer[2]) - + 3U) { - LOG("invalid TLV format\n"); - G_io_app.apdu_state = APDU_IDLE; - G_io_app.apdu_length = 0; - continue; - } - - io_seproxyhal_handle_event(); - } - break; - - default: - return io_exchange_al(channel, tx_len); - } -} - -unsigned int os_io_seph_recv_and_process(unsigned int dont_process_ux_events) -{ - // send general status before receiving next event - io_seproxyhal_general_status(); - - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - - switch (G_io_seproxyhal_spi_buffer[0]) { - case SEPROXYHAL_TAG_FINGER_EVENT: - case SEPROXYHAL_TAG_BUTTON_PUSH_EVENT: - case SEPROXYHAL_TAG_TICKER_EVENT: - case SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT: - case SEPROXYHAL_TAG_STATUS_EVENT: - // perform UX event on these ones, don't process as an IO event - if (dont_process_ux_events) { - return 0; - } - FALL_THROUGH; - - default: - // if malformed, then a stall is likely to occur - if (io_seproxyhal_handle_event()) { - return 1; - } - } - return 0; -} - -#if !defined(APP_UX) -unsigned int os_ux_blocking(bolos_ux_params_t *params) -{ - unsigned int ret; - - // until a real status is returned - os_ux(params); - ret = os_sched_last_status(TASK_BOLOS_UX); - while (ret == BOLOS_UX_IGNORE || ret == BOLOS_UX_CONTINUE) { - // if the IO task is not running, then need to pump events manually - if (os_sched_is_running(TASK_SUBTASKS_START) != BOLOS_TRUE) { - // send general status before receiving next event - io_seproxyhal_general_status(); - io_seproxyhal_spi_recv( - G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - io_event(0); - } - else { - // wait until UX takes some process time and update it's status - os_sched_yield(BOLOS_UX_OK); - } - // only retrieve the current UX state - ret = os_sched_last_status(TASK_BOLOS_UX); - } - - return ret; -} -#endif // !defined(APP_UX) - -#ifdef HAVE_PRINTF -void mcu_usb_prints(const char *str, unsigned int charcount) -{ - unsigned char buf[4]; -#ifdef TARGET_NANOS - buf[0] = SEPROXYHAL_TAG_PRINTF_STATUS; -#else - buf[0] = SEPROXYHAL_TAG_PRINTF; -#endif - buf[1] = charcount >> 8; - buf[2] = charcount; - io_seproxyhal_spi_send(buf, 3); - io_seproxyhal_spi_send((const uint8_t *) str, charcount); -} -#endif // HAVE_PRINTF - -void io_seproxyhal_io_heartbeat(void) -{ - io_seproxyhal_general_status(); - do { - io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); - // avoid a general status to be replied - if (G_io_seproxyhal_spi_buffer[0] != SEPROXYHAL_TAG_TICKER_EVENT) { - io_seproxyhal_handle_event(); - } - } while (io_seproxyhal_spi_is_status_sent()); -} -#endif // OS_IO_SEPROXYHAL diff --git a/src/os_io_task.c b/src/os_io_task.c deleted file mode 100644 index 8cb4538b5..000000000 --- a/src/os_io_task.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "app_config.h" -#include "decorators.h" -#include "exceptions.h" -#include "os_io_seproxyhal.h" -#include "os_task.h" -#include "os_types.h" -#include "os_io_nfc.h" - -#include - -#ifdef HAVE_BLE -#include "ledger_ble.h" -bolos_ux_asynch_callback_t G_io_asynch_ux_callback; -#endif // HAVE_BLE - -#ifdef HAVE_BOLOS -#ifdef HAVE_BLE -#if (IO_SEPROXYHAL_BUFFER_SIZE_B < 192) \ - && (defined(BOLOS_RELEASE) || !defined(DEBUG_VARIABLE_SPI_SIZE)) -#error IO_SEPROXYHAL_BUFFER_SIZE_B size is invalid -#endif // (IO_SEPROXYHAL_BUFFER_SIZE_B < 192) && (defined(BOLOS_RELEASE) || - // !defined(DEBUG_VARIABLE_SPI_SIZE)) -#else // !HAVE_BLE -#if (IO_SEPROXYHAL_BUFFER_SIZE_B != 128) \ - && (defined(BOLOS_RELEASE) || !defined(DEBUG_VARIABLE_SPI_SIZE)) -#error IO_SEPROXYHAL_BUFFER_SIZE_B size is invalid -#endif // (IO_SEPROXYHAL_BUFFER_SIZE_B != 128) && (defined(BOLOS_RELEASE) || - // !defined(DEBUG_VARIABLE_SPI_SIZE)) -#endif // !HAVE_BLE - -#ifdef HAVE_NFC_READER -// For some reason the linker only works correctly -// if the struct declaration is in this file -struct nfc_reader_context G_io_reader_ctx; -#endif - -// Buffer dedicated to the MCU <-> SE data transfer. -unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; -io_seph_app_t G_io_app; -#endif // HAVE_BOLOS - -#ifdef HAVE_IO_TASK -void io_start(void) -{ -#else // HAVE_IO_TASK -void bolos_init_ios(void) -{ -#endif // HAVE_IO_TASK - -#ifdef OS_IO_SEPROXYHAL - io_seproxyhal_init(); -#endif - -#ifdef HAVE_IO_USB - USB_power(0); -#endif - -#ifdef HAVE_BLE - memset(&G_io_asynch_ux_callback, 0, sizeof(G_io_asynch_ux_callback)); - LEDGER_BLE_init(); -#endif // HAVE_BLE - -#ifdef OS_IO_SEPROXYHAL - io_seproxyhal_init(); -#endif - -#ifdef HAVE_IO_USB - USB_power(1); -#endif -} - -#ifdef HAVE_IO_TASK -void io_process(void) -{ - for (;;) { - if (!(G_io_app.io_flags & IO_FINISHED)) { - G_io_app.apdu_length - = io_exchange(CHANNEL_APDU | G_io_app.io_flags, G_io_app.apdu_length); - // mark IO as ended - G_io_app.io_flags |= IO_FINISHED; - } - else { - // pump packets (process all through handle_events) - os_io_seph_recv_and_process(0); - } - // we have finished our call, notify the other tasks - os_sched_yield(BOLOS_TRUE); - } -} - -void io_task(void) -{ - for (;;) { - BEGIN_TRY - { - TRY - { - io_start(); - io_process(); - } - CATCH_ALL - { - // any error leading here is triggering an IO stack reset - os_sched_yield(EXCEPTION_IO_RESET); - } - FINALLY {} - } - END_TRY; - } -} -#endif // HAVE_IO_TASK diff --git a/src/os_io_usb.c b/src/os_io_usb.c deleted file mode 100644 index 5af0ee509..000000000 --- a/src/os_io_usb.c +++ /dev/null @@ -1,312 +0,0 @@ - -/******************************************************************************* - * Ledger Nano S - Secure firmware - * (c) 2022 Ledger - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ********************************************************************************/ - -#include "os_io_usb.h" -#include "os_utils.h" -#include "lcx_rng.h" -#include - -#ifdef HAVE_USB_APDU - -// usb endpoint buffer -unsigned char G_io_usb_ep_buffer[MAX(USB_SEGMENT_SIZE, BLE_SEGMENT_SIZE)]; - -uint16_t io_seproxyhal_get_ep_rx_size(uint8_t epnum) -{ - if ((epnum & 0x7F) < IO_USB_MAX_ENDPOINTS) { - return G_io_app.usb_ep_xfer_len[epnum & 0x7F]; - } - return 0; -} - -#ifndef IO_RAPDU_TRANSMIT_TIMEOUT_MS -#define IO_RAPDU_TRANSMIT_TIMEOUT_MS 2000UL -#endif // IO_RAPDU_TRANSMIT_TIMEOUT_MS - -// TODO, refactor this using the USB DataIn event like for the U2F tunnel -// TODO add a blocking parameter, for HID KBD sending, or use a USB busy flag per channel to know if -// the transfer has been processed or not. and move on to the next transfer on the same endpoint -void io_usb_send_ep(unsigned int ep, - unsigned char *buffer, - unsigned short length, - __attribute__((unused)) unsigned int timeout) -{ - // won't send if overflowing seproxyhal buffer format - if (length > 255) { - return; - } - - uint8_t buf[6]; - buf[0] = SEPROXYHAL_TAG_USB_EP_PREPARE; - buf[1] = (3 + length) >> 8; - buf[2] = (3 + length); - buf[3] = ep | 0x80; - buf[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN; - buf[5] = length; - io_seproxyhal_spi_send(buf, 6); - io_seproxyhal_spi_send(buffer, length); - // setup timeout of the endpoint - G_io_app.usb_ep_timeouts[ep & 0x7F].timeout = IO_RAPDU_TRANSMIT_TIMEOUT_MS; -} - -void io_usb_send_apdu_data(unsigned char *buffer, unsigned short length) -{ - // wait for 20 events before hanging up and timeout (~2 seconds of timeout) - io_usb_send_ep(0x82, buffer, length, 20); -} - -/** - * Ledger Protocol - * HID Report Content - * [______________________________] - * CCCC TT VVVV.........VV FILL.. - * - * All fields are big endian encoded. - * CCCC: 2 bytes channel identifier (when multi application are processing). - * TT: 1 byte content tag - * VVVV..VV: variable length content - * FILL..: 00's to fillup the HID report length - * - * LL is at most the length of the HID Report. - * - * Command/Response APDU are split in chunks. - * - * Filler only allowed at the end of the last hid report of a apdu chain in each direction. - * - * APDU are using either standard or extended header. up to the application to check the total - * received length and the lc field - * - * Tags: - * Direction:Host>Token T:0x00 V:no Get protocol version big endian encoded. Replied with a - * protocol-version. Channel identifier is ignored for this command. Direction:Token>Host T:0x00 - * V:yes protocol-version-4-bytes-big-endian. Channel identifier is ignored for this reply. - * Direction:Host>Token T:0x01 V:no Allocate channel. Replied with a channel identifier. Channel - * identifier is ignored for this command. Direction:Token>Host T:0x01 V:yes - * channel-identifier-2-bytes. Channel identifier is ignored for this reply. Direction:* T:0x02 V:no - * Ping. replied with a ping. Channel identifier is ignored for this command. NOTSUPPORTED - * Direction:* T:0x03 V:no Abort. replied with an abort if accepted, else not replied. - * Direction:* T:0x05 V= APDU - * (command/response) packet. - */ - -volatile unsigned int G_io_usb_hid_total_length; -volatile unsigned int G_io_usb_hid_channel; -volatile unsigned int G_io_usb_hid_remaining_length; -volatile unsigned int G_io_usb_hid_sequence_number; -static uint8_t *G_io_usb_hid_current_buffer; - -io_usb_hid_receive_status_t io_usb_hid_receive(io_send_t sndfct, - unsigned char *buffer, - unsigned short l, - apdu_buffer_t *apdu_buffer) -{ - uint8_t *apdu_buf; - uint16_t apdu_buf_len; -#ifndef HAVE_LOCAL_APDU_BUFFER - if (apdu_buffer == NULL) { - apdu_buf = G_io_apdu_buffer; - apdu_buf_len = sizeof(G_io_apdu_buffer); - } - else -#endif // HAVE_LOCAL_APDU_BUFFER - { - apdu_buf = apdu_buffer->buf; - apdu_buf_len = apdu_buffer->len; - } - - // avoid over/under flows - if (buffer != G_io_usb_ep_buffer) { - memset(G_io_usb_ep_buffer, 0, sizeof(G_io_usb_ep_buffer)); - memmove(G_io_usb_ep_buffer, buffer, MIN(l, sizeof(G_io_usb_ep_buffer))); - } - - // process the chunk content - switch (G_io_usb_ep_buffer[2]) { - case 0x05: - // ensure sequence idx is 0 for the first chunk ! - if ((unsigned int) U2BE(G_io_usb_ep_buffer, 3) - != (unsigned int) G_io_usb_hid_sequence_number) { - // ignore packet - goto apdu_reset; - } - // cid, tag, seq - l -= 2 + 1 + 2; - - // append the received chunk to the current command apdu - if (G_io_usb_hid_sequence_number == 0) { - /// This is the apdu first chunk - // total apdu size to receive - G_io_usb_hid_total_length - = U2BE(G_io_usb_ep_buffer, - 5); //(G_io_usb_ep_buffer[5]<<8)+(G_io_usb_ep_buffer[6]&0xFF); - // check for invalid length encoding (more data in chunk that announced in the total - // apdu) - if (G_io_usb_hid_total_length > (uint32_t) apdu_buf_len) { - goto apdu_reset; - } - // seq and total length - l -= 2; - // compute remaining size to receive - G_io_usb_hid_remaining_length = G_io_usb_hid_total_length; - G_io_usb_hid_current_buffer = apdu_buf; - - // retain the channel id to use for the reply - G_io_usb_hid_channel = U2BE(G_io_usb_ep_buffer, 0); - - if (l > G_io_usb_hid_remaining_length) { - l = G_io_usb_hid_remaining_length; - } - - if (l > sizeof(G_io_usb_ep_buffer) - 7) { - l = sizeof(G_io_usb_ep_buffer) - 7; - } - - // copy data - memmove((void *) G_io_usb_hid_current_buffer, G_io_usb_ep_buffer + 7, l); - } - else { - // check for invalid length encoding (more data in chunk that announced in the total - // apdu) - if (l > G_io_usb_hid_remaining_length) { - l = G_io_usb_hid_remaining_length; - } - - if (l > sizeof(G_io_usb_ep_buffer) - 5) { - l = sizeof(G_io_usb_ep_buffer) - 5; - } - - /// This is a following chunk - // append content - memmove((void *) G_io_usb_hid_current_buffer, G_io_usb_ep_buffer + 5, l); - } - // factorize (f) - G_io_usb_hid_current_buffer += l; - G_io_usb_hid_remaining_length -= l; - G_io_usb_hid_sequence_number++; - break; - - case 0x00: // get version ID - // do not reset the current apdu reception if any - memset(G_io_usb_ep_buffer + 3, 0, 4); // PROTOCOL VERSION is 0 - // send the response - sndfct(G_io_usb_ep_buffer, IO_HID_EP_LENGTH); - // await for the next chunk - goto apdu_reset; - - case 0x01: // ALLOCATE CHANNEL - // do not reset the current apdu reception if any - cx_rng_no_throw(G_io_usb_ep_buffer + 3, 4); - // send the response - sndfct(G_io_usb_ep_buffer, IO_HID_EP_LENGTH); - // await for the next chunk - goto apdu_reset; - - case 0x02: // ECHO|PING - // do not reset the current apdu reception if any - // send the response - sndfct(G_io_usb_ep_buffer, IO_HID_EP_LENGTH); - // await for the next chunk - goto apdu_reset; - } - - // if more data to be received, notify it - if (G_io_usb_hid_remaining_length) { - return IO_USB_APDU_MORE_DATA; - } - - // reset sequence number for next exchange - io_usb_hid_init(); - return IO_USB_APDU_RECEIVED; - -apdu_reset: - io_usb_hid_init(); - return IO_USB_APDU_RESET; -} - -void io_usb_hid_init(void) -{ - G_io_usb_hid_sequence_number = 0; - G_io_usb_hid_remaining_length = 0; - G_io_usb_hid_current_buffer = NULL; -} - -/** - * sent the next io_usb_hid transport chunk (rx on the host, tx on the device) - */ -void io_usb_hid_sent(io_send_t sndfct) -{ - unsigned int l; - - // only prepare next chunk if some data to be sent remain - if (G_io_usb_hid_remaining_length && G_io_usb_hid_current_buffer) { - // fill the chunk - memset(G_io_usb_ep_buffer, 0, sizeof(G_io_usb_ep_buffer)); - - // keep the channel identifier - G_io_usb_ep_buffer[0] = (G_io_usb_hid_channel >> 8) & 0xFF; - G_io_usb_ep_buffer[1] = G_io_usb_hid_channel & 0xFF; - G_io_usb_ep_buffer[2] = 0x05; - G_io_usb_ep_buffer[3] = G_io_usb_hid_sequence_number >> 8; - G_io_usb_ep_buffer[4] = G_io_usb_hid_sequence_number; - - if (G_io_usb_hid_sequence_number == 0) { - l = ((G_io_usb_hid_remaining_length > IO_HID_EP_LENGTH - 7) - ? IO_HID_EP_LENGTH - 7 - : G_io_usb_hid_remaining_length); - G_io_usb_ep_buffer[5] = G_io_usb_hid_remaining_length >> 8; - G_io_usb_ep_buffer[6] = G_io_usb_hid_remaining_length; - memmove(G_io_usb_ep_buffer + 7, (const void *) G_io_usb_hid_current_buffer, l); - G_io_usb_hid_current_buffer += l; - G_io_usb_hid_remaining_length -= l; - } - else { - l = ((G_io_usb_hid_remaining_length > IO_HID_EP_LENGTH - 5) - ? IO_HID_EP_LENGTH - 5 - : G_io_usb_hid_remaining_length); - memmove(G_io_usb_ep_buffer + 5, (const void *) G_io_usb_hid_current_buffer, l); - G_io_usb_hid_current_buffer += l; - G_io_usb_hid_remaining_length -= l; - } - // prepare next chunk numbering - G_io_usb_hid_sequence_number++; - // send the chunk - // always padded (USB HID transport) :) - sndfct(G_io_usb_ep_buffer, sizeof(G_io_usb_ep_buffer)); - } - // cleanup when everything has been sent (ack for the last sent usb in packet) - else { - io_usb_hid_init(); - - // we sent the whole response - G_io_app.apdu_state = APDU_IDLE; - } -} - -void io_usb_hid_send(io_send_t sndfct, unsigned short sndlength, unsigned char *apdu_buffer) -{ - // perform send - if (sndlength) { - G_io_usb_hid_sequence_number = 0; - G_io_usb_hid_current_buffer = apdu_buffer; - G_io_usb_hid_remaining_length = sndlength; - G_io_usb_hid_total_length = sndlength; - io_usb_hid_sent(sndfct); - } -} - -#endif // HAVE_USB_APDU diff --git a/src/os_printf.c b/src/os_printf.c index 9e4c85471..c7f13cdb7 100644 --- a/src/os_printf.c +++ b/src/os_printf.c @@ -67,7 +67,7 @@ static const char g_pcHex_cap[] = { #endif // defined(HAVE_PRINTF) || defined(HAVE_SPRINTF) #ifdef HAVE_PRINTF -#include "os_io_seproxyhal.h" +#include "os_io_seph_cmd.h" void screen_printf(const char *format, ...) __attribute__((weak, alias("mcu_usb_printf"))); @@ -103,7 +103,7 @@ void mcu_usb_printf(const char *format, ...) // // Write this portion of the string. // - mcu_usb_prints(format, ulIdx); + os_io_seph_cmd_printf(format, ulIdx); // // Skip the portion of the string that was written. @@ -186,7 +186,7 @@ void mcu_usb_printf(const char *format, ...) // // Print out the character. // - mcu_usb_prints((char *) &ulValue, 1); + os_io_seph_cmd_printf((char *) &ulValue, 1); // // This command has been handled. @@ -321,7 +321,7 @@ void mcu_usb_printf(const char *format, ...) if (pcStr[0] == '\0') { // pad with ulStrlen white spaces do { - mcu_usb_prints(" ", 1); + os_io_seph_cmd_printf(" ", 1); } while (ulStrlen-- > 0); goto s_pad; @@ -338,7 +338,7 @@ void mcu_usb_printf(const char *format, ...) // switch (ulBase) { default: - mcu_usb_prints(pcStr, ulIdx); + os_io_seph_cmd_printf(pcStr, ulIdx); break; case 16: { unsigned char nibble1, nibble2; @@ -357,12 +357,12 @@ void mcu_usb_printf(const char *format, ...) break; } if (idx + 1 >= sizeof(pcBuf)) { - mcu_usb_prints(pcBuf, idx); + os_io_seph_cmd_printf(pcBuf, idx); idx = 0; } } if (idx != 0) { - mcu_usb_prints(pcBuf, idx); + os_io_seph_cmd_printf(pcBuf, idx); } break; } @@ -375,7 +375,7 @@ void mcu_usb_printf(const char *format, ...) if (ulCount > ulIdx) { ulCount -= ulIdx; while (ulCount--) { - mcu_usb_prints(" ", 1); + os_io_seph_cmd_printf(" ", 1); } } // @@ -518,7 +518,7 @@ void mcu_usb_printf(const char *format, ...) // // Write the string. // - mcu_usb_prints(pcBuf, ulPos); + os_io_seph_cmd_printf(pcBuf, ulPos); // // This command has been handled. @@ -533,7 +533,7 @@ void mcu_usb_printf(const char *format, ...) // // Simply write a single %. // - mcu_usb_prints(format - 1, 1); + os_io_seph_cmd_printf(format - 1, 1); // // This command has been handled. @@ -549,7 +549,7 @@ void mcu_usb_printf(const char *format, ...) // // Indicate an error. // - mcu_usb_prints("ERROR", 5); + os_io_seph_cmd_printf("ERROR", 5); // // This command has been handled. diff --git a/src/syscalls.c b/src/syscalls.c index 34efba01c..7b15d7faa 100644 --- a/src/syscalls.c +++ b/src/syscalls.c @@ -16,8 +16,9 @@ #include "os_memory.h" #include "os_registry.h" #include "os_ux.h" -#ifdef HAVE_SE_TOUCH #include "os_io.h" +#ifdef HAVE_SE_TOUCH +#include "os_io_seph_ux.h" #endif // HAVE_SE_TOUCH #include "ox_ec.h" #include "ox_bn.h" @@ -1275,10 +1276,10 @@ void os_perso_set_words(const unsigned char *words, unsigned int length) return; } -void os_perso_finalize(void) +void os_perso_finalize(uint8_t disable_io) { unsigned int parameters[2]; - parameters[1] = 0; + parameters[0] = disable_io; SVC_Call(SYSCALL_os_perso_finalize_ID, parameters); return; } @@ -1807,29 +1808,73 @@ void os_sched_kill(unsigned int taskidx) return; } -void io_seph_send(const unsigned char *buffer, unsigned short length) +int os_io_seph_tx(const unsigned char *buffer, unsigned short length, unsigned int *timeout_ms) { - unsigned int parameters[2]; + unsigned int parameters[3]; parameters[0] = (unsigned int) buffer; parameters[1] = (unsigned int) length; - SVC_Call(SYSCALL_io_seph_send_ID, parameters); - return; + parameters[2] = (unsigned int) timeout_ms; + return (int) SVC_Call(SYSCALL_os_io_seph_tx_ID, parameters); +} + +int os_io_seph_se_rx_event(unsigned char *buffer, + unsigned short max_length, + unsigned int *timeout_ms, + bool check_se_event, + unsigned int flags) +{ + unsigned int parameters[5]; + parameters[0] = (unsigned int) buffer; + parameters[1] = (unsigned int) max_length; + parameters[2] = (unsigned int) timeout_ms; + parameters[3] = (unsigned int) check_se_event; + parameters[4] = (unsigned int) flags; + return (int) SVC_Call(SYSCALL_os_io_seph_se_rx_event_ID, parameters); +} + +__attribute((weak)) int os_io_init(os_io_init_t *init) +{ + unsigned int parameters[1]; + parameters[0] = (unsigned int) init; + return (int) SVC_Call(SYSCALL_os_io_init_ID, parameters); } -unsigned int io_seph_is_status_sent(void) +__attribute((weak)) int os_io_start(void) { unsigned int parameters[2]; parameters[1] = 0; - return (unsigned int) SVC_Call(SYSCALL_io_seph_is_status_sent_ID, parameters); + return (int) SVC_Call(SYSCALL_os_io_start_ID, parameters); } -unsigned short io_seph_recv(unsigned char *buffer, unsigned short maxlength, unsigned int flags) +__attribute((weak)) int os_io_stop(void) +{ + unsigned int parameters[2]; + parameters[1] = 0; + return (int) SVC_Call(SYSCALL_os_io_stop_ID, parameters); +} + +__attribute((weak)) int os_io_tx_cmd(unsigned char type, + const unsigned char *buffer, + unsigned short length, + unsigned int *timeout_ms) +{ + unsigned int parameters[4]; + parameters[0] = (unsigned int) type; + parameters[1] = (unsigned int) buffer; + parameters[2] = (unsigned int) length; + parameters[3] = (unsigned int) timeout_ms; + return (int) SVC_Call(SYSCALL_os_io_tx_cmd_ID, parameters); +} + +__attribute((weak)) int os_io_rx_evt(unsigned char *buffer, + unsigned short buffer_max_length, + unsigned int *timeout_ms) { unsigned int parameters[3]; parameters[0] = (unsigned int) buffer; - parameters[1] = (unsigned int) maxlength; - parameters[2] = (unsigned int) flags; - return (unsigned short) SVC_Call(SYSCALL_io_seph_recv_ID, parameters); + parameters[1] = (unsigned int) buffer_max_length; + parameters[2] = (unsigned int) timeout_ms; + return (int) SVC_Call(SYSCALL_os_io_rx_evt_ID, parameters); } void nvm_write_page(unsigned int page_adr, bool force) @@ -2036,7 +2081,7 @@ void bagl_hal_draw_rect(unsigned int color, int x, int y, unsigned int width, un SVC_Call(SYSCALL_bagl_hal_draw_rect_ID, parameters); return; } -#endif +#endif // HAVE_SE_SCREEN #ifdef HAVE_BLE void os_ux_set_status(unsigned int ux_id, unsigned int status) @@ -2115,9 +2160,9 @@ uint8_t touch_exclude_borders(uint8_t excluded_borders) } #ifdef HAVE_TOUCH_READ_DEBUG_DATA_SYSCALL -uint8_t touch_switch_debug_mode_and_read(io_touch_debug_mode_t mode, - uint8_t buffer_type, - uint8_t *read_buffer) +uint8_t touch_switch_debug_mode_and_read(os_io_touch_debug_mode_t mode, + uint8_t buffer_type, + uint8_t *read_buffer) { unsigned int parameters[3]; parameters[0] = (unsigned int) mode; @@ -2129,57 +2174,6 @@ uint8_t touch_switch_debug_mode_and_read(io_touch_debug_mode_t mode, #endif // HAVE_SE_TOUCH -#ifdef HAVE_IO_I2C -void io_i2c_setmode(unsigned int speed_and_master, unsigned int address) -{ - unsigned int parameters[2]; - parameters[0] = (unsigned int) speed_and_master; - parameters[1] = (unsigned int) address; - SVC_Call(SYSCALL_io_i2c_setmode_ID, parameters); - return; -} - -void io_i2c_prepare(unsigned int maxlength) -{ - unsigned int parameters[2]; - parameters[0] = (unsigned int) maxlength; - parameters[1] = 0; - SVC_Call(SYSCALL_io_i2c_prepare_ID, parameters); - return; -} - -void io_i2c_xfer(void *buffer, unsigned int length, unsigned int flags) -{ - unsigned int parameters[3]; - parameters[0] = (unsigned int) buffer; - parameters[1] = (unsigned int) length; - parameters[2] = (unsigned int) flags; - SVC_Call(SYSCALL_io_i2c_xfer_ID, parameters); - return; -} - -#ifndef BOLOS_RELEASE -#ifdef BOLOS_DEBUG -void io_i2c_dumpstate(void) -{ - unsigned int parameters[2]; - parameters[1] = 0; - SVC_Call(SYSCALL_io_i2c_dumpstate_ID, parameters); - return; -} - -void io_debug(char *chars, unsigned int len) -{ - unsigned int parameters[2]; - parameters[0] = (unsigned int) chars; - parameters[1] = (unsigned int) len; - SVC_Call(SYSCALL_io_debug_ID, parameters); - return; -} -#endif // BOLOS_DEBUG -#endif // BOLOS_RELEASE -#endif // HAVE_IO_I2C - #ifdef DEBUG_OS_STACK_CONSUMPTION int os_stack_operations(unsigned char mode) { diff --git a/target/flex/script.ld b/target/flex/script.ld index 100201cb5..9e6b33cc9 100644 --- a/target/flex/script.ld +++ b/target/flex/script.ld @@ -26,7 +26,7 @@ MEMORY FLASH (rx) : ORIGIN = 0xc0de0000, LENGTH = 400K DATA (r) : ORIGIN = 0xc0de0000, LENGTH = 400K - SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 40K + SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 36K } PAGE_SIZE = 512; diff --git a/target/nanos2/script.ld b/target/nanos2/script.ld index 94b0b2e18..5c295e440 100644 --- a/target/nanos2/script.ld +++ b/target/nanos2/script.ld @@ -26,7 +26,7 @@ MEMORY FLASH (rx) : ORIGIN = 0xc0de0000, LENGTH = 400K DATA (r) : ORIGIN = 0xc0de0000, LENGTH = 400K - SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 44K + SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 40K } PAGE_SIZE = 512; diff --git a/target/nanox/script.ld b/target/nanox/script.ld index cfca329f1..c402f3cdb 100644 --- a/target/nanox/script.ld +++ b/target/nanox/script.ld @@ -26,7 +26,7 @@ MEMORY FLASH (rx) : ORIGIN = 0xc0de0000, LENGTH = 400K DATA (r) : ORIGIN = 0xc0de0000, LENGTH = 400K - SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 28K + SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 24K } PAGE_SIZE = 256; diff --git a/target/stax/script.ld b/target/stax/script.ld index 100201cb5..9e6b33cc9 100644 --- a/target/stax/script.ld +++ b/target/stax/script.ld @@ -26,7 +26,7 @@ MEMORY FLASH (rx) : ORIGIN = 0xc0de0000, LENGTH = 400K DATA (r) : ORIGIN = 0xc0de0000, LENGTH = 400K - SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 40K + SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 36K } PAGE_SIZE = 512; diff --git a/unit-tests/lib_nbgl/CMakeLists.txt b/unit-tests/lib_nbgl/CMakeLists.txt index 815bc2a08..d5c7f3b80 100644 --- a/unit-tests/lib_nbgl/CMakeLists.txt +++ b/unit-tests/lib_nbgl/CMakeLists.txt @@ -64,6 +64,7 @@ include_directories(../../include) include_directories(../../lib_nbgl/include) include_directories(../../lib_nbgl/include/fonts) include_directories(../../lib_ux_nbgl) +include_directories(../../io/include) add_executable(test_nbgl_fonts test_nbgl_fonts.c) add_executable(test_nbgl_obj_pool test_nbgl_obj_pool.c) diff --git a/unit-tests/lib_ux_sync/CMakeLists.txt b/unit-tests/lib_ux_sync/CMakeLists.txt index 579dd4507..9d45d0ca0 100644 --- a/unit-tests/lib_ux_sync/CMakeLists.txt +++ b/unit-tests/lib_ux_sync/CMakeLists.txt @@ -47,6 +47,7 @@ include_directories(../../lib_nbgl/include) include_directories(../../lib_nbgl/include/fonts) include_directories(../../lib_ux_nbgl) include_directories(../../lib_ux_sync/include) +include_directories(../../io/include) add_executable(test_ux_sync test_ux_sync.c) diff --git a/unit-tests/lib_ux_sync/glyphs.h b/unit-tests/lib_ux_sync/glyphs.h new file mode 100644 index 000000000..62f64b29e --- /dev/null +++ b/unit-tests/lib_ux_sync/glyphs.h @@ -0,0 +1,35 @@ +// This file is just a stub necessary to build nbgl_obj.c for Stax +#pragma once + +#ifndef GLYPH_radio_active_32px_BPP +#define GLYPH_radio_active_32px_WIDTH 32 +#define GLYPH_radio_active_32px_HEIGHT 32 +#define GLYPH_radio_active_32px_ISFILE true +#define GLYPH_radio_active_32px_BPP 1 +extern uint8_t const C_radio_active_32px_bitmap[82]; +#ifdef HAVE_NBGL +extern const nbgl_icon_details_t C_radio_active_32px; +#endif // HAVE_NBGL +#endif // GLYPH_radio_active_32px_BPP + +#ifndef GLYPH_radio_inactive_32px_BPP +#define GLYPH_radio_inactive_32px_WIDTH 32 +#define GLYPH_radio_inactive_32px_HEIGHT 32 +#define GLYPH_radio_inactive_32px_ISFILE true +#define GLYPH_radio_inactive_32px_BPP 1 +extern uint8_t const C_radio_inactive_32px_bitmap[82]; +#ifdef HAVE_NBGL +extern const nbgl_icon_details_t C_radio_inactive_32px; +#endif // HAVE_NBGL +#endif // GLYPH_radio_inactive_32px_BPP + +#ifndef GLYPH_switch_60_40_BPP +#define GLYPH_switch_60_40_WIDTH 60 +#define GLYPH_switch_60_40_HEIGHT 40 +#define GLYPH_switch_60_40_ISFILE false +#define GLYPH_switch_60_40_BPP 1 +extern uint8_t const C_switch_60_40_bitmap[300]; +#ifdef HAVE_NBGL +extern const nbgl_icon_details_t C_switch_60_40; +#endif // HAVE_NBGL +#endif // GLYPH_switch_60_40_BPP