Peripheral
case GAPROLE_PARAM_UPDATE_ENABLE:
if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= TRUE) )
{
gapRole_ParamUpdateEnable = *((uint8*)pValue);
}
else
{
ret = bleInvalidRange;
}
break;
case GAP_LINK_ESTABLISHED_EVENT:
// Check whether update parameter request is enabled
if ( gapRole_ParamUpdateEnable == TRUE )
{
// Get the minimum time upon connection establishment before the
// peripheral can start a connection update procedure.
uint16 timeout = GAP_GetParamValue( TGAP_CONN_PAUSE_PERIPHERAL );
osal_start_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT, timeout*1000 );
}
if ( events & START_CONN_UPDATE_EVT )
{
// Start connection update procedure
gapRole_startConnUpdate( GAPROLE_NO_ACTION );
return ( events ^ START_CONN_UPDATE_EVT );
}
static void gapRole_startConnUpdate( uint8 handleFailure )
{
// First check the current connection parameters versus the configured parameters
if ( (gapRole_ConnInterval < gapRole_MinConnInterval) ||
(gapRole_ConnInterval > gapRole_MaxConnInterval) ||
(gapRole_ConnSlaveLatency != gapRole_SlaveLatency) ||
(gapRole_ConnTimeout != gapRole_TimeoutMultiplier) )
{
l2capParamUpdateReq_t updateReq;
uint16 timeout = GAP_GetParamValue( TGAP_CONN_PARAM_TIMEOUT );
updateReq.intervalMin = gapRole_MinConnInterval;
updateReq.intervalMax = gapRole_MaxConnInterval;
updateReq.slaveLatency = gapRole_SlaveLatency;
updateReq.timeoutMultiplier = gapRole_TimeoutMultiplier;
VOID L2CAP_ConnParamUpdateReq( gapRole_ConnectionHandle, &updateReq, gapRole_TaskID );
paramUpdateNoSuccessOption = handleFailure;
// Let's wait for L2CAP Connection Parameters Update Response
VOID osal_start_timerEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT, timeout );
}
}
if ( events & CONN_PARAM_TIMEOUT_EVT )
{
// Unsuccessful in updating connection parameters
gapRole_HandleParamUpdateNoSuccess();
return ( events ^ CONN_PARAM_TIMEOUT_EVT );
}
static void gapRole_HandleParamUpdateNoSuccess( void )
{
// See which option was choosen for unsuccessful updates
switch ( paramUpdateNoSuccessOption )
{
case GAPROLE_RESEND_PARAM_UPDATE:
GAPRole_SendUpdateParam( gapRole_MinConnInterval, gapRole_MaxConnInterval,
gapRole_SlaveLatency, gapRole_TimeoutMultiplier,
GAPROLE_RESEND_PARAM_UPDATE );
break;
case GAPROLE_TERMINATE_LINK:
GAPRole_TerminateConnection();
break;
case GAPROLE_NO_ACTION:
// fall through
default:
//do nothing
break;
}
}
bStatus_t GAPRole_SendUpdateParam( uint16 minConnInterval, uint16 maxConnInterval,
uint16 latency, uint16 connTimeout, uint8 handleFailure )
{
// If there is no existing connection no update need be sent
if ( gapRole_state != GAPROLE_CONNECTED )
{
return ( bleNotConnected );
}
// Check that all parameters are in range before sending request
if ( ( minConnInterval >= DEFAULT_MIN_CONN_INTERVAL ) &&
( minConnInterval < DEFAULT_MAX_CONN_INTERVAL ) &&
( maxConnInterval >= DEFAULT_MIN_CONN_INTERVAL ) &&
( maxConnInterval < DEFAULT_MAX_CONN_INTERVAL ) &&
( latency < MAX_SLAVE_LATENCY ) &&
( connTimeout >= MIN_TIMEOUT_MULTIPLIER ) &&
( connTimeout < MAX_TIMEOUT_MULTIPLIER ) )
{
gapRole_MinConnInterval = minConnInterval;
gapRole_MaxConnInterval = maxConnInterval;
gapRole_SlaveLatency = latency;
gapRole_TimeoutMultiplier = connTimeout;
// Start connection update procedure
gapRole_startConnUpdate( handleFailure );
// Connection update requested by app, cancel such pending procedure (if active)
VOID osal_stop_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT );
return ( SUCCESS );
}
return ( bleInvalidRange );
}
case GAPROLE_PARAM_UPDATE_REQ:
{
uint8 req = *((uint8*)pValue);
if ( len == sizeof ( uint8 ) && (req == TRUE) )
{
// Make sure we don't send an L2CAP Connection Parameter Update Request
// command within TGAP(conn_param_timeout) of an L2CAP Connection Parameter
// Update Response being received.
if ( osal_get_timeoutEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT ) == 0 )
{
// Start connection update procedure
gapRole_startConnUpdate( GAPROLE_NO_ACTION );
// Connection update requested by app, cancel such pending procedure (if active)
VOID osal_stop_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT );
}
else
{
ret = blePending;
}
}
else
{
ret = bleInvalidRange;
}
}
break;
static void hidDevSendReport( uint8 id, uint8 type, uint8 len, uint8 *pData )
{
hidRptMap_t *pRpt;
gattAttribute_t *pAttr;
uint16 retHandle;
// 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();
}
}
}
}
Central
simpleBLECentral
1. update connection parameters event
simpleBLECentralEventCB(){
case GAP_LINK_PARAM_UPDATE_EVENT:
{
LCD_WRITE_STRING( "Param Update", HAL_LCD_LINE_1 );
}
break;
}
event触发源:
A. 连接更新是从机请求的,
B. 调用GAPCentralRol_UpdateLink()
// Connection update
if ( simpleBLEState == BLE_STATE_CONNECTED )
{
GAPCentralRole_UpdateLink( simpleBLEConnHandle,
DEFAULT_UPDATE_MIN_CONN_INTERVAL,
DEFAULT_UPDATE_MAX_CONN_INTERVAL,
DEFAULT_UPDATE_SLAVE_LATENCY,
DEFAULT_UPDATE_CONN_TIMEOUT );
}