diff options
Diffstat (limited to 'Projects/NUCLEO-WB15CC/Applications/BLE/BLE_MeshLightingPRFNode/STM32_WPAN/app/app_ble.c')
-rw-r--r-- | Projects/NUCLEO-WB15CC/Applications/BLE/BLE_MeshLightingPRFNode/STM32_WPAN/app/app_ble.c | 509 |
1 files changed, 509 insertions, 0 deletions
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE/BLE_MeshLightingPRFNode/STM32_WPAN/app/app_ble.c b/Projects/NUCLEO-WB15CC/Applications/BLE/BLE_MeshLightingPRFNode/STM32_WPAN/app/app_ble.c new file mode 100644 index 000000000..9f3857506 --- /dev/null +++ b/Projects/NUCLEO-WB15CC/Applications/BLE/BLE_MeshLightingPRFNode/STM32_WPAN/app/app_ble.c @@ -0,0 +1,509 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file app_ble.c + * @author MCD Application Team + * @brief BLE Application + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +#include "app_common.h" + +#include "dbg_trace.h" +#include "ble.h" +#include "tl.h" +#include "app_ble.h" + +#include "stm32_seq.h" +#include "shci.h" +#include "stm32_lpm.h" +#include "otp.h" + +#include "types.h" +#include "ble_mesh.h" +#include "mesh_cfg.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ + +/** + * security parameters structure + */ +typedef struct _tSecurityParams +{ + /** + * IO capability of the device + */ + uint8_t ioCapability; + + /** + * Authentication requirement of the device + * Man In the Middle protection required? + */ + uint8_t mitm_mode; + + /** + * bonding mode of the device + */ + uint8_t bonding_mode; + + /** + * this variable indicates whether to use a fixed pin + * during the pairing process or a passkey has to be + * requested to the application during the pairing process + * 0 implies use fixed pin and 1 implies request for passkey + */ + uint8_t Use_Fixed_Pin; + + /** + * minimum encryption key size requirement + */ + uint8_t encryptionKeySizeMin; + + /** + * maximum encryption key size requirement + */ + uint8_t encryptionKeySizeMax; + + /** + * fixed pin to be used in the pairing process if + * Use_Fixed_Pin is set to 1 + */ + uint32_t Fixed_Pin; + + /** + * this flag indicates whether the host has to initiate + * the security, wait for pairing or does not have any security + * requirements.\n + * 0x00 : no security required + * 0x01 : host should initiate security by sending the slave security + * request command + * 0x02 : host need not send the clave security request but it + * has to wait for paiirng to complete before doing any other + * processing + */ + uint8_t initiateSecurity; +}tSecurityParams; + +/** + * global context + * contains the variables common to all + * services + */ +typedef struct _tBLEProfileGlobalContext +{ + + /** + * security requirements of the host + */ + tSecurityParams bleSecurityParam; + + /** + * gap service handle + */ + uint16_t gapServiceHandle; + + /** + * device name characteristic handle + */ + uint16_t devNameCharHandle; + + /** + * appearance characteristic handle + */ + uint16_t appearanceCharHandle; + + /** + * connection handle of the current active connection + * When not in connection, the handle is set to 0xFFFF + */ + uint16_t connectionHandle; + + /** + * length of the UUID list to be used while advertising + */ + uint8_t advtServUUIDlen; + + /** + * the UUID list to be used while advertising + */ + uint8_t advtServUUID[100]; + +}BleGlobalContext_t; + +typedef struct +{ + BleGlobalContext_t BleApplicationContext_legacy; + APP_BLE_ConnStatus_t Device_Connection_Status; + + /** + * ID of the Advertising Timeout + */ + uint8_t Advertising_mgr_timer_Id; + +} BleApplicationContext_t; +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private defines -----------------------------------------------------------*/ +#define APPBLE_GAP_DEVICE_NAME_LENGTH 7 +#define FAST_ADV_TIMEOUT (30*1000*1000/CFG_TS_TICK_VAL) /**< 30s */ +#define INITIAL_ADV_TIMEOUT (60*1000*1000/CFG_TS_TICK_VAL) /**< 60s */ + +#define BD_ADDR_SIZE_LOCAL 6 + +/* USER CODE BEGIN PD */ +#define LED_ON_TIMEOUT (0.005*1000*1000/CFG_TS_TICK_VAL) /**< 5ms */ +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer; + +uint8_t Test_Status =0x00; + +static const uint8_t M_bd_addr[BD_ADDR_SIZE_LOCAL] = +{ + (uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000000000FF)), + (uint8_t)((CFG_ADV_BD_ADDRESS & 0x00000000FF00) >> 8), + (uint8_t)((CFG_ADV_BD_ADDRESS & 0x000000FF0000) >> 16), + (uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000FF000000) >> 24), + (uint8_t)((CFG_ADV_BD_ADDRESS & 0x00FF00000000) >> 32), + (uint8_t)((CFG_ADV_BD_ADDRESS & 0xFF0000000000) >> 40) +}; + +static uint8_t bd_addr_udn[BD_ADDR_SIZE_LOCAL]; + +PLACE_IN_SECTION("BLE_APP_CONTEXT") static BleApplicationContext_t BleApplicationContext; + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Extern function prototypes -----------------------------------------------*/ +extern void HCI_Event_CB(void *pckt); + +/* Global variables ----------------------------------------------------------*/ +const uint8_t *bd_addr; + +/* Private function prototypes -----------------------------------------------*/ +static void BLE_UserEvtRx( void * pPayload ); +static void BLE_StatusNot( HCI_TL_CmdStatus_t status ); +static void Ble_Tl_Init( void ); +static const uint8_t* BleGetBdAddress( void ); + +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External variables --------------------------------------------------------*/ + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Functions Definition ------------------------------------------------------*/ +void APP_BLE_Init( void ) +{ +/* USER CODE BEGIN APP_BLE_Init_1 */ + +/* USER CODE END APP_BLE_Init_1 */ + SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = + { + {{0,0,0}}, /**< Header unused */ + {0, /** pBleBufferAddress not used */ + 0, /** BleBufferSize not used */ + CFG_BLE_NUM_GATT_ATTRIBUTES, + CFG_BLE_NUM_GATT_SERVICES, + CFG_BLE_ATT_VALUE_ARRAY_SIZE, + CFG_BLE_NUM_LINK, + CFG_BLE_DATA_LENGTH_EXTENSION, + CFG_BLE_PREPARE_WRITE_LIST_SIZE, + CFG_BLE_MBLOCK_COUNT, + CFG_BLE_MAX_ATT_MTU, + CFG_BLE_SLAVE_SCA, + CFG_BLE_MASTER_SCA, + CFG_BLE_LSE_SOURCE, + CFG_BLE_MAX_CONN_EVENT_LENGTH, + CFG_BLE_HSE_STARTUP_TIME, + CFG_BLE_VITERBI_MODE, + CFG_BLE_OPTIONS, + 0, + CFG_BLE_MAX_COC_INITIATOR_NBR, + CFG_BLE_MIN_TX_POWER, + CFG_BLE_MAX_TX_POWER, + CFG_BLE_RX_MODEL_CONFIG} + }; + + /** + * Initialize Ble Transport Layer + */ + Ble_Tl_Init( ); + +#if (CFG_LPM_STANDBY_SUPPORTED == 0) + UTIL_LPM_SetOffMode(1U << CFG_LPM_APP_BLE, UTIL_LPM_DISABLE); +#endif + + /** + * Do not allow stop mode in the application + */ +#if (LOW_POWER_FEATURE == 0) + UTIL_LPM_SetStopMode(1 << CFG_LPM_APP_BLE, UTIL_LPM_DISABLE); +#endif + + /** + * Register the hci transport layer to handle BLE User Asynchronous Events + */ + UTIL_SEQ_RegTask( 1<<CFG_TASK_HCI_ASYNCH_EVT_ID, UTIL_SEQ_RFU, hci_user_evt_proc); + + /** + * Starts the BLE Stack on CPU2 + */ + if (SHCI_C2_BLE_Init( &ble_init_cmd_packet ) != SHCI_Success) + { + Error_Handler(); + } + + /** + * Initialization of HCI & GATT & GAP layer + */ + { + const uint8_t *bd_addr; + /** + * Write the BD Address + */ + + bd_addr = BleGetBdAddress(); + aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + (uint8_t*) bd_addr); + } + /** + * Initialization of the BLE Services + */ + SVCCTL_Init(); + + /** + * Initialization of the BLE App Context + */ + BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE; + BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0xFFFF; + + /*Radio mask Activity*/ +#if(RADIO_ACTIVITY_EVENT != 0) + aci_hal_set_radio_activity_mask(0x00FF); +#endif + + BleApplicationContext.Device_Connection_Status = APP_BLE_FAST_ADV; + +/* USER CODE BEGIN APP_BLE_Init_2 */ + +/* USER CODE END APP_BLE_Init_2 */ + return; +} + +SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) +{ + /* callback of mesh Library to receive all GAP/GATT events*/ + HCI_Event_CB(pckt); + +#if (LOW_POWER_FEATURE == 1) + UTIL_SEQ_SetTask( 1<<CFG_TASK_MESH_REQ_ID, CFG_SCH_PRIO_0); +#endif + + return (SVCCTL_UserEvtFlowEnable); +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static void Ble_Tl_Init( void ) +{ + HCI_TL_HciInitConf_t Hci_Tl_Init_Conf; + + Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&BleCmdBuffer; + Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot; + hci_init(BLE_UserEvtRx, (void*) &Hci_Tl_Init_Conf); + + return; +} + +const uint8_t* BleGetBdAddress( void ) +{ + uint8_t *otp_addr; + const uint8_t *bd_addr; + uint32_t udn; + uint32_t company_id; + uint32_t device_id; + + udn = LL_FLASH_GetUDN(); + + if(udn != 0xFFFFFFFF) + { + company_id = LL_FLASH_GetSTCompanyID(); + device_id = LL_FLASH_GetDeviceID(); + +/** + * Public Address with the ST company ID + * bit[47:24] : 24bits (OUI) equal to the company ID + * bit[23:16] : Device ID. + * bit[15:0] : The last 16bits from the UDN + * Note: In order to use the Public Address in a final product, a dedicated + * 24bits company ID (OUI) shall be bought. + */ + bd_addr_udn[0] = (uint8_t)(udn & 0x000000FF); + bd_addr_udn[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 ); + bd_addr_udn[2] = (uint8_t)device_id; + bd_addr_udn[3] = (uint8_t)(company_id & 0x000000FF); + bd_addr_udn[4] = (uint8_t)( (company_id & 0x0000FF00) >> 8 ); + bd_addr_udn[5] = (uint8_t)( (company_id & 0x00FF0000) >> 16 ); + + bd_addr = (const uint8_t *)bd_addr_udn; + } + else + { + otp_addr = OTP_Read(0); + if(otp_addr) + { + bd_addr = ((OTP_ID0_t*)otp_addr)->bd_address; + } + else + { + bd_addr = M_bd_addr; + } + } + + return bd_addr; +} + +/* USER CODE BEGIN FD_LOCAL_FUNCTION */ + +/* USER CODE END FD_LOCAL_FUNCTION */ + +/************************************************************* + * + *SPECIFIC FUNCTIONS + * + *************************************************************/ +/* USER CODE BEGIN FD_SPECIFIC_FUNCTIONS */ + +/* USER CODE END FD_SPECIFIC_FUNCTIONS */ +/************************************************************* + * + * WRAP FUNCTIONS + * + *************************************************************/ +void hci_notify_asynch_evt(void* pdata) +{ + UTIL_SEQ_SetTask( 1<<CFG_TASK_HCI_ASYNCH_EVT_ID, CFG_SCH_PRIO_0); + return; +} + +#if (LOW_POWER_FEATURE == 1) +static volatile uint8_t HciResponse = 0; +#endif + +void hci_cmd_resp_release(uint32_t flag) +{ +#if (LOW_POWER_FEATURE == 0) + UTIL_SEQ_SetEvt(1 << CFG_IDLEEVT_HCI_CMD_EVT_RSP_ID); +#else + HciResponse = 1; +#endif + return; +} + +void hci_cmd_resp_wait(uint32_t timeout) +{ +#if (LOW_POWER_FEATURE == 0) + UTIL_SEQ_WaitEvt(1 << CFG_IDLEEVT_HCI_CMD_EVT_RSP_ID); +#else + while(HciResponse == 0); + HciResponse = 0; +#endif + return; +} + +static void BLE_UserEvtRx( void * pPayload ) +{ + SVCCTL_UserEvtFlowStatus_t svctl_return_status; + tHCI_UserEvtRxParam *pParam; + + pParam = (tHCI_UserEvtRxParam *)pPayload; + + svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); + if (svctl_return_status != SVCCTL_UserEvtFlowDisable) + { + pParam->status = HCI_TL_UserEventFlow_Enable; + } + else + { + pParam->status = HCI_TL_UserEventFlow_Disable; + } +} + +static void BLE_StatusNot( HCI_TL_CmdStatus_t status ) +{ + uint32_t task_id_list; + switch (status) + { + case HCI_TL_CmdBusy: + /** + * All tasks that may send an aci/hci commands shall be listed here + * This is to prevent a new command is sent while one is already pending + */ + task_id_list = (1 << CFG_LAST_TASK_ID_WITH_HCICMD) - 1; + UTIL_SEQ_PauseTask(task_id_list); + + break; + + case HCI_TL_CmdAvailable: + /** + * All tasks that may send an aci/hci commands shall be listed here + * This is to prevent a new command is sent while one is already pending + */ + task_id_list = (1 << CFG_LAST_TASK_ID_WITH_HCICMD) - 1; + UTIL_SEQ_ResumeTask(task_id_list); + + break; + + default: + break; + } + return; +} + +void SVCCTL_ResumeUserEventFlow( void ) +{ + hci_resume_flow(); + return; +} + +/* USER CODE BEGIN FD_WRAP_FUNCTIONS */ + +/* USER CODE END FD_WRAP_FUNCTIONS */ |