app_ble.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. #include "main.h"
  2. #include "app_entry.h"
  3. #include "app_common.h"
  4. #include "dbg_trace.h"
  5. #include "ble.h"
  6. #include "tl.h"
  7. #include "app_ble.h"
  8. #include "cmsis_os.h"
  9. #include "shci.h"
  10. #include "otp.h"
  11. #include "dis_app.h"
  12. #include "hrs_app.h"
  13. #include <furi-hal.h>
  14. typedef struct _tSecurityParams {
  15. uint8_t ioCapability;
  16. uint8_t mitm_mode;
  17. uint8_t bonding_mode;
  18. uint8_t Use_Fixed_Pin;
  19. uint8_t encryptionKeySizeMin;
  20. uint8_t encryptionKeySizeMax;
  21. uint32_t Fixed_Pin;
  22. uint8_t initiateSecurity;
  23. } tSecurityParams;
  24. typedef struct _tBLEProfileGlobalContext {
  25. tSecurityParams bleSecurityParam;
  26. uint16_t gapServiceHandle;
  27. uint16_t devNameCharHandle;
  28. uint16_t appearanceCharHandle;
  29. uint16_t connectionHandle;
  30. uint8_t advtServUUIDlen;
  31. uint8_t advtServUUID[100];
  32. } BleGlobalContext_t;
  33. typedef struct {
  34. BleGlobalContext_t BleApplicationContext_legacy;
  35. APP_BLE_ConnStatus_t Device_Connection_Status;
  36. uint8_t Advertising_mgr_timer_Id;
  37. } BleApplicationContext_t;
  38. #define FAST_ADV_TIMEOUT (30*1000*1000/CFG_TS_TICK_VAL) /**< 30s */
  39. #define INITIAL_ADV_TIMEOUT (60*1000*1000/CFG_TS_TICK_VAL) /**< 60s */
  40. #define BD_ADDR_SIZE_LOCAL 6
  41. #define LED_ON_TIMEOUT (0.005*1000*1000/CFG_TS_TICK_VAL) /**< 5ms */
  42. PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer;
  43. static const uint8_t M_bd_addr[BD_ADDR_SIZE_LOCAL] =
  44. {
  45. (uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000000000FF)),
  46. (uint8_t)((CFG_ADV_BD_ADDRESS & 0x00000000FF00) >> 8),
  47. (uint8_t)((CFG_ADV_BD_ADDRESS & 0x000000FF0000) >> 16),
  48. (uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000FF000000) >> 24),
  49. (uint8_t)((CFG_ADV_BD_ADDRESS & 0x00FF00000000) >> 32),
  50. (uint8_t)((CFG_ADV_BD_ADDRESS & 0xFF0000000000) >> 40)
  51. };
  52. static uint8_t bd_addr_udn[BD_ADDR_SIZE_LOCAL];
  53. static const uint8_t BLE_CFG_IR_VALUE[16] = CFG_BLE_IRK;
  54. static const uint8_t BLE_CFG_ER_VALUE[16] = CFG_BLE_ERK;
  55. PLACE_IN_SECTION("TAG_OTA_END") const uint32_t MagicKeywordValue = 0x94448A29 ;
  56. PLACE_IN_SECTION("TAG_OTA_START") const uint32_t MagicKeywordAddress = (uint32_t)&MagicKeywordValue;
  57. PLACE_IN_SECTION("BLE_APP_CONTEXT") static BleApplicationContext_t BleApplicationContext;
  58. PLACE_IN_SECTION("BLE_APP_CONTEXT") static uint16_t AdvIntervalMin, AdvIntervalMax;
  59. uint8_t manuf_data[14] = {
  60. sizeof(manuf_data)-1, AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
  61. 0x01/*SKD version */,
  62. 0x00 /* Generic*/,
  63. 0x00 /* GROUP A Feature */,
  64. 0x00 /* GROUP A Feature */,
  65. 0x00 /* GROUP B Feature */,
  66. 0x00 /* GROUP B Feature */,
  67. 0x00, /* BLE MAC start -MSB */
  68. 0x00,
  69. 0x00,
  70. 0x00,
  71. 0x00,
  72. 0x00, /* BLE MAC stop */
  73. };
  74. osMutexId_t MtxHciId;
  75. osSemaphoreId_t SemHciId;
  76. osThreadId_t AdvUpdateProcessId;
  77. osThreadId_t HciUserEvtProcessId;
  78. const osThreadAttr_t AdvUpdateProcess_attr = {
  79. .name = CFG_ADV_UPDATE_PROCESS_NAME,
  80. .attr_bits = CFG_ADV_UPDATE_PROCESS_ATTR_BITS,
  81. .cb_mem = CFG_ADV_UPDATE_PROCESS_CB_MEM,
  82. .cb_size = CFG_ADV_UPDATE_PROCESS_CB_SIZE,
  83. .stack_mem = CFG_ADV_UPDATE_PROCESS_STACK_MEM,
  84. .priority = CFG_ADV_UPDATE_PROCESS_PRIORITY,
  85. .stack_size = CFG_ADV_UPDATE_PROCESS_STACK_SIZE
  86. };
  87. const osThreadAttr_t HciUserEvtProcess_attr = {
  88. .name = CFG_HCI_USER_EVT_PROCESS_NAME,
  89. .attr_bits = CFG_HCI_USER_EVT_PROCESS_ATTR_BITS,
  90. .cb_mem = CFG_HCI_USER_EVT_PROCESS_CB_MEM,
  91. .cb_size = CFG_HCI_USER_EVT_PROCESS_CB_SIZE,
  92. .stack_mem = CFG_HCI_USER_EVT_PROCESS_STACK_MEM,
  93. .priority = CFG_HCI_USER_EVT_PROCESS_PRIORITY,
  94. .stack_size = CFG_HCI_USER_EVT_PROCESS_STACK_SIZE
  95. };
  96. /* Private function prototypes -----------------------------------------------*/
  97. static void HciUserEvtProcess(void *argument);
  98. static void BLE_UserEvtRx( void * pPayload );
  99. static void BLE_StatusNot( HCI_TL_CmdStatus_t status );
  100. static void Ble_Tl_Init( void );
  101. static void Ble_Hci_Gap_Gatt_Init();
  102. static const uint8_t* BleGetBdAddress( void );
  103. static void Adv_Request( APP_BLE_ConnStatus_t New_Status );
  104. static void Add_Advertisment_Service_UUID( uint16_t servUUID );
  105. static void Adv_Mgr( void );
  106. static void AdvUpdateProcess(void *argument);
  107. static void Adv_Update( void );
  108. bool APP_BLE_Init() {
  109. SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = {
  110. {{0,0,0}}, /**< Header unused */
  111. {0, /** pBleBufferAddress not used */
  112. 0, /** BleBufferSize not used */
  113. CFG_BLE_NUM_GATT_ATTRIBUTES,
  114. CFG_BLE_NUM_GATT_SERVICES,
  115. CFG_BLE_ATT_VALUE_ARRAY_SIZE,
  116. CFG_BLE_NUM_LINK,
  117. CFG_BLE_DATA_LENGTH_EXTENSION,
  118. CFG_BLE_PREPARE_WRITE_LIST_SIZE,
  119. CFG_BLE_MBLOCK_COUNT,
  120. CFG_BLE_MAX_ATT_MTU,
  121. CFG_BLE_SLAVE_SCA,
  122. CFG_BLE_MASTER_SCA,
  123. CFG_BLE_LSE_SOURCE,
  124. CFG_BLE_MAX_CONN_EVENT_LENGTH,
  125. CFG_BLE_HSE_STARTUP_TIME,
  126. CFG_BLE_VITERBI_MODE,
  127. CFG_BLE_LL_ONLY,
  128. 0}
  129. };
  130. // Initialize Ble Transport Layer
  131. Ble_Tl_Init( );
  132. // Register the hci transport layer to handle BLE User Asynchronous Events
  133. HciUserEvtProcessId = osThreadNew(HciUserEvtProcess, NULL, &HciUserEvtProcess_attr);
  134. // Starts the BLE Stack on CPU2
  135. return (SHCI_C2_BLE_Init( &ble_init_cmd_packet ) == SHCI_Success);
  136. }
  137. bool APP_BLE_Start() {
  138. if (APPE_Status() != BleGlueStatusStarted) {
  139. return false;
  140. }
  141. // Initialization of HCI & GATT & GAP layer
  142. Ble_Hci_Gap_Gatt_Init();
  143. // Initialization of the BLE Services
  144. SVCCTL_Init();
  145. // Initialization of the BLE App Context
  146. BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
  147. BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0xFFFF;
  148. // From here, all initialization are BLE application specific
  149. AdvUpdateProcessId = osThreadNew(AdvUpdateProcess, NULL, &AdvUpdateProcess_attr);
  150. // Initialization of ADV - Ad Manufacturer Element - Support OTA Bit Masks
  151. #if(BLE_CFG_OTA_REBOOT_CHAR != 0)
  152. manuf_data[sizeof(manuf_data)-8] = CFG_FEATURE_OTA_REBOOT;
  153. #endif
  154. // Initialize DIS Application
  155. DISAPP_Init();
  156. // Initialize HRS Application
  157. HRSAPP_Init();
  158. // Create timer to handle the connection state machine
  159. HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(BleApplicationContext.Advertising_mgr_timer_Id), hw_ts_SingleShot, Adv_Mgr);
  160. // Make device discoverable
  161. BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = AD_TYPE_16_BIT_SERV_UUID;
  162. BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 1;
  163. Add_Advertisment_Service_UUID(HEART_RATE_SERVICE_UUID);
  164. /* Initialize intervals for reconnexion without intervals update */
  165. AdvIntervalMin = CFG_FAST_CONN_ADV_INTERVAL_MIN;
  166. AdvIntervalMax = CFG_FAST_CONN_ADV_INTERVAL_MAX;
  167. Adv_Request(APP_BLE_FAST_ADV);
  168. return true;
  169. }
  170. SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt )
  171. {
  172. hci_event_pckt *event_pckt;
  173. evt_le_meta_event *meta_evt;
  174. evt_blue_aci *blue_evt;
  175. hci_le_phy_update_complete_event_rp0 *evt_le_phy_update_complete;
  176. uint8_t TX_PHY, RX_PHY;
  177. tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
  178. event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data;
  179. switch (event_pckt->evt) {
  180. case EVT_DISCONN_COMPLETE:
  181. {
  182. hci_disconnection_complete_event_rp0 *disconnection_complete_event;
  183. disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data;
  184. if (disconnection_complete_event->Connection_Handle == BleApplicationContext.BleApplicationContext_legacy.connectionHandle) {
  185. BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0;
  186. BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE;
  187. APP_DBG_MSG("\r\n\r** DISCONNECTION EVENT WITH CLIENT \r\n");
  188. }
  189. /* restart advertising */
  190. Adv_Request(APP_BLE_FAST_ADV);
  191. furi_hal_power_insomnia_exit();
  192. }
  193. break; /* EVT_DISCONN_COMPLETE */
  194. case EVT_LE_META_EVENT:
  195. {
  196. meta_evt = (evt_le_meta_event*) event_pckt->data;
  197. switch (meta_evt->subevent)
  198. {
  199. case EVT_LE_CONN_UPDATE_COMPLETE:
  200. APP_DBG_MSG("\r\n\r** CONNECTION UPDATE EVENT WITH CLIENT \r\n");
  201. /* USER CODE BEGIN EVT_LE_CONN_UPDATE_COMPLETE */
  202. /* USER CODE END EVT_LE_CONN_UPDATE_COMPLETE */
  203. break;
  204. case EVT_LE_PHY_UPDATE_COMPLETE:
  205. APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE \r\n");
  206. evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data;
  207. if (evt_le_phy_update_complete->Status == 0)
  208. {
  209. APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status ok \r\n");
  210. }
  211. else
  212. {
  213. APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status nok \r\n");
  214. }
  215. ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY);
  216. if (ret == BLE_STATUS_SUCCESS)
  217. {
  218. APP_DBG_MSG("Read_PHY success \r\n");
  219. if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M))
  220. {
  221. APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
  222. }
  223. else
  224. {
  225. APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
  226. }
  227. }
  228. else
  229. {
  230. APP_DBG_MSG("Read conf not succeess \r\n");
  231. }
  232. break;
  233. case EVT_LE_CONN_COMPLETE:
  234. {
  235. furi_hal_power_insomnia_enter();
  236. hci_le_connection_complete_event_rp0 *connection_complete_event;
  237. /**
  238. * The connection is done, there is no need anymore to schedule the LP ADV
  239. */
  240. connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data;
  241. HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id);
  242. APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\r\n", connection_complete_event->Connection_Handle);
  243. if (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_CONNECTING)
  244. {
  245. /* Connection as client */
  246. BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_CLIENT;
  247. }
  248. else
  249. {
  250. /* Connection as server */
  251. BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_SERVER;
  252. }
  253. BleApplicationContext.BleApplicationContext_legacy.connectionHandle = connection_complete_event->Connection_Handle;
  254. }
  255. break; /* HCI_EVT_LE_CONN_COMPLETE */
  256. default:
  257. break;
  258. }
  259. }
  260. break; /* HCI_EVT_LE_META_EVENT */
  261. case EVT_VENDOR:
  262. blue_evt = (evt_blue_aci*) event_pckt->data;
  263. switch (blue_evt->ecode) {
  264. aci_gap_pairing_complete_event_rp0 *pairing_complete;
  265. case EVT_BLUE_GAP_LIMITED_DISCOVERABLE:
  266. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_LIMITED_DISCOVERABLE \r\n");
  267. break; /* EVT_BLUE_GAP_LIMITED_DISCOVERABLE */
  268. case EVT_BLUE_GAP_PASS_KEY_REQUEST:
  269. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PASS_KEY_REQUEST \r\n");
  270. aci_gap_pass_key_resp(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,123456);
  271. APP_DBG_MSG("\r\n\r** aci_gap_pass_key_resp \r\n");
  272. break; /* EVT_BLUE_GAP_PASS_KEY_REQUEST */
  273. case EVT_BLUE_GAP_AUTHORIZATION_REQUEST:
  274. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_AUTHORIZATION_REQUEST \r\n");
  275. break; /* EVT_BLUE_GAP_AUTHORIZATION_REQUEST */
  276. case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED:
  277. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED \r\n");
  278. break; /* EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED */
  279. case EVT_BLUE_GAP_BOND_LOST:
  280. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_BOND_LOST \r\n");
  281. aci_gap_allow_rebond(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
  282. APP_DBG_MSG("\r\n\r** Send allow rebond \r\n");
  283. break; /* EVT_BLUE_GAP_BOND_LOST */
  284. case EVT_BLUE_GAP_DEVICE_FOUND:
  285. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \r\n");
  286. break; /* EVT_BLUE_GAP_DEVICE_FOUND */
  287. case EVT_BLUE_GAP_ADDR_NOT_RESOLVED:
  288. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \r\n");
  289. break; /* EVT_BLUE_GAP_DEVICE_FOUND */
  290. case (EVT_BLUE_GAP_KEYPRESS_NOTIFICATION):
  291. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_KEYPRESS_NOTIFICATION \r\n");
  292. break; /* EVT_BLUE_GAP_KEY_PRESS_NOTIFICATION */
  293. case (EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE):
  294. APP_DBG_MSG("numeric_value = %ld\r\n",
  295. ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value);
  296. APP_DBG_MSG("Hex_value = %lx\r\n",
  297. ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value);
  298. aci_gap_numeric_comparison_value_confirm_yesno(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, 1); /* CONFIRM_YES = 1 */
  299. APP_DBG_MSG("\r\n\r** aci_gap_numeric_comparison_value_confirm_yesno-->YES \r\n");
  300. break;
  301. case (EVT_BLUE_GAP_PAIRING_CMPLT):
  302. {
  303. pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data;
  304. APP_DBG_MSG("BLE_CTRL_App_Notification: EVT_BLUE_GAP_PAIRING_CMPLT, pairing_complete->Status = %d\r\n",pairing_complete->Status);
  305. if (pairing_complete->Status == 0) {
  306. APP_DBG_MSG("\r\n\r** Pairing OK \r\n");
  307. } else {
  308. APP_DBG_MSG("\r\n\r** Pairing KO \r\n");
  309. }
  310. }
  311. break;
  312. /* USER CODE END ecode */
  313. case EVT_BLUE_GAP_PROCEDURE_COMPLETE:
  314. APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PROCEDURE_COMPLETE \r\n");
  315. break;
  316. }
  317. break; /* EVT_VENDOR */
  318. default:
  319. break;
  320. }
  321. return (SVCCTL_UserEvtFlowEnable);
  322. }
  323. APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status() {
  324. return BleApplicationContext.Device_Connection_Status;
  325. }
  326. /* USER CODE BEGIN FD*/
  327. void APP_BLE_Key_Button1_Action() {
  328. tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
  329. ret = aci_gap_clear_security_db();
  330. if (ret == BLE_STATUS_SUCCESS) {
  331. APP_DBG_MSG("Successfully aci_gap_clear_security_db()\r\n");
  332. } else {
  333. APP_DBG_MSG("aci_gap_clear_security_db() Failed , result: %d \r\n", ret);
  334. }
  335. }
  336. void APP_BLE_Key_Button2_Action() {
  337. tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
  338. ret = aci_gap_slave_security_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
  339. if (ret == BLE_STATUS_SUCCESS) {
  340. APP_DBG_MSG("Successfully aci_gap_slave_security_req()");
  341. } else {
  342. APP_DBG_MSG("aci_gap_slave_security_req() Failed , result: %d \r\n", ret);
  343. }
  344. }
  345. void APP_BLE_Key_Button3_Action() {
  346. uint8_t TX_PHY, RX_PHY;
  347. tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
  348. ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY);
  349. if (ret == BLE_STATUS_SUCCESS) {
  350. APP_DBG_MSG("Read_PHY success \r\n");
  351. APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY);
  352. if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M)) {
  353. APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_1M, RX_1M);
  354. ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_1M,RX_1M,0);
  355. } else {
  356. APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_2M_PREFERRED, RX_2M_PREFERRED);
  357. ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_2M_PREFERRED,RX_2M_PREFERRED,0);
  358. }
  359. } else {
  360. APP_DBG_MSG("Read conf not succeess \r\n");
  361. }
  362. if (ret == BLE_STATUS_SUCCESS) {
  363. APP_DBG_MSG("set PHY cmd ok\r\n");
  364. } else {
  365. APP_DBG_MSG("set PHY cmd NOK\r\n");
  366. }
  367. }
  368. static void Ble_Tl_Init( void ) {
  369. HCI_TL_HciInitConf_t Hci_Tl_Init_Conf;
  370. MtxHciId = osMutexNew( NULL );
  371. SemHciId = osSemaphoreNew( 1, 0, NULL ); /*< Create the semaphore and make it busy at initialization */
  372. Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&BleCmdBuffer;
  373. Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot;
  374. hci_init(BLE_UserEvtRx, (void*) &Hci_Tl_Init_Conf);
  375. }
  376. static void Ble_Hci_Gap_Gatt_Init() {
  377. uint8_t role;
  378. uint16_t gap_service_handle, gap_dev_name_char_handle, gap_appearance_char_handle;
  379. const uint8_t *bd_addr;
  380. uint32_t srd_bd_addr[2];
  381. uint16_t appearance[1] = { BLE_CFG_GAP_APPEARANCE };
  382. /*HCI Reset to synchronise BLE Stack*/
  383. hci_reset();
  384. /**
  385. * Write the BD Address
  386. */
  387. bd_addr = BleGetBdAddress();
  388. aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
  389. CONFIG_DATA_PUBADDR_LEN,
  390. (uint8_t*) bd_addr);
  391. /* BLE MAC in ADV Packet */
  392. manuf_data[ sizeof(manuf_data)-6] = bd_addr[5];
  393. manuf_data[ sizeof(manuf_data)-5] = bd_addr[4];
  394. manuf_data[ sizeof(manuf_data)-4] = bd_addr[3];
  395. manuf_data[ sizeof(manuf_data)-3] = bd_addr[2];
  396. manuf_data[ sizeof(manuf_data)-2] = bd_addr[1];
  397. manuf_data[ sizeof(manuf_data)-1] = bd_addr[0];
  398. /**
  399. * Write Identity root key used to derive LTK and CSRK
  400. */
  401. aci_hal_write_config_data(CONFIG_DATA_IR_OFFSET,
  402. CONFIG_DATA_IR_LEN,
  403. (uint8_t*) BLE_CFG_IR_VALUE);
  404. /**
  405. * Write Encryption root key used to derive LTK and CSRK
  406. */
  407. aci_hal_write_config_data(CONFIG_DATA_ER_OFFSET,
  408. CONFIG_DATA_ER_LEN,
  409. (uint8_t*) BLE_CFG_ER_VALUE);
  410. /**
  411. * Write random bd_address
  412. */
  413. /* random_bd_address = R_bd_address;
  414. aci_hal_write_config_data(CONFIG_DATA_RANDOM_ADDRESS_WR,
  415. CONFIG_DATA_RANDOM_ADDRESS_LEN,
  416. (uint8_t*) random_bd_address);
  417. */
  418. /**
  419. * Static random Address
  420. * The two upper bits shall be set to 1
  421. * The lowest 32bits is read from the UDN to differentiate between devices
  422. * The RNG may be used to provide a random number on each power on
  423. */
  424. srd_bd_addr[1] = 0x0000ED6E;
  425. srd_bd_addr[0] = LL_FLASH_GetUDN( );
  426. aci_hal_write_config_data( CONFIG_DATA_RANDOM_ADDRESS_OFFSET, CONFIG_DATA_RANDOM_ADDRESS_LEN, (uint8_t*)srd_bd_addr );
  427. /**
  428. * Write Identity root key used to derive LTK and CSRK
  429. */
  430. aci_hal_write_config_data( CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t*)BLE_CFG_IR_VALUE );
  431. /**
  432. * Write Encryption root key used to derive LTK and CSRK
  433. */
  434. aci_hal_write_config_data( CONFIG_DATA_ER_OFFSET, CONFIG_DATA_ER_LEN, (uint8_t*)BLE_CFG_ER_VALUE );
  435. /**
  436. * Set TX Power to 0dBm.
  437. */
  438. aci_hal_set_tx_power_level(1, CFG_TX_POWER);
  439. /**
  440. * Initialize GATT interface
  441. */
  442. aci_gatt_init();
  443. /**
  444. * Initialize GAP interface
  445. */
  446. role = 0;
  447. #if (BLE_CFG_PERIPHERAL == 1)
  448. role |= GAP_PERIPHERAL_ROLE;
  449. #endif
  450. #if (BLE_CFG_CENTRAL == 1)
  451. role |= GAP_CENTRAL_ROLE;
  452. #endif
  453. if (role > 0)
  454. {
  455. const char *name = furi_hal_version_get_device_name_ptr();
  456. aci_gap_init(role, 0,
  457. strlen(name),
  458. &gap_service_handle, &gap_dev_name_char_handle, &gap_appearance_char_handle);
  459. if (aci_gatt_update_char_value(gap_service_handle, gap_dev_name_char_handle, 0, strlen(name), (uint8_t *) name))
  460. {
  461. BLE_DBG_SVCCTL_MSG("Device Name aci_gatt_update_char_value failed.\r\n");
  462. }
  463. }
  464. if(aci_gatt_update_char_value(gap_service_handle,
  465. gap_appearance_char_handle,
  466. 0,
  467. 2,
  468. (uint8_t *)&appearance))
  469. {
  470. BLE_DBG_SVCCTL_MSG("Appearance aci_gatt_update_char_value failed.\r\n");
  471. }
  472. /**
  473. * Initialize Default PHY
  474. */
  475. hci_le_set_default_phy(ALL_PHYS_PREFERENCE,TX_2M_PREFERRED,RX_2M_PREFERRED);
  476. /**
  477. * Initialize IO capability
  478. */
  479. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability = CFG_IO_CAPABILITY;
  480. aci_gap_set_io_capability(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability);
  481. /**
  482. * Initialize authentication
  483. */
  484. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode = CFG_MITM_PROTECTION;
  485. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin = CFG_ENCRYPTION_KEY_SIZE_MIN;
  486. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax = CFG_ENCRYPTION_KEY_SIZE_MAX;
  487. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin = CFG_USED_FIXED_PIN;
  488. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin = CFG_FIXED_PIN;
  489. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode = CFG_BONDING_MODE;
  490. aci_gap_set_authentication_requirement(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode,
  491. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode,
  492. CFG_SC_SUPPORT,
  493. CFG_KEYPRESS_NOTIFICATION_SUPPORT,
  494. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin,
  495. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax,
  496. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin,
  497. BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin,
  498. PUBLIC_ADDR
  499. );
  500. /**
  501. * Initialize whitelist
  502. */
  503. if (BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode)
  504. {
  505. aci_gap_configure_whitelist();
  506. }
  507. }
  508. static void Adv_Request(APP_BLE_ConnStatus_t New_Status)
  509. {
  510. tBleStatus ret = BLE_STATUS_INVALID_PARAMS;
  511. uint16_t Min_Inter, Max_Inter;
  512. if (New_Status == APP_BLE_FAST_ADV)
  513. {
  514. Min_Inter = AdvIntervalMin;
  515. Max_Inter = AdvIntervalMax;
  516. }
  517. else
  518. {
  519. Min_Inter = CFG_LP_CONN_ADV_INTERVAL_MIN;
  520. Max_Inter = CFG_LP_CONN_ADV_INTERVAL_MAX;
  521. }
  522. /**
  523. * Stop the timer, it will be restarted for a new shot
  524. * It does not hurt if the timer was not running
  525. */
  526. HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id);
  527. APP_DBG_MSG("First index in %d state \r\n", BleApplicationContext.Device_Connection_Status);
  528. if ((New_Status == APP_BLE_LP_ADV)
  529. && ((BleApplicationContext.Device_Connection_Status == APP_BLE_FAST_ADV)
  530. || (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_ADV)))
  531. {
  532. /* Connection in ADVERTISE mode have to stop the current advertising */
  533. ret = aci_gap_set_non_discoverable();
  534. if (ret == BLE_STATUS_SUCCESS)
  535. {
  536. APP_DBG_MSG("Successfully Stopped Advertising \r\n");
  537. }
  538. else
  539. {
  540. APP_DBG_MSG("Stop Advertising Failed , result: %d \r\n", ret);
  541. }
  542. }
  543. BleApplicationContext.Device_Connection_Status = New_Status;
  544. const char* name = furi_hal_version_get_ble_local_device_name_ptr();
  545. /* Start Fast or Low Power Advertising */
  546. ret = aci_gap_set_discoverable(
  547. ADV_IND,
  548. Min_Inter,
  549. Max_Inter,
  550. PUBLIC_ADDR,
  551. NO_WHITE_LIST_USE, /* use white list */
  552. strlen(name),
  553. (uint8_t*)name,
  554. BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen,
  555. BleApplicationContext.BleApplicationContext_legacy.advtServUUID,
  556. 0,
  557. 0);
  558. /* Update Advertising data */
  559. ret = aci_gap_update_adv_data(sizeof(manuf_data), (uint8_t*) manuf_data);
  560. if (ret == BLE_STATUS_SUCCESS) {
  561. if (New_Status == APP_BLE_FAST_ADV) {
  562. APP_DBG_MSG("Successfully Start Fast Advertising \r\n" );
  563. /* Start Timer to STOP ADV - TIMEOUT */
  564. HW_TS_Start(BleApplicationContext.Advertising_mgr_timer_Id, INITIAL_ADV_TIMEOUT);
  565. } else {
  566. APP_DBG_MSG("Successfully Start Low Power Advertising \r\n");
  567. }
  568. } else {
  569. if (New_Status == APP_BLE_FAST_ADV) {
  570. APP_DBG_MSG("Start Fast Advertising Failed , result: %d \r\n", ret);
  571. } else {
  572. APP_DBG_MSG("Start Low Power Advertising Failed , result: %d \r\n", ret);
  573. }
  574. }
  575. }
  576. const uint8_t* BleGetBdAddress( void ) {
  577. uint8_t *otp_addr;
  578. const uint8_t *bd_addr;
  579. uint32_t udn;
  580. uint32_t company_id;
  581. uint32_t device_id;
  582. udn = LL_FLASH_GetUDN();
  583. if(udn != 0xFFFFFFFF) {
  584. company_id = LL_FLASH_GetSTCompanyID();
  585. device_id = LL_FLASH_GetDeviceID();
  586. bd_addr_udn[0] = (uint8_t)(udn & 0x000000FF);
  587. bd_addr_udn[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 );
  588. bd_addr_udn[2] = (uint8_t)( (udn & 0x00FF0000) >> 16 );
  589. bd_addr_udn[3] = (uint8_t)device_id;
  590. bd_addr_udn[4] = (uint8_t)(company_id & 0x000000FF);;
  591. bd_addr_udn[5] = (uint8_t)( (company_id & 0x0000FF00) >> 8 );
  592. bd_addr = (const uint8_t *)bd_addr_udn;
  593. } else {
  594. otp_addr = OTP_Read(0);
  595. if(otp_addr) {
  596. bd_addr = ((OTP_ID0_t*)otp_addr)->bd_address;
  597. } else {
  598. bd_addr = M_bd_addr;
  599. }
  600. }
  601. return bd_addr;
  602. }
  603. /*************************************************************
  604. *
  605. *SPECIFIC FUNCTIONS
  606. *
  607. *************************************************************/
  608. static void Add_Advertisment_Service_UUID( uint16_t servUUID ) {
  609. BleApplicationContext.BleApplicationContext_legacy.advtServUUID[BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen] =
  610. (uint8_t) (servUUID & 0xFF);
  611. BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen++;
  612. BleApplicationContext.BleApplicationContext_legacy.advtServUUID[BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen] =
  613. (uint8_t) (servUUID >> 8) & 0xFF;
  614. BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen++;
  615. }
  616. static void Adv_Mgr( void ) {
  617. /**
  618. * The code shall be executed in the background as an aci command may be sent
  619. * The background is the only place where the application can make sure a new aci command
  620. * is not sent if there is a pending one
  621. */
  622. osThreadFlagsSet( AdvUpdateProcessId, 1 );
  623. }
  624. static void AdvUpdateProcess(void *argument) {
  625. UNUSED(argument);
  626. for(;;) {
  627. osThreadFlagsWait( 1, osFlagsWaitAny, osWaitForever);
  628. Adv_Update( );
  629. }
  630. }
  631. static void Adv_Update( void ) {
  632. Adv_Request(APP_BLE_LP_ADV);
  633. }
  634. static void HciUserEvtProcess(void *argument) {
  635. UNUSED(argument);
  636. for(;;)
  637. {
  638. osThreadFlagsWait( 1, osFlagsWaitAny, osWaitForever);
  639. hci_user_evt_proc( );
  640. }
  641. }
  642. /*************************************************************
  643. *
  644. * WRAP FUNCTIONS
  645. *
  646. *************************************************************/
  647. void hci_notify_asynch_evt(void* pdata) {
  648. UNUSED(pdata);
  649. osThreadFlagsSet( HciUserEvtProcessId, 1 );
  650. }
  651. void hci_cmd_resp_release(uint32_t flag) {
  652. UNUSED(flag);
  653. osSemaphoreRelease( SemHciId );
  654. }
  655. void hci_cmd_resp_wait(uint32_t timeout) {
  656. UNUSED(timeout);
  657. osSemaphoreAcquire( SemHciId, osWaitForever );
  658. }
  659. static void BLE_UserEvtRx( void * pPayload ) {
  660. SVCCTL_UserEvtFlowStatus_t svctl_return_status;
  661. tHCI_UserEvtRxParam *pParam;
  662. pParam = (tHCI_UserEvtRxParam *)pPayload;
  663. svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial));
  664. if (svctl_return_status != SVCCTL_UserEvtFlowDisable) {
  665. pParam->status = HCI_TL_UserEventFlow_Enable;
  666. } else {
  667. pParam->status = HCI_TL_UserEventFlow_Disable;
  668. }
  669. }
  670. static void BLE_StatusNot( HCI_TL_CmdStatus_t status ) {
  671. switch (status) {
  672. case HCI_TL_CmdBusy:
  673. osMutexAcquire( MtxHciId, osWaitForever );
  674. break;
  675. case HCI_TL_CmdAvailable:
  676. osMutexRelease( MtxHciId );
  677. break;
  678. default:
  679. break;
  680. }
  681. }
  682. void SVCCTL_ResumeUserEventFlow( void ) {
  683. hci_resume_flow();
  684. }