peripheralBroadcaster.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  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.h"
  16. #include "l2cap.h"
  17. #include "gap.h"
  18. #include "linkdb.h"
  19. #include "att.h"
  20. #include "gatt.h"
  21. #include "osal_snv.h"
  22. #include "hci_tl.h"
  23. #include "peripheralBroadcaster.h"
  24. #include "gapbondmgr.h"
  25. /*********************************************************************
  26. * MACROS
  27. */
  28. /*********************************************************************
  29. * CONSTANTS
  30. */
  31. // Profile Events
  32. #define START_ADVERTISING_EVT 0x0001
  33. #define RSSI_READ_EVT 0x0002
  34. #define UPDATE_PARAMS_TIMEOUT_EVT 0x0004
  35. #define DEFAULT_ADVERT_OFF_TIME 30000 // 30 seconds
  36. #define RSSI_NOT_AVAILABLE 127
  37. #define DEFAULT_MIN_CONN_INTERVAL 0x0006 // 100 milliseconds
  38. #define DEFAULT_MAX_CONN_INTERVAL 0x0C80 // 4 seconds
  39. #define MIN_CONN_INTERVAL 0x0006
  40. #define MAX_CONN_INTERVAL 0x0C80
  41. #define DEFAULT_SLAVE_LATENCY 0
  42. #define DEFAULT_TIMEOUT_MULTIPLIER 1000
  43. #define CONN_INTERVAL_MULTIPLIER 6
  44. #define MAX_SLAVE_LATENCY 500
  45. #define MIN_TIMEOUT_MULTIPLIER 0x000a
  46. #define MAX_TIMEOUT_MULTIPLIER 0x0c80
  47. #define MAX_TIMEOUT_VALUE 0xFFFF
  48. /*********************************************************************
  49. * TYPEDEFS
  50. */
  51. /*********************************************************************
  52. * GLOBAL VARIABLES
  53. */
  54. /*********************************************************************
  55. * EXTERNAL VARIABLES
  56. */
  57. /*********************************************************************
  58. * EXTERNAL FUNCTIONS
  59. */
  60. /*********************************************************************
  61. * LOCAL VARIABLES
  62. */
  63. static uint8 gapRole_TaskID; // Task ID for internal task/event processing
  64. static gaprole_States_t gapRole_state;
  65. /*********************************************************************
  66. * Profile Parameters - reference GAPROLE_PROFILE_PARAMETERS for
  67. * descriptions
  68. */
  69. static uint8 gapRole_profileRole;
  70. static uint8 gapRole_IRK[KEYLEN];
  71. static uint8 gapRole_SRK[KEYLEN];
  72. static uint32 gapRole_signCounter;
  73. static uint8 gapRole_bdAddr[B_ADDR_LEN];
  74. static uint8 gapRole_AdvEnabled = TRUE;
  75. static uint16 gapRole_AdvertOffTime = DEFAULT_ADVERT_OFF_TIME;
  76. static uint8 gapRole_AdvertDataLen = 3;
  77. static uint8 gapRole_AdvertData[B_MAX_ADV_LEN] =
  78. {
  79. 0x02, // length of this data
  80. GAP_ADTYPE_FLAGS, // AD Type = Flags
  81. // Limited Discoverable & BR/EDR not supported
  82. (GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED),
  83. 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
  84. };
  85. static uint8 gapRole_ScanRspDataLen = 0;
  86. static uint8 gapRole_ScanRspData[B_MAX_ADV_LEN] = {0};
  87. static uint8 gapRole_AdvEventType;
  88. static uint8 gapRole_AdvDirectType;
  89. static uint8 gapRole_AdvDirectAddr[B_ADDR_LEN] = {0};
  90. static uint8 gapRole_AdvChanMap;
  91. static uint8 gapRole_AdvFilterPolicy;
  92. static uint16 gapRole_ConnectionHandle = INVALID_CONNHANDLE;
  93. static uint16 gapRole_RSSIReadRate = 0;
  94. static gapRolesCBs_t *pGapRoles_AppCGs = NULL;
  95. static uint8 gapRole_ConnectedDevAddr[B_ADDR_LEN] = {0};
  96. static uint8 gapRole_ParamUpdateEnable = FALSE;
  97. static uint16 gapRole_MinConnInterval = DEFAULT_MIN_CONN_INTERVAL;
  98. static uint16 gapRole_MaxConnInterval = DEFAULT_MAX_CONN_INTERVAL;
  99. static uint16 gapRole_SlaveLatency = DEFAULT_SLAVE_LATENCY;
  100. static uint16 gapRole_TimeoutMultiplier = DEFAULT_TIMEOUT_MULTIPLIER;
  101. /*********************************************************************
  102. * Profile Attributes - variables
  103. */
  104. /*********************************************************************
  105. * Profile Attributes - Table
  106. */
  107. /*********************************************************************
  108. * LOCAL FUNCTIONS
  109. */
  110. static void gapRole_ProcessOSALMsg( osal_event_hdr_t *pMsg );
  111. static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg );
  112. static void gapRole_SetupGAP( void );
  113. static void gapRole_SendUpdateParam( uint16 connInterval, uint16 connLatency );
  114. /*********************************************************************
  115. * NETWORK LAYER CALLBACKS
  116. */
  117. /*********************************************************************
  118. * PUBLIC FUNCTIONS
  119. */
  120. /*********************************************************************
  121. * @brief Set a GAP Role parameter.
  122. *
  123. * Public function defined in peripheral.h.
  124. */
  125. bStatus_t GAPRole_SetParameter( uint16 param, uint8 len, void *pValue )
  126. {
  127. bStatus_t ret = SUCCESS;
  128. switch ( param )
  129. {
  130. case GAPROLE_IRK:
  131. if ( len == KEYLEN )
  132. {
  133. VOID osal_memcpy( gapRole_IRK, pValue, KEYLEN ) ;
  134. }
  135. else
  136. {
  137. ret = bleInvalidRange;
  138. }
  139. break;
  140. case GAPROLE_SRK:
  141. if ( len == KEYLEN )
  142. {
  143. VOID osal_memcpy( gapRole_SRK, pValue, KEYLEN ) ;
  144. }
  145. else
  146. {
  147. ret = bleInvalidRange;
  148. }
  149. break;
  150. case GAPROLE_SIGNCOUNTER:
  151. if ( len == sizeof ( uint32 ) )
  152. {
  153. gapRole_signCounter = *((uint32*)pValue);
  154. }
  155. else
  156. {
  157. ret = bleInvalidRange;
  158. }
  159. break;
  160. case GAPROLE_ADVERT_ENABLED:
  161. if ( len == sizeof( uint8 ) )
  162. {
  163. if ( (gapRole_state == GAPROLE_CONNECTED) || (gapRole_state == GAPROLE_CONNECTED_ADV) )
  164. {
  165. uint8 advEnabled = *((uint8*)pValue);
  166. if ( (gapRole_state == GAPROLE_CONNECTED) && (advEnabled == TRUE) )
  167. {
  168. // Turn on advertising
  169. osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
  170. }
  171. else if ( (gapRole_state == GAPROLE_CONNECTED_ADV) && (advEnabled == FALSE) )
  172. {
  173. // Turn off Advertising
  174. GAP_EndDiscoverable( gapRole_TaskID );
  175. }
  176. }
  177. else
  178. {
  179. uint8 oldAdvEnabled = gapRole_AdvEnabled;
  180. gapRole_AdvEnabled = *((uint8*)pValue);
  181. if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) )
  182. {
  183. // Turn off Advertising
  184. VOID GAP_EndDiscoverable( gapRole_TaskID );
  185. }
  186. else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )
  187. {
  188. // Turn on Advertising
  189. if ( (gapRole_state == GAPROLE_STARTED)
  190. || (gapRole_state == GAPROLE_WAITING )
  191. || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )
  192. {
  193. VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
  194. }
  195. }
  196. }
  197. }
  198. else
  199. {
  200. ret = bleInvalidRange;
  201. }
  202. break;
  203. case GAPROLE_ADVERT_OFF_TIME:
  204. if ( len == sizeof ( uint16 ) )
  205. {
  206. gapRole_AdvertOffTime = *((uint16*)pValue);
  207. }
  208. else
  209. {
  210. ret = bleInvalidRange;
  211. }
  212. break;
  213. case GAPROLE_ADVERT_DATA:
  214. if ( len <= B_MAX_ADV_LEN )
  215. {
  216. VOID osal_memset( gapRole_AdvertData, 0, B_MAX_ADV_LEN );
  217. VOID osal_memcpy( gapRole_AdvertData, pValue, len );
  218. gapRole_AdvertDataLen = len;
  219. }
  220. else
  221. {
  222. ret = bleInvalidRange;
  223. }
  224. break;
  225. case GAPROLE_SCAN_RSP_DATA:
  226. if ( len <= B_MAX_ADV_LEN )
  227. {
  228. VOID osal_memset( gapRole_ScanRspData, 0, B_MAX_ADV_LEN );
  229. VOID osal_memcpy( gapRole_ScanRspData, pValue, len );
  230. gapRole_ScanRspDataLen = len;
  231. }
  232. else
  233. {
  234. ret = bleInvalidRange;
  235. }
  236. break;
  237. case GAPROLE_ADV_EVENT_TYPE:
  238. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_ADTYPE_ADV_LDC_DIRECT_IND) )
  239. {
  240. gapRole_AdvEventType = *((uint8*)pValue);
  241. }
  242. else
  243. {
  244. ret = bleInvalidRange;
  245. }
  246. break;
  247. case GAPROLE_ADV_DIRECT_TYPE:
  248. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= ADDRTYPE_PRIVATE_RESOLVE) )
  249. {
  250. gapRole_AdvDirectType = *((uint8*)pValue);
  251. }
  252. else
  253. {
  254. ret = bleInvalidRange;
  255. }
  256. break;
  257. case GAPROLE_ADV_DIRECT_ADDR:
  258. if ( len == B_ADDR_LEN )
  259. {
  260. VOID osal_memcpy( gapRole_AdvDirectAddr, pValue, B_ADDR_LEN ) ;
  261. }
  262. else
  263. {
  264. ret = bleInvalidRange;
  265. }
  266. break;
  267. case GAPROLE_ADV_CHANNEL_MAP:
  268. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= 0x07) )
  269. {
  270. gapRole_AdvChanMap = *((uint8*)pValue);
  271. }
  272. else
  273. {
  274. ret = bleInvalidRange;
  275. }
  276. break;
  277. case GAPROLE_ADV_FILTER_POLICY:
  278. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_FILTER_POLICY_WHITE) )
  279. {
  280. gapRole_AdvFilterPolicy = *((uint8*)pValue);
  281. }
  282. else
  283. {
  284. ret = bleInvalidRange;
  285. }
  286. break;
  287. case GAPROLE_RSSI_READ_RATE:
  288. if ( len == sizeof ( uint16 ) )
  289. {
  290. gapRole_RSSIReadRate = *((uint16*)pValue);
  291. if ( (gapRole_RSSIReadRate) && (gapRole_state == GAPROLE_CONNECTED) )
  292. {
  293. // Start the RSSI Reads
  294. VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
  295. }
  296. }
  297. else
  298. {
  299. ret = bleInvalidRange;
  300. }
  301. break;
  302. case GAPROLE_PARAM_UPDATE_ENABLE:
  303. if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= TRUE) )
  304. {
  305. gapRole_ParamUpdateEnable = *((uint8*)pValue);
  306. }
  307. else
  308. {
  309. ret = bleInvalidRange;
  310. }
  311. break;
  312. case GAPROLE_MIN_CONN_INTERVAL:
  313. {
  314. uint16 newInterval = *((uint16*)pValue);
  315. if ( len == sizeof ( uint16 ) &&
  316. ( newInterval >= MIN_CONN_INTERVAL ) &&
  317. ( newInterval <= MAX_CONN_INTERVAL ) )
  318. {
  319. gapRole_MinConnInterval = newInterval;
  320. }
  321. else
  322. {
  323. ret = bleInvalidRange;
  324. }
  325. }
  326. break;
  327. case GAPROLE_MAX_CONN_INTERVAL:
  328. {
  329. uint16 newInterval = *((uint16*)pValue);
  330. if ( len == sizeof ( uint16 ) &&
  331. ( newInterval >= MIN_CONN_INTERVAL) &&
  332. ( newInterval <= MAX_CONN_INTERVAL) )
  333. {
  334. gapRole_MaxConnInterval = newInterval;
  335. }
  336. else
  337. {
  338. ret = bleInvalidRange;
  339. }
  340. }
  341. break;
  342. case GAPROLE_SLAVE_LATENCY:
  343. {
  344. uint16 latency = *((uint16*)pValue);
  345. if ( len == sizeof ( uint16 ) && (latency < MAX_SLAVE_LATENCY) )
  346. {
  347. gapRole_SlaveLatency = latency;
  348. }
  349. else
  350. {
  351. ret = bleInvalidRange;
  352. }
  353. }
  354. break;
  355. case GAPROLE_TIMEOUT_MULTIPLIER:
  356. {
  357. uint16 newTimeout = *((uint16*)pValue);
  358. if ( len == sizeof ( uint16 )
  359. && (newTimeout >= MIN_TIMEOUT_MULTIPLIER) && (newTimeout <= MAX_TIMEOUT_MULTIPLIER) )
  360. {
  361. gapRole_TimeoutMultiplier = newTimeout;
  362. }
  363. else
  364. {
  365. ret = bleInvalidRange;
  366. }
  367. }
  368. break;
  369. default:
  370. // The param value isn't part of this profile, try the GAP.
  371. if ( (param < TGAP_PARAMID_MAX) && (len == sizeof ( uint16 )) )
  372. {
  373. ret = GAP_SetParamValue( param, *((uint16*)pValue) );
  374. }
  375. else
  376. {
  377. ret = INVALIDPARAMETER;
  378. }
  379. break;
  380. }
  381. return ( ret );
  382. }
  383. /*********************************************************************
  384. * @brief Get a GAP Role parameter.
  385. *
  386. * Public function defined in peripheral.h.
  387. */
  388. bStatus_t GAPRole_GetParameter( uint16 param, void *pValue )
  389. {
  390. bStatus_t ret = SUCCESS;
  391. switch ( param )
  392. {
  393. case GAPROLE_PROFILEROLE:
  394. *((uint8*)pValue) = gapRole_profileRole;
  395. break;
  396. case GAPROLE_IRK:
  397. VOID osal_memcpy( pValue, gapRole_IRK, KEYLEN ) ;
  398. break;
  399. case GAPROLE_SRK:
  400. VOID osal_memcpy( pValue, gapRole_SRK, KEYLEN ) ;
  401. break;
  402. case GAPROLE_SIGNCOUNTER:
  403. *((uint32*)pValue) = gapRole_signCounter;
  404. break;
  405. case GAPROLE_BD_ADDR:
  406. VOID osal_memcpy( pValue, gapRole_bdAddr, B_ADDR_LEN ) ;
  407. break;
  408. case GAPROLE_ADVERT_ENABLED:
  409. *((uint8*)pValue) = gapRole_AdvEnabled;
  410. break;
  411. case GAPROLE_ADVERT_OFF_TIME:
  412. *((uint16*)pValue) = gapRole_AdvertOffTime;
  413. break;
  414. case GAPROLE_ADVERT_DATA:
  415. VOID osal_memcpy( pValue , gapRole_AdvertData, gapRole_AdvertDataLen );
  416. break;
  417. case GAPROLE_SCAN_RSP_DATA:
  418. VOID osal_memcpy( pValue, gapRole_ScanRspData, gapRole_ScanRspDataLen ) ;
  419. break;
  420. case GAPROLE_ADV_EVENT_TYPE:
  421. *((uint8*)pValue) = gapRole_AdvEventType;
  422. break;
  423. case GAPROLE_ADV_DIRECT_TYPE:
  424. *((uint8*)pValue) = gapRole_AdvDirectType;
  425. break;
  426. case GAPROLE_ADV_DIRECT_ADDR:
  427. VOID osal_memcpy( pValue, gapRole_AdvDirectAddr, B_ADDR_LEN ) ;
  428. break;
  429. case GAPROLE_ADV_CHANNEL_MAP:
  430. *((uint8*)pValue) = gapRole_AdvChanMap;
  431. break;
  432. case GAPROLE_ADV_FILTER_POLICY:
  433. *((uint8*)pValue) = gapRole_AdvFilterPolicy;
  434. break;
  435. case GAPROLE_CONNHANDLE:
  436. *((uint16*)pValue) = gapRole_ConnectionHandle;
  437. break;
  438. case GAPROLE_RSSI_READ_RATE:
  439. *((uint16*)pValue) = gapRole_RSSIReadRate;
  440. break;
  441. case GAPROLE_PARAM_UPDATE_ENABLE:
  442. *((uint16*)pValue) = gapRole_ParamUpdateEnable;
  443. break;
  444. case GAPROLE_MIN_CONN_INTERVAL:
  445. *((uint16*)pValue) = gapRole_MinConnInterval;
  446. break;
  447. case GAPROLE_MAX_CONN_INTERVAL:
  448. *((uint16*)pValue) = gapRole_MaxConnInterval;
  449. break;
  450. case GAPROLE_SLAVE_LATENCY:
  451. *((uint16*)pValue) = gapRole_SlaveLatency;
  452. break;
  453. case GAPROLE_TIMEOUT_MULTIPLIER:
  454. *((uint16*)pValue) = gapRole_TimeoutMultiplier;
  455. break;
  456. case GAPROLE_CONN_BD_ADDR:
  457. VOID osal_memcpy( pValue, gapRole_ConnectedDevAddr, B_ADDR_LEN ) ;
  458. break;
  459. default:
  460. // The param value isn't part of this profile, try the GAP.
  461. if ( param < TGAP_PARAMID_MAX )
  462. {
  463. *((uint16*)pValue) = GAP_GetParamValue( param );
  464. }
  465. else
  466. {
  467. ret = INVALIDPARAMETER;
  468. }
  469. break;
  470. }
  471. return ( ret );
  472. }
  473. /*********************************************************************
  474. * @brief Does the device initialization.
  475. *
  476. * Public function defined in peripheral.h.
  477. */
  478. bStatus_t GAPRole_StartDevice( gapRolesCBs_t *pAppCallbacks )
  479. {
  480. if ( gapRole_state == GAPROLE_INIT )
  481. {
  482. // Clear all of the Application callbacks
  483. if ( pAppCallbacks )
  484. {
  485. pGapRoles_AppCGs = pAppCallbacks;
  486. }
  487. // Start the GAP
  488. gapRole_SetupGAP();
  489. return ( SUCCESS );
  490. }
  491. else
  492. {
  493. return ( bleAlreadyInRequestedMode );
  494. }
  495. }
  496. /*********************************************************************
  497. * @brief Terminates the existing connection.
  498. *
  499. * Public function defined in peripheral.h.
  500. */
  501. bStatus_t GAPRole_TerminateConnection( void )
  502. {
  503. if ( (gapRole_state == GAPROLE_CONNECTED)
  504. || (gapRole_state == GAPROLE_CONNECTED_ADV) )
  505. {
  506. return ( GAP_TerminateLinkReq( gapRole_TaskID, gapRole_ConnectionHandle,
  507. HCI_DISCONNECT_REMOTE_USER_TERM ) );
  508. }
  509. else
  510. {
  511. return ( bleIncorrectMode );
  512. }
  513. }
  514. /*********************************************************************
  515. * LOCAL FUNCTION PROTOTYPES
  516. */
  517. /*********************************************************************
  518. * @brief Task Initialization function.
  519. *
  520. * Internal function defined in peripheral.h.
  521. */
  522. void GAPRole_Init( uint8 task_id )
  523. {
  524. gapRole_TaskID = task_id;
  525. gapRole_state = GAPROLE_INIT;
  526. gapRole_ConnectionHandle = INVALID_CONNHANDLE;
  527. GAP_RegisterForHCIMsgs( gapRole_TaskID );
  528. // Initialize the Profile Advertising and Connection Parameters
  529. gapRole_profileRole = (GAP_PROFILE_PERIPHERAL | GAP_PROFILE_BROADCASTER);
  530. VOID osal_memset( gapRole_IRK, 0, KEYLEN );
  531. VOID osal_memset( gapRole_SRK, 0, KEYLEN );
  532. gapRole_signCounter = 0;
  533. gapRole_AdvEventType = GAP_ADTYPE_ADV_IND;
  534. gapRole_AdvDirectType = ADDRTYPE_PUBLIC;
  535. gapRole_AdvChanMap = GAP_ADVCHAN_ALL;
  536. gapRole_AdvFilterPolicy = GAP_FILTER_POLICY_ALL;
  537. // Restore Items from NV
  538. VOID osal_snv_read( BLE_NVID_IRK, KEYLEN, gapRole_IRK );
  539. VOID osal_snv_read( BLE_NVID_CSRK, KEYLEN, gapRole_SRK );
  540. VOID osal_snv_read( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter );
  541. }
  542. /*********************************************************************
  543. * @brief Task Event Processor function.
  544. *
  545. * Internal function defined in peripheral.h.
  546. */
  547. uint16 GAPRole_ProcessEvent( uint8 task_id, uint16 events )
  548. {
  549. VOID task_id; // OSAL required parameter that isn't used in this function
  550. if ( events & SYS_EVENT_MSG )
  551. {
  552. uint8 *pMsg;
  553. if ( (pMsg = osal_msg_receive( gapRole_TaskID )) != NULL )
  554. {
  555. gapRole_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
  556. // Release the OSAL message
  557. VOID osal_msg_deallocate( pMsg );
  558. }
  559. // return unprocessed events
  560. return (events ^ SYS_EVENT_MSG);
  561. }
  562. if ( events & GAP_EVENT_SIGN_COUNTER_CHANGED )
  563. {
  564. // Sign counter changed, save it to NV
  565. VOID osal_snv_write( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter );
  566. return ( events ^ GAP_EVENT_SIGN_COUNTER_CHANGED );
  567. }
  568. if ( events & START_ADVERTISING_EVT )
  569. {
  570. if ( gapRole_AdvEnabled )
  571. {
  572. gapAdvertisingParams_t params;
  573. // Setup advertisement parameters
  574. if ( gapRole_state == GAPROLE_CONNECTED )
  575. {
  576. // While in a connection, we can only advertise non-connectable undirected.
  577. params.eventType = GAP_ADTYPE_ADV_NONCONN_IND;
  578. }
  579. else
  580. {
  581. params.eventType = gapRole_AdvEventType;
  582. params.initiatorAddrType = gapRole_AdvDirectType;
  583. VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );
  584. }
  585. params.channelMap = gapRole_AdvChanMap;
  586. params.filterPolicy = gapRole_AdvFilterPolicy;
  587. if ( GAP_MakeDiscoverable( gapRole_TaskID, &params ) != SUCCESS )
  588. {
  589. gapRole_state = GAPROLE_ERROR;
  590. if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
  591. {
  592. pGapRoles_AppCGs->pfnStateChange( gapRole_state );
  593. }
  594. }
  595. }
  596. return ( events ^ START_ADVERTISING_EVT );
  597. }
  598. if ( events & RSSI_READ_EVT )
  599. {
  600. // Only get RSSI when in a connection
  601. if ( (gapRole_state == GAPROLE_CONNECTED)
  602. || (gapRole_state == GAPROLE_CONNECTED_ADV) )
  603. {
  604. // Ask for RSSI
  605. VOID HCI_ReadRssiCmd( gapRole_ConnectionHandle );
  606. // Setup next event
  607. if ( gapRole_RSSIReadRate )
  608. {
  609. VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
  610. }
  611. }
  612. return ( events ^ RSSI_READ_EVT );
  613. }
  614. if ( events & UPDATE_PARAMS_TIMEOUT_EVT )
  615. {
  616. // Clear an existing timeout
  617. if ( osal_get_timeoutEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT ) )
  618. {
  619. VOID osal_stop_timerEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT );
  620. }
  621. // The Update Parameters Timeout occurred - Terminate connection
  622. VOID GAP_TerminateLinkReq( gapRole_TaskID, gapRole_ConnectionHandle,
  623. HCI_DISCONNECT_REMOTE_USER_TERM );
  624. return ( events ^ UPDATE_PARAMS_TIMEOUT_EVT );
  625. }
  626. // Discard unknown events
  627. return 0;
  628. }
  629. /*********************************************************************
  630. * @fn gapRole_ProcessOSALMsg
  631. *
  632. * @brief Process an incoming task message.
  633. *
  634. * @param pMsg - message to process
  635. *
  636. * @return none
  637. */
  638. static void gapRole_ProcessOSALMsg( osal_event_hdr_t *pMsg )
  639. {
  640. switch ( pMsg->event )
  641. {
  642. case HCI_GAP_EVENT_EVENT:
  643. if ( pMsg->status == HCI_COMMAND_COMPLETE_EVENT_CODE )
  644. {
  645. hciEvt_CmdComplete_t *pPkt = (hciEvt_CmdComplete_t *)pMsg;
  646. if ( pPkt->cmdOpcode == HCI_READ_RSSI )
  647. {
  648. int8 rssi = (int8)pPkt->pReturnParam[3];
  649. if ( ((gapRole_state == GAPROLE_CONNECTED)
  650. || (gapRole_state == GAPROLE_CONNECTED_ADV))
  651. && (rssi != RSSI_NOT_AVAILABLE) )
  652. {
  653. // Report RSSI to app
  654. if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnRssiRead )
  655. {
  656. pGapRoles_AppCGs->pfnRssiRead( rssi );
  657. }
  658. }
  659. }
  660. }
  661. break;
  662. case GAP_MSG_EVENT:
  663. gapRole_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
  664. break;
  665. case L2CAP_SIGNAL_EVENT:
  666. {
  667. l2capSignalEvent_t *pPkt = (l2capSignalEvent_t *)pMsg;
  668. // Process the Parameter Update Response
  669. if ( pPkt->opcode == L2CAP_PARAM_UPDATE_RSP )
  670. {
  671. l2capParamUpdateRsp_t *pRsp = (l2capParamUpdateRsp_t *)&(pPkt->cmd.updateRsp);
  672. if ( pRsp->result == SUCCESS )
  673. {
  674. // All is good stop Update Parameters timeout
  675. VOID osal_stop_timerEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT );
  676. }
  677. }
  678. }
  679. break;
  680. default:
  681. break;
  682. }
  683. }
  684. /*********************************************************************
  685. * @fn gapRole_ProcessGAPMsg
  686. *
  687. * @brief Process an incoming task message.
  688. *
  689. * @param pMsg - message to process
  690. *
  691. * @return none
  692. */
  693. static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
  694. {
  695. uint8 notify = FALSE; // State changed notify the app? (default no)
  696. switch ( pMsg->opcode )
  697. {
  698. case GAP_DEVICE_INIT_DONE_EVENT:
  699. {
  700. gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
  701. bStatus_t stat = pPkt->hdr.status;
  702. if ( stat == SUCCESS )
  703. {
  704. // Save off the generated keys
  705. VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapRole_IRK );
  706. VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapRole_SRK );
  707. // Save off the information
  708. VOID osal_memcpy( gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN );
  709. gapRole_state = GAPROLE_STARTED;
  710. // Update the advertising data
  711. stat = GAP_UpdateAdvertisingData( gapRole_TaskID,
  712. TRUE, gapRole_AdvertDataLen, gapRole_AdvertData );
  713. }
  714. if ( stat != SUCCESS )
  715. {
  716. gapRole_state = GAPROLE_ERROR;
  717. }
  718. notify = TRUE;
  719. }
  720. break;
  721. case GAP_ADV_DATA_UPDATE_DONE_EVENT:
  722. {
  723. gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;
  724. if ( pPkt->hdr.status == SUCCESS )
  725. {
  726. if ( pPkt->adType )
  727. {
  728. // Setup the Response Data
  729. pPkt->hdr.status = GAP_UpdateAdvertisingData( gapRole_TaskID,
  730. FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
  731. }
  732. else
  733. {
  734. // Start advertising
  735. VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
  736. }
  737. }
  738. if ( pPkt->hdr.status != SUCCESS )
  739. {
  740. // Set into Error state
  741. gapRole_state = GAPROLE_ERROR;
  742. notify = TRUE;
  743. }
  744. }
  745. break;
  746. case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
  747. case GAP_END_DISCOVERABLE_DONE_EVENT:
  748. {
  749. gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;
  750. if ( pPkt->hdr.status == SUCCESS )
  751. {
  752. if ( pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT )
  753. {
  754. if ( gapRole_state == GAPROLE_CONNECTED )
  755. {
  756. gapRole_state = GAPROLE_CONNECTED_ADV;
  757. }
  758. else
  759. {
  760. gapRole_state = GAPROLE_ADVERTISING;
  761. }
  762. }
  763. else // GAP_END_DISCOVERABLE_DONE_EVENT
  764. {
  765. if ( gapRole_AdvertOffTime != 0 )
  766. {
  767. if ( ( gapRole_AdvEnabled ) )
  768. {
  769. VOID osal_start_timerEx( gapRole_TaskID, START_ADVERTISING_EVT, gapRole_AdvertOffTime );
  770. }
  771. }
  772. else
  773. {
  774. // Since gapRole_AdvertOffTime is set to 0, the device should not
  775. // automatically become discoverable again after a period of time.
  776. // Set enabler to FALSE; device will become discoverable again when
  777. // this value gets set to TRUE
  778. gapRole_AdvEnabled = FALSE;
  779. }
  780. // In the Advertising Off period
  781. gapRole_state = GAPROLE_WAITING;
  782. }
  783. }
  784. else
  785. {
  786. gapRole_state = GAPROLE_ERROR;
  787. }
  788. notify = TRUE;
  789. }
  790. break;
  791. case GAP_LINK_ESTABLISHED_EVENT:
  792. {
  793. gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;
  794. if ( pPkt->hdr.status == SUCCESS )
  795. {
  796. VOID osal_memcpy( gapRole_ConnectedDevAddr, pPkt->devAddr, B_ADDR_LEN );
  797. gapRole_ConnectionHandle = pPkt->connectionHandle;
  798. gapRole_state = GAPROLE_CONNECTED;
  799. if ( gapRole_RSSIReadRate )
  800. {
  801. // Start the RSSI Reads
  802. VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
  803. }
  804. // Check whether update parameter request is enabled, and check the connection parameters
  805. if ( ( gapRole_ParamUpdateEnable == TRUE ) &&
  806. ( (pPkt->connInterval < gapRole_MinConnInterval) ||
  807. (pPkt->connInterval > gapRole_MaxConnInterval) ||
  808. (pPkt->connLatency != gapRole_SlaveLatency) ||
  809. (pPkt->connTimeout != gapRole_TimeoutMultiplier) ))
  810. {
  811. gapRole_SendUpdateParam( pPkt->connInterval, pPkt->connLatency );
  812. }
  813. // Notify the Bond Manager to the connection
  814. VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr, pPkt->connectionHandle, GAP_PROFILE_PERIPHERAL );
  815. }
  816. else
  817. {
  818. gapRole_state = GAPROLE_ERROR;
  819. }
  820. notify = TRUE;
  821. }
  822. break;
  823. case GAP_LINK_TERMINATED_EVENT:
  824. {
  825. VOID GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
  826. osal_memset( gapRole_ConnectedDevAddr, 0, B_ADDR_LEN );
  827. if ( gapRole_state == GAPROLE_CONNECTED_ADV )
  828. {
  829. // End the non-connectable advertising
  830. GAP_EndDiscoverable( gapRole_TaskID );
  831. gapRole_state = GAPROLE_CONNECTED;
  832. }
  833. else
  834. {
  835. gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;
  836. if( pPkt->reason == LL_SUPERVISION_TIMEOUT_TERM )
  837. {
  838. gapRole_state = GAPROLE_WAITING_AFTER_TIMEOUT;
  839. }
  840. else
  841. {
  842. gapRole_state = GAPROLE_WAITING;
  843. }
  844. notify = TRUE;
  845. VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
  846. }
  847. gapRole_ConnectionHandle = INVALID_CONNHANDLE;
  848. }
  849. break;
  850. case GAP_LINK_PARAM_UPDATE_EVENT:
  851. {
  852. gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;
  853. if ( (pPkt->hdr.status != SUCCESS)
  854. || (pPkt->connInterval < gapRole_MinConnInterval)
  855. || (pPkt->connInterval > gapRole_MaxConnInterval) )
  856. {
  857. // Ask to change the interval
  858. gapRole_SendUpdateParam( pPkt->connInterval, pPkt->connLatency );
  859. }
  860. else
  861. {
  862. // All is good stop Update Parameters timeout
  863. VOID osal_stop_timerEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT );
  864. }
  865. }
  866. break;
  867. default:
  868. break;
  869. }
  870. if ( notify == TRUE )
  871. {
  872. // Notify the application
  873. if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
  874. {
  875. pGapRoles_AppCGs->pfnStateChange( gapRole_state );
  876. }
  877. }
  878. }
  879. /*********************************************************************
  880. * @fn gapRole_SetupGAP
  881. *
  882. * @brief Call the GAP Device Initialization function using the
  883. * Profile Parameters.
  884. *
  885. * @param none
  886. *
  887. * @return none
  888. */
  889. static void gapRole_SetupGAP( void )
  890. {
  891. VOID GAP_DeviceInit( gapRole_TaskID,
  892. gapRole_profileRole, 0,
  893. gapRole_IRK, gapRole_SRK,
  894. &gapRole_signCounter );
  895. }
  896. /*********************************************************************
  897. * @fn gapRole_SendUpdateParam
  898. *
  899. * @brief Send an Update Connection Parameters.
  900. *
  901. * @param connInterval - current connection interval
  902. * @param connLatency - current connection latency
  903. *
  904. * @return none
  905. */
  906. static void gapRole_SendUpdateParam( uint16 connInterval, uint16 connLatency )
  907. {
  908. l2capParamUpdateReq_t updateReq; // Space for Conn Update parameters
  909. uint32 timeout; // Calculated response timeout
  910. // Calculate the current interval
  911. uint16 effectiveOldInterval = (connInterval * (connLatency + 1));
  912. // Calculate the interval we want
  913. uint16 effectiveNewMaxInterval = (gapRole_MaxConnInterval * (gapRole_SlaveLatency + 1));
  914. // Fill in the wanted parameters
  915. updateReq.intervalMin = gapRole_MinConnInterval;
  916. updateReq.intervalMax = gapRole_MaxConnInterval;
  917. updateReq.slaveLatency = gapRole_SlaveLatency;
  918. updateReq.timeoutMultiplier = gapRole_TimeoutMultiplier;
  919. VOID L2CAP_ConnParamUpdateReq( gapRole_ConnectionHandle, &updateReq, gapRole_TaskID );
  920. // Set up the timeout for expected response
  921. if( effectiveOldInterval > effectiveNewMaxInterval )
  922. {
  923. timeout = (uint32)(effectiveOldInterval) * CONN_INTERVAL_MULTIPLIER;
  924. }
  925. else
  926. {
  927. timeout = (uint32)(effectiveNewMaxInterval) * CONN_INTERVAL_MULTIPLIER;
  928. }
  929. if( timeout > MAX_TIMEOUT_VALUE )
  930. {
  931. timeout = MAX_TIMEOUT_VALUE;
  932. }
  933. VOID osal_start_timerEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT, (uint16)(timeout) );
  934. }
  935. /*********************************************************************
  936. *********************************************************************/