1467 lines
41 KiB
C
1467 lines
41 KiB
C
/*************
|
|
hiddev.c
|
|
SDK_LICENSE
|
|
***************/
|
|
|
|
/*********************************************************************
|
|
INCLUDES
|
|
*/
|
|
|
|
#include "OSAL.h"
|
|
#include "gatt.h"
|
|
#include "hci.h"
|
|
#include "gapgattserver.h"
|
|
#include "gattservapp.h"
|
|
#include "gatt_uuid.h"
|
|
#include "gatt_profile_uuid.h"
|
|
#include "linkdb.h"
|
|
#include "peripheral.h"
|
|
#include "gapbondmgr.h"
|
|
#include "devinfoservice.h"
|
|
#include "battservice.h"
|
|
#include "scanparamservice.h"
|
|
|
|
|
|
#include "hiddev.h"
|
|
#include "hidkbd.h"
|
|
|
|
#include "global_config.h"
|
|
#include "ll_def.h"
|
|
|
|
#include "hidkbdservice.h"
|
|
//#include "touch_key.h"
|
|
#include "log.h"
|
|
|
|
/*********************************************************************
|
|
MACROS
|
|
*/
|
|
|
|
// Battery measurement period in ms
|
|
#define DEFAULT_BATT_PERIOD 15000
|
|
|
|
// TRUE to run scan parameters refresh notify test
|
|
#define DEFAULT_SCAN_PARAM_NOTIFY_TEST TRUE
|
|
|
|
// Advertising intervals (units of 625us, 160=100ms)
|
|
#define HID_INITIAL_ADV_INT_MIN 48
|
|
#define HID_INITIAL_ADV_INT_MAX 80
|
|
#define HID_HIGH_ADV_INT_MIN 32
|
|
#define HID_HIGH_ADV_INT_MAX 48
|
|
#define HID_LOW_ADV_INT_MIN 32//1600
|
|
#define HID_LOW_ADV_INT_MAX 48//1600
|
|
|
|
// Advertising timeouts in sec
|
|
#define HID_INITIAL_ADV_TIMEOUT 60
|
|
#define HID_HIGH_ADV_TIMEOUT 5
|
|
#define HID_LOW_ADV_TIMEOUT 0
|
|
|
|
// Heart Rate Task Events
|
|
#define START_DEVICE_EVT 0x0001
|
|
#define BATT_PERIODIC_EVT 0x0002
|
|
#define HID_IDLE_EVT 0x0004
|
|
#define HID_SEND_REPORT_EVT 0x0008
|
|
|
|
#define HID_UPPARAM_EVT 0X0010
|
|
#define HID_TEST_EVT 0x0100
|
|
|
|
#define reportQEmpty() ( firstQIdx == lastQIdx )
|
|
|
|
|
|
#define CCD_CHECK_EN_FLAG 0
|
|
|
|
/*********************************************************************
|
|
CONSTANTS
|
|
*/
|
|
|
|
#define HID_DEV_DATA_LEN 8
|
|
|
|
#ifdef HID_DEV_RPT_QUEUE_LEN
|
|
#define HID_DEV_REPORT_Q_SIZE (HID_DEV_RPT_QUEUE_LEN+1)
|
|
#else
|
|
#define HID_DEV_REPORT_Q_SIZE (10+1)
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
TYPEDEFS
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
uint8 id;
|
|
uint8 type;
|
|
uint8 len;
|
|
uint8 data[HID_DEV_DATA_LEN];
|
|
} hidDevReport_t;
|
|
|
|
/*********************************************************************
|
|
GLOBAL VARIABLES
|
|
*/
|
|
|
|
// Task ID
|
|
uint8 hidDevTaskId;
|
|
|
|
/*********************************************************************
|
|
EXTERNAL VARIABLES
|
|
*/
|
|
|
|
/*********************************************************************
|
|
EXTERNAL FUNCTIONS
|
|
*/
|
|
|
|
// HID report mapping table
|
|
extern hidRptMap_t hidRptMap[];
|
|
|
|
|
|
/*********************************************************************
|
|
LOCAL VARIABLES
|
|
*/
|
|
|
|
// GAP State
|
|
gaprole_States_t hidDevGapState = GAPROLE_INIT;
|
|
|
|
// TRUE if connection is secure
|
|
static uint8 hidDevConnSecure = FALSE;
|
|
|
|
// GAP connection handle
|
|
uint16 gapConnHandle;
|
|
|
|
// TRUE if pairing in progress
|
|
static uint8 hidDevPairingStarted = FALSE;
|
|
|
|
// Status of last pairing
|
|
static uint8 pairingStatus = SUCCESS;
|
|
|
|
static hidRptMap_t* pHidDevRptTbl;
|
|
|
|
static uint8 hidDevRptTblLen;
|
|
|
|
static hidDevCB_t* pHidDevCB;
|
|
|
|
static hidDevCfg_t* pHidDevCfg;
|
|
|
|
// Whether to change to the preferred connection parameters
|
|
static uint8 updateConnParams = TRUE;
|
|
|
|
// Pending reports
|
|
static uint8 firstQIdx = 0;
|
|
static uint8 lastQIdx = 0;
|
|
static hidDevReport_t hidDevReportQ[HID_DEV_REPORT_Q_SIZE];
|
|
|
|
// Last report sent out
|
|
static attHandleValueNoti_t lastNoti = { 0 };
|
|
|
|
/*********************************************************************
|
|
LOCAL FUNCTIONS
|
|
*/
|
|
|
|
static void hidDev_ProcessOSALMsg( osal_event_hdr_t* pMsg );
|
|
static void hidDevProcessGattMsg( gattMsgEvent_t* pMsg );
|
|
static void hidDevDisconnected( void );
|
|
static void hidDevGapStateCB( gaprole_States_t newState );
|
|
static void hidDevPairStateCB( uint16 connHandle, uint8 state, uint8 status );
|
|
static void hidDevPasscodeCB( uint8* deviceAddr, uint16 connectionHandle,
|
|
uint8 uiInputs, uint8 uiOutputs );
|
|
void hidDevBattCB( uint8 event );
|
|
void hidDevScanParamCB( uint8 event );
|
|
static void hidDevBattPeriodicTask( void );
|
|
static hidRptMap_t* hidDevRptByHandle( uint16 handle );
|
|
static hidRptMap_t* hidDevRptById( uint8 id, uint8 type );
|
|
static hidRptMap_t* hidDevRptByCccdHandle( uint16 handle );
|
|
static void hidDevEnqueueReport( uint8 id, uint8 type, uint8 len, uint8* pData );
|
|
static hidDevReport_t* hidDevDequeueReport( void );
|
|
static void hidDevSendReport( uint8 id, uint8 type, uint8 len, uint8* pData );
|
|
static void hidDevHighAdvertising( void );
|
|
static void hidDevLowAdvertising( void );
|
|
static void hidDevInitialAdvertising( void );
|
|
static uint8 hidDevBondCount( void );
|
|
static void hidDevStartIdleTimer( void );
|
|
static void hidDevStopIdleTimer( void );
|
|
static void HidDev_scanParamCB(uint8_t event);
|
|
|
|
/*********************************************************************
|
|
PROFILE CALLBACKS
|
|
*/
|
|
// GAP Role Callbacks
|
|
static gapRolesCBs_t hidDev_PeripheralCBs =
|
|
{
|
|
hidDevGapStateCB, // Profile State Change Callbacks
|
|
NULL // When a valid RSSI is read from controller
|
|
};
|
|
|
|
// Bond Manager Callbacks
|
|
static const gapBondCBs_t hidDevBondCB =
|
|
{
|
|
hidDevPasscodeCB,
|
|
hidDevPairStateCB
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
PUBLIC FUNCTIONS
|
|
*/
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_Init
|
|
|
|
@brief Initialization function for the Hid Dev Task.
|
|
This is called during initialization and should contain
|
|
any application specific initialization (ie. hardware
|
|
initialization/setup, table initialization, power up
|
|
notificaiton ... ).
|
|
|
|
@param task_id - the ID assigned by OSAL. This ID should be
|
|
used to send messages and set timers.
|
|
|
|
@return none
|
|
*/
|
|
void HidDev_Init( uint8 task_id )
|
|
{
|
|
hidDevTaskId = task_id;
|
|
// Setup the GAP Bond Manager
|
|
{
|
|
uint8 syncWL = TRUE;
|
|
// If a bond is created, the HID Device should write the address of the
|
|
// HID Host in the HID Device controller's white list and set the HID
|
|
// Device controller's advertising filter policy to 'process scan and
|
|
// connection requests only from devices in the White List'.
|
|
VOID GAPBondMgr_SetParameter( GAPBOND_AUTO_SYNC_WL, sizeof( uint8 ), &syncWL );
|
|
}
|
|
// Set up services
|
|
GGS_AddService( GATT_ALL_SERVICES ); // GAP
|
|
GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
|
|
DevInfo_AddService( );
|
|
Batt_AddService();
|
|
ScanParam_AddService();
|
|
Batt_Register(NULL);
|
|
// Register for Scan Parameters service callback.
|
|
ScanParam_Register(HidDev_scanParamCB);
|
|
//touch_init(on_key);
|
|
// Setup a delayed profile startup
|
|
osal_set_event( hidDevTaskId, START_DEVICE_EVT );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_ProcessEvent
|
|
|
|
@brief Hid Dev Task event processor. This function
|
|
is called to process all events for the task. Events
|
|
include timers, messages and any other user defined events.
|
|
|
|
@param task_id - The OSAL assigned task ID.
|
|
@param events - events to process. This is a bit map and can
|
|
contain more than one event.
|
|
|
|
@return events not processed
|
|
*/
|
|
uint16 HidDev_ProcessEvent( uint8 task_id, uint16 events )
|
|
{
|
|
VOID task_id; // OSAL required parameter that isn't used in this function
|
|
LOG("%s\n",__FUNCTION__);
|
|
|
|
if ( events & SYS_EVENT_MSG )
|
|
{
|
|
uint8* pMsg;
|
|
|
|
if ( (pMsg = osal_msg_receive( hidDevTaskId )) != NULL )
|
|
{
|
|
hidDev_ProcessOSALMsg( (osal_event_hdr_t*)pMsg );
|
|
// Release the OSAL message
|
|
VOID osal_msg_deallocate( pMsg );
|
|
}
|
|
|
|
// return unprocessed events
|
|
return (events ^ SYS_EVENT_MSG);
|
|
}
|
|
|
|
if ( events & START_DEVICE_EVT )
|
|
{
|
|
// Start the Device
|
|
VOID GAPRole_StartDevice( &hidDev_PeripheralCBs );
|
|
// Register with bond manager after starting device
|
|
GAPBondMgr_Register( (gapBondCBs_t*) &hidDevBondCB );
|
|
// GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS,0,NULL);
|
|
LOG("start Device EVT\n\r");
|
|
return ( events ^ START_DEVICE_EVT );
|
|
}
|
|
|
|
if ( events & HID_IDLE_EVT )
|
|
{
|
|
if ( hidDevGapState == GAPROLE_CONNECTED )
|
|
{
|
|
// if pairing in progress then restart timer
|
|
if ( hidDevPairingStarted )
|
|
{
|
|
hidDevStartIdleTimer();
|
|
LOG("hidDevStartIdleTimer \n\r");
|
|
}
|
|
// else disconnect
|
|
else
|
|
{
|
|
//GAPRole_TerminateConnection();
|
|
LOG("hidDevStartIdleTimer disconnect \n\r");
|
|
}
|
|
}
|
|
|
|
return ( events ^ HID_IDLE_EVT );
|
|
}
|
|
|
|
if ( events & BATT_PERIODIC_EVT )
|
|
{
|
|
// Perform periodic battery task
|
|
hidDevBattPeriodicTask();
|
|
return ( events ^ BATT_PERIODIC_EVT );
|
|
}
|
|
|
|
if ( events & HID_SEND_REPORT_EVT )
|
|
{
|
|
// if connection is secure
|
|
if ( hidDevConnSecure )
|
|
{
|
|
LOG("Send Hid Report\n\r");
|
|
hidDevReport_t* pReport = hidDevDequeueReport();
|
|
|
|
if ( pReport != NULL )
|
|
{
|
|
// Send report
|
|
hidDevSendReport( pReport->id, pReport->type, pReport->len, pReport->data );
|
|
}
|
|
|
|
return ( reportQEmpty() ? events^ HID_SEND_REPORT_EVT : events );
|
|
}
|
|
|
|
return ( events ^ HID_SEND_REPORT_EVT );
|
|
}
|
|
|
|
if( events & HID_UPPARAM_EVT)
|
|
{
|
|
uint8 bleupdateConnParams = TRUE;
|
|
uint8 enable_update_request= TRUE;
|
|
|
|
if(hidDevGapState == GAPROLE_CONNECTED)
|
|
{
|
|
GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request );
|
|
GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_REQ, sizeof( uint8 ), &bleupdateConnParams );
|
|
LOG("device updata connected parament");
|
|
}
|
|
|
|
return ( events ^ HID_UPPARAM_EVT );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_Register
|
|
|
|
@brief Register a callback function with HID Dev.
|
|
|
|
@param pCfg - Parameter configuration.
|
|
@param pfnServiceCB - Callback function.
|
|
|
|
@return None.
|
|
*/
|
|
void HidDev_Register( hidDevCfg_t* pCfg, hidDevCB_t* pCBs )
|
|
{
|
|
pHidDevCB = pCBs;
|
|
pHidDevCfg = pCfg;
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_RegisterReports
|
|
|
|
@brief Register the report table with HID Dev.
|
|
|
|
@param numReports - Length of report table.
|
|
@param pRpt - Report table.
|
|
|
|
@return None.
|
|
*/
|
|
void HidDev_RegisterReports( uint8 numReports, hidRptMap_t* pRpt )
|
|
{
|
|
pHidDevRptTbl = pRpt;
|
|
hidDevRptTblLen = numReports;
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_Report
|
|
|
|
@brief Send a HID report.
|
|
|
|
@param id - HID report ID.
|
|
@param type - HID report type.
|
|
@param len - Length of report.
|
|
@param pData - Report data.
|
|
|
|
@return None.
|
|
*/
|
|
void HidDev_Report( uint8 id, uint8 type, uint8 len, uint8* pData )
|
|
{
|
|
// if connected
|
|
if ( hidDevGapState == GAPROLE_CONNECTED )
|
|
{
|
|
// if connection is secure
|
|
if ( hidDevConnSecure )
|
|
{
|
|
// Make sure there're no pending reports
|
|
if ( reportQEmpty() )
|
|
{
|
|
// send report
|
|
hidDevSendReport( id, type, len, pData );
|
|
LOG("send key action\n\r");
|
|
return; // we're done
|
|
}
|
|
}
|
|
}
|
|
// else if not already advertising
|
|
else if ( hidDevGapState != GAPROLE_ADVERTISING )
|
|
{
|
|
// if bonded
|
|
if ( hidDevBondCount() > 0 )
|
|
{
|
|
// start high duty cycle advertising
|
|
hidDevHighAdvertising();
|
|
}
|
|
// else not bonded
|
|
else
|
|
{
|
|
// start initial advertising
|
|
hidDevInitialAdvertising();
|
|
}
|
|
}
|
|
|
|
// hidDev task will send report when secure connection is established
|
|
hidDevEnqueueReport( id, type, len, pData );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_Close
|
|
|
|
@brief Close the connection or stop advertising.
|
|
|
|
@return None.
|
|
*/
|
|
void HidDev_Close( void )
|
|
{
|
|
uint8 param;
|
|
|
|
// if connected then disconnect
|
|
if ( hidDevGapState == GAPROLE_CONNECTED )
|
|
{
|
|
GAPRole_TerminateConnection();
|
|
}
|
|
// else stop advertising
|
|
else
|
|
{
|
|
param = FALSE;
|
|
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), ¶m );
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_SetParameter
|
|
|
|
@brief Set a HID Dev parameter.
|
|
|
|
@param param - Profile parameter ID
|
|
@param len - length of data to right
|
|
@param pValue - pointer to data to write. This is dependent on
|
|
the parameter ID and WILL be cast to the appropriate
|
|
data type (example: data type of uint16 will be cast to
|
|
uint16 pointer).
|
|
|
|
@return bStatus_t
|
|
*/
|
|
bStatus_t HidDev_SetParameter( uint8 param, uint8 len, void* pValue )
|
|
{
|
|
bStatus_t ret = SUCCESS;
|
|
|
|
switch ( param )
|
|
{
|
|
case HIDDEV_ERASE_ALLBONDS:
|
|
if ( len == 0 )
|
|
{
|
|
// See if the last report sent out wasn't a release key
|
|
if ( osal_isbufset( lastNoti.value, 0x00, lastNoti.len ) == FALSE )
|
|
{
|
|
// Send a release report before disconnecting, otherwise
|
|
// the last pressed key would get 'stuck' on the HID Host.
|
|
osal_memset( lastNoti.value, 0x00, lastNoti.len );
|
|
GATT_Notification( gapConnHandle, &lastNoti, FALSE );
|
|
}
|
|
|
|
// Drop connection
|
|
if ( hidDevGapState == GAPROLE_CONNECTED )
|
|
{
|
|
GAPRole_TerminateConnection();
|
|
}
|
|
|
|
// Flush report queue
|
|
firstQIdx = lastQIdx = 0;
|
|
// Erase bonding info
|
|
GAPBondMgr_SetParameter( GAPBOND_ERASE_ALLBONDS, 0, NULL );
|
|
}
|
|
else
|
|
{
|
|
ret = bleInvalidRange;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
ret = INVALIDPARAMETER;
|
|
break;
|
|
}
|
|
|
|
return ( ret );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_GetParameter
|
|
|
|
@brief Get a HID Dev parameter.
|
|
|
|
@param param - Profile parameter ID
|
|
@param pValue - pointer to data to get. This is dependent on
|
|
the parameter ID and WILL be cast to the appropriate
|
|
data type (example: data type of uint16 will be cast to
|
|
uint16 pointer).
|
|
|
|
@return bStatus_t
|
|
*/
|
|
bStatus_t HidDev_GetParameter( uint8 param, void* pValue )
|
|
{
|
|
bStatus_t ret = SUCCESS;
|
|
|
|
switch ( param )
|
|
{
|
|
default:
|
|
ret = INVALIDPARAMETER;
|
|
break;
|
|
}
|
|
|
|
return ( ret );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_PasscodeRsp
|
|
|
|
@brief Respond to a passcode request.
|
|
|
|
@param status - SUCCESS if passcode is available, otherwise
|
|
see @ref SMP_PAIRING_FAILED_DEFINES.
|
|
@param passcode - integer value containing the passcode.
|
|
|
|
@return none
|
|
*/
|
|
void HidDev_PasscodeRsp( uint8 status, uint32 passcode )
|
|
{
|
|
// Send passcode response
|
|
GAPBondMgr_PasscodeRsp( gapConnHandle, status, passcode );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_ReadAttrCB
|
|
|
|
@brief HID Dev attribute read callback.
|
|
|
|
@param connHandle - connection message was received on
|
|
@param pAttr - pointer to attribute
|
|
@param pValue - pointer to data to be read
|
|
@param pLen - length of data to be read
|
|
@param offset - offset of the first octet to be read
|
|
@param maxLen - maximum length of data to be read
|
|
@param method - type of read message
|
|
|
|
@return SUCCESS, blePending or Failure
|
|
*/
|
|
uint8 HidDev_ReadAttrCB( uint16 connHandle, gattAttribute_t* pAttr,
|
|
uint8* pValue, uint16* pLen, uint16 offset, uint8 maxLen )
|
|
{
|
|
bStatus_t status = SUCCESS;
|
|
hidRptMap_t* pRpt;
|
|
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
|
|
|
// Only report map is long
|
|
if ( offset > 0 && uuid != REPORT_MAP_UUID )
|
|
{
|
|
return ( ATT_ERR_ATTR_NOT_LONG );
|
|
}
|
|
|
|
if ( uuid == REPORT_UUID ||
|
|
uuid == BOOT_KEY_INPUT_UUID ||
|
|
uuid == BOOT_KEY_OUTPUT_UUID ||
|
|
uuid == BOOT_MOUSE_INPUT_UUID )
|
|
{
|
|
// find report ID in table
|
|
if ( (pRpt = hidDevRptByHandle(pAttr->handle)) != NULL )
|
|
{
|
|
// execute report callback
|
|
status = (*pHidDevCB->reportCB)( pRpt->id, pRpt->type, uuid,
|
|
HID_DEV_OPER_READ, pLen, pValue );
|
|
}
|
|
else
|
|
{
|
|
*pLen = 0;
|
|
}
|
|
}
|
|
else if ( uuid == REPORT_MAP_UUID )
|
|
{
|
|
// verify offset
|
|
if ( offset >= hidReportMapLen )
|
|
{
|
|
status = ATT_ERR_INVALID_OFFSET;
|
|
}
|
|
else
|
|
{
|
|
// determine read length
|
|
*pLen = MIN( maxLen, (hidReportMapLen - offset) );
|
|
// copy data
|
|
osal_memcpy( pValue, pAttr->pValue + offset, *pLen );
|
|
}
|
|
}
|
|
else if ( uuid == HID_INFORMATION_UUID )
|
|
{
|
|
*pLen = HID_INFORMATION_LEN;
|
|
osal_memcpy( pValue, pAttr->pValue, HID_INFORMATION_LEN );
|
|
}
|
|
else if ( uuid == GATT_REPORT_REF_UUID )
|
|
{
|
|
*pLen = HID_REPORT_REF_LEN;
|
|
osal_memcpy( pValue, pAttr->pValue, HID_REPORT_REF_LEN );
|
|
}
|
|
else if ( uuid == PROTOCOL_MODE_UUID )
|
|
{
|
|
*pLen = HID_PROTOCOL_MODE_LEN;
|
|
pValue[0] = pAttr->pValue[0];
|
|
}
|
|
else if ( uuid == GATT_EXT_REPORT_REF_UUID )
|
|
{
|
|
*pLen = HID_EXT_REPORT_REF_LEN;
|
|
osal_memcpy( pValue, pAttr->pValue, HID_EXT_REPORT_REF_LEN );
|
|
}
|
|
|
|
// restart idle timer
|
|
if ( status == SUCCESS )
|
|
{
|
|
hidDevStartIdleTimer();
|
|
}
|
|
|
|
return ( status );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_WriteAttrCB
|
|
|
|
@brief HID Dev attribute read callback.
|
|
|
|
@param connHandle - connection message was received on
|
|
@param pAttr - pointer to attribute
|
|
@param pValue - pointer to data to be written
|
|
@param len - length of data
|
|
@param offset - offset of the first octet to be written
|
|
|
|
@return Success or Failure
|
|
*/
|
|
bStatus_t HidDev_WriteAttrCB( uint16 connHandle, gattAttribute_t* pAttr,
|
|
uint8* pValue, uint16 len, uint16 offset )
|
|
{
|
|
bStatus_t status = SUCCESS;
|
|
hidRptMap_t* pRpt;
|
|
|
|
// Make sure it's not a blob operation (no attributes in the profile are long)
|
|
if ( offset > 0 )
|
|
{
|
|
return ( ATT_ERR_ATTR_NOT_LONG );
|
|
}
|
|
|
|
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
|
|
|
if ( uuid == REPORT_UUID ||
|
|
uuid == BOOT_KEY_OUTPUT_UUID )
|
|
{
|
|
// find report ID in table
|
|
if ((pRpt = hidDevRptByHandle(pAttr->handle)) != NULL)
|
|
{
|
|
// execute report callback
|
|
status = (*pHidDevCB->reportCB)( pRpt->id, pRpt->type, uuid,
|
|
HID_DEV_OPER_WRITE, &len, pValue );
|
|
}
|
|
}
|
|
else if ( uuid == HID_CTRL_PT_UUID )
|
|
{
|
|
// Validate length and value range
|
|
if ( len == 1 )
|
|
{
|
|
if ( pValue[0] == HID_CMD_SUSPEND || pValue[0] == HID_CMD_EXIT_SUSPEND )
|
|
{
|
|
// execute HID app event callback
|
|
(*pHidDevCB->evtCB)( (pValue[0] == HID_CMD_SUSPEND) ?
|
|
HID_DEV_SUSPEND_EVT : HID_DEV_EXIT_SUSPEND_EVT );
|
|
}
|
|
else
|
|
{
|
|
status = ATT_ERR_INVALID_VALUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = ATT_ERR_INVALID_VALUE_SIZE;
|
|
}
|
|
}
|
|
else if ( uuid == GATT_CLIENT_CHAR_CFG_UUID )
|
|
{
|
|
status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
|
|
offset, GATT_CLIENT_CFG_NOTIFY );
|
|
|
|
if ( status == SUCCESS )
|
|
{
|
|
uint16 charCfg = BUILD_UINT16( pValue[0], pValue[1] );
|
|
|
|
// find report ID in table
|
|
if ( (pRpt = hidDevRptByCccdHandle(pAttr->handle)) != NULL )
|
|
{
|
|
// execute report callback
|
|
(*pHidDevCB->reportCB)( pRpt->id, pRpt->type, uuid,
|
|
(charCfg == GATT_CLIENT_CFG_NOTIFY) ?
|
|
HID_DEV_OPER_ENABLE : HID_DEV_OPER_DISABLE,
|
|
&len, pValue );
|
|
}
|
|
}
|
|
}
|
|
else if ( uuid == PROTOCOL_MODE_UUID )
|
|
{
|
|
if ( len == HID_PROTOCOL_MODE_LEN )
|
|
{
|
|
if ( pValue[0] == HID_PROTOCOL_MODE_BOOT ||
|
|
pValue[0] == HID_PROTOCOL_MODE_REPORT )
|
|
{
|
|
pAttr->pValue[0] = pValue[0];
|
|
// execute HID app event callback
|
|
(*pHidDevCB->evtCB)( (pValue[0] == HID_PROTOCOL_MODE_BOOT) ?
|
|
HID_DEV_SET_BOOT_EVT : HID_DEV_SET_REPORT_EVT );
|
|
}
|
|
else
|
|
{
|
|
status = ATT_ERR_INVALID_VALUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = ATT_ERR_INVALID_VALUE_SIZE;
|
|
}
|
|
}
|
|
|
|
// restart idle timer
|
|
if (status == SUCCESS)
|
|
{
|
|
hidDevStartIdleTimer();
|
|
}
|
|
|
|
return ( status );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDev_ProcessOSALMsg
|
|
|
|
@brief Process an incoming task message.
|
|
|
|
@param pMsg - message to process
|
|
|
|
@return none
|
|
*/
|
|
static void hidDev_ProcessOSALMsg( osal_event_hdr_t* pMsg )
|
|
{
|
|
switch ( pMsg->event )
|
|
{
|
|
case GATT_MSG_EVENT:
|
|
hidDevProcessGattMsg( (gattMsgEvent_t*) pMsg );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevProcessGattMsg
|
|
|
|
@brief Process GATT messages
|
|
|
|
@return none
|
|
*/
|
|
static void hidDevProcessGattMsg( gattMsgEvent_t* pMsg )
|
|
{
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevHandleConnStatusCB
|
|
|
|
@brief Reset client char config.
|
|
|
|
@param connHandle - connection handle
|
|
@param changeType - type of change
|
|
|
|
@return none
|
|
*/
|
|
static void hidDevHandleConnStatusCB( uint16 connHandle, uint8 changeType )
|
|
{
|
|
uint8 i;
|
|
hidRptMap_t* p = pHidDevRptTbl;
|
|
uint16 retHandle;
|
|
gattAttribute_t* pAttr;
|
|
|
|
// Make sure this is not loopback connection
|
|
if ( connHandle != LOOPBACK_CONNHANDLE )
|
|
{
|
|
if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
|
|
( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
|
|
( !linkDB_Up( connHandle ) ) ) )
|
|
{
|
|
for ( i = hidDevRptTblLen; i > 0; i--, p++ )
|
|
{
|
|
if ( p->cccdHandle != 0 )
|
|
{
|
|
if ( (pAttr = GATT_FindHandle(p->cccdHandle, &retHandle)) != NULL )
|
|
{
|
|
GATTServApp_InitCharCfg( connHandle, (gattCharCfg_t*) pAttr->pValue );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevDisconnected
|
|
|
|
@brief Handle disconnect.
|
|
|
|
@return none
|
|
*/
|
|
static void hidDevDisconnected( void )
|
|
{
|
|
uint8 enable_update_request =FALSE;
|
|
// Stop idle timer
|
|
hidDevStopIdleTimer();
|
|
// Reset client characteristic configuration descriptors
|
|
Batt_HandleConnStatusCB( gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED );
|
|
//ScanParam_HandleConnStatusCB( gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED );
|
|
hidDevHandleConnStatusCB( gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED );
|
|
// Reset state variables
|
|
hidDevConnSecure = FALSE;
|
|
hidProtocolMode = HID_PROTOCOL_MODE_REPORT;
|
|
hidDevPairingStarted = FALSE;
|
|
// Reset last report sent out
|
|
osal_memset( &lastNoti, 0, sizeof( attHandleValueNoti_t ) );
|
|
GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request );
|
|
osal_stop_timerEx(hidDevTaskId, HID_UPPARAM_EVT);
|
|
|
|
// if bonded and normally connectable start advertising
|
|
if ( ( hidDevBondCount() > 0 ) &&
|
|
( pHidDevCfg->hidFlags & HID_FLAGS_REMOTE_WAKE ) ) //HID_FLAGS_REMOTE_WAKE HID_FLAGS_NORMALLY_CONNECTABLE
|
|
{
|
|
// hidDevDirectAdvertising();
|
|
// LOG("hidDev Direct Advertising \n\r");
|
|
hidDevLowAdvertising();
|
|
LOG("hidDev Low Advertising \n\r");
|
|
}
|
|
else
|
|
{
|
|
hidDevLowAdvertising();
|
|
LOG("hidDev Low Advertising \n\r");
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevGapStateCB
|
|
|
|
@brief Notification from the profile of a state change.
|
|
|
|
@param newState - new state
|
|
|
|
@return none
|
|
*/
|
|
void hidDevGapStateCB( gaprole_States_t newState )
|
|
{
|
|
LOG("%s, %d\n",__FUNCTION__, newState);
|
|
|
|
// if connected
|
|
if ( newState == GAPROLE_CONNECTED )
|
|
{
|
|
// get connection handle
|
|
GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );
|
|
// connection not secure yet
|
|
hidDevConnSecure = FALSE;
|
|
uint8 peerAddress[B_ADDR_LEN];
|
|
GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
|
|
LOG("Master Mac:%02X,%02X,%02X,%02X,%02X,%02X\n\r",peerAddress[5],peerAddress[4],peerAddress[3],peerAddress[2],peerAddress[1],peerAddress[0]);
|
|
// start idle timer
|
|
hidDevStartIdleTimer();
|
|
}
|
|
// if disconnected
|
|
else if ( hidDevGapState == GAPROLE_CONNECTED &&
|
|
newState != GAPROLE_CONNECTED )
|
|
{
|
|
LOG("disconnect advisting \n\r");
|
|
hidDevDisconnected();
|
|
updateConnParams = TRUE;
|
|
g_instant_cnt=0;
|
|
|
|
if ( pairingStatus == SMP_PAIRING_FAILED_CONFIRM_VALUE )
|
|
{
|
|
// bonding failed due to mismatched confirm values
|
|
hidDevInitialAdvertising();
|
|
pairingStatus = SUCCESS;
|
|
LOG("hidDev Initial Advertising \n\r");
|
|
}
|
|
}
|
|
// if started
|
|
else if ( newState == GAPROLE_STARTED )
|
|
{
|
|
// nothing to do for now!
|
|
}
|
|
|
|
hidDevGapState = newState;
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevPairStateCB
|
|
|
|
@brief Pairing state callback.
|
|
|
|
@return none
|
|
*/
|
|
void hidDevPairStateCB( uint16 connHandle, uint8 state, uint8 status )
|
|
{
|
|
if ( state == GAPBOND_PAIRING_STATE_STARTED )
|
|
{
|
|
hidDevPairingStarted = TRUE;
|
|
}
|
|
else if ( state == GAPBOND_PAIRING_STATE_COMPLETE )
|
|
{
|
|
hidDevPairingStarted = FALSE;
|
|
|
|
if ( status == SUCCESS )
|
|
{
|
|
hidDevConnSecure = TRUE;
|
|
LOG("Pair Success\n\r");
|
|
osal_start_timerEx(hidKbdTaskId, HID_TEST_EVT, 5000);
|
|
//osal_start_timerEx(hidDevTaskId, HID_UPPARAM_EVT, 15000);//3000
|
|
}
|
|
else
|
|
{
|
|
LOG("Pair Fail\n\r");
|
|
}
|
|
|
|
pairingStatus = status;
|
|
}
|
|
else if ( state == GAPBOND_PAIRING_STATE_BONDED )
|
|
{
|
|
if ( status == SUCCESS )
|
|
{
|
|
hidDevConnSecure = TRUE;
|
|
// osal_start_timerEx(hidKbdTaskId, HID_TEST_EVT, 5000);
|
|
// osal_start_timerEx(hidDevTaskId, HID_UPPARAM_EVT, 15000);//3000
|
|
osal_start_timerEx(hidKbdTaskId, HID_TEST_EVT, 5000);
|
|
LOG("bond Success\n\r");
|
|
}
|
|
}
|
|
|
|
//if(hidDevConnSecure){
|
|
// osal_start_reload_timer(hidDevTaskId, HID_TEST_EVT, 1000);
|
|
//}
|
|
//LOG("pair state=%d\n\r",state);
|
|
if ( !reportQEmpty() && hidDevConnSecure )
|
|
{
|
|
LOG("Set Send Report EVENT\n\r");
|
|
// Notify our task to send out pending reports
|
|
osal_set_event( hidDevTaskId, HID_SEND_REPORT_EVT );
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevPasscodeCB
|
|
|
|
@brief Passcode callback.
|
|
|
|
@param deviceAddr - address of device to pair with, and could be either public or random.
|
|
@param connectionHandle - connection handle
|
|
@param uiInputs - pairing User Interface Inputs - Ask user to input passcode
|
|
@param uiOutputs - pairing User Interface Outputs - Display passcode
|
|
|
|
@return none
|
|
*/
|
|
void hidDevPasscodeCB( uint8* deviceAddr, uint16 connectionHandle,
|
|
uint8 uiInputs, uint8 uiOutputs )
|
|
{
|
|
if ( pHidDevCB && pHidDevCB->passcodeCB )
|
|
{
|
|
// execute HID app passcode callback
|
|
(*pHidDevCB->passcodeCB)( deviceAddr, connectionHandle, uiInputs, uiOutputs );
|
|
}
|
|
else
|
|
{
|
|
// Send passcode response
|
|
GAPBondMgr_PasscodeRsp( connectionHandle, SUCCESS, 0 );
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevBattCB
|
|
|
|
@brief Callback function for battery service.
|
|
|
|
@param event - service event
|
|
|
|
@return none
|
|
*/
|
|
void hidDevBattCB( uint8 event )
|
|
{
|
|
if ( event == BATT_LEVEL_NOTI_ENABLED )
|
|
{
|
|
// if connected start periodic measurement
|
|
if ( hidDevGapState == GAPROLE_CONNECTED )
|
|
{
|
|
osal_start_timerEx( hidDevTaskId, BATT_PERIODIC_EVT, DEFAULT_BATT_PERIOD );
|
|
}
|
|
}
|
|
else if ( event == BATT_LEVEL_NOTI_DISABLED )
|
|
{
|
|
// stop periodic measurement
|
|
osal_stop_timerEx( hidDevTaskId, BATT_PERIODIC_EVT );
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevScanParamCB
|
|
|
|
@brief Callback function for scan parameter service.
|
|
|
|
@param event - service event
|
|
|
|
@return none
|
|
*/
|
|
void hidDevScanParamCB( uint8 event )
|
|
{
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevBattPeriodicTask
|
|
|
|
@brief Perform a periodic task for battery measurement.
|
|
|
|
@param none
|
|
|
|
@return none
|
|
*/
|
|
static void hidDevBattPeriodicTask( void )
|
|
{
|
|
if ( hidDevGapState == GAPROLE_CONNECTED )
|
|
{
|
|
// perform battery level check
|
|
Batt_MeasLevel( );
|
|
// Restart timer
|
|
osal_start_timerEx( hidDevTaskId, BATT_PERIODIC_EVT, DEFAULT_BATT_PERIOD );
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevRptByHandle
|
|
|
|
@brief Find the HID report structure for the given handle.
|
|
|
|
@param handle - ATT handle
|
|
|
|
@return Pointer to HID report structure
|
|
*/
|
|
static hidRptMap_t* hidDevRptByHandle( uint16 handle )
|
|
{
|
|
uint8 i;
|
|
hidRptMap_t* p = pHidDevRptTbl;
|
|
|
|
for ( i = hidDevRptTblLen; i > 0; i--, p++ )
|
|
{
|
|
if ( p->handle == handle && p->mode == hidProtocolMode)
|
|
{
|
|
return p;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevRptByCccdHandle
|
|
|
|
@brief Find the HID report structure for the given CCC handle.
|
|
|
|
@param handle - ATT handle
|
|
|
|
@return Pointer to HID report structure
|
|
*/
|
|
static hidRptMap_t* hidDevRptByCccdHandle( uint16 handle )
|
|
{
|
|
uint8 i;
|
|
hidRptMap_t* p = pHidDevRptTbl;
|
|
|
|
for ( i = hidDevRptTblLen; i > 0; i--, p++ )
|
|
{
|
|
if ( p->cccdHandle == handle)
|
|
{
|
|
return p;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevRptById
|
|
|
|
@brief Find the HID report structure for the Report ID and type.
|
|
|
|
@param id - HID report ID
|
|
@param type - HID report type
|
|
|
|
@return Pointer to HID report structure
|
|
*/
|
|
static hidRptMap_t* hidDevRptById( uint8 id, uint8 type )
|
|
{
|
|
uint8 i;
|
|
hidRptMap_t* p = pHidDevRptTbl;
|
|
|
|
for ( i = hidDevRptTblLen; i > 0; i--, p++ )
|
|
{
|
|
if ( p->id == id && p->type == type && p->mode == hidProtocolMode )
|
|
{
|
|
return p;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
#if CCD_CHECK_EN_FLAG
|
|
/*********************************************************************
|
|
@fn hidDevSendReport
|
|
|
|
@brief Send a HID report.
|
|
|
|
@param id - HID report ID.
|
|
@param type - HID report type.
|
|
@param len - Length of report.
|
|
@param pData - Report data.
|
|
|
|
@return None.
|
|
*/
|
|
static void hidDevSendReport( uint8 id, uint8 type, uint8 len, uint8* pData )
|
|
{
|
|
hidRptMap_t* pRpt;
|
|
gattAttribute_t* pAttr;
|
|
uint16 retHandle;
|
|
LOG("%s\n",__FUNCTION__);
|
|
|
|
// Get ATT handle for report
|
|
if ( (pRpt = hidDevRptById(id, type)) != NULL )
|
|
{
|
|
// if notifications are enabled
|
|
if ( (pAttr = GATT_FindHandle(pRpt->cccdHandle, &retHandle)) != NULL )
|
|
{
|
|
uint16 value;
|
|
value = GATTServApp_ReadCharCfg( gapConnHandle, (gattCharCfg_t*) pAttr->pValue );
|
|
|
|
if ( value & GATT_CLIENT_CFG_NOTIFY )
|
|
{
|
|
// After service discovery and encryption, the HID Device should request to
|
|
// change to the preferred connection parameters that best suit its use case.
|
|
if ( updateConnParams )
|
|
{
|
|
GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_REQ, sizeof( uint8 ), &updateConnParams );
|
|
updateConnParams = FALSE;
|
|
}
|
|
|
|
// send notification
|
|
lastNoti.handle = pRpt->handle;
|
|
lastNoti.len = len;
|
|
osal_memcpy(lastNoti.value, pData, len);
|
|
GATT_Notification( gapConnHandle, &lastNoti, FALSE );
|
|
// start idle timer
|
|
hidDevStartIdleTimer();
|
|
}
|
|
else
|
|
{
|
|
LOG("notify fail\n\r");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
/*********************************************************************
|
|
@fn hidDevSendReport
|
|
|
|
@brief Send a HID report.
|
|
|
|
@param id - HID report ID.
|
|
@param type - HID report type.
|
|
@param len - Length of report.
|
|
@param pData - Report data.
|
|
|
|
@return None.
|
|
*/
|
|
static void hidDevSendReport( uint8 id, uint8 type, uint8 len, uint8* pData )
|
|
{
|
|
hidRptMap_t* pRpt;
|
|
gattAttribute_t* pAttr;
|
|
uint16 retHandle;
|
|
LOG("%s\n",__FUNCTION__);
|
|
|
|
// Get ATT handle for report
|
|
if ( (pRpt = hidDevRptById(id, type)) != NULL )
|
|
{
|
|
// if notifications are enabled
|
|
if ( (pAttr = GATT_FindHandle(pRpt->cccdHandle, &retHandle)) != NULL )
|
|
{
|
|
uint16 value;
|
|
value = GATTServApp_ReadCharCfg( gapConnHandle, (gattCharCfg_t*) pAttr->pValue );
|
|
|
|
//if ( value & GATT_CLIENT_CFG_NOTIFY )
|
|
{
|
|
// After service discovery and encryption, the HID Device should request to
|
|
// change to the preferred connection parameters that best suit its use case.
|
|
if ( updateConnParams )
|
|
{
|
|
GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_REQ, sizeof( uint8 ), &updateConnParams );
|
|
updateConnParams = FALSE;
|
|
}
|
|
|
|
// send notification
|
|
lastNoti.handle = pRpt->handle;
|
|
lastNoti.len = len;
|
|
osal_memcpy(lastNoti.value, pData, len);
|
|
GATT_Notification( gapConnHandle, &lastNoti, FALSE );
|
|
// start idle timer
|
|
hidDevStartIdleTimer();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/*********************************************************************
|
|
@fn hidDevEnqueueReport
|
|
|
|
@brief Enqueue a HID report to be sent later.
|
|
|
|
@param id - HID report ID.
|
|
@param type - HID report type.
|
|
@param len - Length of report.
|
|
@param pData - Report data.
|
|
|
|
@return None.
|
|
*/
|
|
static void hidDevEnqueueReport( uint8 id, uint8 type, uint8 len, uint8* pData )
|
|
{
|
|
// Enqueue only if bonded
|
|
if ( hidDevBondCount() > 0 )
|
|
{
|
|
// Update last index
|
|
lastQIdx = ( lastQIdx + 1 ) % HID_DEV_REPORT_Q_SIZE;
|
|
|
|
if ( lastQIdx == firstQIdx )
|
|
{
|
|
// Queue overflow; discard oldest report
|
|
firstQIdx = ( firstQIdx + 1 ) % HID_DEV_REPORT_Q_SIZE;
|
|
}
|
|
|
|
// Save report
|
|
hidDevReportQ[lastQIdx].id = id;
|
|
hidDevReportQ[lastQIdx].type = type;
|
|
hidDevReportQ[lastQIdx].len = len;
|
|
osal_memcpy( hidDevReportQ[lastQIdx].data, pData, len );
|
|
|
|
if ( hidDevConnSecure )
|
|
{
|
|
// Notify our task to send out pending reports
|
|
osal_set_event( hidDevTaskId, HID_SEND_REPORT_EVT );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevDequeueReport
|
|
|
|
@brief Dequeue a HID report to be sent out.
|
|
|
|
@param id - HID report ID.
|
|
@param type - HID report type.
|
|
@param len - Length of report.
|
|
@param pData - Report data.
|
|
|
|
@return None.
|
|
*/
|
|
static hidDevReport_t* hidDevDequeueReport( void )
|
|
{
|
|
if ( reportQEmpty() )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Update first index
|
|
firstQIdx = ( firstQIdx + 1 ) % HID_DEV_REPORT_Q_SIZE;
|
|
return ( &(hidDevReportQ[firstQIdx]) );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevHighAdvertising
|
|
|
|
@brief Start advertising at a high duty cycle.
|
|
|
|
@param None.
|
|
|
|
@return None.
|
|
*/
|
|
static void hidDevHighAdvertising( void )
|
|
{
|
|
uint8 param;
|
|
VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, HID_HIGH_ADV_INT_MIN );
|
|
VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, HID_HIGH_ADV_INT_MAX );
|
|
VOID GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, HID_HIGH_ADV_TIMEOUT );
|
|
// Setup adverstising filter policy first
|
|
param = GAP_FILTER_POLICY_WHITE;
|
|
VOID GAPRole_SetParameter( GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), ¶m );
|
|
param = TRUE;
|
|
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), ¶m );
|
|
LOG("high adv\n\r");
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevLowAdvertising
|
|
|
|
@brief Start advertising at a low duty cycle.
|
|
|
|
@param None.
|
|
|
|
@return None.
|
|
*/
|
|
static void hidDevLowAdvertising( void )
|
|
{
|
|
uint8 param;
|
|
#if 0
|
|
static uint8_t cnt=0;
|
|
uint8_t macAddr[6]= {0x11,0x22,0x33,0x44,0x55,0x66};
|
|
param = FALSE;
|
|
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), ¶m );
|
|
cnt++;
|
|
macAddr[5]+=cnt;
|
|
volatile uint8_t* P_ownPublicAddr=(volatile uint8_t*)0x1fff11f9;
|
|
*(P_ownPublicAddr++)=macAddr[0];
|
|
*(P_ownPublicAddr++)=macAddr[1];
|
|
*(P_ownPublicAddr++)=macAddr[2];
|
|
*(P_ownPublicAddr++)=macAddr[3];
|
|
*(P_ownPublicAddr++)=macAddr[4];
|
|
*(P_ownPublicAddr++)=macAddr[5];
|
|
HCI_ReadBDADDRCmd();
|
|
#endif
|
|
param=GAP_ADRPT_ADV_IND;//GAP_ADRPT_ADV_DIRECT_IND;
|
|
GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof(uint8),¶m );
|
|
VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, HID_LOW_ADV_INT_MIN );
|
|
VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, HID_LOW_ADV_INT_MAX );
|
|
VOID GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, HID_LOW_ADV_TIMEOUT );
|
|
// Setup adverstising filter policy first
|
|
param = GAP_FILTER_POLICY_ALL;//GAP_FILTER_POLICY_WHITE teddy modify
|
|
VOID GAPRole_SetParameter( GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), ¶m );
|
|
param = TRUE;
|
|
VOID GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), ¶m );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevInitialAdvertising
|
|
|
|
@brief Start advertising for initial connection
|
|
|
|
@return None.
|
|
*/
|
|
static void hidDevInitialAdvertising( void )
|
|
{
|
|
uint8 param;
|
|
VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, HID_INITIAL_ADV_INT_MIN );
|
|
VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, HID_INITIAL_ADV_INT_MAX );
|
|
VOID GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, HID_INITIAL_ADV_TIMEOUT );
|
|
// Setup adverstising filter policy first
|
|
param = GAP_FILTER_POLICY_ALL;
|
|
VOID GAPRole_SetParameter( GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), ¶m );
|
|
param = TRUE;
|
|
VOID GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), ¶m );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevBondCount
|
|
|
|
@brief Gets the total number of bonded devices.
|
|
|
|
@param None.
|
|
|
|
@return number of bonded devices.
|
|
*/
|
|
static uint8 hidDevBondCount( void )
|
|
{
|
|
uint8 bondCnt = 0;
|
|
VOID GAPBondMgr_GetParameter( GAPBOND_BOND_COUNT, &bondCnt );
|
|
return ( bondCnt );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevStartIdleTimer
|
|
|
|
@brief Start the idle timer.
|
|
|
|
@return None.
|
|
*/
|
|
static void hidDevStartIdleTimer( void )
|
|
{
|
|
if ( pHidDevCfg->idleTimeout > 0 )
|
|
{
|
|
osal_start_timerEx( hidDevTaskId, HID_IDLE_EVT, pHidDevCfg->idleTimeout );
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn hidDevStopIdleTimer
|
|
|
|
@brief Stop the idle timer.
|
|
|
|
@return None.
|
|
*/
|
|
static void hidDevStopIdleTimer( void )
|
|
{
|
|
osal_stop_timerEx( hidDevTaskId, HID_IDLE_EVT );
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
@fn HidDev_scanParamCB
|
|
|
|
@brief Callback function for scan parameter service.
|
|
|
|
@param event - service event
|
|
|
|
@return none
|
|
*/
|
|
static void HidDev_scanParamCB(uint8_t event)
|
|
{
|
|
// Do nothing.
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
*********************************************************************/
|