diff --git a/examples/lighting-app/efr32/BUILD.gn b/examples/lighting-app/efr32/BUILD.gn index 0c36e3bba57314..89274ec986d157 100644 --- a/examples/lighting-app/efr32/BUILD.gn +++ b/examples/lighting-app/efr32/BUILD.gn @@ -122,6 +122,9 @@ efr32_sdk("sdk") { ] include_dirs = [ + "${chip_root}/examples/platform/efr32/rs911x", + "${chip_root}/examples/platform/efr32/rs911x/hal", + "${chip_root}/third_party/silabs/wiseconnect-wifi-bt-sdk/sapi/include", "${chip_root}/src/platform/EFR32", "${efr32_project_dir}/include", "${examples_plat_dir}", diff --git a/examples/lighting-app/efr32/src/main.cpp b/examples/lighting-app/efr32/src/main.cpp index c9838ac87b9e5a..9531a1a14e2c0c 100644 --- a/examples/lighting-app/efr32/src/main.cpp +++ b/examples/lighting-app/efr32/src/main.cpp @@ -23,6 +23,7 @@ #include "init_efrPlatform.h" #include "sl_simple_button_instances.h" #include "sl_system_kernel.h" +#include "wfx_host_events.h" #include #include #include @@ -33,7 +34,7 @@ #include #endif -#define BLE_DEV_NAME "SiLabs-Light" +#define BLE_DEV_NAME "RSI-BLE" using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; diff --git a/examples/platform/efr32/matter_config.cpp b/examples/platform/efr32/matter_config.cpp index d4d651f73ab5d2..2879ee461b7eff 100644 --- a/examples/platform/efr32/matter_config.cpp +++ b/examples/platform/efr32/matter_config.cpp @@ -46,6 +46,10 @@ using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; #include + +#include "event_groups.h" +#include "wfx_rsi.h" + // If building with the EFR32-provided crypto backend, we can use the // opaque keystore #if CHIP_CRYPTO_PLATFORM @@ -148,8 +152,14 @@ CHIP_ERROR EFR32MatterConfig::InitMatter(const char * appName) EFR32_LOG("Init CHIP Stack"); // Init Chip memory management before the stack ReturnErrorOnFailure(chip::Platform::MemoryInit()); + +// EFR32_LOG("Init RSI 911x Platform"); +// wfx_rsi_init_platform(); + + EFR32_LOG("Init CHIP PlatformMgr ChipStack"); ReturnErrorOnFailure(PlatformMgr().InitChipStack()); + EFR32_LOG("Init Set BLE Device Name"); chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(appName); #if CHIP_ENABLE_OPENTHREAD diff --git a/examples/platform/efr32/rs911x/rs911x.gni b/examples/platform/efr32/rs911x/rs911x.gni index 87b30c43a7be33..8fdab0b64c6b56 100644 --- a/examples/platform/efr32/rs911x/rs911x.gni +++ b/examples/platform/efr32/rs911x/rs911x.gni @@ -16,10 +16,12 @@ rs911x_src_plat = [ "${examples_plat_dir}/rs911x/hal/rsi_hal_mcu_timer.c", "${examples_plat_dir}/rs911x/hal/efx_spi.c", ] + rs911x_plat_incs = [ "${wifi_sdk_dir}", "${wifi_sdk_dir}/hal", "${chip_root}/src/platform/EFR32", + "${chip_root}/src/platform/EFR32/RS911x", ] # @@ -95,6 +97,7 @@ rs911x_defs = [ "RSI_SPI_INTERFACE", "RSI_WITH_OS", ] + rs911x_sock_defs = [ "RS911X_SOCKETS", "RSI_IPV6_ENABLE", diff --git a/examples/platform/efr32/rs911x/rsi_if.c b/examples/platform/efr32/rs911x/rsi_if.c index 872d82c411269b..3e58b631d989b5 100644 --- a/examples/platform/efr32/rs911x/rsi_if.c +++ b/examples/platform/efr32/rs911x/rsi_if.c @@ -19,6 +19,7 @@ #include #include + #include "em_bus.h" #include "em_cmu.h" #include "em_gpio.h" @@ -31,6 +32,7 @@ #include "event_groups.h" #include "task.h" +#include "wfx_sl_ble_init.h" #include "wfx_host_events.h" #include "rsi_driver.h" @@ -48,15 +50,17 @@ #include "rsi_bootup_config.h" #include "rsi_error.h" +#include "rsi_bt_common.h" +#include "rsi_ble_apis.h" +#include "rsi_bt_common_apis.h" +#include "rsi_ble_config.h" +#include "rsi_utils.h" + #include "dhcp_client.h" #include "wfx_host_events.h" #include "wfx_rsi.h" -/* Rsi driver Task will use as its stack */ -StackType_t driverRsiTaskStack[WFX_RSI_WLAN_TASK_SZ] = { 0 }; -/* Structure that will hold the TCB of the wfxRsi Task being created. */ -StaticTask_t driverRsiTaskBuffer; /* Declare a variable to hold the data associated with the created event group. */ StaticEventGroup_t rsiDriverEventGroup; @@ -70,7 +74,7 @@ bool hasNotifiedWifiConnectivity = false; /* * This file implements the interface to the RSI SAPIs */ -static uint8_t wfx_rsi_drv_buf[WFX_RSI_BUF_SZ]; +//static uint8_t wfx_rsi_drv_buf[WFX_RSI_BUF_SZ]; wfx_wifi_scan_ext_t * temp_reset; uint8_t security; @@ -293,76 +297,74 @@ static void wfx_rsi_wlan_pkt_cb(uint16_t status, uint8_t * buf, uint32_t len) static int32_t wfx_rsi_init(void) { int32_t status; - uint8_t buf[RSI_RESPONSE_HOLD_BUFF_SIZE]; - extern void rsi_hal_board_init(void); - - WFX_RSI_LOG("%s: starting(HEAP_SZ = %d)", __func__, SL_HEAP_SIZE); - //! Driver initialization - status = rsi_driver_init(wfx_rsi_drv_buf, WFX_RSI_BUF_SZ); - if ((status < RSI_DRIVER_STATUS) || (status > WFX_RSI_BUF_SZ)) - { - WFX_RSI_LOG("%s: error: RSI drv init failed with status: %02x", __func__, status); - return status; - } - - WFX_RSI_LOG("%s: rsi_device_init", __func__); - /* ! Redpine module intialisation */ - if ((status = rsi_device_init(LOAD_NWP_FW)) != RSI_SUCCESS) - { - WFX_RSI_LOG("%s: error: rsi_device_init failed with status: %02x", __func__, status); - return status; - } - WFX_RSI_LOG("%s: start wireless drv task", __func__); - /* - * Create the driver task - */ - wfx_rsi.drv_task = xTaskCreateStatic((TaskFunction_t) rsi_wireless_driver_task, "rsi_drv", WFX_RSI_WLAN_TASK_SZ, NULL, - WLAN_TASK_PRIORITY, driverRsiTaskStack, &driverRsiTaskBuffer); - if (NULL == wfx_rsi.drv_task) - { - WFX_RSI_LOG("%s: error: rsi_wireless_driver_task failed", __func__); - return RSI_ERROR_INVALID_PARAM; - } - - /* Initialize WiSeConnect or Module features. */ - WFX_RSI_LOG("%s: rsi_wireless_init", __func__); - if ((status = rsi_wireless_init(OPER_MODE_0, COEX_MODE_0)) != RSI_SUCCESS) - { - WFX_RSI_LOG("%s: error: rsi_wireless_init failed with status: %02x", __func__, status); - return status; - } + // uint8_t buf[RSI_RESPONSE_HOLD_BUFF_SIZE]; + // extern void rsi_hal_board_init(void); + +// WFX_RSI_LOG("%s: starting(HEAP_SZ = %d)", __func__, SL_HEAP_SIZE); +// //! Driver initialization +// status = rsi_driver_init(wfx_rsi_drv_buf, WFX_RSI_BUF_SZ); +// if ((status < RSI_DRIVER_STATUS) || (status > WFX_RSI_BUF_SZ)) +// { +// WFX_RSI_LOG("%s: error: RSI drv init failed with status: %02x", __func__, status); +// return status; +// } +// +// WFX_RSI_LOG("%s: rsi_device_init", __func__); +// /* ! Redpine module intialisation */ +// if ((status = rsi_device_init(LOAD_NWP_FW)) != RSI_SUCCESS) +// { +// WFX_RSI_LOG("%s: error: rsi_device_init failed with status: %02x", __func__, status); +// return status; +// } +// WFX_RSI_LOG("%s: start wireless drv task", __func__); +// /* +// * Create the driver task +// */ +// wfx_rsi.drv_task = xTaskCreateStatic((TaskFunction_t) rsi_wireless_driver_task, "rsi_drv", WFX_RSI_WLAN_TASK_SZ, NULL, +// WLAN_TASK_PRIORITY, driverRsiTaskStack, &driverRsiTaskBuffer); +// if (NULL == wfx_rsi.drv_task) +// { +// WFX_RSI_LOG("%s: error: rsi_wireless_driver_task failed", __func__); +// return RSI_ERROR_INVALID_PARAM; +// } +// +// /* Initialize WiSeConnect or Module features. */ +// WFX_RSI_LOG("%s: rsi_wireless_init", __func__); +// if ((status = rsi_wireless_init(OPER_MODE_0, COEX_MODE_0)) != RSI_SUCCESS) +// { +// WFX_RSI_LOG("%s: error: rsi_wireless_init failed with status: %02x", __func__, status); +// return status; +// } +// +// WFX_RSI_LOG("%s: get FW version..", __func__); +// /* +// * Get the MAC and other info to let the user know about it. +// */ +// if (rsi_wlan_get(RSI_FW_VERSION, buf, sizeof(buf)) != RSI_SUCCESS) +// { +// WFX_RSI_LOG("%s: error: rsi_wlan_get(RSI_FW_VERSION) failed with status: %02x", __func__, status); +// return status; +// } +// +// buf[sizeof(buf) - 1] = 0; +// WFX_RSI_LOG("%s: RSI firmware version: %s", __func__, buf); +// //! Send feature frame +// if ((status = rsi_send_feature_frame()) != RSI_SUCCESS) +// { +// WFX_RSI_LOG("%s: error: rsi_send_feature_frame failed with status: %02x", __func__, status); +// return status; +// } +// +// WFX_RSI_LOG("%s: sent rsi_send_feature_frame", __func__); +// /* initializes wlan radio parameters and WLAN supplicant parameters. +// */ +// (void) rsi_wlan_radio_init(); /* Required so we can get MAC address */ +// if ((status = rsi_wlan_get(RSI_MAC_ADDRESS, &wfx_rsi.sta_mac.octet[0], RESP_BUFF_SIZE)) != RSI_SUCCESS) +// { +// WFX_RSI_LOG("%s: error: rsi_wlan_get failed with status: %02x", __func__, status); +// return status; +// } - WFX_RSI_LOG("%s: get FW version..", __func__); - /* - * Get the MAC and other info to let the user know about it. - */ - if (rsi_wlan_get(RSI_FW_VERSION, buf, sizeof(buf)) != RSI_SUCCESS) - { - WFX_RSI_LOG("%s: error: rsi_wlan_get(RSI_FW_VERSION) failed with status: %02x", __func__, status); - return status; - } - - buf[sizeof(buf) - 1] = 0; - WFX_RSI_LOG("%s: RSI firmware version: %s", __func__, buf); - //! Send feature frame - if ((status = rsi_send_feature_frame()) != RSI_SUCCESS) - { - WFX_RSI_LOG("%s: error: rsi_send_feature_frame failed with status: %02x", __func__, status); - return status; - } - - WFX_RSI_LOG("%s: sent rsi_send_feature_frame", __func__); - /* initializes wlan radio parameters and WLAN supplicant parameters. - */ - (void) rsi_wlan_radio_init(); /* Required so we can get MAC address */ - if ((status = rsi_wlan_get(RSI_MAC_ADDRESS, &wfx_rsi.sta_mac.octet[0], RESP_BUFF_SIZE)) != RSI_SUCCESS) - { - WFX_RSI_LOG("%s: error: rsi_wlan_get failed with status: %02x", __func__, status); - return status; - } - - WFX_RSI_LOG("%s: WLAN: MAC %02x:%02x:%02x %02x:%02x:%02x", __func__, wfx_rsi.sta_mac.octet[0], wfx_rsi.sta_mac.octet[1], - wfx_rsi.sta_mac.octet[2], wfx_rsi.sta_mac.octet[3], wfx_rsi.sta_mac.octet[4], wfx_rsi.sta_mac.octet[5]); wfx_rsi.events = xEventGroupCreateStatic(&rsiDriverEventGroup); /* * Register callbacks - We are only interested in the connectivity CBs @@ -849,4 +851,28 @@ int32_t wfx_rsi_send_data(void * p, uint16_t len) return status; } + + struct wfx_rsi wfx_rsi; + +//void rsi_init_task(void * arg) +//{ +// uint32_t rsi_status = wfx_sl_module_init(); +// if (rsi_status != RSI_SUCCESS) +// { +// WFX_RSI_LOG("%s: error: wfx_sl_module_init with status: %02x", __func__, rsi_status); +// return; +// } +// WFX_RSI_LOG("After wfx_sl_module_init"); +// rsi_task_suspend((rsi_task_handle_t *)wfx_rsi.init_task); +//} +// +//void wfx_rsi_init_platform() +//{ +// /*init task - RS911x*/ +// WFX_RSI_LOG("WFX:Start ble task"); +// if (xTaskCreate((TaskFunction_t) rsi_init_task, "rsi_init", WFX_RSI_TASK_SZ, NULL, 54, &wfx_rsi.init_task) != pdPASS) +// { +// WFX_RSI_LOG("ERR: RSI ble task create"); +// } +//} diff --git a/examples/platform/efr32/rs911x/wfx_rsi.h b/examples/platform/efr32/rs911x/wfx_rsi.h index 5899a0c45bc31e..78db8a442c323b 100644 --- a/examples/platform/efr32/rs911x/wfx_rsi.h +++ b/examples/platform/efr32/rs911x/wfx_rsi.h @@ -57,6 +57,8 @@ struct wfx_rsi EventGroupHandle_t events; TaskHandle_t drv_task; TaskHandle_t wlan_task; + TaskHandle_t init_task; + TaskHandle_t ble_task; uint16_t dev_state; uint16_t ap_chan; /* The chan our STA is using */ wfx_wifi_provision_t sec; @@ -87,6 +89,7 @@ int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t * ap); int32_t wfx_rsi_get_ap_ext(wfx_wifi_scan_ext_t * extra_info); int32_t wfx_rsi_reset_count(); int32_t wfx_rsi_disconnect(); +void wfx_rsi_init_platform(); #define WFX_RSI_LOG(...) efr32Log(__VA_ARGS__); #ifdef __cplusplus diff --git a/src/include/platform/internal/BLEManager.h b/src/include/platform/internal/BLEManager.h index f37f2f3eb00743..29b034e47da8d7 100644 --- a/src/include/platform/internal/BLEManager.h +++ b/src/include/platform/internal/BLEManager.h @@ -102,7 +102,7 @@ extern BLEManagerImpl & BLEMgrImpl(); #ifdef EXTERNAL_BLEMANAGERIMPL_HEADER #include EXTERNAL_BLEMANAGERIMPL_HEADER #elif defined(CHIP_DEVICE_LAYER_TARGET) -#define BLEMANAGERIMPL_HEADER +#define BLEMANAGERIMPL_HEADER #include BLEMANAGERIMPL_HEADER #endif // defined(CHIP_DEVICE_LAYER_TARGET) diff --git a/src/lwip/efr32/BC4E174.tmp:6E53BFF5-0001-412b-8407-E3AEDE763511 b/src/lwip/efr32/BC4E174.tmp:6E53BFF5-0001-412b-8407-E3AEDE763511 new file mode 100644 index 00000000000000..63b206148c3db0 Binary files /dev/null and b/src/lwip/efr32/BC4E174.tmp:6E53BFF5-0001-412b-8407-E3AEDE763511 differ diff --git a/src/lwip/efr32/lwipopts-wf200.h:6E53BFF5-0001-412b-8407-E3AEDE763511 b/src/lwip/efr32/lwipopts-wf200.h:6E53BFF5-0001-412b-8407-E3AEDE763511 new file mode 100644 index 00000000000000..c037eda921270b Binary files /dev/null and b/src/lwip/efr32/lwipopts-wf200.h:6E53BFF5-0001-412b-8407-E3AEDE763511 differ diff --git a/src/lwip/efr32/lwipopts-wf200.h~:6E53BFF5-0001-412b-8407-E3AEDE763511 b/src/lwip/efr32/lwipopts-wf200.h~:6E53BFF5-0001-412b-8407-E3AEDE763511 new file mode 100644 index 00000000000000..24528e9fb0d243 Binary files /dev/null and b/src/lwip/efr32/lwipopts-wf200.h~:6E53BFF5-0001-412b-8407-E3AEDE763511 differ diff --git a/src/platform/EFR32/BLEManagerImpl.cpp b/src/platform/EFR32/BLEManagerImpl.cpp index 91de55f6698473..1c33d0ae933a85 100644 --- a/src/platform/EFR32/BLEManagerImpl.cpp +++ b/src/platform/EFR32/BLEManagerImpl.cpp @@ -43,7 +43,7 @@ extern "C" { #include #include #include -#include +#include ![](C:/Users/shgutte/AppData/Local/Temp/download.jpg) #include #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING @@ -1017,7 +1017,7 @@ extern "C" void sl_bt_on_event(sl_bt_msg_t * evt) break; case sl_bt_evt_connection_parameters_id: { // ChipLogProgress(DeviceLayer, "Connection parameter ID received"); - } + break; case sl_bt_evt_connection_phy_status_id: { // ChipLogProgress(DeviceLayer, "PHY update procedure is completed"); @@ -1045,10 +1045,13 @@ extern "C" void sl_bt_on_event(sl_bt_msg_t * evt) case sl_bt_evt_gatt_server_characteristic_status_id: { sl_bt_gatt_server_characteristic_status_flag_t StatusFlags; + + StatusFlags = (sl_bt_gatt_server_characteristic_status_flag_t) evt->data.evt_gatt_server_characteristic_status.status_flags; if (sl_bt_gatt_server_confirmation == StatusFlags) { + chip::DeviceLayer::Internal::BLEMgrImpl().HandleTxConfirmationEvent( evt->data.evt_gatt_server_characteristic_status.connection); } diff --git a/src/platform/EFR32/BUILD.gn b/src/platform/EFR32/BUILD.gn index 7e82963582d72e..c201fd0be34696 100644 --- a/src/platform/EFR32/BUILD.gn +++ b/src/platform/EFR32/BUILD.gn @@ -34,8 +34,11 @@ static_library("EFR32") { sources = [ "../FreeRTOS/SystemTimeSupport.cpp", "../SingletonConfigurationManager.cpp", - "BLEManagerImpl.cpp", - "BLEManagerImpl.h", + "RS911x/BLEManagerImpl.cpp", + "RS911x/wfx_sl_ble_init.h", + "RS911x/wfx_sl_ble_init.c", + "RS911x/rsi_ble_config.h", + "RS911x/BLEManagerImpl.h", "BlePlatformConfig.h", "CHIPDevicePlatformConfig.h", "CHIPDevicePlatformEvent.h", diff --git a/src/platform/EFR32/RS911x/BLEManagerImpl.cpp b/src/platform/EFR32/RS911x/BLEManagerImpl.cpp new file mode 100644 index 00000000000000..a66bbae956fd02 --- /dev/null +++ b/src/platform/EFR32/RS911x/BLEManagerImpl.cpp @@ -0,0 +1,1062 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * 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. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the Silicon Labs EFR32 platforms. + */ + +/* this file behaves like a config.h, comes first */ +#include +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include +#define RSI_BLE_ENABLE 1 + +#include "rail.h" +extern "C" { +#include +#include "FreeRTOS.h" +#include "event_groups.h" +#include "task.h" +#include "timers.h" +#include "wfx_host_events.h" +#include "wfx_rsi.h" +#include "wfx_sl_ble_init.h" +#include +#include +} +#include +#include +#include +#include +#include +#include + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +#include +#endif + +// static int32_t handleTxConfirmationFlag = 0; +extern uint16_t rsi_ble_measurement_hndl; +extern rsi_ble_event_conn_status_t conn_event_to_app; +extern sl_wfx_msg_t event_msg; + +StaticTask_t busInitTaskStruct; + +/* wfxRsi Task will use as its stack */ +StackType_t wfxRsiInitTaskStack[WFX_RSI_TASK_SZ] = { 0 }; + +using namespace ::chip; +using namespace ::chip::Ble; + +void rsi_ble_event_handling_task(void) +{ + int32_t event_id; + + WFX_RSI_LOG("StartAdvertising"); + chip::DeviceLayer::Internal::BLEManagerImpl().StartAdvertising(); //TODO:: Called on after init of module + + // Application event map + while (1) + { + // checking for events list + event_id = rsi_ble_app_get_event(); + if (event_id == -1) + { + continue; + } + switch (event_id) + { + case RSI_BLE_CONN_EVENT: { + rsi_ble_app_clear_event(RSI_BLE_CONN_EVENT); + chip::DeviceLayer::Internal::BLEMgrImpl().HandleConnectEvent(); + WFX_RSI_LOG(" RSI_BLE : Module got connected"); + } + break; + case RSI_BLE_DISCONN_EVENT: { + // event invokes when disconnection was completed + WFX_RSI_LOG(" RSI_BLE : Module got Disconnected"); + chip::DeviceLayer::Internal::BLEMgrImpl().HandleConnectionCloseEvent(event_msg.reason); + // clear the served event + rsi_ble_app_clear_event(RSI_BLE_DISCONN_EVENT); + } + break; + case RSI_BLE_MTU_EVENT: { + // event invokes when write/notification events received + WFX_RSI_LOG("RSI_BLE:: RSI_BLE_MTU_EVENT"); + chip::DeviceLayer::Internal::BLEMgrImpl().UpdateMtu(event_msg.rsi_ble_mtu); + // clear the served event + rsi_ble_app_clear_event(RSI_BLE_MTU_EVENT); + } + break; + case RSI_BLE_GATT_WRITE_EVENT: { + // event invokes when write/notification events received + WFX_RSI_LOG("RSI_BLE : RSI_BLE_GATT_WRITE_EVENT"); + chip::DeviceLayer::Internal::BLEMgrImpl().HandleWriteEvent(event_msg.rsi_ble_write); + // clear the served event + rsi_ble_app_clear_event(RSI_BLE_GATT_WRITE_EVENT); + } + break; + case RSI_BLE_GATT_INDICATION_CONFIRMATION: { + WFX_RSI_LOG("RSI_BLE : indication confirmation"); + chip::DeviceLayer::Internal::BLEMgrImpl().HandleTxConfirmationEvent(1); + rsi_ble_app_clear_event(RSI_BLE_GATT_INDICATION_CONFIRMATION); + } + break; + + case RSI_BLE_RESP_ATT_VALUE: { + WFX_RSI_LOG("RSI_BLE : RESP_ATT confirmation"); + } + default: + break; + } + } + + WFX_RSI_LOG("%s END", __func__); +} + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +namespace { + +#define CHIP_ADV_DATA_TYPE_FLAGS 0x01 +#define CHIP_ADV_DATA_TYPE_UUID 0x03 +#define CHIP_ADV_DATA_TYPE_NAME 0x09 +#define CHIP_ADV_DATA_TYPE_SERVICE_DATA 0x16 + +#define CHIP_ADV_DATA_FLAGS 0x06 + +#define CHIP_ADV_DATA 0 +#define CHIP_ADV_SCAN_RESPONSE_DATA 1 +#define CHIP_ADV_SHORT_UUID_LEN 2 + +#define MAX_RESPONSE_DATA_LEN 31 +#define MAX_ADV_DATA_LEN 31 + +// Timer Frequency used. +#define TIMER_CLK_FREQ ((uint32_t) 32768) + +// Convert msec to timer ticks. +#define TIMER_MS_2_TIMERTICK(ms) ((TIMER_CLK_FREQ * ms) / 1000) +#define TIMER_S_2_TIMERTICK(s) (TIMER_CLK_FREQ * s) + +#define BLE_MAX_BUFFER_SIZE (3076) +#define BLE_MAX_ADVERTISERS (1) +#define BLE_CONFIG_MAX_PERIODIC_ADVERTISING_SYNC (0) +#define BLE_CONFIG_MAX_SOFTWARE_TIMERS (4) +#define BLE_CONFIG_MIN_TX_POWER (-30) +#define BLE_CONFIG_MAX_TX_POWER (80) +#define BLE_CONFIG_RF_PATH_GAIN_TX (0) +#define BLE_CONFIG_RF_PATH_GAIN_RX (0) + +// Default Connection parameters +#define BLE_CONFIG_MIN_INTERVAL (16) // Time = Value x 1.25 ms = 30ms +#define BLE_CONFIG_MAX_INTERVAL (80) // Time = Value x 1.25 ms = 100ms +#define BLE_CONFIG_LATENCY (0) +#define BLE_CONFIG_TIMEOUT (100) // Time = Value x 10 ms = 1s +#define BLE_CONFIG_MIN_CE_LENGTH (0) // Leave to min value +#define BLE_CONFIG_MAX_CE_LENGTH (0xFFFF) // Leave to max value + +#define BLE__DEFAULT_TIMER_PERIOD 1 + +TimerHandle_t sbleAdvTimeoutTimer; // FreeRTOS sw timer. + +const uint8_t UUID_CHIPoBLEService[] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x10, 0x00, 0x00, 0xF6, 0xFF, 0x00, 0x00 }; +const uint8_t ShortUUID_CHIPoBLEService[] = { 0xF6, 0xFF }; +const ChipBleUUID ChipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x11 } }; +const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x12 } }; + +} // namespace + +BLEManagerImpl BLEManagerImpl::sInstance; + +CHIP_ERROR BLEManagerImpl::_Init() +{ + CHIP_ERROR err; + ChipLogProgress(DeviceLayer, "%s Start ", __func__); + + wfx_rsi.init_task = xTaskCreateStatic((TaskFunction_t) wfx_sl_module_init, "init_task", WFX_RSI_TASK_SZ, NULL, 1, wfxRsiInitTaskStack, &busInitTaskStruct); + + if (NULL == wfx_rsi.init_task) { + WFX_RSI_LOG("%s: error: failed to create task.", __func__); + } + + // Initialize the CHIP BleLayer. + err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); + SuccessOrExit(err); + + memset(mBleConnections, 0, sizeof(mBleConnections)); + memset(mIndConfId, kUnusedIndex, sizeof(mIndConfId)); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + + // Create FreeRTOS sw timer for BLE timeouts and interval change. + sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel + BLE__DEFAULT_TIMER_PERIOD, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = ble obj context + BleAdvTimeoutHandler // timer callback handler + ); + + mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + +exit: + ChipLogProgress(DeviceLayer, "%s END ", __func__); + return err; +} + +uint16_t BLEManagerImpl::_NumConnections(void) +{ + uint16_t numCons = 0; + for (uint16_t i = 0; i < kMaxConnections; i++) + { + if (mBleConnections[i].allocated) + { + numCons++; + } + } + + return numCons; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (mFlags.Has(Flags::kAdvertisingEnabled) != val) + { + mFlags.Set(Flags::kAdvertisingEnabled, val); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + +exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) +{ + switch (mode) + { + case BLEAdvertisingMode::kFastAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + break; + case BLEAdvertisingMode::kSlowAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, false); + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + mFlags.Set(Flags::kRestartAdvertising); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) +{ + if (strlen(mDeviceName) >= bufSize) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + strcpy(buf, mDeviceName); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName) +{ + ChipLogProgress(DeviceLayer, "_SetDeviceName Started"); + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported) + { + ChipLogProgress(DeviceLayer, "_SetDeviceName CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE"); + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + } + if (deviceName != NULL && deviceName[0] != 0) + { + if (strlen(deviceName) >= kMaxDeviceNameLength) + { + ChipLogProgress(DeviceLayer, "_SetDeviceName CHIP_ERROR_INVALID_ARGUMENT"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + strcpy(mDeviceName, deviceName); + mFlags.Set(Flags::kDeviceNameSet); + mFlags.Set(Flags::kRestartAdvertising); + ChipLogProgress(DeviceLayer, "Setting device name to : \"%s\"", mDeviceName); + } + else + { + mDeviceName[0] = 0; + } + PlatformMgr().ScheduleWork(DriveBLEState, 0); + ChipLogProgress(DeviceLayer, "_SetDeviceName Ended"); + return CHIP_NO_ERROR; +} + +void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLESubscribe: { + ChipDeviceEvent connEstEvent; + + ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLESubscribe"); + HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); + connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + PlatformMgr().PostEventOrDie(&connEstEvent); + } + break; + + case DeviceEventType::kCHIPoBLEUnsubscribe: { + ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe"); + HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); + } + break; + + case DeviceEventType::kCHIPoBLEWriteReceived: { + ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEWriteReceived"); + HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX, + PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); + } + break; + + case DeviceEventType::kCHIPoBLEConnectionError: { + ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEConnectionError"); + HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason); + } + break; + + case DeviceEventType::kCHIPoBLEIndicateConfirm: { + ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEIndicateConfirm"); + HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); + } + break; + + default: + ChipLogProgress(DeviceLayer, "_OnPlatformEvent default: event->Type = %d", event->Type); + break; + } +} + +bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SubscribeCharacteristic() not supported"); + return false; +} + +bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::UnsubscribeCharacteristic() not supported"); + return false; +} + +bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + // int32_t ret; + + ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId); + + // ret = rsi_ble_disconnect(1); + // err = MapBLEError(ret); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "sl_bt_connection_close() failed: %s", ErrorStr(err)); + } + + return true; //(err == CHIP_NO_ERROR); +} + +uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + CHIPoBLEConState * conState = const_cast(this)->GetConnectionState(conId); + return (conState != NULL) ? conState->mtu : 0; +} + +bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle data) +{ + int32_t status = 0; + WFX_RSI_LOG("In send indication"); + status = rsi_ble_indicate_value(event_msg.resp_enh_conn.dev_addr, event_msg.rsi_ble_measurement_hndl, (data->DataLength()), data->Start()); + if (status != RSI_SUCCESS) + { + WFX_RSI_LOG("indication %d failed with error code %lx ", status); + } + + return true; +} + +bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported"); + return false; +} + +bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported"); + return false; +} + +bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, + const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported"); + return false; +} + +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + // Nothing to do +} + +CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) +{ + switch (bleErr) + { + case SL_STATUS_OK: + return CHIP_NO_ERROR; + case SL_STATUS_BT_ATT_INVALID_ATT_LENGTH: + return CHIP_ERROR_INVALID_STRING_LENGTH; + case SL_STATUS_INVALID_PARAMETER: + return CHIP_ERROR_INVALID_ARGUMENT; + case SL_STATUS_INVALID_STATE: + return CHIP_ERROR_INCORRECT_STATE; + case SL_STATUS_NOT_SUPPORTED: + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + default: + return CHIP_ERROR(ChipError::Range::kPlatform, bleErr + CHIP_DEVICE_CONFIG_EFR32_BLE_ERROR_MIN); + } +} + +void BLEManagerImpl::DriveBLEState(void) +{ + + ChipLogProgress(DeviceLayer, "DriveBLEState starting"); + CHIP_ERROR err = CHIP_NO_ERROR; + + // Check if BLE stack is initialized + // VerifyOrExit(mFlags.Has(Flags::kEFRBLEStackInitialized), /* */); + + ChipLogProgress(DeviceLayer, "Start advertising if needed..."); + // Start advertising if needed... + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled) && + NumConnections() < kMaxConnections) + { + + ChipLogProgress(DeviceLayer, "Start/re-start advertising if not already started, or if there is a pending change"); + // Start/re-start advertising if not already started, or if there is a pending change + // to the advertising configuration. + if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kRestartAdvertising)) + { + err = StartAdvertising(); + SuccessOrExit(err); + } + } + + // Otherwise, stop advertising if it is enabled. + else if (mFlags.Has(Flags::kAdvertising)) + { + err = StopAdvertising(); + SuccessOrExit(err); + } + +exit: + ChipLogProgress(DeviceLayer, "DriveBLEState End"); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + } +} + +CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) +{ + + ChipBLEDeviceIdentificationInfo mDeviceIdInfo; + CHIP_ERROR err; + int32_t result; + uint8_t responseData[MAX_RESPONSE_DATA_LEN]; + uint8_t advData[MAX_ADV_DATA_LEN]; + uint32_t index = 0; + uint32_t mDeviceNameLength = 0; + uint8_t mDeviceIdInfoLength = 0; + err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); + + ChipLogProgress(DeviceLayer, "ConfigureAdvertisingData start"); + + VerifyOrExit((kMaxDeviceNameLength + 1) < UINT8_MAX, err = CHIP_ERROR_INVALID_ARGUMENT); + + memset(responseData, 0, MAX_RESPONSE_DATA_LEN); + memset(advData, 0, MAX_ADV_DATA_LEN); + + SuccessOrExit(err); + + if (!mFlags.Has(Flags::kDeviceNameSet)) + { + uint16_t discriminator; + SuccessOrExit(err = GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator)); + + snprintf(mDeviceName, sizeof(mDeviceName), "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, discriminator); + + mDeviceName[kMaxDeviceNameLength] = 0; + mDeviceNameLength = strlen(mDeviceName); + + VerifyOrExit(mDeviceNameLength < kMaxDeviceNameLength, err = CHIP_ERROR_INVALID_ARGUMENT); + } + + mDeviceNameLength = strlen(mDeviceName); // Device Name length + length field + VerifyOrExit(mDeviceNameLength < kMaxDeviceNameLength, err = CHIP_ERROR_INVALID_ARGUMENT); + + mDeviceIdInfoLength = sizeof(mDeviceIdInfo); // Servicedatalen + length+ UUID (Short) + static_assert(sizeof(mDeviceIdInfo) + CHIP_ADV_SHORT_UUID_LEN + 1 <= UINT8_MAX, "Our length won't fit in a uint8_t"); + static_assert(2 + CHIP_ADV_SHORT_UUID_LEN + sizeof(mDeviceIdInfo) + 1 <= MAX_ADV_DATA_LEN, "Our buffer is not big enough"); + + index = 0; + advData[index++] = 0x02; // length + advData[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags + advData[index++] = CHIP_ADV_DATA_FLAGS; // AD value + advData[index++] = static_cast(mDeviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1); // AD length + advData[index++] = CHIP_ADV_DATA_TYPE_SERVICE_DATA; // AD type : Service Data + advData[index++] = ShortUUID_CHIPoBLEService[0]; // AD value + advData[index++] = ShortUUID_CHIPoBLEService[1]; + + // TODO:: replace the hardcoded values by calling the GetBLEDeviceIdentificationInfo + advData[index++] = 0; // OpCode + advData[index++] = 0; // DeviceDiscriminatorAndAdvVersion [] + advData[index++] = 15; // DeviceDiscriminatorAndAdvVersion [] + advData[index++] = 241; // DeviceVendorId [] + advData[index++] = 255; // DeviceVendorId [] + advData[index++] = 5; // DeviceProductId[] + advData[index++] = 128; // DeviceProductId[] + advData[index++] = 0; // AdditionalDataFlag + + //! prepare advertise data //local/device name + advData[index++] = strlen(RSI_BLE_DEV_NAME) + 1; + advData[index++] = 9; + + memcpy(&advData[index], RSI_BLE_DEV_NAME, strlen(RSI_BLE_DEV_NAME)); // AD value + index += strlen(RSI_BLE_DEV_NAME); + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + ReturnErrorOnFailure(EncodeAdditionalDataTlv()); +#endif + + result = rsi_ble_set_advertise_data(advData, index); + if (result != SL_STATUS_OK) + { + err = MapBLEError(result); + ChipLogError(DeviceLayer, "rsi_ble_set_advertise_data() failed: %ld", result); + ExitNow(); + } + else + { + ChipLogError(DeviceLayer, "rsi_ble_set_advertise_data() success: %ld", result); + } + + err = MapBLEError(result); + + ChipLogProgress(DeviceLayer, "ConfigureAdvertisingData End"); +exit: + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::StartAdvertising(void) +{ + CHIP_ERROR err; + int32_t status = 0; + + ChipLogProgress(DeviceLayer, "StartAdvertising start"); + + // If already advertising, stop it, before changing values + if (mFlags.Has(Flags::kAdvertising)) + { + // sl_bt_advertiser_stop(advertising_set_handle); + } + else + { + ChipLogDetail(DeviceLayer, "Start BLE advertissement"); + } + + bd_addr unusedBdAddr; // We can ignore this field when setting random address. + + (void) unusedBdAddr; + + err = ConfigureAdvertisingData(); + SuccessOrExit(err); + + mFlags.Clear(Flags::kRestartAdvertising); + + sl_wfx_mac_address_t macaddr; + wfx_get_wifi_mac_addr(SL_WFX_STA_INTERFACE, &macaddr); + + //! Set local name + status = rsi_ble_start_advertising(); + if (status == RSI_SUCCESS) + { + ChipLogProgress(DeviceLayer, "rsi_ble_start_advertising Success"); + + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME); + } + mFlags.Set(Flags::kAdvertising); + } + else + { + ChipLogProgress(DeviceLayer, "rsi_ble_start_advertising Failed with status: %lx", status); + } + +exit: + ChipLogError(DeviceLayer, "StartAdvertising() End error: %s", ErrorStr(err)); + return CHIP_NO_ERROR; // err; +} + +// TODO:: Implementation need to be done. +CHIP_ERROR BLEManagerImpl::StopAdvertising(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + // sl_status_t ret; + + if (mFlags.Has(Flags::kAdvertising)) + { + mFlags.Clear(Flags::kAdvertising).Clear(Flags::kRestartAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + + // ret = sl_bt_advertiser_stop(advertising_set_handle); + // sl_bt_advertiser_delete_set(advertising_set_handle); + advertising_set_handle = 0xff; + // err = MapBLEError(ret); + // SuccessOrExit(err); + + CancelBleAdvTimeoutTimer(); + } + + // exit: + return err; +} + +void BLEManagerImpl::UpdateMtu(rsi_ble_event_mtu_t evt) +{ + CHIPoBLEConState * bleConnState = GetConnectionState(event_msg.connectionHandle); + if (bleConnState != NULL) + { + // bleConnState->MTU is a 10-bit field inside a uint16_t. We're + // assigning to it from a uint16_t, and compilers warn about + // possibly not fitting. There's no way to suppress that warning + // via explicit cast; we have to disable the warning around the + // assignment. + // + // TODO: https://github.com/project-chip/connectedhomeip/issues/2569 + // tracks making this safe with a check or explaining why no check + // is needed. + ChipLogProgress(DeviceLayer, "DriveBLEState UpdateMtu %d", evt.mtu_size); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" + bleConnState->mtu = evt.mtu_size; +#pragma GCC diagnostic pop + ; + } +} + +void BLEManagerImpl::HandleBootEvent(void) +{ + mFlags.Set(Flags::kEFRBLEStackInitialized); + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + +void BLEManagerImpl::HandleConnectEvent(void) +{ + ChipLogProgress(DeviceLayer, "Connect Event for handle : %d", event_msg.connectionHandle); + AddConnection(event_msg.connectionHandle, event_msg.bondingHandle); + + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + +// TODO:: Implementation need to be done. +void BLEManagerImpl::HandleConnectionCloseEvent(uint16_t reason) +{ + uint8_t connHandle = 1; + + ChipLogProgress(DeviceLayer, "Disconnect Event for handle : %d", connHandle); + + if (RemoveConnection(connHandle)) + { + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEConnectionError; + event.CHIPoBLEConnectionError.ConId = connHandle; + + switch (reason) + { + + case RSI_BT_CTRL_REMOTE_USER_TERMINATED: + case RSI_BT_CTRL_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES: + case RSI_BT_CTRL_REMOTE_POWERING_OFF: + event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; + break; + default: + event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; + } + + ChipLogProgress(DeviceLayer, "BLE GATT connection closed (con %u, reason %x)", connHandle, reason); + + PlatformMgr().PostEventOrDie(&event); + + // Arrange to re-enable connectable advertising in case it was disabled due to the + // maximum connection limit being reached. + mFlags.Set(Flags::kRestartAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } +} + +void BLEManagerImpl::HandleWriteEvent(rsi_ble_event_write_t evt) +{ + // RSI_BLE_WRITE_REQUEST_EVENT + ChipLogProgress(DeviceLayer, "Char Write Req, packet type %d", evt.pkt_type); + // uint8_t attribute = (uint8_t) event_msg.rsi_ble_measurement_hndl; + + WFX_RSI_LOG("event_msg.rsi_ble_gatt_server_client_config_hndl = %d", event_msg.rsi_ble_gatt_server_client_config_hndl); + + if (evt.handle[0] == (uint8_t) event_msg.rsi_ble_gatt_server_client_config_hndl) //TODO:: compare the handle exactly + { + WFX_RSI_LOG("Inside HandleTXCharCCCDWrite "); + HandleTXCharCCCDWrite(&evt); + } + else + { + HandleRXCharWrite(&evt); + } +} + +void BLEManagerImpl::HandleTXCharCCCDWrite(rsi_ble_event_write_t *evt) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + // CHIPoBLEConState * bleConnState; + bool isIndicationEnabled = false; + ChipDeviceEvent event; + +// bleConnState = GetConnectionState(evt->data.evt_gatt_server_user_write_request.connection); +// VerifyOrExit(bleConnState != NULL, err = CHIP_ERROR_NO_MEMORY); + + // Determine if the client is enabling or disabling notification/indication. + if(evt->att_value[0] == 1){ + isIndicationEnabled = true; + } + ChipLogProgress(DeviceLayer, "HandleTXcharCCCDWrite - Config Flags value : %d", + evt->att_value[0] ); + ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", isIndicationEnabled ? "subscribe" : "unsubscribe"); + + if (isIndicationEnabled) + { +// // If indications are not already enabled for the connection... +// if (!event_msg->subscribed) +// { + event_msg.subscribed = 1; + // Post an event to the CHIP queue to process either a CHIPoBLE Subscribe or Unsubscribe based on + // whether the client is enabling or disabling indications. + { + event.Type = DeviceEventType::kCHIPoBLESubscribe; + event.CHIPoBLESubscribe.ConId = 1; + err = PlatformMgr().PostEvent(&event); + } + //} + } + else + { + event_msg.subscribed = 0; + event.Type = DeviceEventType::kCHIPoBLEUnsubscribe; + event.CHIPoBLESubscribe.ConId = 1; + err = PlatformMgr().PostEvent(&event); + } + +// CHIP_ERROR err = CHIP_NO_ERROR; +// ChipDeviceEvent event; +// // whether the client is enabling or disabling indications. +// { +// event.Type = DeviceEventType::kCHIPoBLESubscribe; +// event.CHIPoBLESubscribe.ConId = 1; +// err = PlatformMgr().PostEvent(&event); +// } +} + +void BLEManagerImpl::HandleRXCharWrite(rsi_ble_event_write_t * evt) +{ + uint8_t conId = 1; + CHIP_ERROR err = CHIP_NO_ERROR; + System::PacketBufferHandle buf; + uint16_t writeLen = evt->length; + uint8_t * data = (uint8_t *) evt->att_value; + + for (int i = 0; i < evt->length; i++) + { + ChipLogDetail(DeviceLayer, "HandleRXCharWrite value : %d", evt->att_value[i]); + } + + // Copy the data to a packet buffer. + buf = System::PacketBufferHandle::NewWithData(data, writeLen, 0, 0); + VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY); + + ChipLogDetail(DeviceLayer, "Write request/command received for CHIPoBLE RX characteristic ( len %d)", writeLen); + + // Post an event to the CHIP queue to deliver the data into the CHIP stack. + { + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEWriteReceived; + event.CHIPoBLEWriteReceived.ConId = conId; + event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); + err = PlatformMgr().PostEvent(&event); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err)); + } +} + +void BLEManagerImpl::HandleTxConfirmationEvent(BLE_CONNECTION_OBJECT conId) +{ + ChipDeviceEvent event; +// uint8_t timerHandle = sInstance.GetTimerHandle(conId, false); +// +// ChipLogProgress(DeviceLayer, "Tx Confirmation received"); +// +// // stop indication confirmation timer // TODO:: Need to find the proper repleacement +// if (timerHandle < kMaxConnections) +// { +// ChipLogProgress(DeviceLayer, " stop soft timer"); +// // sl_bt_system_set_lazy_soft_timer(0, 0, timerHandle, false); +// } + + event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; + event.CHIPoBLEIndicateConfirm.ConId = conId; + PlatformMgr().PostEventOrDie(&event); +} + +// TODO:: Need to Implement +void BLEManagerImpl::HandleSoftTimerEvent(void) +{ + + // BLE Manager starts soft timers with timer handles less than kMaxConnections + // If we receive a callback for unknown timer handle ignore this. + // if (evt->data.evt_system_soft_timer.handle < kMaxConnections) + // { + // ChipLogProgress(DeviceLayer, "BLEManagerImpl::HandleSoftTimerEvent CHIPOBLE_PROTOCOL_ABORT"); + // ChipDeviceEvent event; + // event.Type = DeviceEventType::kCHIPoBLEConnectionError; + // event.CHIPoBLEConnectionError.ConId = mIndConfId[evt->data.evt_system_soft_timer.handle]; + // sInstance.mIndConfId[evt->data.evt_system_soft_timer.handle] = kUnusedIndex; + // event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; + // PlatformMgr().PostEventOrDie(&event); + // } +} + +bool BLEManagerImpl::RemoveConnection(uint8_t connectionHandle) +{ + CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle, true); + bool status = false; + + if (bleConnState != NULL) + { + memset(bleConnState, 0, sizeof(CHIPoBLEConState)); + status = true; + } + + return status; +} + +void BLEManagerImpl::AddConnection(uint8_t connectionHandle, uint8_t bondingHandle) +{ + CHIPoBLEConState * bleConnState = GetConnectionState(connectionHandle, true); + + if (bleConnState != NULL) + { + memset(bleConnState, 0, sizeof(CHIPoBLEConState)); + bleConnState->allocated = 1; + bleConnState->connectionHandle = connectionHandle; + bleConnState->bondingHandle = bondingHandle; + } +} + +BLEManagerImpl::CHIPoBLEConState * BLEManagerImpl::GetConnectionState(uint8_t connectionHandle, bool allocate) +{ + uint8_t freeIndex = kMaxConnections; + + for (uint8_t i = 0; i < kMaxConnections; i++) + { + if (mBleConnections[i].allocated == 1) + { + if (mBleConnections[i].connectionHandle == connectionHandle) + { + return &mBleConnections[i]; + } + } + + else if (i < freeIndex) + { + freeIndex = i; + } + } + + if (allocate) + { + if (freeIndex < kMaxConnections) + { + return &mBleConnections[freeIndex]; + } + + ChipLogError(DeviceLayer, "Failed to allocate CHIPoBLEConState"); + } + + return NULL; +} + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +CHIP_ERROR BLEManagerImpl::EncodeAdditionalDataTlv() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BitFlags additionalDataFields; + AdditionalDataPayloadGeneratorParams additionalDataPayloadParams; + +#if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) + uint8_t rotatingDeviceIdUniqueId[ConfigurationManager::kRotatingDeviceIDUniqueIDLength] = {}; + MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId); + + err = DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan); + SuccessOrExit(err); + err = ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter); + SuccessOrExit(err); + additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan; + additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId); +#endif /* CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID) */ + + err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(additionalDataPayloadParams, c3AdditionalDataBufferHandle, + additionalDataFields); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data (%s)", __func__); + } + + return err; +} + +// TODO:: Need the +void BLEManagerImpl::HandleC3ReadRequest(void) +{ + // sl_bt_evt_gatt_server_user_read_request_t * readReq = + // (sl_bt_evt_gatt_server_user_read_request_t *) &(evt->data.evt_gatt_server_user_read_request); + // ChipLogDetail(DeviceLayer, "Read request received for CHIPoBLEChar_C3 - opcode:%d", readReq->att_opcode); + // sl_status_t ret = sl_bt_gatt_server_send_user_read_response(readReq->connection, readReq->characteristic, 0, + // sInstance.c3AdditionalDataBufferHandle->DataLength(), + // sInstance.c3AdditionalDataBufferHandle->Start(), nullptr); + + // if (ret != SL_STATUS_OK) + // { + // ChipLogDetail(DeviceLayer, "Failed to send read response, err:%ld", ret); + // } +} +#endif // CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + +uint8_t BLEManagerImpl::GetTimerHandle(uint8_t connectionHandle, bool allocate) +{ + uint8_t freeIndex = kMaxConnections; + + for (uint8_t i = 0; i < kMaxConnections; i++) + { + if (mIndConfId[i] == connectionHandle) + { + return i; + } + else if (allocate) + { + if (i < freeIndex) + { + freeIndex = i; + } + } + } + + if (freeIndex < kMaxConnections) + { + mIndConfId[freeIndex] = connectionHandle; + } + else + { + ChipLogError(DeviceLayer, "Failed to Save Conn Handle for indication"); + } + + return freeIndex; +} + +void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) +{ + if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertissment"); + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); + } +} + +void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) +{ + if (xTimerStop(sbleAdvTimeoutTimer, 0) == pdFAIL) + { + ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); + } +} + +void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) + { + CancelBleAdvTimeoutTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sbleAdvTimeoutTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) + { + ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); + } +} + +void BLEManagerImpl::DriveBLEState(intptr_t arg) +{ + sInstance.DriveBLEState(); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/EFR32/BLEManagerImpl.h b/src/platform/EFR32/RS911x/BLEManagerImpl.h similarity index 90% rename from src/platform/EFR32/BLEManagerImpl.h rename to src/platform/EFR32/RS911x/BLEManagerImpl.h index 0f1d478f179b61..cd51fe3fc626a7 100644 --- a/src/platform/EFR32/BLEManagerImpl.h +++ b/src/platform/EFR32/RS911x/BLEManagerImpl.h @@ -27,10 +27,18 @@ #include "FreeRTOS.h" #include "gatt_db.h" -#include "sl_bgapi.h" -#include "sl_bt_api.h" #include "timers.h" +extern "C" { +#include +#include +#include +#include +#include +//#include "wfx_sl_ble_init.h" + +} + namespace chip { namespace DeviceLayer { namespace Internal { @@ -45,16 +53,16 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla public: void HandleBootEvent(void); - void HandleConnectEvent(volatile sl_bt_msg_t * evt); - void HandleConnectionCloseEvent(volatile sl_bt_msg_t * evt); - void HandleWriteEvent(volatile sl_bt_msg_t * evt); - void UpdateMtu(volatile sl_bt_msg_t * evt); + void HandleConnectEvent(void);//volatile sl_bt_msg_t * evt); + void HandleConnectionCloseEvent(uint16_t reason); + void HandleWriteEvent(rsi_ble_event_write_t evt); + void UpdateMtu(rsi_ble_event_mtu_t evt); void HandleTxConfirmationEvent(BLE_CONNECTION_OBJECT conId); - void HandleTXCharCCCDWrite(volatile sl_bt_msg_t * evt); - void HandleSoftTimerEvent(volatile sl_bt_msg_t * evt); + void HandleTXCharCCCDWrite(rsi_ble_event_write_t *evt); + void HandleSoftTimerEvent(void); #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - static void HandleC3ReadRequest(volatile sl_bt_msg_t * evt); + static void HandleC3ReadRequest(void); #endif private: @@ -144,16 +152,20 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING PacketBufferHandle c3AdditionalDataBufferHandle; #endif +public: + void DriveBLEState(void); + CHIP_ERROR StartAdvertising(void); +private: CHIP_ERROR MapBLEError(int bleErr); - void DriveBLEState(void); +// void DriveBLEState(void); CHIP_ERROR ConfigureAdvertisingData(void); - CHIP_ERROR StartAdvertising(void); + //CHIP_ERROR StartAdvertising(void); CHIP_ERROR StopAdvertising(void); #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING CHIP_ERROR EncodeAdditionalDataTlv(); #endif - void HandleRXCharWrite(volatile sl_bt_msg_t * evt); + void HandleRXCharWrite(rsi_ble_event_write_t * evt); bool RemoveConnection(uint8_t connectionHandle); void AddConnection(uint8_t connectionHandle, uint8_t bondingHandle); void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs); diff --git a/src/platform/EFR32/RS911x/rsi_ble_config.h b/src/platform/EFR32/RS911x/rsi_ble_config.h new file mode 100644 index 00000000000000..bfc710f45ebacc --- /dev/null +++ b/src/platform/EFR32/RS911x/rsi_ble_config.h @@ -0,0 +1,283 @@ +/******************************************************************************* + * @file rsi_ble_config.h + * @brief + ******************************************************************************* + * # License + * Copyright 2020 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef RSI_BLE_CONFIG_H +#define RSI_BLE_CONFIG_H + +#include "rsi_ble_apis.h" +#include +/****************************************************** + * * Macros + * ******************************************************/ +//! application event list +#define RSI_BLE_CONN_EVENT 0x01 +#define RSI_BLE_DISCONN_EVENT 0x02 +#define RSI_BLE_GATT_WRITE_EVENT 0x03 +#define RSI_BLE_MTU_EVENT 0x04 +#define RSI_BLE_GATT_INDICATION_CONFIRMATION 0x05 +#define RSI_BLE_RESP_ATT_VALUE 0x06 +#define RSI_SSID 0x0D +#define RSI_SECTYPE 0x0E +#define RSI_BLE_WLAN_DISCONN_NOTIFY 0x0F +#define RSI_WLAN_ALREADY 0x10 +#define RSI_WLAN_NOT_ALREADY 0x11 +#define RSI_BLE_WLAN_TIMEOUT_NOTIFY 0x12 +#define RSI_BLE_WLAN_JOIN_STATUS 0x15 +#define RSI_APP_FW_VERSION 0x13 +#define RSI_BLE_WLAN_DISCONNECT_STATUS 0x14 + +#define RSI_REM_DEV_ADDR_LEN 18 +#define RSI_REM_DEV_NAME_LEN 31 + +#define RSI_BLE_DEV_NAME "WFX_RSI_dev" +#define RSI_BLE_SET_RAND_ADDR "00:23:A7:12:34:56" + +#define CLEAR_WHITELIST 0x00 +#define ADD_DEVICE_TO_WHITELIST 0x01 +#define DELETE_DEVICE_FROM_WHITELIST 0x02 + +#define ALL_PHYS 0x00 + +#define RSI_BLE_DEV_ADDR_RESOLUTION_ENABLE 0 + +#define RSI_OPERMODE_WLAN_BLE 13 + +/***********************************************************************************************************************************************/ +//! Characteristic Presenatation Format Fields +/***********************************************************************************************************************************************/ +#define RSI_BLE_UINT8_FORMAT 0x04 +#define RSI_BLE_EXPONENT 0x00 +#define RSI_BLE_PERCENTAGE_UNITS_UUID 0x27AD +#define RSI_BLE_NAME_SPACE 0x01 +#define RSI_BLE_DESCRIPTION 0x010B + +//! BLE characteristic custom service uuid +#define RSI_BLE_CUSTOM_SERVICE_UUID 0xFFF6 +#define RSI_BLE_CUSTOM_LEVEL_UUID 0x1FF1 + +#ifdef RSI_M4_INTERFACE +#define RSI_BLE_MAX_NBR_ATT_REC 20 +#define RSI_BLE_MAX_NBR_SLAVES 1 +#define RSI_BLE_NUM_CONN_EVENTS 2 +#else +#define RSI_BLE_MAX_NBR_ATT_REC 80 +#define RSI_BLE_MAX_NBR_SLAVES 3 +#define RSI_BLE_NUM_CONN_EVENTS 20 +#endif + +#define RSI_BLE_MAX_NBR_ATT_SERV 10 + +#define RSI_BLE_MAX_NBR_MASTERS 1 +#define RSI_BLE_GATT_ASYNC_ENABLE 1 +#define RSI_BLE_GATT_INIT 0 + +/* Number of BLE GATT RECORD SIZE IN (n*16 BYTES), eg:(0x40*16)=1024 bytes */ +#define RSI_BLE_NUM_REC_BYTES 0x40 + +#define RSI_BLE_INDICATE_CONFIRMATION_FROM_HOST 0 + +/*=======================================================================*/ +//! Advertising command parameters +/*=======================================================================*/ + +#define RSI_BLE_ADV_TYPE UNDIR_CONN +#define RSI_BLE_ADV_FILTER_TYPE ALLOW_SCAN_REQ_ANY_CONN_REQ_ANY +#define RSI_BLE_ADV_DIR_ADDR_TYPE LE_PUBLIC_ADDRESS +#define RSI_BLE_ADV_DIR_ADDR "00:15:83:6A:64:17" + +#define RSI_BLE_ADV_INT_MIN 0x100 +#define RSI_BLE_ADV_INT_MAX 0x200 +#define RSI_BLE_ADV_CHANNEL_MAP 0x07 + +//! Advertise status +//! Start the advertising process +#define RSI_BLE_START_ADV 0x01 +//! Stop the advertising process +#define RSI_BLE_STOP_ADV 0x00 + +//! BLE Tx Power Index On Air +#define RSI_BLE_PWR_INX 30 + +//! BLE Active H/w Pwr Features +#define BLE_DISABLE_DUTY_CYCLING 0 +#define BLE_DUTY_CYCLING 1 +#define BLR_DUTY_CYCLING 2 +#define BLE_4X_PWR_SAVE_MODE 4 +#define RSI_BLE_PWR_SAVE_OPTIONS BLE_DISABLE_DUTY_CYCLING + +//! Advertise types + +/* Advertising will be visible(discoverable) to all the devices. + * Scanning/Connection is also accepted from all devices + * */ +#define UNDIR_CONN 0x80 + +/* Advertising will be visible(discoverable) to the particular device + * mentioned in RSI_BLE_ADV_DIR_ADDR only. + * Scanning and Connection will be accepted from that device only. + * */ +#define DIR_CONN 0x81 + +/* Advertising will be visible(discoverable) to all the devices. + * Scanning will be accepted from all the devices. + * Connection will be not be accepted from any device. + * */ +#define UNDIR_SCAN 0x82 + +/* Advertising will be visible(discoverable) to all the devices. + * Scanning and Connection will not be accepted from any device + * */ +#define UNDIR_NON_CONN 0x83 + +/* Advertising will be visible(discoverable) to the particular device + * mentioned in RSI_BLE_ADV_DIR_ADDR only. + * Scanning and Connection will be accepted from that device only. + * */ +#define DIR_CONN_LOW_DUTY_CYCLE 0x84 + +//! Advertising flags +#define LE_LIMITED_DISCOVERABLE 0x01 +#define LE_GENERAL_DISCOVERABLE 0x02 +#define LE_BR_EDR_NOT_SUPPORTED 0x04 + +//! Advertise filters +#define ALLOW_SCAN_REQ_ANY_CONN_REQ_ANY 0x00 +#define ALLOW_SCAN_REQ_WHITE_LIST_CONN_REQ_ANY 0x01 +#define ALLOW_SCAN_REQ_ANY_CONN_REQ_WHITE_LIST 0x02 +#define ALLOW_SCAN_REQ_WHITE_LIST_CONN_REQ_WHITE_LIST 0x03 + +//! Address types +#define LE_PUBLIC_ADDRESS 0x00 +#define LE_RANDOM_ADDRESS 0x01 +#define LE_RESOLVABLE_PUBLIC_ADDRESS 0x02 +#define LE_RESOLVABLE_RANDOM_ADDRESS 0x03 + +/*=======================================================================*/ + +/*=======================================================================*/ +//! Connection parameters +/*=======================================================================*/ +#define LE_SCAN_INTERVAL 0x0100 +#define LE_SCAN_WINDOW 0x0050 + +#define CONNECTION_INTERVAL_MIN 0x00A0 +#define CONNECTION_INTERVAL_MAX 0x00A0 + +#define CONNECTION_LATENCY 0x0000 +#define SUPERVISION_TIMEOUT 0x07D0 // 2000 + +/*=======================================================================*/ + +/*=======================================================================*/ +//! Scan command parameters +/*=======================================================================*/ + +#define RSI_BLE_SCAN_TYPE SCAN_TYPE_ACTIVE +#define RSI_BLE_SCAN_FILTER_TYPE SCAN_FILTER_TYPE_ALL + +//!Scan status +#define RSI_BLE_START_SCAN 0x01 +#define RSI_BLE_STOP_SCAN 0x00 + +//!Scan types +#define SCAN_TYPE_ACTIVE 0x01 +#define SCAN_TYPE_PASSIVE 0x00 + +//!Scan filters +#define SCAN_FILTER_TYPE_ALL 0x00 +#define SCAN_FILTER_TYPE_ONLY_WHITE_LIST 0x01 + +#define RSI_SEL_INTERNAL_ANTENNA 0x00 +#define RSI_SEL_EXTERNAL_ANTENNA 0x01 + +#define SL_WFX_BLE_SCAN_TYPE SCAN_TYPE_ACTIVE +#define SL_WFX_BLE_SCAN_FILTER_TYPE SCAN_FILTER_TYPE_ALL + +//! Scan status +#define SL_WFX_BLE_START_SCAN 0x01 +#define SL_WFX_BLE_STOP_SCAN 0x00 + +//! Scan types +#define SCAN_TYPE_ACTIVE 0x01 +#define SCAN_TYPE_PASSIVE 0x00 + +//! Scan filters +#define SCAN_FILTER_TYPE_ALL 0x00 +#define SCAN_FILTER_TYPE_ONLY_WHITE_LIST 0x01 + +#define SL_WFX_SEL_INTERNAL_ANTENNA 0x00 +#define SL_WFX_SEL_EXTERNAL_ANTENNA 0x01 + +#define SL_WFX_BT_CTRL_REMOTE_USER_TERMINATED 0x4E13 +#define SL_WFX_BT_CTRL_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES 0x4E14 +#define SL_WFX_BT_CTRL_REMOTE_POWERING_OFF 0x4E15 +#define SL_WFX_BT_CTRL_TERMINATED_MIC_FAILURE 0x4E3D +#define SL_WFX_BT_FAILED_TO_ESTABLISH_CONN 0x4E3E +#define SL_WFX_BT_INVALID_RANGE 0x4E60 + + +/***********************************************************************************************************************************************/ +//! RS9116 Firmware Configurations +/***********************************************************************************************************************************************/ + +/*=======================================================================*/ +//! Opermode command parameters +/*=======================================================================*/ +/* +#define RSI_FEATURE_BIT_MAP \ + (FEAT_ULP_GPIO_BASED_HANDSHAKE | FEAT_DEV_TO_HOST_ULP_GPIO_1) //! To set wlan feature select bit map +#define RSI_TCP_IP_BYPASS RSI_DISABLE //! TCP IP BYPASS feature check +#define RSI_TCP_IP_FEATURE_BIT_MAP \ + (TCP_IP_FEAT_DHCPV4_CLIENT) //! TCP/IP feature select bitmap for selecting TCP/IP features +#define RSI_EXT_TCPIP_FEATURE_BITMAP 0 + +#define RSI_CUSTOM_FEATURE_BIT_MAP FEAT_CUSTOM_FEAT_EXTENTION_VALID //! To set custom feature select bit map + +#define RSI_EXT_CUSTOM_FEATURE_BIT_MAP (EXT_FEAT_LOW_POWER_MODE | EXT_FEAT_XTAL_CLK_ENABLE | EXT_FEAT_384K_MODE) + +#define RSI_BT_FEATURE_BITMAP (BT_RF_TYPE | ENABLE_BLE_PROTOCOL) +*/ +/*=======================================================================*/ +//! Power save command parameters +/*=======================================================================*/ +//! set handshake type of power mode +//#define RSI_HAND_SHAKE_TYPE GPIO_BASED + +#define BLE_ATT_REC_SIZE 500 +#define NO_OF_VAL_ATT 5 //! Attribute value count + +/***********************************************************************************************************************************************/ +//! user defined structure +/***********************************************************************************************************************************************/ +typedef struct rsi_ble_att_list_s +{ + uuid_t char_uuid; + uint16_t handle; + uint16_t value_len; + uint16_t max_value_len; + uint8_t char_val_prop; + void * value; +} rsi_ble_att_list_t; +typedef struct rsi_ble_s +{ + uint8_t DATA[BLE_ATT_REC_SIZE]; + uint16_t DATA_ix; + uint16_t att_rec_list_count; + rsi_ble_att_list_t att_rec_list[NO_OF_VAL_ATT]; +} rsi_ble_t; + +#endif diff --git a/src/platform/EFR32/RS911x/wfx_sl_ble_init.c b/src/platform/EFR32/RS911x/wfx_sl_ble_init.c new file mode 100644 index 00000000000000..63426e0c9dd014 --- /dev/null +++ b/src/platform/EFR32/RS911x/wfx_sl_ble_init.c @@ -0,0 +1,552 @@ +/******************************************************************************* +* @file wfx_sl_ble_init.c +* @brief +******************************************************************************* +* # License +* Copyright 2021 Silicon Laboratories Inc. www.silabs.com +******************************************************************************* +* +* The licensor of this software is Silicon Laboratories Inc. Your use of this +* software is governed by the terms of Silicon Labs Master Software License +* Agreement (MSLA) available at +* www.silabs.com/about-us/legal/master-software-license-agreement. This +* software is distributed to you in Source Code format and is governed by the +* sections of the MSLA applicable to Source Code. +* +******************************************************************************/ +/************************************************************************* + * + */ + + /*================================================================================ + * @brief : This file contains example application for Wlan Station BLE + * Provisioning + * @section Description : + * This application explains how to get the WLAN connection functionality using + * BLE provisioning. + * Silicon Labs Module starts advertising and with BLE Provisioning the Access Point + * details are fetched. + * Silicon Labs device is configured as a WiFi station and connects to an Access Point. + =================================================================================*/ + +#include "wfx_sl_ble_init.h" +#include "rsi_ble_config.h" + +// application defines +rsi_ble_event_conn_status_t conn_event_to_app; +rsi_ble_t att_list; +sl_wfx_msg_t event_msg; + +// Memory to initialize driver +uint8_t bt_global_buf[BT_GLOBAL_BUFF_LEN]; +static uint8_t wfx_rsi_drv_buf[WFX_RSI_BUF_SZ]; +const uint8_t ShortUUID_CHIPoBLEService[] = { 0xF6, 0xFF }; + +/* Rsi driver Task will use as its stack */ +StackType_t driverRsiTaskStack[WFX_RSI_WLAN_TASK_SZ] = { 0 }; + +/* Structure that will hold the TCB of the wfxRsi Task being created. */ +StaticTask_t driverRsiTaskBuffer; + +StaticTask_t rsiBLETaskStruct; + +/* wfxRsi Task will use as its stack */ +StackType_t wfxBLETaskStack[WFX_RSI_TASK_SZ] = { 0 }; + +int32_t wfx_sl_module_init(void) +{ + int32_t status; + uint8_t buf[RSI_RESPONSE_HOLD_BUFF_SIZE]; + extern void rsi_hal_board_init(void); + + WFX_RSI_LOG("%s: starting(HEAP_SZ = %d)", __func__, SL_HEAP_SIZE); + + //! Driver initialization + status = rsi_driver_init(wfx_rsi_drv_buf, WFX_RSI_BUF_SZ); + if ((status < RSI_DRIVER_STATUS) || (status > WFX_RSI_BUF_SZ)) + { + WFX_RSI_LOG("%s: error: RSI Driver initialization failed with status: %02x", __func__, status); + return status; + } + + WFX_RSI_LOG("%s: rsi_device_init", __func__); + + /* ! Redpine module intialisation */ + if ((status = rsi_device_init(LOAD_NWP_FW)) != RSI_SUCCESS) + { + WFX_RSI_LOG("%s: error: rsi_device_init failed with status: %02x", __func__, status); + return status; + } + WFX_RSI_LOG("%s: start wireless drv task", __func__); + + /* + * Create the driver task + */ + wfx_rsi.drv_task = xTaskCreateStatic((TaskFunction_t) rsi_wireless_driver_task, "rsi_drv", WFX_RSI_WLAN_TASK_SZ, NULL, + 1, driverRsiTaskStack, &driverRsiTaskBuffer); + if (NULL == wfx_rsi.drv_task) + { + WFX_RSI_LOG("%s: error: Create the driver task failed", __func__); + return RSI_ERROR_INVALID_PARAM; + } + + /* Initialize WiSeConnect or Module features. */ + WFX_RSI_LOG("%s: rsi_wireless_init", __func__); + if ((status = rsi_wireless_init(OPER_MODE_0, RSI_OPERMODE_WLAN_BLE)) != RSI_SUCCESS) + { + WFX_RSI_LOG("%s: error: Initialize WiSeConnect failed with status: %02x", __func__, status); + return status; + } + + WFX_RSI_LOG("%s: get FW version..", __func__); + + /* + * Get the MAC and other info to let the user know about it. + */ + if (rsi_wlan_get(RSI_FW_VERSION, buf, sizeof(buf)) != RSI_SUCCESS) + { + WFX_RSI_LOG("%s: error: rsi_wlan_get(RSI_FW_VERSION) failed with status: %02x", __func__, status); + return status; + } + + buf[sizeof(buf) - 1] = 0; + WFX_RSI_LOG("%s: RSI firmware version: %s", __func__, buf); + //! Send feature frame + if ((status = rsi_send_feature_frame()) != RSI_SUCCESS) + { + WFX_RSI_LOG("%s: error: rsi_send_feature_frame failed with status: %02x", __func__, status); + return status; + } + + WFX_RSI_LOG("%s: sent rsi_send_feature_frame", __func__); + /* initializes wlan radio parameters and WLAN supplicant parameters. + */ + (void) rsi_wlan_radio_init(); /* Required so we can get MAC address */ + if ((status = rsi_wlan_get(RSI_MAC_ADDRESS, &wfx_rsi.sta_mac.octet[0], RESP_BUFF_SIZE)) != RSI_SUCCESS) + { + WFX_RSI_LOG("%s: error: rsi_wlan_get failed with status: %02x", __func__, status); + return status; + } + + // registering the GAP callback functions + rsi_ble_gap_register_callbacks(NULL, NULL, rsi_ble_on_disconnect_event, NULL, NULL, NULL, rsi_ble_on_enhance_conn_status_event, + NULL, NULL, NULL); + + // registering the GATT call back functions + rsi_ble_gatt_register_callbacks(NULL, NULL, NULL, NULL, NULL, NULL, NULL, rsi_ble_on_gatt_write_event, NULL, NULL, NULL, + rsi_ble_on_mtu_event, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rsi_ble_on_event_indication_confirmation, NULL); + + WFX_RSI_LOG("registering rsi_ble_add_service"); + + // Exchange of GATT info with BLE stack + rsi_ble_add_matter_service(); + + // initializing the application events map + rsi_ble_app_init_events(); + + wfx_rsi.ble_task = xTaskCreateStatic((TaskFunction_t) rsi_ble_event_handling_task, "rsi_ble", WFX_RSI_TASK_SZ, NULL, 1, wfxBLETaskStack, &rsiBLETaskStruct); + WFX_RSI_LOG("%s: rsi_task_suspend init_task ", __func__); + if (wfx_rsi.ble_task == NULL) + { + WFX_RSI_LOG("%s: error: failed to create ble task.", __func__); + } + + WFX_RSI_LOG("%s complete", __func__); + rsi_task_destroy((rsi_task_handle_t *)wfx_rsi.init_task); + return RSI_SUCCESS; +} + + +/*==============================================*/ +/** + * @fn rsi_ble_app_init_events + * @brief initializes the event parameter. + * @param[in] none. + * @return none. + * @section description + * This function is used during BLE initialization. + */ +void rsi_ble_app_init_events() +{ + event_msg.ble_app_event_map = 0; + event_msg.ble_app_event_mask = 0xFFFFFFFF; + event_msg.ble_app_event_mask = event_msg.ble_app_event_mask; // To suppress warning while compiling + WFX_RSI_LOG("Function :: rsi_ble_app_init_events"); + return; +} + +/*==============================================*/ +/** + * @fn rsi_ble_app_clear_event + * @brief clears the specific event. + * @param[in] event_num, specific event number. + * @return none. + * @section description + * This function is used to clear the specific event. + */ +void rsi_ble_app_clear_event(uint32_t event_num) +{ + event_msg.event_num = event_num; + event_msg.ble_app_event_map &= ~BIT(event_num); + return; +} + +/*==============================================*/ +/** + * @fn rsi_ble_on_mtu_event + * @brief its invoked when mtu exhange event is received. + * @param[in] rsi_ble_mtu, mtu event paramaters. + * @return none. + * @section description + * This callback function is invoked when mtu exhange event is received + */ +void rsi_ble_on_mtu_event(rsi_ble_event_mtu_t * rsi_ble_mtu) +{ + WFX_RSI_LOG(" RSI_BLE : rsi_ble_on_mtu_event"); + memset(&event_msg.rsi_ble_mtu,0,sizeof(rsi_ble_event_mtu_t)); + memcpy(&event_msg.rsi_ble_mtu,rsi_ble_mtu,sizeof(rsi_ble_event_mtu_t)); + rsi_ble_app_set_event(RSI_BLE_MTU_EVENT); +} + +/*==============================================*/ +/** + * @fn rsi_ble_on_gatt_write_event + * @brief its invoked when write/notify/indication events are received. + * @param[in] event_id, it indicates write/notification event id. + * @param[in] rsi_ble_write, write event parameters. + * @return none. + * @section description + * This callback function is invoked when write/notify/indication events are received + */ +void rsi_ble_on_gatt_write_event(uint16_t event_id, rsi_ble_event_write_t *rsi_ble_write) +{ + WFX_RSI_LOG(" RSI_BLE : rsi_ble_on_gatt_write_event"); + memset(&event_msg.rsi_ble_write, 0, sizeof(rsi_ble_event_write_t)); + event_msg.event_id = event_id; + memcpy(&event_msg.rsi_ble_write,rsi_ble_write,sizeof(rsi_ble_event_write_t)); + rsi_ble_app_set_event(RSI_BLE_GATT_WRITE_EVENT); +} + +/*==============================================*/ +/** + * @fn rsi_ble_on_enhance_conn_status_event + * @brief invoked when enhanced connection complete event is received + * @param[out] resp_conn, connected remote device information + * @return none. + * @section description + * This callback function indicates the status of the connection + */ +void rsi_ble_on_enhance_conn_status_event(rsi_ble_event_enhance_conn_status_t *resp_enh_conn) +{ + WFX_RSI_LOG(" RSI_BLE : rsi_ble_on_enhance_conn_status_event"); + event_msg.connectionHandle = 1; + event_msg.bondingHandle = 255; + memcpy(event_msg.resp_enh_conn.dev_addr, resp_enh_conn->dev_addr, RSI_DEV_ADDR_LEN); + rsi_ble_app_set_event(RSI_BLE_CONN_EVENT); +} + + +/*==============================================*/ +/** + * @fn rsi_ble_on_disconnect_event + * @brief invoked when disconnection event is received + * @param[in] resp_disconnect, disconnected remote device information + * @param[in] reason, reason for disconnection. + * @return none. + * @section description + * This callback function indicates disconnected device information and status + */ +void rsi_ble_on_disconnect_event(rsi_ble_event_disconnect_t *resp_disconnect, uint16_t reason) +{ + WFX_RSI_LOG(" RSI_BLE : rsi_ble_on_disconnect_event"); + event_msg.reason = reason; + //memcpy(event_msg.resp_disconnect,resp_disconnect,sizeof(rsi_ble_event_disconnect_t)); + rsi_ble_app_set_event(RSI_BLE_DISCONN_EVENT); +} + + +/*==============================================*/ +/** + * @fn rsi_ble_on_event_indication_confirmation + * @brief this function will invoke when received indication confirmation event + * @param[out] resp_id, response id + * @param[out] status, status of the response + * @return none + * @section description + */ +void rsi_ble_on_event_indication_confirmation(uint16_t resp_status, rsi_ble_set_att_resp_t * rsi_ble_event_set_att_rsp) +{ + WFX_RSI_LOG(" RSI_BLE : rsi_ble_on_event_indication_confirmation"); + event_msg.resp_status = resp_status; + memcpy(&event_msg.rsi_ble_event_set_att_rsp, rsi_ble_event_set_att_rsp, sizeof(rsi_ble_set_att_resp_t)); + rsi_ble_app_set_event(RSI_BLE_GATT_INDICATION_CONFIRMATION); +} + +/*==============================================*/ +/** + * @fn rsi_ble_app_get_event + * @brief returns the first set event based on priority + * @param[in] none. + * @return int32_t + * > 0 = event number + * -1 = not received any event + * @section description + * This function returns the highest priority event among all the set events + */ +int32_t rsi_ble_app_get_event(void) +{ + uint32_t ix; + + for (ix = 0; ix < 32; ix++) + { + if (event_msg.ble_app_event_map & (1 << ix)) + { + return ix; + } + } + + return (-1); +} + +/*==============================================*/ +/** + * @fn rsi_ble_app_set_event + * @brief set the specific event. + * @param[in] event_num, specific event number. + * @return none. + * @section description + * This function is used to set/raise the specific event. + */ +void rsi_ble_app_set_event(uint32_t event_num) +{ + event_msg.ble_app_event_map |= BIT(event_num); + return; +} + + + +/*==============================================*/ +/** + * @fn rsi_gatt_add_attribute_to_list + * @brief This function is used to store characteristic service attribute. + * @param[in] p_val, pointer to homekit structure + * @param[in] handle, characteristic service attribute handle. + * @param[in] data_len, characteristic value length + * @param[in] data, characteristic value pointer + * @param[in] uuid, characteristic value uuid + * @return none. + * @section description + * This function is used to store all attribute records + */ +void rsi_gatt_add_attribute_to_list(rsi_ble_t * p_val, uint16_t handle, uint16_t data_len, uint8_t * data, uuid_t uuid, + uint8_t char_prop) +{ + if ((p_val->DATA_ix + data_len) >= BLE_ATT_REC_SIZE) + { //! Check for max data length for the characteristic value + LOG_PRINT("\r\n no data memory for att rec values \r\n"); + return; + } + + p_val->att_rec_list[p_val->att_rec_list_count].char_uuid = uuid; + p_val->att_rec_list[p_val->att_rec_list_count].handle = handle; + p_val->att_rec_list[p_val->att_rec_list_count].value_len = data_len; + p_val->att_rec_list[p_val->att_rec_list_count].max_value_len = data_len; + p_val->att_rec_list[p_val->att_rec_list_count].char_val_prop = char_prop; + memcpy(p_val->DATA + p_val->DATA_ix, data, data_len); + p_val->att_rec_list[p_val->att_rec_list_count].value = p_val->DATA + p_val->DATA_ix; + p_val->att_rec_list_count++; + p_val->DATA_ix += p_val->att_rec_list[p_val->att_rec_list_count].max_value_len; + + return; +} + +/*==============================================*/ +/** + * @fn rsi_ble_add_char_serv_att + * @brief this function is used to add characteristic service attribute.. + * @param[in] serv_handler, service handler. + * @param[in] handle, characteristic service attribute handle. + * @param[in] val_prop, characteristic value property. + * @param[in] att_val_handle, characteristic value handle + * @param[in] att_val_uuid, characteristic value uuid + * @return none. + * @section description + * This function is used at application to add characteristic attribute + */ +void rsi_ble_add_char_serv_att(void * serv_handler, uint16_t handle, uint8_t val_prop, uint16_t att_val_handle, + uuid_t att_val_uuid) +{ + rsi_ble_req_add_att_t new_att = { 0 }; + + //! preparing the attribute service structure + new_att.serv_handler = serv_handler; + new_att.handle = handle; + new_att.att_uuid.size = 2; + new_att.att_uuid.val.val16 = RSI_BLE_CHAR_SERV_UUID; + new_att.property = RSI_BLE_ATT_PROPERTY_READ; + + //! preparing the characteristic attribute value + new_att.data_len = att_val_uuid.size + 4; + new_att.data[0] = val_prop; + rsi_uint16_to_2bytes(&new_att.data[2], att_val_handle); + if (new_att.data_len == 6) + { + rsi_uint16_to_2bytes(&new_att.data[4], att_val_uuid.val.val16); + } + else if (new_att.data_len == 8) + { + rsi_uint32_to_4bytes(&new_att.data[4], att_val_uuid.val.val32); + } + else if (new_att.data_len == 20) + { + memcpy(&new_att.data[4], &att_val_uuid.val.val128, att_val_uuid.size); + } + //! Add attribute to the service + rsi_ble_add_attribute(&new_att); + + return; +} + +/*==============================================*/ +/** + * @fn rsi_ble_add_char_val_att + * @brief this function is used to add characteristic value attribute. + * @param[in] serv_handler, new service handler. + * @param[in] handle, characteristic value attribute handle. + * @param[in] att_type_uuid, attribute uuid value. + * @param[in] val_prop, characteristic value property. + * @param[in] data, characteristic value data pointer. + * @param[in] data_len, characteristic value length. + * @return none. + * @section description + * This function is used at application to create new service. + */ + +void rsi_ble_add_char_val_att(void * serv_handler, uint16_t handle, uuid_t att_type_uuid, uint8_t val_prop, uint8_t * data, + uint8_t data_len, uint8_t auth_read) +{ + rsi_ble_req_add_att_t new_att = { 0 }; + + memset(&new_att, 0, sizeof(rsi_ble_req_add_att_t)); + //! preparing the attributes + new_att.serv_handler = serv_handler; + new_att.handle = handle; + new_att.config_bitmap = auth_read; + memcpy(&new_att.att_uuid, &att_type_uuid, sizeof(uuid_t)); + new_att.property = val_prop; + + if (data != NULL) + memcpy(new_att.data, data, RSI_MIN(sizeof(new_att.data), data_len)); + + //! preparing the attribute value + new_att.data_len = data_len; + + //! add attribute to the service + rsi_ble_add_attribute(&new_att); + + if ((auth_read == ATT_REC_MAINTAIN_IN_HOST) || (data_len > 20)) + { + if (data != NULL) + { + rsi_gatt_add_attribute_to_list(&att_list, handle, data_len, data, att_type_uuid, val_prop); + } + } + + //! check the attribute property with notification/Indication + if ((val_prop & RSI_BLE_ATT_PROPERTY_NOTIFY) || (val_prop & RSI_BLE_ATT_PROPERTY_INDICATE)) + { + //! if notification/indication property supports then we need to add client characteristic service. + + //! preparing the client characteristic attribute & values + memset(&new_att, 0, sizeof(rsi_ble_req_add_att_t)); + new_att.serv_handler = serv_handler; + new_att.handle = handle + 1; + new_att.att_uuid.size = 2; + new_att.att_uuid.val.val16 = RSI_BLE_CLIENT_CHAR_UUID; + new_att.property = RSI_BLE_ATT_PROPERTY_READ | RSI_BLE_ATT_PROPERTY_WRITE; + new_att.data_len = 2; + + //! add attribute to the service + rsi_ble_add_attribute(&new_att); + } + + return; +} + + +/*==============================================*/ +/** + * @fn rsi_ble_add_matter_service + * @brief this function is used to add service for matter + * @return status (uint32_t) 0 for success. + * @section description + * This function is used at application to create new service. + */ + +uint32_t rsi_ble_add_matter_service(void) +{ + uuid_t custom_service = { RSI_BLE_MATTER_CUSTOM_SERVICE_UUID }; + custom_service.size = RSI_BLE_MATTER_CUSTOM_SERVICE_SIZE; + custom_service.val.val16 = RSI_BLE_MATTER_CUSTOM_SERVICE_VALUE_16; + uint8_t data[230] = { RSI_BLE_MATTER_CUSTOM_SERVICE_DATA }; + + static const uuid_t custom_characteristic_RX = { .size = RSI_BLE_CUSTOM_CHARACTERISTIC_RX_SIZE, + .reserved = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_RESERVED }, + .val.val128.data1 = RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_1, + .val.val128.data2 = RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_2, + .val.val128.data3 = RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_3, + .val.val128.data4 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_4 } }; + + rsi_ble_resp_add_serv_t new_serv_resp = { 0 }; + rsi_ble_add_service(custom_service, &new_serv_resp); + + // Adding custom characteristic declaration to the custom service + rsi_ble_add_char_serv_att(new_serv_resp.serv_handler, + new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_ATTRIBUTE_HANDLE_LOCATION, + RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ, // Set read, write, write without response + new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_VALUE_HANDLE_LOCATION, + custom_characteristic_RX); + + // Adding characteristic value attribute to the service + rsi_ble_add_char_val_att(new_serv_resp.serv_handler, + new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_VALUE_HANDLE_LOCATION, + custom_characteristic_RX, + RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ, // Set read, write, write without response + data, + sizeof(data), + ATT_REC_IN_HOST); + + + + static const uuid_t custom_characteristic_TX = { .size = RSI_BLE_CUSTOM_CHARACTERISTIC_TX_SIZE, + .reserved = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_RESERVED }, + .val.val128.data1 = RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_1, + .val.val128.data2 = RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_2, + .val.val128.data3 = RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_3, + .val.val128.data4 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_4 } }; + + // Adding custom characteristic declaration to the custom service + rsi_ble_add_char_serv_att(new_serv_resp.serv_handler, + new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_ATTRIBUTE_HANDLE_LOCATION, + RSI_BLE_ATT_PROPERTY_WRITE_NO_RESPONSE | RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ | RSI_BLE_ATT_PROPERTY_NOTIFY | RSI_BLE_ATT_PROPERTY_INDICATE, // Set read, write, write without response + new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_MEASUREMENT_HANDLE_LOCATION, + custom_characteristic_TX); + + // Adding characteristic value attribute to the service + event_msg.rsi_ble_measurement_hndl = new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_MEASUREMENT_HANDLE_LOCATION; + + // Adding characteristic value attribute to the service + event_msg.rsi_ble_gatt_server_client_config_hndl = new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_GATT_SERVER_CLIENT_HANDLE_LOCATION; + + rsi_ble_add_char_val_att(new_serv_resp.serv_handler, + event_msg.rsi_ble_measurement_hndl, + custom_characteristic_TX, + RSI_BLE_ATT_PROPERTY_WRITE_NO_RESPONSE | RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ | RSI_BLE_ATT_PROPERTY_NOTIFY | RSI_BLE_ATT_PROPERTY_INDICATE, // Set read, write, write without response + data, + sizeof(data), + ATT_REC_MAINTAIN_IN_HOST); + + memset(&data, 0, sizeof(data)); + return 0; +} \ No newline at end of file diff --git a/src/platform/EFR32/RS911x/wfx_sl_ble_init.h b/src/platform/EFR32/RS911x/wfx_sl_ble_init.h new file mode 100644 index 00000000000000..23196d69c5e12d --- /dev/null +++ b/src/platform/EFR32/RS911x/wfx_sl_ble_init.h @@ -0,0 +1,134 @@ +/******************************************************************************* + * @file wfx_sl_ble_init.h + * @brief + ******************************************************************************* + * # License + * Copyright 2021 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ +/************************************************************************* + * + */ + +/** + * Include files + * */ + +#ifndef WFX_SL_BLE_INIT +#define WFX_SL_BLE_INIT +#define RSI_BLE_ENABLE 1 + +// BLE include file to refer BLE APIs +#include +#include "FreeRTOS.h" +#include "event_groups.h" +#include "rsi_ble_config.h" +#include "task.h" +#include "timers.h" +#include "wfx_host_events.h" +#include "wfx_rsi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef RSI_M4_INTERFACE +#include "rsi_board.h" +#endif + + +#define ATT_REC_IN_HOST 0 + +#define RSI_BT_CTRL_REMOTE_USER_TERMINATED 0x4E13 +#define RSI_BT_CTRL_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES 0x4E14 +#define RSI_BT_CTRL_REMOTE_POWERING_OFF 0x4E15 +#define RSI_BT_CTRL_TERMINATED_MIC_FAILURE 0x4E3D +#define RSI_BT_FAILED_TO_ESTABLISH_CONN 0x4E3E +#define RSI_BT_INVALID_RANGE 0x4E60 + +#define RSI_BLE_MATTER_CUSTOM_SERVICE_UUID 0 +#define RSI_BLE_MATTER_CUSTOM_SERVICE_SIZE 2 +#define RSI_BLE_MATTER_CUSTOM_SERVICE_VALUE_16 0xFFF6 +#define RSI_BLE_MATTER_CUSTOM_SERVICE_DATA 0x00 + +#define RSI_BLE_CUSTOM_CHARACTERISTIC_RX_SIZE 16 +#define RSI_BLE_CUSTOM_CHARACTERISTIC_RX_RESERVED 0x00, 0x00, 0x00 +#define RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_1 0x18EE2EF5 +#define RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_2 0x263D +#define RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_3 0x4559 +#define RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_4 0x9F, 0x95, 0x9C, 0x4F, 0x11, 0x9D, 0x9F, 0x42 +#define RSI_BLE_CHARACTERISTIC_RX_ATTRIBUTE_HANDLE_LOCATION 1 +#define RSI_BLE_CHARACTERISTIC_RX_VALUE_HANDLE_LOCATION 2 + + +#define RSI_BLE_CUSTOM_CHARACTERISTIC_TX_SIZE 16 +#define RSI_BLE_CUSTOM_CHARACTERISTIC_TX_RESERVED 0x00, 0x00, 0x00 +#define RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_1 0x18EE2EF5 +#define RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_2 0x263D +#define RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_3 0x4559 +#define RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_4 0x9F, 0x95, 0x9C, 0x4F, 0x12, 0x9D, 0x9F, 0x42 +#define RSI_BLE_CHARACTERISTIC_TX_ATTRIBUTE_HANDLE_LOCATION 3 +#define RSI_BLE_CHARACTERISTIC_TX_MEASUREMENT_HANDLE_LOCATION 4 +#define RSI_BLE_CHARACTERISTIC_TX_GATT_SERVER_CLIENT_HANDLE_LOCATION 5 + + + +typedef struct sl_wfx_msg_s +{ + uint8_t connectionHandle; + uint8_t bondingHandle; + uint32_t event_num; + uint16_t reason; + uint16_t event_id; + uint16_t resp_status; + rsi_ble_event_mtu_t rsi_ble_mtu; + rsi_ble_event_write_t rsi_ble_write; + rsi_ble_event_enhance_conn_status_t resp_enh_conn; + rsi_ble_event_disconnect_t * resp_disconnect; + rsi_ble_set_att_resp_t rsi_ble_event_set_att_rsp; + uint32_t ble_app_event_map; + uint32_t ble_app_event_mask; + uint16_t rsi_ble_measurement_hndl; + uint16_t rsi_ble_gatt_server_client_config_hndl; + uint16_t subscribed; + +} sl_wfx_msg_t; + +int32_t wfx_sl_module_init(void); +void rsi_ble_on_connect_event(rsi_ble_event_conn_status_t * resp_conn); +void rsi_ble_on_disconnect_event(rsi_ble_event_disconnect_t * resp_disconnect, uint16_t reason); +void rsi_ble_on_enhance_conn_status_event(rsi_ble_event_enhance_conn_status_t * resp_enh_conn); +void rsi_ble_on_gatt_write_event(uint16_t event_id, rsi_ble_event_write_t * rsi_ble_write); +void rsi_ble_on_mtu_event(rsi_ble_event_mtu_t * rsi_ble_mtu); +void rsi_ble_on_event_indication_confirmation(uint16_t resp_status, rsi_ble_set_att_resp_t * rsi_ble_event_set_att_rsp); +void rsi_gatt_add_attribute_to_list(rsi_ble_t * p_val, uint16_t handle, uint16_t data_len, uint8_t * data, uuid_t uuid, + uint8_t char_prop); +void rsi_ble_add_char_serv_att(void * serv_handler, uint16_t handle, uint8_t val_prop, uint16_t att_val_handle, + uuid_t att_val_uuid); +void rsi_ble_add_char_val_att(void * serv_handler, uint16_t handle, uuid_t att_type_uuid, uint8_t val_prop, uint8_t * data, + uint8_t data_len, uint8_t auth_read); +uint32_t rsi_ble_add_matter_service(void); +void rsi_ble_app_set_event(uint32_t event_num); +int32_t rsi_ble_app_get_event(void); +void rsi_ble_app_clear_event(uint32_t event_num); +void rsi_ble_app_init_events(); +void rsi_ble_event_handling_task(void); + +#endif \ No newline at end of file diff --git a/src/platform/EFR32/wifi/wfx_host_events.h b/src/platform/EFR32/wifi/wfx_host_events.h index 6a1e367d29cad0..fb5669c866f63f 100644 --- a/src/platform/EFR32/wifi/wfx_host_events.h +++ b/src/platform/EFR32/wifi/wfx_host_events.h @@ -276,6 +276,7 @@ void wfx_lwip_set_sta_link_up(void); void wfx_lwip_set_sta_link_down(void); void wfx_lwip_start(void); struct netif * wfx_get_netif(sl_wfx_interface_t interface); +struct netif * wfx_get_netif(sl_wfx_interface_t interface); void wfx_dhcp_got_ipv4(uint32_t); bool wfx_hw_ready(void); void wfx_ip_changed_notify(int got_ip); diff --git a/third_party/bouffalolab/bl602_sdk/repo b/third_party/bouffalolab/bl602_sdk/repo new file mode 160000 index 00000000000000..38b4bd921d3620 --- /dev/null +++ b/third_party/bouffalolab/bl602_sdk/repo @@ -0,0 +1 @@ +Subproject commit 38b4bd921d3620a85d5306874247f45aab64eace diff --git a/third_party/qpg_sdk/repo b/third_party/qpg_sdk/repo index 8aadeb12092272..35ccb383fb401a 160000 --- a/third_party/qpg_sdk/repo +++ b/third_party/qpg_sdk/repo @@ -1 +1 @@ -Subproject commit 8aadeb120922720aba2bf0be8d5230d979856a4e +Subproject commit 35ccb383fb401ad8ed02162a33915b1dff2af9d0 diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index a7b803473f90da..298cd22c60cbe2 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -20,6 +20,8 @@ import("//build_overrides/mbedtls.gni") import("${chip_root}/src/lib/lib.gni") import("silabs_board.gni") +wiseconnect_sdk_root = "${chip_root}/third_party/silabs/wiseconnect-wifi-bt-sdk" + declare_args() { # Location of the efr32 SDK. efr32_sdk_root = "${chip_root}/third_party/silabs/gecko_sdk" @@ -158,6 +160,9 @@ template("efr32_sdk") { "${efr32_sdk_root}/util/third_party/freertos/kernel/include", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/config", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen", + "${chip_root}/examples/platform/efr32/rs911x", + "${chip_root}/examples/platform/efr32/rs911x/hal", + "${chip_root}/third_party/silabs/wiseconnect-wifi-bt-sdk/sapi/include", ] # Note that we're setting the mbedTLS and PSA configuration files through a @@ -193,6 +198,7 @@ template("efr32_sdk") { "USE_NVM3=1", #"__STACK_SIZE=0", + "RSI_BLE_ENABLE=1", ] defines += board_defines @@ -564,11 +570,15 @@ template("efr32_sdk") { "${efr32_sdk_root}/util/third_party/freertos/kernel/tasks.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/timers.c", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/gatt_db.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_bluetooth.c", +# "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_bluetooth.c", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_board_default_init.c", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_device_init_clocks.c", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_event_handler.c", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_simple_button_instances.c", + "${wiseconnect_sdk_root}/sapi/bluetooth/rsi_ble_gap_apis.c", + "${wiseconnect_sdk_root}/sapi/bluetooth/rsi_bt_common_apis.c", + "${wiseconnect_sdk_root}/sapi/bluetooth/rsi_ble_gatt_apis.c", + "${wiseconnect_sdk_root}/sapi/driver/rsi_bt_ble.c", ] if (use_wstk_leds) { diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index 58b1a4fd07291a..7474cf819c2c3c 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit 58b1a4fd07291aecf710b5de268d34682c3768c2 +Subproject commit 7474cf819c2c3c31414a6ef8e8b685956e21b842 diff --git a/third_party/silabs/wiseconnect-wifi-bt-sdk b/third_party/silabs/wiseconnect-wifi-bt-sdk index 94a6ce54e67d11..a57fad197407f7 160000 --- a/third_party/silabs/wiseconnect-wifi-bt-sdk +++ b/third_party/silabs/wiseconnect-wifi-bt-sdk @@ -1 +1 @@ -Subproject commit 94a6ce54e67d11aa1714300fcf85a7505d70b648 +Subproject commit a57fad197407f7df21b37b99a441b49023ea807d diff --git a/third_party/simw-top-mini/repo b/third_party/simw-top-mini/repo index bb2b2e95335394..aa51a4c0e93257 160000 --- a/third_party/simw-top-mini/repo +++ b/third_party/simw-top-mini/repo @@ -1 +1 @@ -Subproject commit bb2b2e95335394c999812de97a8bec73d7c6dc1a +Subproject commit aa51a4c0e9325761cba47c07b9f3d1d4343f84f1 diff --git a/third_party/zap/repo b/third_party/zap/repo index 8a3a89a5a936f4..a94875d430d199 160000 --- a/third_party/zap/repo +++ b/third_party/zap/repo @@ -1 +1 @@ -Subproject commit 8a3a89a5a936f4c9dfd4518eda14ebf95177a7ad +Subproject commit a94875d430d199ece002ab5bd971fdb78305fd4e