Project

General

Profile

/*******************************************************************************
File Name: CYBLE_gatt.c
Version 2.0

Description:
This file contains the source code for the GATT API of the BLE Component.

********************************************************************************
Copyright 2014-2015, Cypress Semiconductor Corporation. All rights reserved.
You may use this file only in accordance with the license, terms, conditions,
disclaimers, and limitations in the end user license agreement accompanying
the software package with which this file was provided.
*******************************************************************************/


#include "BLE_eventHandler.h"


/***************************************
##Global variables
***************************************/

CYBLE_STATE_T cyBle_state;


#if(CYBLE_GATT_ROLE_SERVER)
const CYBLE_GATTS_T cyBle_gatts =
{
0x0008u, /* Handle of the GATT service */
0x000Au, /* Handle of the Service Changed characteristic */
0x000Bu, /* Handle of the Client Characteristic Configuration descriptor */
};
static uint8 cyBle_attValues[0x1Au] = {
/* Device Name */
(uint8)'B', (uint8)'L', (uint8)'E', (uint8)' ', (uint8)'L', (uint8)'a', (uint8)'b', (uint8)' ', (uint8)'1', (uint8)'_',
(uint8)'1',

/* Appearance */
0x00u, 0x02u,

/* Peripheral Preferred Connection Parameters */
0x06u, 0x00u, 0x28u, 0x00u, 0x00u, 0x00u, 0xE8u, 0x03u,

/* Service Changed */
0x00u, 0x00u, 0x00u, 0x00u,

/* Alert Level */
0x00u,

};

#if defined(__GNUC__) || defined(__ARMCC_VERSION)
const uint8 cyBle_attValuesCCCDFlashMemory[CYBLE_GAP_MAX_BONDED_DEVICE + 1u][CYBLE_GATT_DB_CCCD_COUNT] CYBLE_FLASH_ROW_ALIGNED = {
#elif defined(__ICCARM__)
/* The cyBle_attValuesCCCDFlashMemory[] should be aligned to the size of a Flash row */
#pragma data_alignment=CY_FLASH_SIZEOF_ROW
const uint8 cyBle_attValuesCCCDFlashMemory[CYBLE_GAP_MAX_BONDED_DEVICE + 1u][CYBLE_GATT_DB_CCCD_COUNT] = {
#endif /* defined(__GNUC__) || defined(__ARMCC_VERSION) */
{
0x00u, 0x00u,
},
{
0x00u, 0x00u,
},
{
0x00u, 0x00u,
},
{
0x00u, 0x00u,
},
{
0x00u, 0x00u,
},
};
uint8 cyBle_attValuesCCCD[CYBLE_GATT_DB_CCCD_COUNT];

CYBLE_GATTS_ATT_GEN_VAL_LEN_T cyBle_attValuesLen[CYBLE_GATT_DB_ATT_VAL_COUNT] = {
{ 0x000Bu, (void *)&cyBle_attValues[0] }, /* Device Name */
{ 0x0002u, (void *)&cyBle_attValues[11] }, /* Appearance */
{ 0x0008u, (void *)&cyBle_attValues[13] }, /* Peripheral Preferred Connection Parameters */
{ 0x0004u, (void *)&cyBle_attValues[21] }, /* Service Changed */
{ 0x0002u, (void *)&cyBle_attValuesCCCD[0] }, /* Client Characteristic Configuration */
{ 0x0001u, (void *)&cyBle_attValues[25] }, /* Alert Level */
};

const CYBLE_GATTS_DB_T cyBle_gattDB[0x0Eu] = {
{ 0x0001u, 0x2800u /* Primary service */, 0x00000001u /* */, 0x0007u, {{0x1800u, NULL}} },
{ 0x0002u, 0x2803u /* Characteristic */, 0x00000201u /* rd */, 0x0003u, {{0x2A00u, NULL}} },
{ 0x0003u, 0x2A00u /* Device Name */, 0x00000201u /* rd */, 0x0003u, {{0x000Bu, (void *)&cyBle_attValuesLen[0]}} },
{ 0x0004u, 0x2803u /* Characteristic */, 0x00000201u /* rd */, 0x0005u, {{0x2A01u, NULL}} },
{ 0x0005u, 0x2A01u /* Appearance */, 0x00000201u /* rd */, 0x0005u, {{0x0002u, (void *)&cyBle_attValuesLen[1]}} },
{ 0x0006u, 0x2803u /* Characteristic */, 0x00000201u /* rd */, 0x0007u, {{0x2A04u, NULL}} },
{ 0x0007u, 0x2A04u /* Peripheral Preferred Connection Par */, 0x00000201u /* rd */, 0x0007u, {{0x0008u, (void *)&cyBle_attValuesLen[2]}} },
{ 0x0008u, 0x2800u /* Primary service */, 0x00000001u /* */, 0x000Bu, {{0x1801u, NULL}} },
{ 0x0009u, 0x2803u /* Characteristic */, 0x00002201u /* rd,ind */, 0x000Bu, {{0x2A05u, NULL}} },
{ 0x000Au, 0x2A05u /* Service Changed */, 0x00002201u /* rd,ind */, 0x000Bu, {{0x0004u, (void *)&cyBle_attValuesLen[3]}} },
{ 0x000Bu, 0x2902u /* Client Characteristic Configuration */, 0x00000A04u /* rd,wr */, 0x000Bu, {{0x0002u, (void *)&cyBle_attValuesLen[4]}} },
{ 0x000Cu, 0x2800u /* Primary service */, 0x00000001u /* */, 0x000Eu, {{0x1802u, NULL}} },
{ 0x000Du, 0x2803u /* Characteristic */, 0x00000401u /* wwr */, 0x000Eu, {{0x2A06u, NULL}} },
{ 0x000Eu, 0x2A06u /* Alert Level */, 0x00000402u /* wwr */, 0x000Eu, {{0x0001u, (void *)&cyBle_attValuesLen[5]}} },
};


#endif /* (CYBLE_GATT_ROLE_SERVER) */

#if(CYBLE_GATT_ROLE_CLIENT)
CYBLE_CLIENT_STATE_T cyBle_clientState;
CYBLE_GATTC_T cyBle_gattc;
#endif /* (CYBLE_GATT_ROLE_CLIENT) */


#if(CYBLE_GATT_ROLE_SERVER)

/******************************************************************************
##Function Name: CyBle_GattsReInitGattDb
*******************************************************************************

Summary:
Reinitializes the GATT database.

Parameters:
None

Return:
CYBLE_API_RESULT_T: An API result states if the API succeeded or failed with
error codes:
* CYBLE_ERROR_OK: GATT database was reinitialized successfully
* CYBLE_ERROR_INVALID_STATE: If the function is called in any state except
CYBLE_STATE_DISCONNECTED.
* Any of the CyBle_GattsDbRegister() stack API function return values.

******************************************************************************/
CYBLE_API_RESULT_T CyBle_GattsReInitGattDb(void)
{
CYBLE_API_RESULT_T apiResult;
if(CYBLE_STATE_DISCONNECTED == CyBle_GetState())
{
apiResult = CyBle_GattsDbRegister(cyBle_gattDB, CYBLE_GATT_DB_INDEX_COUNT, CYBLE_GATT_DB_MAX_VALUE_LEN);
}
else
{
apiResult = CYBLE_ERROR_INVALID_STATE;
}
return(apiResult);
}


/******************************************************************************
##Function Name: CyBle_GattsWriteEventHandler
*******************************************************************************

Summary:
Handles the Write Request Event for GATT service.

Parameters:
*eventParam: The pointer to the data structure specified by the event.

Return:
* CYBLE_GATT_ERR_CODE_T: An API result returns one of the following status
values
* CYBLE_GATT_ERR_NONE - Write is successful.

******************************************************************************/
CYBLE_GATT_ERR_CODE_T CyBle_GattsWriteEventHandler(CYBLE_GATTS_WRITE_REQ_PARAM_T *eventParam)
{
CYBLE_GATT_ERR_CODE_T gattErr = CYBLE_GATT_ERR_NONE;
/* Client Characteristic Configuration descriptor write request */
if(eventParam->handleValPair.attrHandle == cyBle_gatts.cccdHandle)
{
/* Store value to database */
gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u,
&eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED);
if(CYBLE_GATT_ERR_NONE == gattErr)
{
if(CYBLE_IS_INDICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val))
{
CyBle_ApplCallback((uint32)CYBLE_EVT_GATTS_INDICATION_ENABLED, eventParam);
}
else
{
CyBle_ApplCallback((uint32)CYBLE_EVT_GATTS_INDICATION_DISABLED, eventParam);
}
}
cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK;
}
return (gattErr);
}


#endif /* (CYBLE_GATT_ROLE_SERVER) */

#if(CYBLE_GATT_ROLE_CLIENT)


/******************************************************************************
##Function Name: CyBle_GattcStartDiscovery
*******************************************************************************

Summary:
Starts the automatic server discovery process. Two events may be generated
after calling this function - CYBLE_EVT_GATTC_DISCOVERY_COMPLETE or
CYBLE_EVT_GATTC_ERROR_RSP. The CYBLE_EVT_GATTC_DISCOVERY_COMPLETE event is
generated when the remote device was successfully discovered. The
CYBLE_EVT_GATTC_ERROR_RSP is generated if the device discovery is failed.

Parameters:
connHandle: The handle which consists of the device ID and ATT connection ID.

Return:
CYBLE_API_RESULT_T : Return value indicates if the function succeeded or
failed. Following are the possible error codes.
CYBLE_ERROR_OK - On successful operation
CYBLE_ERROR_INVALID_PARAMETER - 'connHandle' value does not represent any
existing entry.
in the Stack
CYBLE_ERROR_INVALID_OPERATION - The operation is not permitted.
CYBLE_ERROR_MEMORY_ALLOCATION_FAILED - Memory allocation failed.

******************************************************************************/
CYBLE_API_RESULT_T CyBle_GattcStartDiscovery(CYBLE_CONN_HANDLE_T connHandle)
{
uint8 j;
CYBLE_API_RESULT_T apiResult;
if(CYBLE_STATE_CONNECTED != CyBle_GetState())
{
apiResult = CYBLE_ERROR_INVALID_STATE;
}
else
{
CyBle_ServiceInit();
cyBle_connHandle = connHandle;

/* Clean old discovery information */
for(j = 0u; j < (uint8) CYBLE_SRVI_COUNT; j++)
{
(void)memset(&cyBle_serverInfo[j].range, 0, sizeof(cyBle_serverInfo[0].range));
}

apiResult = CyBle_GattcDiscoverAllPrimaryServices(connHandle);

if(CYBLE_ERROR_OK == apiResult)
{
CyBle_SetClientState(CYBLE_CLIENT_STATE_SRVC_DISCOVERING);
cyBle_eventHandlerFlag |= CYBLE_AUTO_DISCOVERY;
}
}
return (apiResult);
}


/******************************************************************************
##Function Name: CyBle_GattcDiscoverCharacteristicsEventHandler
*******************************************************************************

Summary:
This function is called on receiving a "CYBLE_EVT_GATTC_READ_BY_TYPE_RSP"
event. Based on the service UUID, an appropriate data structure is populated
using the data received as part of the callback.

Parameters:
*discCharInfo: The pointer to a characteristic information structure.

Return:
None

******************************************************************************/
void CyBle_GattcDiscoverCharacteristicsEventHandler(CYBLE_DISC_CHAR_INFO_T *discCharInfo)
{
if(discCharInfo->uuid.uuid16 == CYBLE_UUID_CHAR_SERVICE_CHANGED)
{
CyBle_CheckStoreCharHandle(cyBle_gattc.serviceChanged);
}
}


/******************************************************************************
##Function Name: CyBle_GattcDiscoverCharDescriptorsEventHandler
*******************************************************************************

Summary:
This function is called on receiving a "CYBLE_EVT_GATTC_FIND_INFO_RSP" event.
Based on the descriptor UUID, an appropriate data structure is populated
using the data received as part of the callback.

Parameters:
*discDescrInfo: The pointer to a descriptor information structure.
discoveryService: The index of the service instance

Return:
None

******************************************************************************/
void CyBle_GattcDiscoverCharDescriptorsEventHandler(CYBLE_DISC_DESCR_INFO_T *discDescrInfo)
{
if(discDescrInfo->uuid.uuid16 == CYBLE_UUID_CHAR_CLIENT_CONFIG)
{
CyBle_CheckStoreCharDescrHandle(cyBle_gattc.cccdHandle);
}
}


/******************************************************************************
##Function Name: CyBle_GattcIndicationEventHandler
*******************************************************************************

Summary:
Handles the Indication Event.

Parameters:
*eventParam: The pointer to the data structure specified by the event.

Return:
None.

******************************************************************************/
void CyBle_GattcIndicationEventHandler(CYBLE_GATTC_HANDLE_VALUE_IND_PARAM_T *eventParam)
{
if(cyBle_gattc.serviceChanged.valueHandle == eventParam->handleValPair.attrHandle)
{
CyBle_ApplCallback((uint32)CYBLE_EVT_GATTC_INDICATION, eventParam);
cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK;
}
}


#endif /* (CYBLE_GATT_ROLE_CLIENT) */


/* [] END OF FILE */
(46-46/102)