392 lines
9.7 KiB
C
392 lines
9.7 KiB
C
/*
|
|
thservice.c
|
|
*/
|
|
|
|
/*********************************************************************
|
|
INCLUDES
|
|
*/
|
|
#include "types.h"
|
|
#include "config.h"
|
|
#if (DEV_SERVICES & SERVICE_THS)
|
|
#include "bcomdef.h"
|
|
#include "OSAL.h"
|
|
#include "linkdb.h"
|
|
#include "att.h"
|
|
#include "gatt.h"
|
|
#include "gatt_uuid.h"
|
|
#include "gatt_profile_uuid.h"
|
|
#include "gattservapp.h"
|
|
#include "peripheral.h"
|
|
//#include "hiddev.h"
|
|
|
|
#include "thservice.h"
|
|
#include "sensor.h"
|
|
/*********************************************************************
|
|
MACROS
|
|
*/
|
|
/*********************************************************************
|
|
CONSTANTS
|
|
*/
|
|
|
|
#define TEMP_LEVEL_VALUE_IDX 2 // Position of temp level in attribute array
|
|
#define TEMP_LEVEL_VALUE_CCCD_IDX 3 // Position of temp level CCCD in attribute array
|
|
#define HUMI_LEVEL_VALUE_IDX 5 // Position of humi level in attribute array
|
|
#define HUMI_LEVEL_VALUE_CCCD_IDX 6 // Position of humi level CCCD in attribute array
|
|
|
|
/*********************************************************************
|
|
TYPEDEFS
|
|
*/
|
|
|
|
/*********************************************************************
|
|
GLOBAL VARIABLES
|
|
*/
|
|
// Battery service
|
|
CONST uint8 temphumServUUID[ATT_BT_UUID_SIZE] =
|
|
{
|
|
LO_UINT16(ENV_SENSING_SERV_UUID), HI_UINT16(ENV_SENSING_SERV_UUID)
|
|
};
|
|
|
|
// Temperatyre level characteristic
|
|
CONST uint8 tempLevelUUID[ATT_BT_UUID_SIZE] =
|
|
{
|
|
LO_UINT16(TEMPERATYRE_UUID), HI_UINT16(TEMPERATYRE_UUID)
|
|
};
|
|
|
|
// Humidity level characteristic
|
|
CONST uint8 humiLevelUUID[ATT_BT_UUID_SIZE] =
|
|
{
|
|
LO_UINT16(HUMIDITY_UUID), HI_UINT16(HUMIDITY_UUID)
|
|
};
|
|
|
|
|
|
/*********************************************************************
|
|
EXTERNAL VARIABLES
|
|
*/
|
|
|
|
/*********************************************************************
|
|
EXTERNAL FUNCTIONS
|
|
*/
|
|
|
|
/*********************************************************************
|
|
LOCAL VARIABLES
|
|
*/
|
|
|
|
// Application callback
|
|
static thServiceCB_t thServiceCB;
|
|
|
|
/*********************************************************************
|
|
Profile Attributes - variables
|
|
*/
|
|
|
|
// TH Service attribute
|
|
static CONST gattAttrType_t thService = { ATT_BT_UUID_SIZE, temphumServUUID };
|
|
|
|
// TH level characteristic
|
|
static uint8 thProps = GATT_PROP_READ | GATT_PROP_NOTIFY;
|
|
|
|
static gattCharCfg_t tempLevelClientCharCfg[GATT_MAX_NUM_CONN];
|
|
static gattCharCfg_t humiLevelClientCharCfg[GATT_MAX_NUM_CONN];
|
|
|
|
|
|
/*********************************************************************
|
|
Profile Attributes - Table
|
|
*/
|
|
|
|
static gattAttribute_t thAttrTbl[] =
|
|
{
|
|
// 0 TH Service
|
|
{
|
|
{ ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
|
|
GATT_PERMIT_READ, /* permissions */
|
|
0, /* handle */
|
|
(uint8*)& thService /* pValue */
|
|
},
|
|
|
|
// 1 Temp Level Declaration
|
|
{
|
|
{ ATT_BT_UUID_SIZE, characterUUID },
|
|
GATT_PERMIT_READ,
|
|
0,
|
|
&thProps
|
|
},
|
|
|
|
// 2 Temp Level Value
|
|
{
|
|
{ ATT_BT_UUID_SIZE, tempLevelUUID },
|
|
GATT_PERMIT_READ,
|
|
0,
|
|
(uint8_t*)&measured_data.temp
|
|
},
|
|
|
|
// 3 Temp Level Client Characteristic Configuration
|
|
{
|
|
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
|
|
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
|
|
0,
|
|
(uint8*)& tempLevelClientCharCfg
|
|
},
|
|
|
|
// 4 Humi Level Declaration
|
|
{
|
|
{ ATT_BT_UUID_SIZE, characterUUID },
|
|
GATT_PERMIT_READ,
|
|
0,
|
|
&thProps
|
|
},
|
|
|
|
// 5 Humi Level Value
|
|
{
|
|
{ ATT_BT_UUID_SIZE, humiLevelUUID },
|
|
GATT_PERMIT_READ,
|
|
0,
|
|
(uint8_t*)&measured_data.humi
|
|
},
|
|
|
|
// 6 Humi Level Client Characteristic Configuration
|
|
{
|
|
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
|
|
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
|
|
0,
|
|
(uint8*)& humiLevelClientCharCfg
|
|
},
|
|
|
|
};
|
|
|
|
|
|
/*********************************************************************
|
|
LOCAL FUNCTIONS
|
|
*/
|
|
static uint8 thReadAttrCB( uint16 connHandle, gattAttribute_t* pAttr,
|
|
uint8* pValue, uint16* pLen, uint16 offset, uint8 maxLen );
|
|
static bStatus_t thWriteAttrCB( uint16 connHandle, gattAttribute_t* pAttr,
|
|
uint8* pValue, uint16 len, uint16 offset );
|
|
static void thNotifyCB( linkDBItem_t* pLinkItem );
|
|
|
|
/*********************************************************************
|
|
PROFILE CALLBACKS
|
|
*/
|
|
// TH Service Callbacks
|
|
CONST gattServiceCBs_t thCBs =
|
|
{
|
|
thReadAttrCB, // Read callback function pointer
|
|
thWriteAttrCB, // Write callback function pointer
|
|
NULL // Authorization callback function pointer
|
|
};
|
|
|
|
/*********************************************************************
|
|
PUBLIC FUNCTIONS
|
|
*/
|
|
|
|
/*********************************************************************
|
|
@fn TH_AddService
|
|
|
|
@brief Initializes the Battery Service by registering
|
|
GATT attributes with the GATT server.
|
|
|
|
@return Success or Failure
|
|
*/
|
|
bStatus_t TH_AddService( void )
|
|
{
|
|
uint8 status = SUCCESS;
|
|
// Initialize Client Characteristic Configuration attributes
|
|
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, tempLevelClientCharCfg );
|
|
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, humiLevelClientCharCfg );
|
|
// Register GATT attribute list and CBs with GATT Server App
|
|
status = GATTServApp_RegisterService( thAttrTbl,
|
|
GATT_NUM_ATTRS( thAttrTbl ),
|
|
&thCBs );
|
|
return ( status );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn Batt_Register
|
|
|
|
@brief Register a callback function with the Battery Service.
|
|
|
|
@param pfnServiceCB - Callback function.
|
|
|
|
@return None.
|
|
*/
|
|
extern void TH_Register( thServiceCB_t pfnServiceCB )
|
|
{
|
|
thServiceCB = pfnServiceCB;
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn thReadAttrCB
|
|
|
|
@brief Read an attribute.
|
|
|
|
@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
|
|
|
|
@return Success or Failure
|
|
*/
|
|
static uint8 thReadAttrCB( uint16 connHandle, gattAttribute_t* pAttr,
|
|
uint8* pValue, uint16* pLen, uint16 offset, uint8 maxLen )
|
|
{
|
|
(void)connHandle;
|
|
(void)maxLen;
|
|
bStatus_t status = SUCCESS;
|
|
|
|
// 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] );
|
|
|
|
// Measure temp level if reading level
|
|
if ( uuid == TEMPERATYRE_UUID )
|
|
{
|
|
*pLen = 2;
|
|
pValue[0] = measured_data.temp;
|
|
pValue[1] = measured_data.temp >> 8;
|
|
}
|
|
// Measure humi level if reading level
|
|
else if ( uuid == HUMIDITY_UUID)
|
|
{
|
|
*pLen = 2;
|
|
pValue[0] = measured_data.humi;
|
|
pValue[1] = measured_data.humi >> 8;
|
|
}
|
|
else
|
|
{
|
|
status = ATT_ERR_ATTR_NOT_FOUND;
|
|
}
|
|
return ( status );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn thWriteAttrCB
|
|
|
|
@brief Validate attribute data prior to a write operation
|
|
|
|
@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
|
|
*/
|
|
static bStatus_t thWriteAttrCB( uint16 connHandle, gattAttribute_t* pAttr,
|
|
uint8* pValue, uint16 len, uint16 offset )
|
|
{
|
|
bStatus_t status = SUCCESS;
|
|
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
|
|
|
switch ( uuid )
|
|
{
|
|
case 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] );
|
|
|
|
if ( thServiceCB )
|
|
{
|
|
(*thServiceCB)( (charCfg == GATT_CFG_NO_OPERATION) ?
|
|
TEMP_LEVEL_NOTI_DISABLED :
|
|
TEMP_LEVEL_NOTI_ENABLED);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
status = ATT_ERR_ATTR_NOT_FOUND;
|
|
break;
|
|
}
|
|
|
|
return ( status );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn thNotifyCB
|
|
|
|
@brief Send a notification of the level state characteristic.
|
|
|
|
@param connHandle - linkDB item
|
|
|
|
@return None.
|
|
*/
|
|
static void thNotifyCB( linkDBItem_t* pLinkItem )
|
|
{
|
|
attHandleValueNoti_t noti;
|
|
|
|
if ( pLinkItem->stateFlags & LINK_CONNECTED )
|
|
{
|
|
if ( GATTServApp_ReadCharCfg( pLinkItem->connectionHandle,
|
|
tempLevelClientCharCfg )
|
|
& GATT_CLIENT_CFG_NOTIFY )
|
|
{
|
|
noti.handle = thAttrTbl[TEMP_LEVEL_VALUE_IDX].handle;
|
|
noti.len = 2;
|
|
noti.value[0] = measured_data.temp;
|
|
noti.value[1] = measured_data.temp >> 8;
|
|
GATT_Notification( pLinkItem->connectionHandle, ¬i, FALSE );
|
|
}
|
|
|
|
if ( GATTServApp_ReadCharCfg( pLinkItem->connectionHandle,
|
|
humiLevelClientCharCfg )
|
|
& GATT_CLIENT_CFG_NOTIFY )
|
|
{
|
|
noti.handle = thAttrTbl[HUMI_LEVEL_VALUE_IDX].handle;
|
|
noti.len = 2;
|
|
noti.value[0] = measured_data.humi;
|
|
noti.value[1] = measured_data.humi >> 8;
|
|
GATT_Notification( pLinkItem->connectionHandle, ¬i, FALSE );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn thNotifyLevelState
|
|
|
|
@brief Send a notification of the th state
|
|
characteristic if a connection is established.
|
|
|
|
@return None.
|
|
*/
|
|
void TH_NotifyLevel(void)
|
|
{
|
|
// Execute linkDB callback to send notification
|
|
linkDB_PerformFunc( thNotifyCB );
|
|
}
|
|
|
|
/*********************************************************************
|
|
@fn TH_HandleConnStatusCB
|
|
|
|
@brief TH Service link status change handler function.
|
|
|
|
@param connHandle - connection handle
|
|
@param changeType - type of change
|
|
|
|
@return none
|
|
*/
|
|
void TH_HandleConnStatusCB( uint16 connHandle, uint8 changeType )
|
|
{
|
|
// Make sure this is not loopback connection
|
|
if ( connHandle != LOOPBACK_CONNHANDLE )
|
|
{
|
|
// Reset Client Char Config if connection has dropped
|
|
if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
|
|
( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
|
|
( !linkDB_Up( connHandle ) ) ) )
|
|
{
|
|
GATTServApp_InitCharCfg( connHandle, tempLevelClientCharCfg );
|
|
GATTServApp_InitCharCfg( connHandle, humiLevelClientCharCfg );
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // (DEV_SERVICES & SERVICE_THS)
|
|
|