central.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. /**************************************************************************************************
  2. Phyplus Microelectronics Limited confidential and proprietary.
  3. All rights reserved.
  4. IMPORTANT: All rights of this software belong to Phyplus Microelectronics
  5. Limited ("Phyplus"). Your use of this Software is limited to those
  6. specific rights granted under the terms of the business contract, the
  7. confidential agreement, the non-disclosure agreement and any other forms
  8. of agreements as a customer or a partner of Phyplus. You may not use this
  9. Software unless you agree to abide by the terms of these agreements.
  10. You acknowledge that the Software may not be modified, copied,
  11. distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
  12. (BLE) integrated circuit, either as a product or is integrated into your
  13. products. Other than for the aforementioned purposes, you may not use,
  14. reproduce, copy, prepare derivative works of, modify, distribute, perform,
  15. display or sell this Software and/or its documentation for any purposes.
  16. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  17. PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  18. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  19. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  20. PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
  21. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  22. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  23. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  24. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  25. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  26. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  27. **************************************************************************************************/
  28. /*********************************************************************
  29. * INCLUDES
  30. */
  31. #include "bcomdef.h"
  32. #include "OSAL.h"
  33. #include "osal_cbTimer.h"
  34. #include "osal_snv.h"
  35. #include "hci_tl.h"
  36. #include "l2cap.h"
  37. #include "linkdb.h"
  38. #include "gap.h"
  39. #include "gapbondmgr.h"
  40. #include "central.h"
  41. /*********************************************************************
  42. * MACROS
  43. */
  44. /*********************************************************************
  45. * CONSTANTS
  46. */
  47. // Profile Events
  48. #define START_ADVERTISING_EVT 0x0001
  49. #define RSSI_READ_EVT 0x0002
  50. #define UPDATE_PARAMS_TIMEOUT_EVT 0x0004
  51. // Profile OSAL Message IDs
  52. #define GAPCENTRALROLE_RSSI_MSG_EVT 0xE0
  53. /*********************************************************************
  54. * TYPEDEFS
  55. */
  56. // RSSI read data structure
  57. typedef struct
  58. {
  59. uint16 period;
  60. uint16 connHandle;
  61. uint8 timerId;
  62. } gapCentralRoleRssi_t;
  63. // OSAL event structure for RSSI timer events
  64. typedef struct
  65. {
  66. osal_event_hdr_t hdr;
  67. gapCentralRoleRssi_t *pRssi;
  68. } gapCentralRoleRssiEvent_t;
  69. /*********************************************************************
  70. * GLOBAL VARIABLES
  71. */
  72. /*********************************************************************
  73. * EXTERNAL VARIABLES
  74. */
  75. /*********************************************************************
  76. * EXTERNAL FUNCTIONS
  77. */
  78. /*********************************************************************
  79. * LOCAL VARIABLES
  80. */
  81. // Task ID
  82. static uint8 gapCentralRoleTaskId;
  83. // App callbacks
  84. static gapCentralRoleCB_t *pGapCentralRoleCB;
  85. // Array of RSSI read structures
  86. static gapCentralRoleRssi_t gapCentralRoleRssi[GAPCENTRALROLE_NUM_RSSI_LINKS];
  87. /*********************************************************************
  88. * Profile Parameters - reference GAPCENTRALROLE_PROFILE_PARAMETERS for
  89. * descriptions
  90. */
  91. static uint8 gapCentralRoleIRK[KEYLEN];
  92. static uint8 gapCentralRoleSRK[KEYLEN];
  93. static uint32 gapCentralRoleSignCounter;
  94. static uint8 gapCentralRoleBdAddr[B_ADDR_LEN];
  95. static uint8 gapCentralRoleMaxScanRes = 0;
  96. /*********************************************************************
  97. * LOCAL FUNCTIONS
  98. */
  99. static void gapCentralRole_ProcessOSALMsg( osal_event_hdr_t *pMsg );
  100. static void gapCentralRole_ProcessGAPMsg( gapEventHdr_t *pMsg );
  101. static gapCentralRoleRssi_t *gapCentralRole_RssiAlloc( uint16 connHandle );
  102. static gapCentralRoleRssi_t *gapCentralRole_RssiFind( uint16 connHandle );
  103. static void gapCentralRole_RssiFree( uint16 connHandle );
  104. static void gapCentralRole_timerCB( uint8 *pData );
  105. /*********************************************************************
  106. * PUBLIC FUNCTIONS
  107. */
  108. /**
  109. * @brief Start the device in Central role. This function is typically
  110. * called once during system startup.
  111. *
  112. * Public function defined in central.h.
  113. */
  114. bStatus_t GAPCentralRole_StartDevice( gapCentralRoleCB_t *pAppCallbacks )
  115. {
  116. if ( pAppCallbacks )
  117. {
  118. pGapCentralRoleCB = pAppCallbacks;
  119. }
  120. return GAP_DeviceInit( gapCentralRoleTaskId, GAP_PROFILE_CENTRAL,
  121. gapCentralRoleMaxScanRes, gapCentralRoleIRK,
  122. gapCentralRoleSRK, &gapCentralRoleSignCounter );
  123. }
  124. /**
  125. * @brief Set a parameter in the Central Profile.
  126. *
  127. * Public function defined in central.h.
  128. */
  129. bStatus_t GAPCentralRole_SetParameter( uint16 param, uint8 len, void *pValue )
  130. {
  131. bStatus_t ret = SUCCESS;
  132. switch ( param )
  133. {
  134. case GAPCENTRALROLE_IRK:
  135. if ( len == KEYLEN )
  136. {
  137. VOID osal_memcpy( gapCentralRoleIRK, pValue, KEYLEN ) ;
  138. }
  139. else
  140. {
  141. ret = bleInvalidRange;
  142. }
  143. break;
  144. case GAPCENTRALROLE_SRK:
  145. if ( len == KEYLEN )
  146. {
  147. VOID osal_memcpy( gapCentralRoleSRK, pValue, KEYLEN ) ;
  148. }
  149. else
  150. {
  151. ret = bleInvalidRange;
  152. }
  153. break;
  154. case GAPCENTRALROLE_SIGNCOUNTER:
  155. if ( len == sizeof ( uint32 ) )
  156. {
  157. gapCentralRoleSignCounter = *((uint32*)pValue);
  158. }
  159. else
  160. {
  161. ret = bleInvalidRange;
  162. }
  163. break;
  164. case GAPCENTRALROLE_MAX_SCAN_RES:
  165. if ( len == sizeof ( uint8 ) )
  166. {
  167. gapCentralRoleMaxScanRes = *((uint8*)pValue);
  168. }
  169. else
  170. {
  171. ret = bleInvalidRange;
  172. }
  173. break;
  174. default:
  175. ret = INVALIDPARAMETER;
  176. break;
  177. }
  178. return ret;
  179. }
  180. /**
  181. * @brief Get a parameter in the Central Profile.
  182. *
  183. * Public function defined in central.h.
  184. */
  185. bStatus_t GAPCentralRole_GetParameter( uint16 param, void *pValue )
  186. {
  187. bStatus_t ret = SUCCESS;
  188. switch ( param )
  189. {
  190. case GAPCENTRALROLE_IRK:
  191. VOID osal_memcpy( pValue, gapCentralRoleIRK, KEYLEN ) ;
  192. break;
  193. case GAPCENTRALROLE_SRK:
  194. VOID osal_memcpy( pValue, gapCentralRoleSRK, KEYLEN ) ;
  195. break;
  196. case GAPCENTRALROLE_SIGNCOUNTER:
  197. *((uint32*)pValue) = gapCentralRoleSignCounter;
  198. break;
  199. case GAPCENTRALROLE_BD_ADDR:
  200. VOID osal_memcpy( pValue, gapCentralRoleBdAddr, B_ADDR_LEN ) ;
  201. break;
  202. case GAPCENTRALROLE_MAX_SCAN_RES:
  203. *((uint8*)pValue) = gapCentralRoleMaxScanRes;
  204. break;
  205. default:
  206. ret = INVALIDPARAMETER;
  207. break;
  208. }
  209. return ret;
  210. }
  211. /**
  212. * @brief Terminate a link.
  213. *
  214. * Public function defined in central.h.
  215. */
  216. bStatus_t GAPCentralRole_TerminateLink( uint16 connHandle )
  217. {
  218. return GAP_TerminateLinkReq( gapCentralRoleTaskId, connHandle, HCI_DISCONNECT_REMOTE_USER_TERM ) ;
  219. }
  220. /**
  221. * @brief Establish a link to a peer device.
  222. *
  223. * Public function defined in central.h.
  224. */
  225. bStatus_t GAPCentralRole_EstablishLink( uint8 highDutyCycle, uint8 whiteList,
  226. uint8 addrTypePeer, uint8 *peerAddr )
  227. {
  228. gapEstLinkReq_t params;
  229. params.taskID = gapCentralRoleTaskId;
  230. params.highDutyCycle = highDutyCycle;
  231. params.whiteList = whiteList;
  232. params.addrTypePeer = addrTypePeer;
  233. VOID osal_memcpy( params.peerAddr, peerAddr, B_ADDR_LEN );
  234. return GAP_EstablishLinkReq( &params );
  235. }
  236. /**
  237. * @brief Update the link connection parameters.
  238. *
  239. * Public function defined in central.h.
  240. */
  241. bStatus_t GAPCentralRole_UpdateLink( uint16 connHandle, uint16 connIntervalMin,
  242. uint16 connIntervalMax, uint16 connLatency,
  243. uint16 connTimeout )
  244. {
  245. return (bStatus_t) HCI_LE_ConnUpdateCmd( connHandle, connIntervalMin,
  246. connIntervalMax, connLatency,
  247. connTimeout, 0, 0 );
  248. }
  249. /**
  250. * @brief Start a device discovery scan.
  251. *
  252. * Public function defined in central.h.
  253. */
  254. bStatus_t GAPCentralRole_StartDiscovery( uint8 mode, uint8 activeScan, uint8 whiteList )
  255. {
  256. gapDevDiscReq_t params;
  257. params.taskID = gapCentralRoleTaskId;
  258. params.mode = mode;
  259. params.activeScan = activeScan;
  260. params.whiteList = whiteList;
  261. return GAP_DeviceDiscoveryRequest( &params );
  262. }
  263. /**
  264. * @brief Cancel a device discovery scan.
  265. *
  266. * Public function defined in central.h.
  267. */
  268. bStatus_t GAPCentralRole_CancelDiscovery( void )
  269. {
  270. return GAP_DeviceDiscoveryCancel( gapCentralRoleTaskId );
  271. }
  272. /**
  273. * @brief Start periodic RSSI reads on a link.
  274. *
  275. * Public function defined in central.h.
  276. */
  277. bStatus_t GAPCentralRole_StartRssi( uint16 connHandle, uint16 period )
  278. {
  279. gapCentralRoleRssi_t *pRssi;
  280. // Verify link is up
  281. if (!linkDB_Up(connHandle))
  282. {
  283. return bleIncorrectMode;
  284. }
  285. // If already allocated
  286. if ((pRssi = gapCentralRole_RssiFind( connHandle )) != NULL)
  287. {
  288. // Stop timer
  289. osal_CbTimerStop( pRssi->timerId );
  290. }
  291. // Allocate structure
  292. else if ((pRssi = gapCentralRole_RssiAlloc( connHandle )) != NULL)
  293. {
  294. pRssi->period = period;
  295. }
  296. // Allocate failed
  297. else
  298. {
  299. return bleNoResources;
  300. }
  301. // Start timer
  302. osal_CbTimerStart( gapCentralRole_timerCB, (uint8 *) pRssi,
  303. period, &pRssi->timerId );
  304. return SUCCESS;
  305. }
  306. /**
  307. * @brief Cancel periodic RSSI reads on a link.
  308. *
  309. * Public function defined in central.h.
  310. */
  311. bStatus_t GAPCentralRole_CancelRssi(uint16 connHandle )
  312. {
  313. gapCentralRoleRssi_t *pRssi;
  314. if ((pRssi = gapCentralRole_RssiFind( connHandle )) != NULL)
  315. {
  316. // Stop timer
  317. osal_CbTimerStop( pRssi->timerId );
  318. // Free RSSI structure
  319. gapCentralRole_RssiFree( connHandle );
  320. return SUCCESS;
  321. }
  322. // Not found
  323. return bleIncorrectMode;
  324. }
  325. /**
  326. * @brief Central Profile Task initialization function.
  327. *
  328. * @param taskId - Task ID.
  329. *
  330. * @return void
  331. */
  332. void GAPCentralRole_Init( uint8 taskId )
  333. {
  334. uint8 i;
  335. gapCentralRoleTaskId = taskId;
  336. // Initialize internal data
  337. for ( i = 0; i < GAPCENTRALROLE_NUM_RSSI_LINKS; i++ )
  338. {
  339. gapCentralRoleRssi[i].connHandle = GAP_CONNHANDLE_ALL;
  340. gapCentralRoleRssi[i].timerId = INVALID_TIMER_ID;
  341. }
  342. // Initialize parameters
  343. // Retore items from NV
  344. // VOID osal_snv_read( BLE_NVID_IRK, KEYLEN, gapCentralRoleIRK );
  345. // VOID osal_snv_read( BLE_NVID_CSRK, KEYLEN, gapCentralRoleSRK );
  346. // VOID osal_snv_read( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapCentralRoleSignCounter );
  347. // Register for HCI messages (for RSSI)
  348. GAP_RegisterForHCIMsgs( taskId );
  349. }
  350. /**
  351. * @brief Central Profile Task event processing function.
  352. *
  353. * @param taskId - Task ID
  354. * @param events - Events.
  355. *
  356. * @return events not processed
  357. */
  358. uint16 GAPCentralRole_ProcessEvent( uint8 taskId, uint16 events )
  359. {
  360. if ( events & SYS_EVENT_MSG )
  361. {
  362. uint8 *pMsg;
  363. if ( (pMsg = osal_msg_receive( gapCentralRoleTaskId )) != NULL )
  364. {
  365. gapCentralRole_ProcessOSALMsg( (osal_event_hdr_t *) pMsg );
  366. // Release the OSAL message
  367. VOID osal_msg_deallocate( pMsg );
  368. }
  369. // return unprocessed events
  370. return (events ^ SYS_EVENT_MSG);
  371. }
  372. if ( events & GAP_EVENT_SIGN_COUNTER_CHANGED )
  373. {
  374. // Sign counter changed, save it to NV
  375. // VOID osal_snv_write( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapCentralRoleSignCounter );
  376. return ( events ^ GAP_EVENT_SIGN_COUNTER_CHANGED );
  377. }
  378. // Discard unknown events
  379. return 0;
  380. }
  381. /*********************************************************************
  382. * @fn gapCentralRole_ProcessOSALMsg
  383. *
  384. * @brief Process an incoming task message.
  385. *
  386. * @param pMsg - message to process
  387. *
  388. * @return none
  389. */
  390. static void gapCentralRole_ProcessOSALMsg( osal_event_hdr_t *pMsg )
  391. {
  392. switch ( pMsg->event )
  393. {
  394. case HCI_GAP_EVENT_EVENT:
  395. if ( pMsg->status == HCI_COMMAND_COMPLETE_EVENT_CODE )
  396. {
  397. hciEvt_CmdComplete_t *pPkt = (hciEvt_CmdComplete_t *) pMsg;
  398. if ( pPkt->cmdOpcode == HCI_READ_RSSI )
  399. {
  400. uint16 connHandle = BUILD_UINT16( pPkt->pReturnParam[1], pPkt->pReturnParam[2] );
  401. int8 rssi = (int8) pPkt->pReturnParam[3];
  402. // Report RSSI to app
  403. if ( pGapCentralRoleCB && pGapCentralRoleCB->rssiCB )
  404. {
  405. pGapCentralRoleCB->rssiCB( connHandle, rssi );
  406. }
  407. }
  408. }
  409. break;
  410. case GAP_MSG_EVENT:
  411. gapCentralRole_ProcessGAPMsg( (gapEventHdr_t *) pMsg );
  412. break;
  413. case GAPCENTRALROLE_RSSI_MSG_EVT:
  414. {
  415. gapCentralRoleRssi_t *pRssi = ((gapCentralRoleRssiEvent_t *) pMsg)->pRssi;
  416. // If link is up and RSSI reads active
  417. if (pRssi->connHandle != GAP_CONNHANDLE_ALL &&
  418. linkDB_Up(pRssi->connHandle))
  419. {
  420. // Restart timer
  421. osal_CbTimerStart( gapCentralRole_timerCB, (uint8 *) pRssi,
  422. pRssi->period, &pRssi->timerId );
  423. // Read RSSI
  424. VOID HCI_ReadRssiCmd( pRssi->connHandle );
  425. }
  426. }
  427. break;
  428. default:
  429. break;
  430. }
  431. }
  432. /*********************************************************************
  433. * @fn gapCentralRole_ProcessGAPMsg
  434. *
  435. * @brief Process an incoming task message from GAP.
  436. *
  437. * @param pMsg - message to process
  438. *
  439. * @return none
  440. */
  441. static void gapCentralRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
  442. {
  443. switch ( pMsg->opcode )
  444. {
  445. case GAP_DEVICE_INIT_DONE_EVENT:
  446. {
  447. gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *) pMsg;
  448. if ( pPkt->hdr.status == SUCCESS )
  449. {
  450. // Save off the generated keys
  451. // VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapCentralRoleIRK );
  452. // VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapCentralRoleSRK );
  453. // Save off the information
  454. VOID osal_memcpy( gapCentralRoleBdAddr, pPkt->devAddr, B_ADDR_LEN );
  455. }
  456. }
  457. break;
  458. case GAP_LINK_ESTABLISHED_EVENT:
  459. {
  460. gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *) pMsg;
  461. if (pPkt->hdr.status == SUCCESS)
  462. {
  463. // Notify the Bond Manager of the connection
  464. VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr,
  465. pPkt->connectionHandle, GAP_PROFILE_CENTRAL );
  466. }
  467. }
  468. break;
  469. case GAP_LINK_TERMINATED_EVENT:
  470. {
  471. uint16 connHandle = ((gapTerminateLinkEvent_t *) pMsg)->connectionHandle;
  472. VOID GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
  473. // Cancel RSSI reads
  474. GAPCentralRole_CancelRssi( connHandle );
  475. }
  476. break;
  477. // temporary workaround
  478. case GAP_SLAVE_REQUESTED_SECURITY_EVENT:
  479. VOID GAPBondMgr_ProcessGAPMsg( pMsg );
  480. break;
  481. default:
  482. break;
  483. }
  484. // Pass event to app
  485. if ( pGapCentralRoleCB && pGapCentralRoleCB->eventCB )
  486. {
  487. pGapCentralRoleCB->eventCB( (gapCentralRoleEvent_t *) pMsg );
  488. }
  489. }
  490. /*********************************************************************
  491. * @fn gapCentralRole_RssiAlloc
  492. *
  493. * @brief Allocate an RSSI structure.
  494. *
  495. * @param connHandle - Connection handle
  496. *
  497. * @return pointer to structure or NULL if allocation failed.
  498. */
  499. static gapCentralRoleRssi_t *gapCentralRole_RssiAlloc( uint16 connHandle )
  500. {
  501. uint8 i;
  502. // Find free RSSI structure
  503. for ( i = 0; i < GAPCENTRALROLE_NUM_RSSI_LINKS; i++ )
  504. {
  505. if ( gapCentralRoleRssi[i].connHandle == GAP_CONNHANDLE_ALL )
  506. {
  507. gapCentralRoleRssi[i].connHandle = connHandle;
  508. return &gapCentralRoleRssi[i];
  509. }
  510. }
  511. // No free structure found
  512. return NULL;
  513. }
  514. /*********************************************************************
  515. * @fn gapCentralRole_RssiFind
  516. *
  517. * @brief Find an RSSI structure.
  518. *
  519. * @param connHandle - Connection handle
  520. *
  521. * @return pointer to structure or NULL if not found.
  522. */
  523. static gapCentralRoleRssi_t *gapCentralRole_RssiFind( uint16 connHandle )
  524. {
  525. uint8 i;
  526. // Find free RSSI structure
  527. for ( i = 0; i < GAPCENTRALROLE_NUM_RSSI_LINKS; i++ )
  528. {
  529. if ( gapCentralRoleRssi[i].connHandle == connHandle )
  530. {
  531. return &gapCentralRoleRssi[i];
  532. }
  533. }
  534. // Not found
  535. return NULL;
  536. }
  537. /*********************************************************************
  538. * @fn gapCentralRole_RssiFree
  539. *
  540. * @brief Free an RSSI structure.
  541. *
  542. * @param connHandle - Connection handle
  543. *
  544. * @return none
  545. */
  546. static void gapCentralRole_RssiFree( uint16 connHandle )
  547. {
  548. uint8 i;
  549. // Find RSSI structure
  550. for ( i = 0; i < GAPCENTRALROLE_NUM_RSSI_LINKS; i++ )
  551. {
  552. if ( gapCentralRoleRssi[i].connHandle == connHandle )
  553. {
  554. gapCentralRoleRssi[i].connHandle = GAP_CONNHANDLE_ALL;
  555. break;
  556. }
  557. }
  558. }
  559. /*********************************************************************
  560. * @fn gapCentralRole_timerCB
  561. *
  562. * @brief OSAL timer callback function
  563. *
  564. * @param pData - Data pointer
  565. *
  566. * @return none
  567. */
  568. static void gapCentralRole_timerCB( uint8 *pData )
  569. {
  570. gapCentralRoleRssiEvent_t *pMsg;
  571. // Timer has expired so clear timer ID
  572. ((gapCentralRoleRssi_t *) pData)->timerId = INVALID_TIMER_ID;
  573. // Send OSAL message
  574. pMsg = (gapCentralRoleRssiEvent_t *) osal_msg_allocate( sizeof(gapCentralRoleRssiEvent_t) );
  575. if ( pMsg )
  576. {
  577. pMsg->hdr.event = GAPCENTRALROLE_RSSI_MSG_EVT;
  578. pMsg->pRssi = (gapCentralRoleRssi_t *) pData;
  579. osal_msg_send ( gapCentralRoleTaskId, (uint8 *) pMsg );
  580. }
  581. }
  582. /*********************************************************************
  583. *********************************************************************/