Unverified Commit 71b620ed authored by Ken A. Redergård's avatar Ken A. Redergård Committed by GitHub
Browse files

Fix GH issue #112 Writing more than 20 bytes to peripheral crashes driver (#126)

When writing more than 20 bytes to a connected peripheral the connectivity firmware crash.
The issue is in the serialization codecs and is fixed in nRF5 SDK version 15 (SDKv15).

The fix requires the codecs for the connectivity firmware (connfw) to be updated.
To make this maintainable we align connfw for SoftDevice API v3 and v5 on SDKv15.
The build scripts and patch files are changed to make this happen.

The codecs on PC side is updated with codecs from SDKv15 since the codecs need to match the ones in connfw.

A test is implemented to verify that the issue is resolved.

Issues related to initialization of the H5Transport class and handling of unknown packets and state was discovered during fixing this issue.
This commit address these issues and reported linting issues in files affected.
parent f0542c4e
......@@ -162,7 +162,11 @@ function sdk_download () {
fi
echo "> Unzipping SDK..."
unzip -q $DL_LOCATION/$SDK_FILE -d $DL_LOCATION/$SDK_NAME
# Disable globbing of files/directories we do not want to extract from the ZIP file
set -f
ZIP_EXCLUDE_LIST="**/*.msi **/external/cifra_AES128-EAX/** **/external/cJSON/** **/external/fatfs/** **/external/fnmatch/** **/external/freertos/** **/external/infineon/** **/external/licenses_external.txt** **/external/lwip/** **/external/mbedtls/** **/external/micro-ecc/** **/external/nano/** **/external/nano-pb/** **/external/nfc_adafruit_library/** **/external/nrf_cc310/** **/external/nrf_cc310_bl/** **/external/nrf_oberon/** **/external/nrf_tls/** **/external/protothreads/** **/external/thedotfactory_fonts/** **/components/802_15_4/** **/components/ant/** **/components/drivers_ext/** **/components/iot/** **/components/nfc/** **/components/proprietary_rf/** **/components/softdevice/s112/** **/components/softdevice/s140/** **/components/softdevice/s212/** **/examples/802_15_4/** **/examples/ant/** **/examples/ble_** **/examples/usb_** **/examples/iot/** **/examples/peripheral/** **/examples/proprietary_rf/** **/examples/dfu/** **/examples/crypto/** **/examples/nfc/** **/examples/dtm/** **/examples/multiprotocol/** **/examples/connectivity/experimental_ant/** **/examples/connectivity/ble_connectivity/**/ser_s*_spi*/** **/examples/connectivity/ble_connectivity/**/ser_s*_uart/** **/examples/connectivity/ble_connectivity/pca10040e/** **/documentation/**"
unzip -n -q $DL_LOCATION/$SDK_FILE -d $DL_LOCATION -x $ZIP_EXCLUDE_LIST
set +f
err_code=$?
if [ "$err_code" != "0" ]; then
......
#!/bin/bash
#
# Download an patch the nRF5 SDK to compile the connectivity application.
# Use the nRF5 SDK 12.1 and the SoftDevice API version 3.
# Download and patch the nRF5 SDK to compile the connectivity application.
# Use the nRF5 SDK 15 and the SoftDevice API version 5.
ABS_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source $ABS_PATH/../bootstrap.sh \
-l 'https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v14.x.x/nRF5_SDK_14.0.0_3bcc1f7.zip' \
-f 'https://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/NordicSemiconductor.nRF_DeviceFamilyPack.8.14.1.pack' \
-l 'https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.0.0_a53641a.zip' \
-f 'https://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/NordicSemiconductor.nRF_DeviceFamilyPack.8.16.0.pack' \
-d "../sdk" \
-p 'sd_api_v5/sdk140_connectivity.patch'
-p 'sdk150_add_sd_v3v5_support.patch'
@ECHO OFF
SETLOCAL
SET startpath=%cd%
SET scriptpath=%~dp0
SET rootpath=%scriptpath%..\..
REM Get command line argument
IF "%1"=="" (SET CONN_VERSION=0.0.0
) ELSE (SET CONN_VERSION=%1)
REM Environment variables that is changed between SDK versions
@SET SDK_NAME=nRF5_SDK_15.0.0_a53641a
@SET SOFTDEVICE_MAJOR=5
@SET SOFTDEVICE_MINOR=0
@SET SOFTDEVICE_PATCH=0
REM Environment variables that are below that are mostly based on the ones above
REM Do not know why a shortened name is used
@SET TEMP_NAME=s150
@SET SOFTDEVICE_PATH="%rootpath%\sdk\%TEMP_NAME%\components\softdevice\s132v%SOFTDEVICE_MAJOR%\hex\s132_nrf52_%SOFTDEVICE_MAJOR%.%SOFTDEVICE_MINOR%.%SOFTDEVICE_PATCH%_softdevice.hex"
@SET MERGED_HEX_FILENAME_PCA10040_1m="%rootpath%\sdk\connectivity_%CONN_VERSION%_1m_with_s132_%SOFTDEVICE_MAJOR%.%SOFTDEVICE_MINOR%.hex"
@SET MERGED_HEX_FILENAME_PCA10040_115k2="%rootpath%\sdk\connectivity_%CONN_VERSION%_115k2_with_s132_%SOFTDEVICE_MAJOR%.%SOFTDEVICE_MINOR%.hex"
@SET MERGED_HEX_FILENAME_PCA10059_usb="%rootpath%\sdk\connectivity_%CONN_VERSION%_usb_with_s132_%SOFTDEVICE_MAJOR%.%SOFTDEVICE_MINOR%.hex"
@SET BASH_EXE="c:\program files\git\bin\bash.exe"
@SET MERGE_HEX="c:\Program Files (x86)\Nordic Semiconductor\nrf5x\bin\mergehex.exe"
@SET UV_EXE="\Keil_v5\UV4\UV4.exe"
@SET UV_PROJECT_FILE_PCA10040="ble_connectivity_s132v%SOFTDEVICE_MAJOR%_hci_pca10040.uvprojx"
@SET UV_PROJECT_FILE_PCA10059="ble_connectivity_s132v%SOFTDEVICE_MAJOR%_usb_hci_pca10059.uvprojx"
@ECHO Starting build of BLE Connectivity firmware with SDK %SDK_NAME%
cd "%scriptpath%" || GOTO :error
"c:\program files\git\bin\bash.exe" bootstrap_sd_api_v%SOFTDEVICE_MAJOR%.sh || GOTO :error
@ECHO Workaround to reduce path length before build
cd %rootpath%\sdk || GOTO :error
rename %SDK_NAME% %TEMP_NAME% || GOTO :error
REM ##############
REM # PCA10040 #
REM ##############
@ECHO.
@ECHO Compiling for PCA10040, 1M baudrate
@cd %rootpath%\sdk\%TEMP_NAME%\examples\connectivity\ble_connectivity\pca10040\ser_s132v%SOFTDEVICE_MAJOR%_hci\arm5_no_packs || GOTO :error
%UV_EXE% -b %UV_PROJECT_FILE_PCA10040% -j0 -o pca10040_log_1m.txt
REM Warnings are expected, UV return codes: http://www.keil.com/support/man/docs/uv4/uv4_commandline.htm
@if %ERRORLEVEL% GTR 1 GOTO :error
@ECHO Merge hex SoftDevice and application.
%MERGE_HEX% -m _build\nrf52832_xxaa.hex %SOFTDEVICE_PATH% -o %MERGED_HEX_FILENAME_PCA10040_1m% || GOTO :error
@ECHO String replace baudrate.
%BASH_EXE% -c "sed -i -e 's/SER_PHY_UART_BAUDRATE_VAL 1000000$/SER_PHY_UART_BAUDRATE_VAL 115200/' ../../../../../../../%TEMP_NAME%/components/serialization/common/ser_config.h" || GOTO :error
@ECHO.
@ECHO Compiling for PCA10040, 115k2 baudrate
%UV_EXE% -b %UV_PROJECT_FILE_PCA10040% -j0 -o pca10040_log_115k2.txt
@if %ERRORLEVEL% GTR 1 GOTO :error
@ECHO Merge hex SoftDevice and application.
%MERGE_HEX% -m _build\nrf52832_xxaa.hex %SOFTDEVICE_PATH% -o %MERGED_HEX_FILENAME_PCA10040_115k2% || GOTO :error
REM ##############
REM # PCA10059 #
REM ##############
@ECHO.
@ECHO Compiling for PCA10059, USB
@SET PROJECT_ROOT_PATH="%rootpath%\sdk\%TEMP_NAME%\examples\connectivity\ble_connectivity\pca10059\ser_s132v%SOFTDEVICE_MAJOR%_usb_hci\arm5_no_packs"
@IF NOT EXIST %PROJECT_ROOT_PATH% CALL :skipping "PCA10059, USB"
@IF %ERRORLEVEL%==1 GOTO :summary
@cd %PROJECT_ROOT_PATH% || GOTO :error
%UV_EXE% -b %UV_PROJECT_FILE_PCA10059% -j0 -o pca10059_log_usb.txt
REM Warnings are expected, UV return codes: http://www.keil.com/support/man/docs/uv4/uv4_commandline.htm
@if %ERRORLEVEL% GTR 1 GOTO :error
@ECHO Merge hex SoftDevice and application.
%MERGE_HEX% -m _build\nrf52832_xxaa.hex %SOFTDEVICE_PATH% -o %MERGED_HEX_FILENAME_PCA10059_usb% || GOTO :error
:summary
@ECHO.
@ECHO Connectivity firmwares compiled and merged:
@IF EXIST %MERGED_HEX_FILENAME_PCA10040_1m% ECHO %MERGED_HEX_FILENAME_PCA10040_1m%
@IF EXIST %MERGED_HEX_FILENAME_PCA10040_115k2% ECHO %MERGED_HEX_FILENAME_PCA10040_115k2%
@IF EXIST %MERGED_HEX_FILENAME_PCA10059_usb% ECHO %MERGED_HEX_FILENAME_PCA10059_usb%
GOTO :EOF
:error
ECHO Command failed with error code %errorlevel%.
EXIT /b %errorlevel%
:skipping
ECHO Skipping compilation of %~1 since the project file does not exist
EXIT /b 1
diff --git a/components/serialization/common/ble_serialization.h b/components/serialization/common/ble_serialization.h
index 86cde74..2bfb8cd 100644
--- a/components/serialization/common/ble_serialization.h
+++ b/components/serialization/common/ble_serialization.h
@@ -166,7 +166,7 @@ typedef enum
#endif
/** Maximum length of p_value in \ref ble_gattc_write_params_t. See Bluetooth 4.0 spec: 3.4.5.1 and
* 3.4.5.3. */
-#define BLE_GATTC_WRITE_P_VALUE_LEN_MAX (GATT_MTU_SIZE_DEFAULT - 3)
+#define BLE_GATTC_WRITE_P_VALUE_LEN_MAX (247 - 3)
/** See Bluetooth 4.0 spec: 3.4.4.7. */
#define BLE_GATTC_HANDLE_COUNT_LEN_MAX ((GATT_MTU_SIZE_DEFAULT - 1) / 2)
diff --git a/components/serialization/common/ser_config.h b/components/serialization/common/ser_config.h
index a4dfe24..5184dcd 100644
--- a/components/serialization/common/ser_config.h
+++ b/components/serialization/common/ser_config.h
@@ -66,8 +66,8 @@ extern "C" {
/** Max packets size in serialization HAL Transport layer (packets before adding PHY header i.e.
* packet length). */
-#define SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE (384UL)
-#define SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE (384UL)
+#define SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE (500UL)
+#define SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE (500UL)
#define SER_HAL_TRANSPORT_MAX_PKT_SIZE ((SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE) >= \
(SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE) \
@@ -99,7 +99,7 @@ extern "C" {
/** UART transmission parameters */
#define SER_PHY_UART_FLOW_CTRL NRF_UART_HWFC_ENABLED
-#define SER_PHY_UART_PARITY NRF_UART_PARITY_INCLUDED
+#define SER_PHY_UART_PARITY NRF_UART_PARITY_EXCLUDED
#define SER_PHY_UART_BAUDRATE UART_BAUDRATE_BAUDRATE_Baud1M
/** Find UART baud rate value based on the chosen register setting. */
@@ -145,6 +145,7 @@ extern "C" {
#define SER_MAX_CONNECTIONS 8
+#define HCI_LINK_CONTROL
#ifdef __cplusplus
}
diff --git a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h b/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h
index 9eaf33a..7b4fe8e 100644
--- a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h
+++ b/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h
@@ -65,10 +65,10 @@ extern "C" {
/* UART configuration */
#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST
-#define SER_PHY_UART_RX SER_CON_RX_PIN
-#define SER_PHY_UART_TX SER_CON_TX_PIN
-#define SER_PHY_UART_CTS SER_CON_CTS_PIN
-#define SER_PHY_UART_RTS SER_CON_RTS_PIN
+#define SER_PHY_UART_RX RX_PIN_NUMBER
+#define SER_PHY_UART_TX TX_PIN_NUMBER
+#define SER_PHY_UART_CTS CTS_PIN_NUMBER
+#define SER_PHY_UART_RTS RTS_PIN_NUMBER
#ifdef __cplusplus
diff --git a/components/serialization/common/transport/ser_phy/ser_phy_hci.c b/components/serialization/common/transport/ser_phy/ser_phy_hci.c
index 216ed97..147d7d5 100644
--- a/components/serialization/common/transport/ser_phy/ser_phy_hci.c
+++ b/components/serialization/common/transport/ser_phy/ser_phy_hci.c
@@ -39,6 +39,8 @@
(SER_HAL_TRANSPORT_MAX_PKT_SIZE + PKT_HDR_SIZE + PKT_CRC_SIZE))
#define BAUD_TIME_us (1000000uL / SER_PHY_UART_BAUDRATE_VAL)
+#define PKT_TYPE_RESET 5
+
#define TX_EVT_QUEUE_SIZE 16
#define RX_EVT_QUEUE_SIZE 16
#define PKT_TYPE_VENDOR_SPECIFIC 14 /**< Packet type vendor specific. */
@@ -50,7 +52,7 @@
#define INITIAL_SEQ_NUMBER INITIAL_ACK_NUMBER_EXPECTED /**< Initial acknowledge number transmitted. */
#define INVALID_PKT_TYPE 0xFFFFFFFFu /**< Internal invalid packet type value. */
#define MAX_TRANSMISSION_TIME_ms (MAX_PACKET_SIZE_IN_BITS * BAUD_TIME_us / 1000uL) /**< Max transmission time of a single application packet over UART in units of mseconds. */
-#define RETRANSMISSION_TIMEOUT_IN_ms (10uL * MAX_TRANSMISSION_TIME_ms) /**< Retransmission timeout for application packet in units of mseconds. */
+#define RETRANSMISSION_TIMEOUT_IN_ms (50uL * MAX_TRANSMISSION_TIME_ms) /**< Retransmission timeout for application packet in units of mseconds. */
#ifdef HCI_LINK_CONTROL
#define HCI_PKT_SYNC 0x7E01u /**< Link Control Packet: type SYNC */
@@ -770,6 +772,10 @@ static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event)
NRF_LOG_DEBUG("EVT_PKT_RECEIVED 0x%X/%u\r\n", packet_type,
p_event->evt_params.received_pkt.num_of_bytes);
+ if (packet_type == PKT_TYPE_RESET)
+ {
+ NVIC_SystemReset();
+ }
if (packet_type == PKT_TYPE_ACK )
{
diff --git a/components/serialization/connectivity/ser_conn_error_handling.c b/components/serialization/connectivity/ser_conn_error_handling.c
index 5252a19..cd73f30 100644
--- a/components/serialization/connectivity/ser_conn_error_handling.c
+++ b/components/serialization/connectivity/ser_conn_error_handling.c
@@ -101,7 +101,7 @@ void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
/* ble_debug_assert_handler(error_code, line_num, p_file_name); */
-#if 0
+#if 1
/* Reset the chip. Should be used in the release version. */
NVIC_SystemReset();
#else /* Debug version. */
diff --git a/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/config/sdk_config.h b/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/config/sdk_config.h
index 9358db3..9ad5be2 100644
--- a/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/config/sdk_config.h
+++ b/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/config/sdk_config.h
@@ -48,6 +48,8 @@
#endif
// <h> nRF_BLE
+#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 250
+
//==========================================================
// <q> BLE_DTM_ENABLED - ble_dtm - Module for testing RF/PHY using DTM commands
@@ -226,7 +228,7 @@
#ifndef APP_SCHEDULER_WITH_PROFILER
-#define APP_SCHEDULER_WITH_PROFILER 0
+#define APP_SCHEDULER_WITH_PROFILER 1
#endif
// </e>
diff --git a/examples/connectivity/ble_connectivity/main.c b/examples/connectivity/ble_connectivity/main.c
index bcb67e3..516ccd7 100644
--- a/examples/connectivity/ble_connectivity/main.c
+++ b/examples/connectivity/ble_connectivity/main.c
@@ -57,6 +57,7 @@
#include "ser_conn_handlers.h"
#include "boards.h"
#include "nrf_drv_clock.h"
+#include "ser_config.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
@@ -65,6 +66,38 @@ NRF_LOG_MODULE_REGISTER();
#include "ser_phy_debug_comm.h"
+#if defined ( __CC_ARM )
+typedef struct __attribute__((packed))
+{
+ uint32_t magic_number; /* Magic number to verify the presence of this structure in memory */
+ uint32_t struct_version : 8; /* Version of this struct format */
+ uint32_t rfu0 : 24; /* Reserved for future use, shall be 0xFFFFFF */
+ uint32_t revision_hash; /* Unique revision identifier */
+ uint32_t version_major : 8; /* Major version number */
+ uint32_t version_minor : 8; /* Minor version number */
+ uint32_t version_patch : 8; /* Patch version number */
+ uint32_t rfu1 : 8; /* Reserved for future use, shall be 0xFF */
+ uint32_t sd_ble_api_version : 8; /* SoftDevice BLE API version number */
+ uint32_t transport_type : 8; /* Connectivity transport type, 1 = UART HCI */
+ uint32_t rfu2 : 16; /* Reserved for future use, shall be 0xFFFF */
+ uint32_t baud_rate; /* UART transport baud rate */
+} version_info_t;
+static const version_info_t version_info __attribute__((at(0x30000))) = {
+ .magic_number = 0x46D8A517,
+ .struct_version = 2,
+ .rfu0 = 0xFFFFFF,
+ .revision_hash = 0,
+ .version_major = 2,
+ .version_minor = 0,
+ .version_patch = 1,
+ .rfu1 = 0xFF,
+ .sd_ble_api_version = NRF_SD_BLE_API_VERSION,
+ .transport_type = 1,
+ .rfu2 = 0xFFFF,
+ .baud_rate = SER_PHY_UART_BAUDRATE_VAL,
+};
+#endif
+
/**@brief Main function of the connectivity application. */
int main(void)
{
diff --git a/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/arm5_no_packs/ble_connectivity_s132_hci_pca10040.uvprojx b/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/arm5_no_packs/ble_connectivity_s132_hci_pca10040.uvprojx
index a73bb70..dea709c 100644
--- a/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/arm5_no_packs/ble_connectivity_s132_hci_pca10040.uvprojx
+++ b/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/arm5_no_packs/ble_connectivity_s132_hci_pca10040.uvprojx
@@ -329,8 +329,8 @@
</OCR_RVCT8>
<OCR_RVCT9>
<Type>0</Type>
- <StartAddress>0x2000b668</StartAddress>
- <Size>0x4998</Size>
+ <StartAddress>0x2000bcc0</StartAddress>
+ <Size>0x4340</Size>
</OCR_RVCT9>
<OCR_RVCT10>
<Type>0</Type>
diff --git a/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/armgcc/ble_connectivity_gcc_nrf52.ld b/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/armgcc/ble_connectivity_gcc_nrf52.ld
index db96bf9..08e5b25 100644
--- a/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/armgcc/ble_connectivity_gcc_nrf52.ld
+++ b/examples/connectivity/ble_connectivity/pca10040/ser_s132_hci/armgcc/ble_connectivity_gcc_nrf52.ld
@@ -6,7 +6,7 @@ GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0x23000, LENGTH = 0x5d000
- RAM (rwx) : ORIGIN = 0x2000b668, LENGTH = 0x4998
+ RAM (rwx) : ORIGIN = 0x2000bcc0, LENGTH = 0x4340
}
SECTIONS
This diff is collapsed.
......@@ -74,7 +74,7 @@ void h5_encode(const std::vector<uint8_t> &in_packet,
bool reliable_packet,
h5_pkt_type_t packet_type);
uint32_t h5_decode(std::vector<uint8_t> &slip_dec_packet,
uint32_t h5_decode(const std::vector<uint8_t> &slip_dec_packet,
std::vector<uint8_t> &h5_dec_packet,
uint8_t *seq_num,
uint8_t *ack_num,
......
......@@ -64,6 +64,16 @@ typedef enum
STATE_UNKNOWN
} h5_state_t;
constexpr uint8_t SyncFirstByte = 0x01;
constexpr uint8_t SyncSecondByte = 0x7E;
constexpr uint8_t SyncRspFirstByte = 0x02;
constexpr uint8_t SyncRspSecondByte = 0x7D;
constexpr uint8_t SyncConfigFirstByte = 0x03;
constexpr uint8_t SyncConfigSecondByte = 0xFC;
constexpr uint8_t SyncConfigRspFirstByte = 0x04;
constexpr uint8_t SyncConfigRspSecondByte = 0x7B;
constexpr uint8_t SyncConfigField = 0x11;
using state_action_t = std::function<h5_state_t()>;
using payload_t = std::vector<uint8_t>;
......@@ -89,7 +99,7 @@ public:
private:
void dataHandler(uint8_t *data, size_t length);
void statusHandler(sd_rpc_app_status_t code, const char * error);
void processPacket(payload_t &packet);
void processPacket(const payload_t &packet);
void sendControlPacket(control_pkt_type type);
......@@ -124,15 +134,15 @@ private:
uint32_t outgoingPacketCount;
uint32_t errorPacketCount;
void logPacket(bool outgoing, payload_t &packet);
void logPacket(const bool outgoing, const payload_t &packet);
void log(std::string &logLine) const;
void log(char const *logLine) const;
void logStateTransition(h5_state_t from, h5_state_t to) const;
static std::string stateToString(h5_state_t state);
std::string asHex(payload_t &packet) const;
std::string hciPacketLinkControlToString(payload_t payload) const;
std::string h5PktToString(bool out, payload_t &h5Packet) const;
static std::string pktTypeToString(h5_pkt_type_t pktType);
void logStateTransition(const h5_state_t from, const h5_state_t to) const;
static std::string stateToString(const h5_state_t state);
static std::string asHex(const payload_t &packet);
static std::string hciPacketLinkControlToString(const payload_t &payload);
std::string h5PktToString(const bool out, const payload_t &h5Packet) const;
static std::string pktTypeToString(const h5_pkt_type_t pktType);
// State machine related
h5_state_t currentState;
......@@ -153,19 +163,9 @@ private:
bool waitForState(h5_state_t state, std::chrono::milliseconds timeout);
std::condition_variable stateWaitCondition;
static std::map<control_pkt_type, payload_t> pkt_pattern;
static std::map<h5_state_t, std::string> stateString;
static std::map<h5_pkt_type_t, std::string> pktTypeString;
static const uint8_t SyncFirstByte = 0x01;
static const uint8_t SyncSecondByte = 0x7E;
static const uint8_t SyncRspFirstByte = 0x02;
static const uint8_t SyncRspSecondByte = 0x7D;
static const uint8_t SyncConfigFirstByte = 0x03;
static const uint8_t SyncConfigSecondByte = 0xFC;
static const uint8_t SyncConfigRspFirstByte = 0x04;
static const uint8_t SyncConfigRspSecondByte = 0x7B;
static const uint8_t SyncConfigField = 0x11;
static const std::map<const control_pkt_type, const payload_t> pkt_pattern;
static const std::map<const h5_state_t, const std::string> stateString;
static const std::map<const h5_pkt_type_t, const std::string> pktTypeString;
};
#endif //H5_TRANSPORT_H
......@@ -41,7 +41,7 @@
#include <stdint.h>
#include <vector>
void slip_encode(std::vector<uint8_t> &in_packet, std::vector<uint8_t> &out_packet);
uint32_t slip_decode(std::vector<uint8_t> &packet, std::vector<uint8_t> &out_packet);
void slip_encode(const std::vector<uint8_t> &in_packet, std::vector<uint8_t> &out_packet);
uint32_t slip_decode(const std::vector<uint8_t> &packet, std::vector<uint8_t> &out_packet);
#endif
......@@ -53,11 +53,9 @@ const uint16_t payloadLengthFirstNibbleMask = 0x000F;
const uint16_t payloadLengthSecondNibbleMask = 0x0FF0;
const uint8_t payloadLengthOffset = 4;
uint8_t calculate_header_checksum(std::vector<uint8_t> &header)
uint8_t calculate_header_checksum(const std::vector<uint8_t> &header)
{
uint16_t checksum;
checksum = header[0];
uint16_t checksum = header[0];
checksum += header[1];
checksum += header[2];
checksum &= 0xFFu;
......@@ -66,11 +64,11 @@ uint8_t calculate_header_checksum(std::vector<uint8_t> &header)
return static_cast<uint8_t>(checksum);
}
uint16_t calculate_crc16_checksum(std::vector<uint8_t>::iterator start, std::vector<uint8_t>::iterator end)
uint16_t calculate_crc16_checksum(const std::vector<uint8_t>::const_iterator &start, const std::vector<uint8_t>::const_iterator &end)
{
uint16_t crc = 0xFFFF;
std::for_each(start, end, [&crc](uint8_t data) {
std::for_each(start, end, [&crc](const uint8_t data) {
crc = (crc >> 8) | (crc << 8);
crc ^= data;
crc ^= (crc & 0xFF) >> 4;
......@@ -82,12 +80,12 @@ uint16_t calculate_crc16_checksum(std::vector<uint8_t>::iterator start, std::vec
}
void add_h5_header(std::vector<uint8_t> &out_packet,
uint8_t seq_num,
uint8_t ack_num,
bool crc_present,
bool reliable_packet,
uint8_t packet_type,
uint16_t payload_length)
const uint8_t seq_num,
const uint8_t ack_num,
const bool crc_present,
const bool reliable_packet,
const uint8_t packet_type,
const uint16_t payload_length)
{
out_packet.push_back(
(seq_num & seqNumMask)
......@@ -105,18 +103,18 @@ void add_h5_header(std::vector<uint8_t> &out_packet,
void add_crc16(std::vector<uint8_t> &out_packet)
{
uint16_t crc16 = calculate_crc16_checksum(out_packet.begin(), out_packet.end());
const auto crc16 = calculate_crc16_checksum(out_packet.begin(), out_packet.end());
out_packet.push_back(crc16 & 0xFF);
out_packet.push_back((crc16 >> 8) & 0xFF);
}
void h5_encode(const std::vector<uint8_t> &in_packet,
std::vector<uint8_t> &out_packet,
uint8_t seq_num,
uint8_t ack_num,
bool crc_present,
bool reliable_packet,
h5_pkt_type_t packet_type)
const uint8_t seq_num,
const uint8_t ack_num,
const bool crc_present,
const bool reliable_packet,
const h5_pkt_type_t packet_type)
{
add_h5_header(
out_packet,
......@@ -136,7 +134,7 @@ void h5_encode(const std::vector<uint8_t> &in_packet,
}
}
uint32_t h5_decode(std::vector<uint8_t> &slipPayload,
uint32_t h5_decode(const std::vector<uint8_t> &slipPayload,
std::vector<uint8_t> &h5Payload,
uint8_t *seq_num,
uint8_t *ack_num,
......@@ -146,8 +144,6 @@ uint32_t h5_decode(std::vector<uint8_t> &slipPayload,
bool *reliable_packet,
h5_pkt_type_t *packet_type)
{
uint16_t payload_length;
if (slipPayload.size() < 4)
{
return NRF_ERROR_INVALID_LENGTH;
......@@ -155,14 +151,14 @@ uint32_t h5_decode(std::vector<uint8_t> &slipPayload,
*seq_num = slipPayload[0] & seqNumMask;
*ack_num = (slipPayload[0] >> ackNumPos) & ackNumMask;
auto crc_present = static_cast<bool>(((slipPayload[0] >> crcPresentPos) & crcPresentMask) != 0);
const auto crc_present = static_cast<bool>(((slipPayload[0] >> crcPresentPos) & crcPresentMask) != 0);
*reliable_packet = static_cast<bool>(((slipPayload[0] >> reliablePacketPos) & reliablePacketMask) != 0);
*packet_type = static_cast<h5_pkt_type_t>(slipPayload[1] & packetTypeMask);
payload_length = ((slipPayload[1] >> payloadLengthOffset) & payloadLengthFirstNibbleMask) + (static_cast<uint16_t>(slipPayload[2]) << payloadLengthOffset);
auto header_checksum = slipPayload[3];
const uint16_t payload_length = ((slipPayload[1] >> payloadLengthOffset) & payloadLengthFirstNibbleMask) + (static_cast<uint16_t>(slipPayload[2]) << payloadLengthOffset);
const auto header_checksum = slipPayload[3];
// Check if received packet size matches the packet size stated in header
auto calculatedPayloadSize = payload_length + H5_HEADER_LENGTH + (crc_present ? 2 : 0);
const auto calculatedPayloadSize = payload_length + H5_HEADER_LENGTH + (crc_present ? 2 : 0);
if (slipPayload.size() != calculatedPayloadSize)
{
......@@ -173,7 +169,7 @@ uint32_t h5_decode(std::vector<uint8_t> &slipPayload,
if (_data_integrity != nullptr) *_data_integrity = crc_present;
if (_header_checksum != nullptr) *_header_checksum = header_checksum;
auto calculated_header_checksum = calculate_header_checksum(slipPayload);
const auto calculated_header_checksum = calculate_header_checksum(slipPayload);
if (header_checksum != calculated_header_checksum)
{
......@@ -182,8 +178,8 @@ uint32_t h5_decode(std::vector<uint8_t> &slipPayload,
if (crc_present)
{
uint16_t packet_checksum = slipPayload[payload_length + H5_HEADER_LENGTH] + (slipPayload[payload_length + H5_HEADER_LENGTH + 1] << 8);
auto calculated_packet_checksum = calculate_crc16_checksum(slipPayload.begin(), slipPayload.begin() + payload_length + H5_HEADER_LENGTH);
const uint16_t packet_checksum = slipPayload[payload_length + H5_HEADER_LENGTH] + (slipPayload[payload_length + H5_HEADER_LENGTH + 1] << 8);
const auto calculated_packet_checksum = calculate_crc16_checksum(slipPayload.begin(), slipPayload.begin() + payload_length + H5_HEADER_LENGTH);
if (packet_checksum != calculated_packet_checksum)
{
......@@ -193,7 +189,7 @@ uint32_t h5_decode(std::vector<uint8_t> &slipPayload,
if (payload_length > 0)
{
auto payloadIterator = slipPayload.begin() + 4;
const auto payloadIterator = slipPayload.begin() + 4;
h5Payload.insert(h5Payload.begin(), payloadIterator, payloadIterator + payload_length);
}
......
......@@ -99,7 +99,7 @@ H5Transport::~H5Transport()
#pragma region Static initializers
std::map<h5_state_t, std::string> H5Transport::stateString{
const std::map<const h5_state_t, const std::string> H5Transport::stateString{
{ STATE_UNKNOWN, "STATE_UNKNOWN" },
{ STATE_START, "STATE_START" },
{ STATE_UNINITIALIZED, "STATE_UNINITIALIZED" },
......@@ -111,15 +111,16 @@ std::map<h5_state_t, std::string> H5Transport::stateString{
{ STATE_NO_RESPONSE, "STATE_NO_RESPONSE" },
};
std::map<control_pkt_type, std::vector<uint8_t>> H5Transport::pkt_pattern = {
const std::map<const control_pkt_type, const std::vector<uint8_t>> H5Transport::pkt_pattern = {
{ CONTROL_PKT_RESET, {} },
{ CONTROL_PKT_ACK, {} },
{ CONTROL_PKT_SYNC, { SyncFirstByte, SyncSecondByte } },
{ CONTROL_PKT_SYNC_RESPONSE, { SyncRspFirstByte, SyncRspSecondByte } },
{ CONTROL_PKT_SYNC_CONFIG, { SyncConfigFirstByte, SyncConfigSecondByte, SyncConfigField } },
{ CONTROL_PKT_SYNC_CONFIG_RESPONSE, { SyncConfigRspFirstByte, SyncConfigRspSecondByte, SyncConfigField } }
};
std::map<h5_pkt_type_t, std::string> H5Transport::pktTypeString{
const std::map<const h5_pkt_type_t, const std::string> H5Transport::pktTypeString = {
{ ACK_PACKET, "ACK" },
{ HCI_COMMAND_PACKET, "HCI_COMMAND_PACKET" },
{ ACL_DATA_PACKET, "ACL_DATA_PACKET" },
......@@ -302,7 +303,7 @@ h5_state_t H5Transport::state() const