初次接触TI的CC2640BLE,如何在CC2640中添加一个service,该笔记大概记录了添加一个service的详细过程,在学习这部分内容要参考《SimpleLink Bluetooth low energy CC2640 wireless MCU》
```
#define TESTBLESERVICEUUID 0x1666
#define TESTBLEDATA_UUID 0x1868
#define TEST_BLE_DATA_LEN 10
#define TESTBLE_CHANGEPOT_CHECK 0
/*****************************************以下是关于UUID以及全局变量*********************************************/
// Service UUID
static const uint8_t TestBLEServiceUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(TESTBLESERVICEUUID),HI_UINT16(TESTBLESERVICEUUID)
};
static const uint8_t TestBleDataUUID[ATT_BT_UUID_SIZE]=
{
LO_UINT16(TESTBLEDATA_UUID),HI_UINT16(TESTBLEDATA_UUID)
};
static gattCharCfg_t *TestConfig;
static uint8_t TestBleDsp[] = "Test for snowstrom";
//Profile Service attribute
static CONST gattAttrType_t TestBLEService = {ATT_BT_UUID_SIZE,TestBLEServiceUUID};
//Charateristic Properties:data
static uint8_t TestBLEProps = GATT_PROP_READ | GATT_PROP_NOTIFY ;
static uint8_t TestBleData[TEST_BLE_DATA_LEN]={0xa0,0xb0,0xc0,0xd0};
/****************************************功能函数*************************************************/
第一步:Add Service Function
bStatus_t SnowstormService(void)
{
//Allocate Client Characteristic Configuration table.
TestConfig = (gattCharCfg_t *) ICall_malloc(sizeof(gattCharCfg_t)*linkDBNumConns);// 如果不配置notifie ,该函数以及下面的GATTServApp_InitCharCfg可以不调用
if(TestConfig == NULL) // 为notifie开辟内存空间
{
return bleMemAllocError;
}
//Initialize Client Characteristic Configuration attributes.
GATTServApp_InitCharCfg(INVALID_CONNHANDLE,TestConfig); //This function will attempt to initialize the CCC`s with information from a
//Register GATT attribute list and CBs with GATT App // previously bonded connection and,if not found,set the intial
return GATTServApp_RegisterService(TestAttrTable, //values to default values
GATT_NUM_ATTRS(TestAttrTable),
GATT_MAX_ENCRYPT_KEY_SIZE,
&TestBleDataCBs);
}
第二步:Attribute Table Definition
/*profile Attributes -Table*/
static gattAttribute_t TestAttrTable[]=
{
//Service declaration ,primary service UUID 0x2800
{
{ATT_BT_UUID_SIZE,primaryServiceUUID}, /*type*/
GATT_PERMIT_READ, /*permissions*/
0, /*handle*/
(uint8_t*)&TestBLEService /*pValue,0x1666*/
},
//Characteristic declaration ,characterUUID 0x2803,添加notifie
{
{ATT_BT_UUID_SIZE,characterUUID},
GATT_PERMIT_READ,
0,
&TestBLEProps
},
//Charateristic Value "Data",UUID:0x1868
{
{ATT_BT_UUID_SIZE,TestBleDataUUID},
GATT_PERMIT_READ,
0,
(uint8_t*)TestBleData
},
//Client Charateristic configuration
{
{ATT_BT_UUID_SIZE,clientCharCfgUUID}, //2902
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8_t *)&TestConfig
},
//Charateristic User Description
{
{ATT_BT_UUID_SIZE,charUserDescUUID},
GATT_PERMIT_READ,
0,
TestBleDsp
},
};
第三步:Register Application callback function
// Profile calllbacks
static CONST gattServiceCBs_t TestBleDataCBs =
{
TestBle_ReadAttrCB, //读回调
TestBle_WriteAttrCB, //写回调
NULL
};
/*********蓝牙控制器把采集的数据发送给手机*********/
static bStatus_t TestBle_ReadAttrCB(uint16_t connHandle,gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen,
uint16_t offset, uint16_t maxLen,
uint8_t method)
{
uint16_t uuid;
bStatus_t status = SUCCESS;
// If attribute permissions require authorization to read, return error
if (gattPermitAuthorRead(pAttr->permissions))
{
// Insufficient authorization
return (ATT_ERR_INSUFFICIENT_AUTHOR);
}
// Make sure it's not a blob operation (no attributes in the profile are long)
if (offset > 0)
{
return (ATT_ERR_ATTR_NOT_LONG);
}
if (utilExtractUuid16(pAttr,&uuid) == FAILURE) {
// Invalid handle
*pLen = 0;
return ATT_ERR_INVALID_HANDLE;
}
switch(uuid)
{
// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
// gattserverapp handles those reads
case TESTBLEDATA_UUID: //1868
*pLen = TEST_BLE_DATA_LEN;
memcpy(pValue, pAttr->pValue, TEST_BLE_DATA_LEN);
break;
default:
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
return (status);
}
/*控制器读取手机端的数据*/
static bStatus_t TestBle_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len,
uint16_t offset, uint8_t method)
{
uint16_t uuid;
bStatus_t status = SUCCESS;
uint8_t notifyApp = 0xFF;
//If attribute permissions require authorization to read ,read return error
if(gattPermitAuthorWrite(pAttr->permissions))
{
//Insufficient authorization
return ATT_ERR_INSUFFICIENT_AUTHOR;
}
if(utilExtractUuid16(pAttr,&uuid) == FAILURE)
{
//Invalid handle
return ATT_ERR_INVALID_HANDLE;
}
switch(uuid)
{
case GATT_CLIENT_CHAR_CFG_UUID: //2902
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY);
break;
default:
//should nerver get here!
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
// If a characteristic value changed then callback function
// to notify application of change
if ((notifyApp != 0xFF ) && sensor_AppCBs && sensor_AppCBs->pfnSensorChange)
{
sensor_AppCBs->pfnSensorChange(notifyApp);
}
return status;
}
第四步:数据传输函数,想通过的BLE发送的数据,通过此函数来完成。
bStatus_t TestBle_setParameter(uint8_t param,uint8_t len,void *value)
{
bStatus_t ret = SUCCESS;
switch (param)
{
case TESTBLE_CHANGEPOT_CHECK:
if(len == TEST_BLE_DATA_LEN)
{
memcpy(TestBleData,value,TEST_BLE_DATA_LEN);
//see if notifiaction has been enabled
ret = GATTServApp_ProcessCharCfg(TestConfig,TestBleData,FALSE,
TestAttrTable,
GATT_NUM_ATTRS(TestAttrTable),
INVALID_TASK_ID,TestBle_ReadAttrCB);
}
else
{
ret = bleInvalidRange;
}
break;
default :
ret = INVALIDPARAMETER;
break;
}
return ret;
}
```
阅读(3183) | 评论(0) | 转发(0) |