hiddev.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410
  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 "OSAL.h"
  14. #include "gatt.h"
  15. #include "hci.h"
  16. #include "gapgattserver.h"
  17. #include "gattservapp.h"
  18. #include "gatt_uuid.h"
  19. #include "gatt_profile_uuid.h"
  20. #include "linkdb.h"
  21. #include "peripheral.h"
  22. #include "gapbondmgr.h"
  23. #include "devinfoservice.h"
  24. #include "battservice.h"
  25. #include "scanparamservice.h"
  26. #include "hiddev.h"
  27. #include "hidkbd.h"
  28. #include "hidkbdservice.h"
  29. //#include "touch_key.h"
  30. #include "log.h"
  31. /*********************************************************************
  32. * MACROS
  33. */
  34. // Battery measurement period in ms
  35. #define DEFAULT_BATT_PERIOD 15000
  36. // TRUE to run scan parameters refresh notify test
  37. #define DEFAULT_SCAN_PARAM_NOTIFY_TEST TRUE
  38. // Advertising intervals (units of 625us, 160=100ms)
  39. #define HID_INITIAL_ADV_INT_MIN 48
  40. #define HID_INITIAL_ADV_INT_MAX 80
  41. #define HID_HIGH_ADV_INT_MIN 32
  42. #define HID_HIGH_ADV_INT_MAX 48
  43. #define HID_LOW_ADV_INT_MIN 1600
  44. #define HID_LOW_ADV_INT_MAX 1600
  45. // Advertising timeouts in sec
  46. #define HID_INITIAL_ADV_TIMEOUT 60
  47. #define HID_HIGH_ADV_TIMEOUT 5
  48. #define HID_LOW_ADV_TIMEOUT 0
  49. // Heart Rate Task Events
  50. #define START_DEVICE_EVT 0x0001
  51. #define BATT_PERIODIC_EVT 0x0002
  52. #define HID_IDLE_EVT 0x0004
  53. #define HID_SEND_REPORT_EVT 0x0008
  54. #define reportQEmpty() ( firstQIdx == lastQIdx )
  55. /*********************************************************************
  56. * CONSTANTS
  57. */
  58. #define HID_DEV_DATA_LEN 8
  59. #ifdef HID_DEV_RPT_QUEUE_LEN
  60. #define HID_DEV_REPORT_Q_SIZE (HID_DEV_RPT_QUEUE_LEN+1)
  61. #else
  62. #define HID_DEV_REPORT_Q_SIZE (10+1)
  63. #endif
  64. /*********************************************************************
  65. * TYPEDEFS
  66. */
  67. typedef struct
  68. {
  69. uint8 id;
  70. uint8 type;
  71. uint8 len;
  72. uint8 data[HID_DEV_DATA_LEN];
  73. } hidDevReport_t;
  74. /*********************************************************************
  75. * GLOBAL VARIABLES
  76. */
  77. // Task ID
  78. uint8 hidDevTaskId;
  79. /*********************************************************************
  80. * EXTERNAL VARIABLES
  81. */
  82. /*********************************************************************
  83. * EXTERNAL FUNCTIONS
  84. */
  85. // HID report mapping table
  86. extern hidRptMap_t hidRptMap[];
  87. /*********************************************************************
  88. * LOCAL VARIABLES
  89. */
  90. // GAP State
  91. gaprole_States_t hidDevGapState = GAPROLE_INIT;
  92. // TRUE if connection is secure
  93. static uint8 hidDevConnSecure = FALSE;
  94. // GAP connection handle
  95. uint16 gapConnHandle;
  96. // TRUE if pairing in progress
  97. static uint8 hidDevPairingStarted = FALSE;
  98. // Status of last pairing
  99. static uint8 pairingStatus = SUCCESS;
  100. static hidRptMap_t *pHidDevRptTbl;
  101. static uint8 hidDevRptTblLen;
  102. static hidDevCB_t *pHidDevCB;
  103. static hidDevCfg_t *pHidDevCfg;
  104. // Whether to change to the preferred connection parameters
  105. static uint8 updateConnParams = TRUE;
  106. // Pending reports
  107. static uint8 firstQIdx = 0;
  108. static uint8 lastQIdx = 0;
  109. static hidDevReport_t hidDevReportQ[HID_DEV_REPORT_Q_SIZE];
  110. // Last report sent out
  111. static attHandleValueNoti_t lastNoti = { 0 };
  112. /*********************************************************************
  113. * LOCAL FUNCTIONS
  114. */
  115. static void hidDev_ProcessOSALMsg( osal_event_hdr_t *pMsg );
  116. static void hidDevProcessGattMsg( gattMsgEvent_t *pMsg );
  117. static void hidDevDisconnected( void );
  118. static void hidDevGapStateCB( gaprole_States_t newState );
  119. static void hidDevPairStateCB( uint16 connHandle, uint8 state, uint8 status );
  120. static void hidDevPasscodeCB( uint8 *deviceAddr, uint16 connectionHandle,
  121. uint8 uiInputs, uint8 uiOutputs );
  122. void hidDevBattCB( uint8 event );
  123. void hidDevScanParamCB( uint8 event );
  124. static void hidDevBattPeriodicTask( void );
  125. static hidRptMap_t *hidDevRptByHandle( uint16 handle );
  126. static hidRptMap_t *hidDevRptById( uint8 id, uint8 type );
  127. static hidRptMap_t *hidDevRptByCccdHandle( uint16 handle );
  128. static void hidDevEnqueueReport( uint8 id, uint8 type, uint8 len, uint8 *pData );
  129. static hidDevReport_t *hidDevDequeueReport( void );
  130. static void hidDevSendReport( uint8 id, uint8 type, uint8 len, uint8 *pData );
  131. static void hidDevHighAdvertising( void );
  132. static void hidDevLowAdvertising( void );
  133. static void hidDevInitialAdvertising( void );
  134. static uint8 hidDevBondCount( void );
  135. static void hidDevStartIdleTimer( void );
  136. static void hidDevStopIdleTimer( void );
  137. static void HidDev_scanParamCB(uint8_t event);
  138. /*********************************************************************
  139. * PROFILE CALLBACKS
  140. */
  141. // GAP Role Callbacks
  142. static gapRolesCBs_t hidDev_PeripheralCBs =
  143. {
  144. hidDevGapStateCB, // Profile State Change Callbacks
  145. NULL // When a valid RSSI is read from controller
  146. };
  147. // Bond Manager Callbacks
  148. static const gapBondCBs_t hidDevBondCB =
  149. {
  150. hidDevPasscodeCB,
  151. hidDevPairStateCB
  152. };
  153. /*********************************************************************
  154. * PUBLIC FUNCTIONS
  155. */
  156. /*********************************************************************
  157. * @fn HidDev_Init
  158. *
  159. * @brief Initialization function for the Hid Dev Task.
  160. * This is called during initialization and should contain
  161. * any application specific initialization (ie. hardware
  162. * initialization/setup, table initialization, power up
  163. * notificaiton ... ).
  164. *
  165. * @param task_id - the ID assigned by OSAL. This ID should be
  166. * used to send messages and set timers.
  167. *
  168. * @return none
  169. */
  170. void HidDev_Init( uint8 task_id )
  171. {
  172. hidDevTaskId = task_id;
  173. // Setup the GAP Bond Manager
  174. {
  175. uint8 syncWL = FALSE;//TRUE;
  176. // If a bond is created, the HID Device should write the address of the
  177. // HID Host in the HID Device controller's white list and set the HID
  178. // Device controller's advertising filter policy to 'process scan and
  179. // connection requests only from devices in the White List'.
  180. VOID GAPBondMgr_SetParameter( GAPBOND_AUTO_SYNC_WL, sizeof( uint8 ), &syncWL );
  181. }
  182. // Set up services
  183. GGS_AddService( GATT_ALL_SERVICES ); // GAP
  184. GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
  185. DevInfo_AddService( );
  186. Batt_AddService();
  187. ScanParam_AddService();
  188. Batt_Register(NULL);
  189. // Register for Scan Parameters service callback.
  190. ScanParam_Register(HidDev_scanParamCB);
  191. //touch_init(on_key);
  192. // Setup a delayed profile startup
  193. osal_set_event( hidDevTaskId, START_DEVICE_EVT );
  194. }
  195. /*********************************************************************
  196. * @fn HidDev_ProcessEvent
  197. *
  198. * @brief Hid Dev Task event processor. This function
  199. * is called to process all events for the task. Events
  200. * include timers, messages and any other user defined events.
  201. *
  202. * @param task_id - The OSAL assigned task ID.
  203. * @param events - events to process. This is a bit map and can
  204. * contain more than one event.
  205. *
  206. * @return events not processed
  207. */
  208. uint16 HidDev_ProcessEvent( uint8 task_id, uint16 events )
  209. {
  210. VOID task_id; // OSAL required parameter that isn't used in this function
  211. LOG("%s\n",__FUNCTION__);
  212. if ( events & SYS_EVENT_MSG )
  213. {
  214. uint8 *pMsg;
  215. if ( (pMsg = osal_msg_receive( hidDevTaskId )) != NULL )
  216. {
  217. hidDev_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
  218. // Release the OSAL message
  219. VOID osal_msg_deallocate( pMsg );
  220. }
  221. // return unprocessed events
  222. return (events ^ SYS_EVENT_MSG);
  223. }
  224. if ( events & START_DEVICE_EVT )
  225. {
  226. // Start the Device
  227. VOID GAPRole_StartDevice( &hidDev_PeripheralCBs );
  228. // Register with bond manager after starting device
  229. GAPBondMgr_Register( (gapBondCBs_t *) &hidDevBondCB );
  230. GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS,0,NULL);
  231. LOG("start Device EVT\n\r");
  232. return ( events ^ START_DEVICE_EVT );
  233. }
  234. if ( events & HID_IDLE_EVT )
  235. {
  236. if ( hidDevGapState == GAPROLE_CONNECTED )
  237. {
  238. // if pairing in progress then restart timer
  239. if ( hidDevPairingStarted )
  240. {
  241. hidDevStartIdleTimer();
  242. LOG("hidDevStartIdleTimer \n\r");
  243. }
  244. // else disconnect
  245. else
  246. {
  247. GAPRole_TerminateConnection();
  248. }
  249. }
  250. return ( events ^ HID_IDLE_EVT );
  251. }
  252. if ( events & BATT_PERIODIC_EVT )
  253. {
  254. // Perform periodic battery task
  255. hidDevBattPeriodicTask();
  256. return ( events ^ BATT_PERIODIC_EVT );
  257. }
  258. if ( events & HID_SEND_REPORT_EVT )
  259. {
  260. // if connection is secure
  261. if ( hidDevConnSecure )
  262. {
  263. LOG("Send Hid Report\n\r");
  264. hidDevReport_t *pReport = hidDevDequeueReport();
  265. if ( pReport != NULL )
  266. {
  267. // Send report
  268. hidDevSendReport( pReport->id, pReport->type, pReport->len, pReport->data );
  269. }
  270. return ( reportQEmpty() ? events ^ HID_SEND_REPORT_EVT : events );
  271. }
  272. return ( events ^ HID_SEND_REPORT_EVT );
  273. }
  274. return 0;
  275. }
  276. /*********************************************************************
  277. * @fn HidDev_Register
  278. *
  279. * @brief Register a callback function with HID Dev.
  280. *
  281. * @param pCfg - Parameter configuration.
  282. * @param pfnServiceCB - Callback function.
  283. *
  284. * @return None.
  285. */
  286. void HidDev_Register( hidDevCfg_t *pCfg, hidDevCB_t *pCBs )
  287. {
  288. pHidDevCB = pCBs;
  289. pHidDevCfg = pCfg;
  290. }
  291. /*********************************************************************
  292. * @fn HidDev_RegisterReports
  293. *
  294. * @brief Register the report table with HID Dev.
  295. *
  296. * @param numReports - Length of report table.
  297. * @param pRpt - Report table.
  298. *
  299. * @return None.
  300. */
  301. void HidDev_RegisterReports( uint8 numReports, hidRptMap_t *pRpt )
  302. {
  303. pHidDevRptTbl = pRpt;
  304. hidDevRptTblLen = numReports;
  305. }
  306. /*********************************************************************
  307. * @fn HidDev_Report
  308. *
  309. * @brief Send a HID report.
  310. *
  311. * @param id - HID report ID.
  312. * @param type - HID report type.
  313. * @param len - Length of report.
  314. * @param pData - Report data.
  315. *
  316. * @return None.
  317. */
  318. void HidDev_Report( uint8 id, uint8 type, uint8 len, uint8*pData )
  319. {
  320. // if connected
  321. if ( hidDevGapState == GAPROLE_CONNECTED )
  322. {
  323. // if connection is secure
  324. if ( hidDevConnSecure )
  325. {
  326. // Make sure there're no pending reports
  327. if ( reportQEmpty() )
  328. {
  329. // send report
  330. hidDevSendReport( id, type, len, pData );
  331. LOG("send key action\n\r");
  332. return; // we're done
  333. }
  334. }
  335. }
  336. // else if not already advertising
  337. else if ( hidDevGapState != GAPROLE_ADVERTISING )
  338. {
  339. // if bonded
  340. if ( hidDevBondCount() > 0 )
  341. {
  342. // start high duty cycle advertising
  343. hidDevHighAdvertising();
  344. }
  345. // else not bonded
  346. else
  347. {
  348. // start initial advertising
  349. hidDevInitialAdvertising();
  350. }
  351. }
  352. // hidDev task will send report when secure connection is established
  353. hidDevEnqueueReport( id, type, len, pData );
  354. }
  355. /*********************************************************************
  356. * @fn HidDev_Close
  357. *
  358. * @brief Close the connection or stop advertising.
  359. *
  360. * @return None.
  361. */
  362. void HidDev_Close( void )
  363. {
  364. uint8 param;
  365. // if connected then disconnect
  366. if ( hidDevGapState == GAPROLE_CONNECTED )
  367. {
  368. GAPRole_TerminateConnection();
  369. }
  370. // else stop advertising
  371. else
  372. {
  373. param = FALSE;
  374. GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &param );
  375. }
  376. }
  377. /*********************************************************************
  378. * @fn HidDev_SetParameter
  379. *
  380. * @brief Set a HID Dev parameter.
  381. *
  382. * @param param - Profile parameter ID
  383. * @param len - length of data to right
  384. * @param pValue - pointer to data to write. This is dependent on
  385. * the parameter ID and WILL be cast to the appropriate
  386. * data type (example: data type of uint16 will be cast to
  387. * uint16 pointer).
  388. *
  389. * @return bStatus_t
  390. */
  391. bStatus_t HidDev_SetParameter( uint8 param, uint8 len, void *pValue )
  392. {
  393. bStatus_t ret = SUCCESS;
  394. switch ( param )
  395. {
  396. case HIDDEV_ERASE_ALLBONDS:
  397. if ( len == 0 )
  398. {
  399. // See if the last report sent out wasn't a release key
  400. if ( osal_isbufset( lastNoti.value, 0x00, lastNoti.len ) == FALSE )
  401. {
  402. // Send a release report before disconnecting, otherwise
  403. // the last pressed key would get 'stuck' on the HID Host.
  404. osal_memset( lastNoti.value, 0x00, lastNoti.len );
  405. GATT_Notification( gapConnHandle, &lastNoti, FALSE );
  406. }
  407. // Drop connection
  408. if ( hidDevGapState == GAPROLE_CONNECTED )
  409. {
  410. GAPRole_TerminateConnection();
  411. }
  412. // Flush report queue
  413. firstQIdx = lastQIdx = 0;
  414. // Erase bonding info
  415. GAPBondMgr_SetParameter( GAPBOND_ERASE_ALLBONDS, 0, NULL );
  416. }
  417. else
  418. {
  419. ret = bleInvalidRange;
  420. }
  421. break;
  422. default:
  423. ret = INVALIDPARAMETER;
  424. break;
  425. }
  426. return ( ret );
  427. }
  428. /*********************************************************************
  429. * @fn HidDev_GetParameter
  430. *
  431. * @brief Get a HID Dev parameter.
  432. *
  433. * @param param - Profile parameter ID
  434. * @param pValue - pointer to data to get. This is dependent on
  435. * the parameter ID and WILL be cast to the appropriate
  436. * data type (example: data type of uint16 will be cast to
  437. * uint16 pointer).
  438. *
  439. * @return bStatus_t
  440. */
  441. bStatus_t HidDev_GetParameter( uint8 param, void *pValue )
  442. {
  443. bStatus_t ret = SUCCESS;
  444. switch ( param )
  445. {
  446. default:
  447. ret = INVALIDPARAMETER;
  448. break;
  449. }
  450. return ( ret );
  451. }
  452. /*********************************************************************
  453. * @fn HidDev_PasscodeRsp
  454. *
  455. * @brief Respond to a passcode request.
  456. *
  457. * @param status - SUCCESS if passcode is available, otherwise
  458. * see @ref SMP_PAIRING_FAILED_DEFINES.
  459. * @param passcode - integer value containing the passcode.
  460. *
  461. * @return none
  462. */
  463. void HidDev_PasscodeRsp( uint8 status, uint32 passcode )
  464. {
  465. // Send passcode response
  466. GAPBondMgr_PasscodeRsp( gapConnHandle, status, passcode );
  467. }
  468. /*********************************************************************
  469. * @fn HidDev_ReadAttrCB
  470. *
  471. * @brief HID Dev attribute read callback.
  472. *
  473. * @param connHandle - connection message was received on
  474. * @param pAttr - pointer to attribute
  475. * @param pValue - pointer to data to be read
  476. * @param pLen - length of data to be read
  477. * @param offset - offset of the first octet to be read
  478. * @param maxLen - maximum length of data to be read
  479. * @param method - type of read message
  480. *
  481. * @return SUCCESS, blePending or Failure
  482. */
  483. uint8 HidDev_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
  484. uint8 *pValue, uint16 *pLen, uint16 offset, uint8 maxLen )
  485. {
  486. bStatus_t status = SUCCESS;
  487. hidRptMap_t *pRpt;
  488. uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
  489. // Only report map is long
  490. if ( offset > 0 && uuid != REPORT_MAP_UUID )
  491. {
  492. return ( ATT_ERR_ATTR_NOT_LONG );
  493. }
  494. if ( uuid == REPORT_UUID ||
  495. uuid == BOOT_KEY_INPUT_UUID ||
  496. uuid == BOOT_KEY_OUTPUT_UUID ||
  497. uuid == BOOT_MOUSE_INPUT_UUID )
  498. {
  499. // find report ID in table
  500. if ( (pRpt = hidDevRptByHandle(pAttr->handle)) != NULL )
  501. {
  502. // execute report callback
  503. status = (*pHidDevCB->reportCB)( pRpt->id, pRpt->type, uuid,
  504. HID_DEV_OPER_READ, pLen, pValue );
  505. }
  506. else
  507. {
  508. *pLen = 0;
  509. }
  510. }
  511. else if ( uuid == REPORT_MAP_UUID )
  512. {
  513. // verify offset
  514. if ( offset >= hidReportMapLen )
  515. {
  516. status = ATT_ERR_INVALID_OFFSET;
  517. }
  518. else
  519. {
  520. // determine read length
  521. *pLen = MIN( maxLen, (hidReportMapLen - offset) );
  522. // copy data
  523. osal_memcpy( pValue, pAttr->pValue + offset, *pLen );
  524. }
  525. }
  526. else if ( uuid == HID_INFORMATION_UUID )
  527. {
  528. *pLen = HID_INFORMATION_LEN;
  529. osal_memcpy( pValue, pAttr->pValue, HID_INFORMATION_LEN );
  530. }
  531. else if ( uuid == GATT_REPORT_REF_UUID )
  532. {
  533. *pLen = HID_REPORT_REF_LEN;
  534. osal_memcpy( pValue, pAttr->pValue, HID_REPORT_REF_LEN );
  535. }
  536. else if ( uuid == PROTOCOL_MODE_UUID )
  537. {
  538. *pLen = HID_PROTOCOL_MODE_LEN;
  539. pValue[0] = pAttr->pValue[0];
  540. }
  541. else if ( uuid == GATT_EXT_REPORT_REF_UUID )
  542. {
  543. *pLen = HID_EXT_REPORT_REF_LEN;
  544. osal_memcpy( pValue, pAttr->pValue, HID_EXT_REPORT_REF_LEN );
  545. }
  546. // restart idle timer
  547. if ( status == SUCCESS )
  548. {
  549. hidDevStartIdleTimer();
  550. }
  551. return ( status );
  552. }
  553. /*********************************************************************
  554. * @fn HidDev_WriteAttrCB
  555. *
  556. * @brief HID Dev attribute read callback.
  557. *
  558. * @param connHandle - connection message was received on
  559. * @param pAttr - pointer to attribute
  560. * @param pValue - pointer to data to be written
  561. * @param len - length of data
  562. * @param offset - offset of the first octet to be written
  563. *
  564. * @return Success or Failure
  565. */
  566. bStatus_t HidDev_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
  567. uint8 *pValue, uint16 len, uint16 offset )
  568. {
  569. bStatus_t status = SUCCESS;
  570. hidRptMap_t *pRpt;
  571. // Make sure it's not a blob operation (no attributes in the profile are long)
  572. if ( offset > 0 )
  573. {
  574. return ( ATT_ERR_ATTR_NOT_LONG );
  575. }
  576. uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
  577. if ( uuid == REPORT_UUID ||
  578. uuid == BOOT_KEY_OUTPUT_UUID )
  579. {
  580. // find report ID in table
  581. if ((pRpt = hidDevRptByHandle(pAttr->handle)) != NULL)
  582. {
  583. // execute report callback
  584. status = (*pHidDevCB->reportCB)( pRpt->id, pRpt->type, uuid,
  585. HID_DEV_OPER_WRITE, &len, pValue );
  586. }
  587. }
  588. else if ( uuid == HID_CTRL_PT_UUID )
  589. {
  590. // Validate length and value range
  591. if ( len == 1 )
  592. {
  593. if ( pValue[0] == HID_CMD_SUSPEND || pValue[0] == HID_CMD_EXIT_SUSPEND )
  594. {
  595. // execute HID app event callback
  596. (*pHidDevCB->evtCB)( (pValue[0] == HID_CMD_SUSPEND) ?
  597. HID_DEV_SUSPEND_EVT : HID_DEV_EXIT_SUSPEND_EVT );
  598. }
  599. else
  600. {
  601. status = ATT_ERR_INVALID_VALUE;
  602. }
  603. }
  604. else
  605. {
  606. status = ATT_ERR_INVALID_VALUE_SIZE;
  607. }
  608. }
  609. else if ( uuid == GATT_CLIENT_CHAR_CFG_UUID )
  610. {
  611. status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
  612. offset, GATT_CLIENT_CFG_NOTIFY );
  613. if ( status == SUCCESS )
  614. {
  615. uint16 charCfg = BUILD_UINT16( pValue[0], pValue[1] );
  616. // find report ID in table
  617. if ( (pRpt = hidDevRptByCccdHandle(pAttr->handle)) != NULL )
  618. {
  619. if(hidRptMap[5].cccdHandle==pRpt->cccdHandle)
  620. {
  621. LOG("Audio cfg%4X\n\r",charCfg);
  622. }
  623. // execute report callback
  624. (*pHidDevCB->reportCB)( pRpt->id, pRpt->type, uuid,
  625. (charCfg == GATT_CLIENT_CFG_NOTIFY) ?
  626. HID_DEV_OPER_ENABLE : HID_DEV_OPER_DISABLE,
  627. &len, pValue );
  628. }
  629. }
  630. }
  631. else if ( uuid == PROTOCOL_MODE_UUID )
  632. {
  633. if ( len == HID_PROTOCOL_MODE_LEN )
  634. {
  635. if ( pValue[0] == HID_PROTOCOL_MODE_BOOT ||
  636. pValue[0] == HID_PROTOCOL_MODE_REPORT )
  637. {
  638. pAttr->pValue[0] = pValue[0];
  639. // execute HID app event callback
  640. (*pHidDevCB->evtCB)( (pValue[0] == HID_PROTOCOL_MODE_BOOT) ?
  641. HID_DEV_SET_BOOT_EVT : HID_DEV_SET_REPORT_EVT );
  642. }
  643. else
  644. {
  645. status = ATT_ERR_INVALID_VALUE;
  646. }
  647. }
  648. else
  649. {
  650. status = ATT_ERR_INVALID_VALUE_SIZE;
  651. }
  652. }
  653. // restart idle timer
  654. if (status == SUCCESS)
  655. {
  656. hidDevStartIdleTimer();
  657. }
  658. return ( status );
  659. }
  660. /*********************************************************************
  661. * @fn hidDev_ProcessOSALMsg
  662. *
  663. * @brief Process an incoming task message.
  664. *
  665. * @param pMsg - message to process
  666. *
  667. * @return none
  668. */
  669. static void hidDev_ProcessOSALMsg( osal_event_hdr_t *pMsg )
  670. {
  671. switch ( pMsg->event )
  672. {
  673. case GATT_MSG_EVENT:
  674. hidDevProcessGattMsg( (gattMsgEvent_t *) pMsg );
  675. break;
  676. default:
  677. break;
  678. }
  679. }
  680. /*********************************************************************
  681. * @fn hidDevProcessGattMsg
  682. *
  683. * @brief Process GATT messages
  684. *
  685. * @return none
  686. */
  687. static void hidDevProcessGattMsg( gattMsgEvent_t *pMsg )
  688. {
  689. }
  690. /*********************************************************************
  691. * @fn hidDevHandleConnStatusCB
  692. *
  693. * @brief Reset client char config.
  694. *
  695. * @param connHandle - connection handle
  696. * @param changeType - type of change
  697. *
  698. * @return none
  699. */
  700. static void hidDevHandleConnStatusCB( uint16 connHandle, uint8 changeType )
  701. {
  702. uint8 i;
  703. hidRptMap_t *p = pHidDevRptTbl;
  704. uint16 retHandle;
  705. gattAttribute_t *pAttr;
  706. // Make sure this is not loopback connection
  707. if ( connHandle != LOOPBACK_CONNHANDLE )
  708. {
  709. if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
  710. ( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
  711. ( !linkDB_Up( connHandle ) ) ) )
  712. {
  713. for ( i = hidDevRptTblLen; i > 0; i--, p++ )
  714. {
  715. if ( p->cccdHandle != 0 )
  716. {
  717. if ( (pAttr = GATT_FindHandle(p->cccdHandle, &retHandle)) != NULL )
  718. {
  719. GATTServApp_InitCharCfg( connHandle, (gattCharCfg_t *) pAttr->pValue );
  720. }
  721. }
  722. }
  723. }
  724. }
  725. }
  726. /*********************************************************************
  727. * @fn hidDevDisconnected
  728. *
  729. * @brief Handle disconnect.
  730. *
  731. * @return none
  732. */
  733. static void hidDevDisconnected( void )
  734. {
  735. // Stop idle timer
  736. hidDevStopIdleTimer();
  737. // Reset client characteristic configuration descriptors
  738. Batt_HandleConnStatusCB( gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED );
  739. //ScanParam_HandleConnStatusCB( gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED );
  740. hidDevHandleConnStatusCB( gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED );
  741. // Reset state variables
  742. hidDevConnSecure = FALSE;
  743. hidProtocolMode = HID_PROTOCOL_MODE_REPORT;
  744. hidDevPairingStarted = FALSE;
  745. // Reset last report sent out
  746. osal_memset( &lastNoti, 0, sizeof( attHandleValueNoti_t ) );
  747. // if bonded and normally connectable start advertising
  748. if ( ( hidDevBondCount() > 0 ) &&
  749. ( pHidDevCfg->hidFlags & HID_FLAGS_NORMALLY_CONNECTABLE ) )
  750. {
  751. hidDevLowAdvertising();
  752. }
  753. }
  754. /*********************************************************************
  755. * @fn hidDevGapStateCB
  756. *
  757. * @brief Notification from the profile of a state change.
  758. *
  759. * @param newState - new state
  760. *
  761. * @return none
  762. */
  763. void hidDevGapStateCB( gaprole_States_t newState )
  764. {
  765. LOG("%s, %d\n",__FUNCTION__, newState);
  766. // if connected
  767. if ( newState == GAPROLE_CONNECTED )
  768. {
  769. // get connection handle
  770. GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );
  771. // connection not secure yet
  772. hidDevConnSecure = FALSE;
  773. // don't start advertising when connection is closed
  774. uint8 param = FALSE;
  775. GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &param );
  776. uint8 peerAddress[B_ADDR_LEN];
  777. GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
  778. LOG("Master Mac:%02X,%02X,%02X,%02X,%02X,%02X\n\r",peerAddress[5],peerAddress[4],peerAddress[3],peerAddress[2],peerAddress[1],peerAddress[0]);
  779. // start idle timer
  780. hidDevStartIdleTimer();
  781. }
  782. // if disconnected
  783. else if ( hidDevGapState == GAPROLE_CONNECTED &&
  784. newState != GAPROLE_CONNECTED )
  785. {
  786. // GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS,0,NULL);
  787. hidDevDisconnected();
  788. updateConnParams = TRUE;
  789. if ( pairingStatus == SMP_PAIRING_FAILED_CONFIRM_VALUE )
  790. {
  791. // bonding failed due to mismatched confirm values
  792. hidDevInitialAdvertising();
  793. pairingStatus = SUCCESS;
  794. }
  795. }
  796. // if started
  797. else if ( newState == GAPROLE_STARTED )
  798. {
  799. // nothing to do for now!
  800. }
  801. hidDevGapState = newState;
  802. }
  803. /*********************************************************************
  804. * @fn hidDevPairStateCB
  805. *
  806. * @brief Pairing state callback.
  807. *
  808. * @return none
  809. */
  810. static void hidDevPairStateCB( uint16 connHandle, uint8 state, uint8 status )
  811. {
  812. if ( state == GAPBOND_PAIRING_STATE_STARTED )
  813. {
  814. hidDevPairingStarted = TRUE;
  815. }
  816. else if ( state == GAPBOND_PAIRING_STATE_COMPLETE )
  817. {
  818. hidDevPairingStarted = FALSE;
  819. if ( status == SUCCESS )
  820. {
  821. hidDevConnSecure = TRUE;
  822. LOG("Pair Success\n\r");
  823. }
  824. else
  825. {
  826. LOG("Pair Fail\n\r");
  827. }
  828. pairingStatus = status;
  829. }
  830. else if ( state == GAPBOND_PAIRING_STATE_BONDED )
  831. {
  832. if ( status == SUCCESS )
  833. {
  834. hidDevConnSecure = TRUE;
  835. }
  836. }
  837. if ( !reportQEmpty() && hidDevConnSecure )
  838. {
  839. LOG("Set Send Report EVENT\n\r");
  840. // Notify our task to send out pending reports
  841. osal_set_event( hidDevTaskId, HID_SEND_REPORT_EVT );
  842. }
  843. }
  844. /*********************************************************************
  845. * @fn hidDevPasscodeCB
  846. *
  847. * @brief Passcode callback.
  848. *
  849. * @param deviceAddr - address of device to pair with, and could be either public or random.
  850. * @param connectionHandle - connection handle
  851. * @param uiInputs - pairing User Interface Inputs - Ask user to input passcode
  852. * @param uiOutputs - pairing User Interface Outputs - Display passcode
  853. *
  854. * @return none
  855. */
  856. void hidDevPasscodeCB( uint8 *deviceAddr, uint16 connectionHandle,
  857. uint8 uiInputs, uint8 uiOutputs )
  858. {
  859. if ( pHidDevCB && pHidDevCB->passcodeCB )
  860. {
  861. // execute HID app passcode callback
  862. (*pHidDevCB->passcodeCB)( deviceAddr, connectionHandle, uiInputs, uiOutputs );
  863. }
  864. else
  865. {
  866. // Send passcode response
  867. GAPBondMgr_PasscodeRsp( connectionHandle, SUCCESS, 0 );
  868. }
  869. }
  870. /*********************************************************************
  871. * @fn hidDevBattCB
  872. *
  873. * @brief Callback function for battery service.
  874. *
  875. * @param event - service event
  876. *
  877. * @return none
  878. */
  879. void hidDevBattCB( uint8 event )
  880. {
  881. if ( event == BATT_LEVEL_NOTI_ENABLED )
  882. {
  883. // if connected start periodic measurement
  884. if ( hidDevGapState == GAPROLE_CONNECTED )
  885. {
  886. osal_start_timerEx( hidDevTaskId, BATT_PERIODIC_EVT, DEFAULT_BATT_PERIOD );
  887. }
  888. }
  889. else if ( event == BATT_LEVEL_NOTI_DISABLED )
  890. {
  891. // stop periodic measurement
  892. osal_stop_timerEx( hidDevTaskId, BATT_PERIODIC_EVT );
  893. }
  894. }
  895. /*********************************************************************
  896. * @fn hidDevScanParamCB
  897. *
  898. * @brief Callback function for scan parameter service.
  899. *
  900. * @param event - service event
  901. *
  902. * @return none
  903. */
  904. void hidDevScanParamCB( uint8 event )
  905. {
  906. }
  907. /*********************************************************************
  908. * @fn hidDevBattPeriodicTask
  909. *
  910. * @brief Perform a periodic task for battery measurement.
  911. *
  912. * @param none
  913. *
  914. * @return none
  915. */
  916. static void hidDevBattPeriodicTask( void )
  917. {
  918. if ( hidDevGapState == GAPROLE_CONNECTED )
  919. {
  920. // perform battery level check
  921. Batt_MeasLevel( );
  922. // Restart timer
  923. osal_start_timerEx( hidDevTaskId, BATT_PERIODIC_EVT, DEFAULT_BATT_PERIOD );
  924. }
  925. }
  926. /*********************************************************************
  927. * @fn hidDevRptByHandle
  928. *
  929. * @brief Find the HID report structure for the given handle.
  930. *
  931. * @param handle - ATT handle
  932. *
  933. * @return Pointer to HID report structure
  934. */
  935. static hidRptMap_t *hidDevRptByHandle( uint16 handle )
  936. {
  937. uint8 i;
  938. hidRptMap_t *p = pHidDevRptTbl;
  939. for ( i = hidDevRptTblLen; i > 0; i--, p++ )
  940. {
  941. if ( p->handle == handle && p->mode == hidProtocolMode)
  942. {
  943. return p;
  944. }
  945. }
  946. return NULL;
  947. }
  948. /*********************************************************************
  949. * @fn hidDevRptByCccdHandle
  950. *
  951. * @brief Find the HID report structure for the given CCC handle.
  952. *
  953. * @param handle - ATT handle
  954. *
  955. * @return Pointer to HID report structure
  956. */
  957. static hidRptMap_t *hidDevRptByCccdHandle( uint16 handle )
  958. {
  959. uint8 i;
  960. hidRptMap_t *p = pHidDevRptTbl;
  961. for ( i = hidDevRptTblLen; i > 0; i--, p++ )
  962. {
  963. if ( p->cccdHandle == handle)
  964. {
  965. if(i==HID_VOICE_START_IN_CCCD_IDX)
  966. {
  967. LOG("Voice Notify Enable!!!!!\n\r");
  968. }
  969. return p;
  970. }
  971. }
  972. return NULL;
  973. }
  974. /*********************************************************************
  975. * @fn hidDevRptById
  976. *
  977. * @brief Find the HID report structure for the Report ID and type.
  978. *
  979. * @param id - HID report ID
  980. * @param type - HID report type
  981. *
  982. * @return Pointer to HID report structure
  983. */
  984. static hidRptMap_t *hidDevRptById( uint8 id, uint8 type )
  985. {
  986. uint8 i;
  987. hidRptMap_t *p = pHidDevRptTbl;
  988. for ( i = hidDevRptTblLen; i > 0; i--, p++ )
  989. {
  990. if ( p->id == id && p->type == type && p->mode == hidProtocolMode )
  991. {
  992. return p;
  993. }
  994. }
  995. return NULL;
  996. }
  997. /*********************************************************************
  998. * @fn hidDevSendReport
  999. *
  1000. * @brief Send a HID report.
  1001. *
  1002. * @param id - HID report ID.
  1003. * @param type - HID report type.
  1004. * @param len - Length of report.
  1005. * @param pData - Report data.
  1006. *
  1007. * @return None.
  1008. */
  1009. static void hidDevSendReport( uint8 id, uint8 type, uint8 len, uint8 *pData )
  1010. {
  1011. hidRptMap_t *pRpt;
  1012. gattAttribute_t *pAttr;
  1013. uint16 retHandle;
  1014. LOG("%s\n",__FUNCTION__);
  1015. // Get ATT handle for report
  1016. if ( (pRpt = hidDevRptById(id, type)) != NULL )
  1017. {
  1018. // if notifications are enabled
  1019. if ( (pAttr = GATT_FindHandle(pRpt->cccdHandle, &retHandle)) != NULL )
  1020. {
  1021. uint16 value;
  1022. value = GATTServApp_ReadCharCfg( gapConnHandle, (gattCharCfg_t *) pAttr->pValue );
  1023. if ( value & GATT_CLIENT_CFG_NOTIFY )
  1024. {
  1025. // After service discovery and encryption, the HID Device should request to
  1026. // change to the preferred connection parameters that best suit its use case.
  1027. if ( updateConnParams )
  1028. {
  1029. GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_REQ, sizeof( uint8 ), &updateConnParams );
  1030. updateConnParams = FALSE;
  1031. }
  1032. // send notification
  1033. lastNoti.handle = pRpt->handle;
  1034. lastNoti.len = len;
  1035. osal_memcpy(lastNoti.value, pData, len);
  1036. GATT_Notification( gapConnHandle, &lastNoti, FALSE );
  1037. // start idle timer
  1038. hidDevStartIdleTimer();
  1039. }
  1040. else
  1041. {
  1042. LOG("notify fail\n\r");
  1043. }
  1044. }
  1045. }
  1046. }
  1047. /*********************************************************************
  1048. * @fn hidDevEnqueueReport
  1049. *
  1050. * @brief Enqueue a HID report to be sent later.
  1051. *
  1052. * @param id - HID report ID.
  1053. * @param type - HID report type.
  1054. * @param len - Length of report.
  1055. * @param pData - Report data.
  1056. *
  1057. * @return None.
  1058. */
  1059. static void hidDevEnqueueReport( uint8 id, uint8 type, uint8 len, uint8 *pData )
  1060. {
  1061. // Enqueue only if bonded
  1062. if ( hidDevBondCount() > 0 )
  1063. {
  1064. // Update last index
  1065. lastQIdx = ( lastQIdx + 1 ) % HID_DEV_REPORT_Q_SIZE;
  1066. if ( lastQIdx == firstQIdx )
  1067. {
  1068. // Queue overflow; discard oldest report
  1069. firstQIdx = ( firstQIdx + 1 ) % HID_DEV_REPORT_Q_SIZE;
  1070. }
  1071. // Save report
  1072. hidDevReportQ[lastQIdx].id = id;
  1073. hidDevReportQ[lastQIdx].type = type;
  1074. hidDevReportQ[lastQIdx].len = len;
  1075. osal_memcpy( hidDevReportQ[lastQIdx].data, pData, len );
  1076. if ( hidDevConnSecure )
  1077. {
  1078. // Notify our task to send out pending reports
  1079. osal_set_event( hidDevTaskId, HID_SEND_REPORT_EVT );
  1080. }
  1081. }
  1082. }
  1083. /*********************************************************************
  1084. * @fn hidDevDequeueReport
  1085. *
  1086. * @brief Dequeue a HID report to be sent out.
  1087. *
  1088. * @param id - HID report ID.
  1089. * @param type - HID report type.
  1090. * @param len - Length of report.
  1091. * @param pData - Report data.
  1092. *
  1093. * @return None.
  1094. */
  1095. static hidDevReport_t *hidDevDequeueReport( void )
  1096. {
  1097. if ( reportQEmpty() )
  1098. {
  1099. return NULL;
  1100. }
  1101. // Update first index
  1102. firstQIdx = ( firstQIdx + 1 ) % HID_DEV_REPORT_Q_SIZE;
  1103. return ( &(hidDevReportQ[firstQIdx]) );
  1104. }
  1105. /*********************************************************************
  1106. * @fn hidDevHighAdvertising
  1107. *
  1108. * @brief Start advertising at a high duty cycle.
  1109. * @param None.
  1110. *
  1111. * @return None.
  1112. */
  1113. static void hidDevHighAdvertising( void )
  1114. {
  1115. uint8 param;
  1116. VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, HID_HIGH_ADV_INT_MIN );
  1117. VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, HID_HIGH_ADV_INT_MAX );
  1118. VOID GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, HID_HIGH_ADV_TIMEOUT );
  1119. // Setup adverstising filter policy first
  1120. param = GAP_FILTER_POLICY_WHITE;
  1121. VOID GAPRole_SetParameter( GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), &param );
  1122. param = TRUE;
  1123. GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &param );
  1124. }
  1125. /*********************************************************************
  1126. * @fn hidDevLowAdvertising
  1127. *
  1128. * @brief Start advertising at a low duty cycle.
  1129. *
  1130. * @param None.
  1131. *
  1132. * @return None.
  1133. */
  1134. static void hidDevLowAdvertising( void )
  1135. {
  1136. uint8 param;
  1137. VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, HID_LOW_ADV_INT_MIN );
  1138. VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, HID_LOW_ADV_INT_MAX );
  1139. VOID GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, HID_LOW_ADV_TIMEOUT );
  1140. // Setup adverstising filter policy first
  1141. param = GAP_FILTER_POLICY_ALL;//GAP_FILTER_POLICY_WHITE teddy modify
  1142. VOID GAPRole_SetParameter( GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), &param );
  1143. param = TRUE;
  1144. VOID GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &param );
  1145. }
  1146. /*********************************************************************
  1147. * @fn hidDevInitialAdvertising
  1148. *
  1149. * @brief Start advertising for initial connection
  1150. *
  1151. * @return None.
  1152. */
  1153. static void hidDevInitialAdvertising( void )
  1154. {
  1155. uint8 param;
  1156. VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, HID_INITIAL_ADV_INT_MIN );
  1157. VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, HID_INITIAL_ADV_INT_MAX );
  1158. VOID GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, HID_INITIAL_ADV_TIMEOUT );
  1159. // Setup adverstising filter policy first
  1160. param = GAP_FILTER_POLICY_ALL;
  1161. VOID GAPRole_SetParameter( GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), &param );
  1162. param = TRUE;
  1163. VOID GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &param );
  1164. }
  1165. /*********************************************************************
  1166. * @fn hidDevBondCount
  1167. *
  1168. * @brief Gets the total number of bonded devices.
  1169. *
  1170. * @param None.
  1171. *
  1172. * @return number of bonded devices.
  1173. */
  1174. static uint8 hidDevBondCount( void )
  1175. {
  1176. uint8 bondCnt = 0;
  1177. VOID GAPBondMgr_GetParameter( GAPBOND_BOND_COUNT, &bondCnt );
  1178. return ( bondCnt );
  1179. }
  1180. /*********************************************************************
  1181. * @fn hidDevStartIdleTimer
  1182. *
  1183. * @brief Start the idle timer.
  1184. *
  1185. * @return None.
  1186. */
  1187. static void hidDevStartIdleTimer( void )
  1188. {
  1189. if ( pHidDevCfg->idleTimeout > 0 )
  1190. {
  1191. osal_start_timerEx( hidDevTaskId, HID_IDLE_EVT, pHidDevCfg->idleTimeout );
  1192. }
  1193. }
  1194. /*********************************************************************
  1195. * @fn hidDevStopIdleTimer
  1196. *
  1197. * @brief Stop the idle timer.
  1198. *
  1199. * @return None.
  1200. */
  1201. static void hidDevStopIdleTimer( void )
  1202. {
  1203. osal_stop_timerEx( hidDevTaskId, HID_IDLE_EVT );
  1204. }
  1205. /*********************************************************************
  1206. * @fn HidDev_scanParamCB
  1207. *
  1208. * @brief Callback function for scan parameter service.
  1209. *
  1210. * @param event - service event
  1211. *
  1212. * @return none
  1213. */
  1214. static void HidDev_scanParamCB(uint8_t event)
  1215. {
  1216. // Do nothing.
  1217. }
  1218. /*********************************************************************
  1219. *********************************************************************/