broadcaster.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /**
  2. * @file
  3. * @author chipsea
  4. * @brief
  5. * @version 0.1
  6. * @date 2020-11-30
  7. * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
  8. * @note
  9. */
  10. /*********************************************************************
  11. * INCLUDES
  12. */
  13. #include "bcomdef.h"
  14. #include "OSAL.h"
  15. #include "hci_tl.h"
  16. #include "gap.h"
  17. #include "broadcaster.h"
  18. /*********************************************************************
  19. * MACROS
  20. */
  21. /*********************************************************************
  22. * CONSTANTS
  23. */
  24. // Profile Events
  25. #define START_ADVERTISING_EVT 0x0001
  26. #define DEFAULT_ADVERT_OFF_TIME 30000 // 30 seconds
  27. /*********************************************************************
  28. * TYPEDEFS
  29. */
  30. /*********************************************************************
  31. * GLOBAL VARIABLES
  32. */
  33. /*********************************************************************
  34. * EXTERNAL VARIABLES
  35. */
  36. /*********************************************************************
  37. * EXTERNAL FUNCTIONS
  38. */
  39. /*********************************************************************
  40. * LOCAL VARIABLES
  41. */
  42. static uint8 gapRole_TaskID; // Task ID for internal task/event processing
  43. static gaprole_States_t gapRole_state;
  44. /*********************************************************************
  45. * Profile Parameters - reference GAPROLE_PROFILE_PARAMETERS for
  46. * descriptions
  47. */
  48. static uint8 gapRole_profileRole;
  49. static uint8 gapRole_bdAddr[B_ADDR_LEN];
  50. static uint8 gapRole_AdvEnabled = TRUE;
  51. static uint16 gapRole_AdvertOffTime = DEFAULT_ADVERT_OFF_TIME;
  52. static uint8 gapRole_AdvertDataLen = 3;
  53. static uint8 gapRole_AdvertData[B_MAX_ADV_LEN] =
  54. {
  55. 0x02, // length of this data
  56. GAP_ADTYPE_FLAGS, // AD Type = Flags
  57. // BR/EDR not supported
  58. GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
  59. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  60. };
  61. static uint8 gapRole_ScanRspDataLen = 0;
  62. static uint8 gapRole_ScanRspData[B_MAX_ADV_LEN] = {0};
  63. static uint8 gapRole_AdvEventType;
  64. static uint8 gapRole_AdvDirectType;
  65. static uint8 gapRole_AdvDirectAddr[B_ADDR_LEN] = {0};
  66. static uint8 gapRole_AdvChanMap;
  67. static uint8 gapRole_AdvFilterPolicy;
  68. // Application callbacks
  69. static gapRolesCBs_t *pGapRoles_AppCGs = NULL;
  70. /*********************************************************************
  71. * Profile Attributes - variables
  72. */
  73. /*********************************************************************
  74. * Profile Attributes - Table
  75. */
  76. /*********************************************************************
  77. * LOCAL FUNCTIONS
  78. */
  79. static void gapRole_ProcessOSALMsg( osal_event_hdr_t *pMsg );
  80. static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg );
  81. static void gapRole_SetupGAP( void );
  82. /*********************************************************************
  83. * NETWORK LAYER CALLBACKS
  84. */
  85. /*********************************************************************
  86. * PUBLIC FUNCTIONS
  87. */
  88. /*********************************************************************
  89. * @brief Set a GAP Role parameter.
  90. *
  91. * Public function defined in broadcaster.h.
  92. */
  93. bStatus_t GAPRole_SetParameter( uint16 param, uint8 len, void *pValue )
  94. {
  95. bStatus_t ret = SUCCESS;
  96. switch ( param )
  97. {
  98. case GAPROLE_ADVERT_ENABLED:
  99. if ( len == sizeof( uint8 ) )
  100. {
  101. uint8 oldAdvEnabled = gapRole_AdvEnabled;
  102. gapRole_AdvEnabled = *((uint8*)pValue);
  103. if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) )
  104. {
  105. // Turn off Advertising
  106. if ( gapRole_state == GAPROLE_ADVERTISING )
  107. {
  108. VOID GAP_EndDiscoverable( gapRole_TaskID );
  109. }
  110. }
  111. else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )
  112. {
  113. // Turn on Advertising
  114. if ( (gapRole_state == GAPROLE_STARTED)
  115. || (gapRole_state == GAPROLE_WAITING) )
  116. {
  117. VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
  118. }
  119. }
  120. }
  121. else
  122. {
  123. ret = bleInvalidRange;
  124. }
  125. break;
  126. case GAPROLE_ADVERT_OFF_TIME:
  127. if ( len == sizeof ( uint16 ) )
  128. {
  129. gapRole_AdvertOffTime = *((uint16*)pValue);
  130. }
  131. else
  132. {
  133. ret = bleInvalidRange;
  134. }
  135. break;
  136. case GAPROLE_ADVERT_DATA:
  137. if ( len <= B_MAX_ADV_LEN )
  138. {
  139. VOID osal_memset( gapRole_AdvertData, 0, B_MAX_ADV_LEN );
  140. VOID osal_memcpy( gapRole_AdvertData, pValue, len );
  141. gapRole_AdvertDataLen = len;
  142. }
  143. else
  144. {
  145. ret = bleInvalidRange;
  146. }
  147. break;
  148. case GAPROLE_SCAN_RSP_DATA:
  149. if ( len <= B_MAX_ADV_LEN )
  150. {
  151. VOID osal_memset( gapRole_ScanRspData, 0, B_MAX_ADV_LEN );
  152. VOID osal_memcpy( gapRole_ScanRspData, pValue, len );
  153. gapRole_ScanRspDataLen = len;
  154. }
  155. else
  156. {
  157. ret = bleInvalidRange;
  158. }
  159. break;
  160. case GAPROLE_ADV_EVENT_TYPE:
  161. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_ADTYPE_ADV_LDC_DIRECT_IND) )
  162. {
  163. gapRole_AdvEventType = *((uint8*)pValue);
  164. }
  165. else
  166. {
  167. ret = bleInvalidRange;
  168. }
  169. break;
  170. case GAPROLE_ADV_DIRECT_TYPE:
  171. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= ADDRTYPE_PRIVATE_RESOLVE) )
  172. {
  173. gapRole_AdvDirectType = *((uint8*)pValue);
  174. }
  175. else
  176. {
  177. ret = bleInvalidRange;
  178. }
  179. break;
  180. case GAPROLE_ADV_DIRECT_ADDR:
  181. if ( len == B_ADDR_LEN )
  182. {
  183. VOID osal_memcpy( gapRole_AdvDirectAddr, pValue, B_ADDR_LEN ) ;
  184. }
  185. else
  186. {
  187. ret = bleInvalidRange;
  188. }
  189. break;
  190. case GAPROLE_ADV_CHANNEL_MAP:
  191. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= 0x07) )
  192. {
  193. gapRole_AdvChanMap = *((uint8*)pValue);
  194. }
  195. else
  196. {
  197. ret = bleInvalidRange;
  198. }
  199. break;
  200. case GAPROLE_ADV_FILTER_POLICY:
  201. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_FILTER_POLICY_WHITE) )
  202. {
  203. gapRole_AdvFilterPolicy = *((uint8*)pValue);
  204. }
  205. else
  206. {
  207. ret = bleInvalidRange;
  208. }
  209. break;
  210. default:
  211. // The param value isn't part of this profile, try the GAP.
  212. if ( (param < TGAP_PARAMID_MAX) && (len == sizeof ( uint16 )) )
  213. {
  214. ret = GAP_SetParamValue( param, *((uint16*)pValue) );
  215. }
  216. else
  217. {
  218. ret = INVALIDPARAMETER;
  219. }
  220. break;
  221. }
  222. return ( ret );
  223. }
  224. /*********************************************************************
  225. * @brief Get a GAP Role parameter.
  226. *
  227. * Public function defined in broadcaster.h.
  228. */
  229. bStatus_t GAPRole_GetParameter( uint16 param, void *pValue )
  230. {
  231. bStatus_t ret = SUCCESS;
  232. switch ( param )
  233. {
  234. case GAPROLE_PROFILEROLE:
  235. *((uint8*)pValue) = gapRole_profileRole;
  236. break;
  237. case GAPROLE_BD_ADDR:
  238. VOID osal_memcpy( pValue, gapRole_bdAddr, B_ADDR_LEN ) ;
  239. break;
  240. case GAPROLE_ADVERT_ENABLED:
  241. *((uint8*)pValue) = gapRole_AdvEnabled;
  242. break;
  243. case GAPROLE_ADVERT_OFF_TIME:
  244. *((uint16*)pValue) = gapRole_AdvertOffTime;
  245. break;
  246. case GAPROLE_ADVERT_DATA:
  247. VOID osal_memcpy( pValue , gapRole_AdvertData, gapRole_AdvertDataLen );
  248. break;
  249. case GAPROLE_SCAN_RSP_DATA:
  250. VOID osal_memcpy( pValue, gapRole_ScanRspData, gapRole_ScanRspDataLen ) ;
  251. break;
  252. case GAPROLE_ADV_EVENT_TYPE:
  253. *((uint8*)pValue) = gapRole_AdvEventType;
  254. break;
  255. case GAPROLE_ADV_DIRECT_TYPE:
  256. *((uint8*)pValue) = gapRole_AdvDirectType;
  257. break;
  258. case GAPROLE_ADV_DIRECT_ADDR:
  259. VOID osal_memcpy( pValue, gapRole_AdvDirectAddr, B_ADDR_LEN ) ;
  260. break;
  261. case GAPROLE_ADV_CHANNEL_MAP:
  262. *((uint8*)pValue) = gapRole_AdvChanMap;
  263. break;
  264. case GAPROLE_ADV_FILTER_POLICY:
  265. *((uint8*)pValue) = gapRole_AdvFilterPolicy;
  266. break;
  267. default:
  268. // The param value isn't part of this profile, try the GAP.
  269. if ( param < TGAP_PARAMID_MAX )
  270. {
  271. *((uint16*)pValue) = GAP_GetParamValue( param );
  272. }
  273. else
  274. {
  275. ret = INVALIDPARAMETER;
  276. }
  277. break;
  278. }
  279. return ( ret );
  280. }
  281. /*********************************************************************
  282. * @brief Does the device initialization.
  283. *
  284. * Public function defined in broadcaster.h.
  285. */
  286. bStatus_t GAPRole_StartDevice( gapRolesCBs_t *pAppCallbacks )
  287. {
  288. if ( gapRole_state == GAPROLE_INIT )
  289. {
  290. // Clear all of the Application callbacks
  291. if ( pAppCallbacks )
  292. {
  293. pGapRoles_AppCGs = pAppCallbacks;
  294. }
  295. // Start the GAP
  296. gapRole_SetupGAP();
  297. return ( SUCCESS );
  298. }
  299. else
  300. {
  301. return ( bleAlreadyInRequestedMode );
  302. }
  303. }
  304. /*********************************************************************
  305. * LOCAL FUNCTION PROTOTYPES
  306. */
  307. /*********************************************************************
  308. * @brief Task Initialization function.
  309. *
  310. * Internal function defined in broadcaster.h.
  311. */
  312. void GAPRole_Init( uint8 task_id )
  313. {
  314. gapRole_TaskID = task_id;
  315. gapRole_state = GAPROLE_INIT;
  316. GAP_RegisterForHCIMsgs( gapRole_TaskID );
  317. // Initialize the Profile Advertising and Connection Parameters
  318. gapRole_profileRole = GAP_PROFILE_BROADCASTER;
  319. gapRole_AdvEventType = GAP_ADTYPE_ADV_NONCONN_IND;
  320. gapRole_AdvDirectType = ADDRTYPE_PUBLIC;
  321. gapRole_AdvChanMap = GAP_ADVCHAN_ALL;
  322. gapRole_AdvFilterPolicy = GAP_FILTER_POLICY_ALL;
  323. }
  324. /*********************************************************************
  325. * @brief Task Event Processor function.
  326. *
  327. * Internal function defined in broadcaster.h.
  328. */
  329. uint16 GAPRole_ProcessEvent( uint8 task_id, uint16 events )
  330. {
  331. VOID task_id; // OSAL required parameter that isn't used in this function
  332. if ( events & SYS_EVENT_MSG )
  333. {
  334. uint8 *pMsg;
  335. if ( (pMsg = osal_msg_receive( gapRole_TaskID )) != NULL )
  336. {
  337. gapRole_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
  338. // Release the OSAL message
  339. VOID osal_msg_deallocate( pMsg );
  340. }
  341. // return unprocessed events
  342. return (events ^ SYS_EVENT_MSG);
  343. }
  344. if ( events & START_ADVERTISING_EVT )
  345. {
  346. if ( gapRole_AdvEnabled )
  347. {
  348. gapAdvertisingParams_t params;
  349. // Setup advertisement parameters
  350. params.eventType = gapRole_AdvEventType;
  351. params.initiatorAddrType = gapRole_AdvDirectType;
  352. VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );
  353. params.channelMap = gapRole_AdvChanMap;
  354. params.filterPolicy = gapRole_AdvFilterPolicy;
  355. if ( GAP_MakeDiscoverable( gapRole_TaskID, &params ) != SUCCESS )
  356. {
  357. gapRole_state = GAPROLE_ERROR;
  358. if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
  359. {
  360. pGapRoles_AppCGs->pfnStateChange( gapRole_state );
  361. }
  362. }
  363. }
  364. return ( events ^ START_ADVERTISING_EVT );
  365. }
  366. // Discard unknown events
  367. return 0;
  368. }
  369. /*********************************************************************
  370. * @fn gapRole_ProcessOSALMsg
  371. *
  372. * @brief Process an incoming task message.
  373. *
  374. * @param pMsg - message to process
  375. *
  376. * @return none
  377. */
  378. static void gapRole_ProcessOSALMsg( osal_event_hdr_t *pMsg )
  379. {
  380. switch ( pMsg->event )
  381. {
  382. case HCI_GAP_EVENT_EVENT:
  383. if ( pMsg->status == HCI_COMMAND_COMPLETE_EVENT_CODE )
  384. {
  385. //hciEvt_CmdComplete_t *pPkt = (hciEvt_CmdComplete_t *)pMsg;
  386. }
  387. break;
  388. case GAP_MSG_EVENT:
  389. gapRole_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
  390. break;
  391. default:
  392. break;
  393. }
  394. }
  395. /*********************************************************************
  396. * @fn gapRole_ProcessGAPMsg
  397. *
  398. * @brief Process an incoming task message.
  399. *
  400. * @param pMsg - message to process
  401. *
  402. * @return none
  403. */
  404. static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
  405. {
  406. uint8 notify = FALSE; // State changed notify the app? (default no)
  407. switch ( pMsg->opcode )
  408. {
  409. case GAP_DEVICE_INIT_DONE_EVENT:
  410. {
  411. gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
  412. bStatus_t stat = pPkt->hdr.status;
  413. if ( stat == SUCCESS )
  414. {
  415. // Save off the information
  416. VOID osal_memcpy( gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN );
  417. gapRole_state = GAPROLE_STARTED;
  418. // Update the advertising data
  419. stat = GAP_UpdateAdvertisingData( gapRole_TaskID, TRUE,
  420. gapRole_AdvertDataLen,
  421. gapRole_AdvertData );
  422. }
  423. if ( stat != SUCCESS )
  424. {
  425. gapRole_state = GAPROLE_ERROR;
  426. }
  427. notify = TRUE;
  428. }
  429. break;
  430. case GAP_ADV_DATA_UPDATE_DONE_EVENT:
  431. {
  432. gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;
  433. if ( pPkt->hdr.status == SUCCESS )
  434. {
  435. if ( pPkt->adType )
  436. {
  437. // Setup the Response Data
  438. pPkt->hdr.status = GAP_UpdateAdvertisingData( gapRole_TaskID,
  439. FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
  440. }
  441. else
  442. {
  443. // Start advertising
  444. VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
  445. }
  446. }
  447. if ( pPkt->hdr.status != SUCCESS )
  448. {
  449. // Set into Error state
  450. gapRole_state = GAPROLE_ERROR;
  451. notify = TRUE;
  452. }
  453. }
  454. break;
  455. case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
  456. case GAP_END_DISCOVERABLE_DONE_EVENT:
  457. {
  458. gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;
  459. if ( pPkt->hdr.status == SUCCESS )
  460. {
  461. if ( pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT )
  462. {
  463. gapRole_state = GAPROLE_ADVERTISING;
  464. }
  465. else // GAP_END_DISCOVERABLE_DONE_EVENT
  466. {
  467. if ( gapRole_AdvertOffTime != 0 )
  468. {
  469. if ( ( gapRole_AdvEnabled ) )
  470. {
  471. VOID osal_start_timerEx( gapRole_TaskID, START_ADVERTISING_EVT, gapRole_AdvertOffTime );
  472. }
  473. }
  474. else
  475. {
  476. // Since gapRole_AdvertOffTime is set to 0, the device should not
  477. // automatically become discoverable again after a period of time.
  478. // Set enabler to FALSE; device will become discoverable again when
  479. // this value gets set to TRUE
  480. gapRole_AdvEnabled = FALSE;
  481. }
  482. // In the Advertising Off period
  483. gapRole_state = GAPROLE_WAITING;
  484. }
  485. }
  486. else
  487. {
  488. gapRole_state = GAPROLE_ERROR;
  489. }
  490. notify = TRUE;
  491. }
  492. break;
  493. default:
  494. break;
  495. }
  496. if ( notify == TRUE )
  497. {
  498. // Notify the application
  499. if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
  500. {
  501. pGapRoles_AppCGs->pfnStateChange( gapRole_state );
  502. }
  503. }
  504. }
  505. /*********************************************************************
  506. * @fn gapRole_SetupGAP
  507. *
  508. * @brief Call the GAP Device Initialization function using the
  509. * Profile Parameters.
  510. *
  511. * @param none
  512. *
  513. * @return none
  514. */
  515. static void gapRole_SetupGAP( void )
  516. {
  517. VOID GAP_DeviceInit( gapRole_TaskID,
  518. gapRole_profileRole, 0,
  519. NULL, NULL, NULL );
  520. }
  521. /*********************************************************************
  522. *********************************************************************/