芯片:CC2652
工程:ProjectZero
还在研究ProjectZero,看在datasrevice这一块的功能,利用hostTest读取dataservice的string值,ProjectZero应该利用蓝牙协议栈回复读取的请求,向hostTest发送当前string的值,但是我没找到调用BLE LIB的函数。
我有查到dataservice.c文件,Data_Service_ReadAttrCB和Data_Service_WriteAttrCB写在Data_ServiceCBs中,Data_ServiceCBs又注册到GATTServApp_RegisterService()函数中,但是这两个函数并没有调用BLE底层。同时ProjectZero.c中,收到dataservice相关数据后,是利用ProjectZero_DataService_ValueChangeHandler()函数和ProjectZero_DataService_CfgChangeHandler()两个函数处理的,似乎并没有关联到dataservice.c中的函数和功能啊,请问是怎么实现对string的读取和修改操作的呢?
z z46:
不要沉啊,求大神回复
Alvin Chen:
回复 z z46:
static bStatus_t Data_Service_WriteAttrCB(uint16_t connHandle,gattAttribute_t *pAttr,uint8_t *pValue, uint16_t len,uint16_t offset,uint8_t method)
{bStatus_t status = SUCCESS;uint8_t paramID = 0xFF;uint8_t changeParamID = 0xFF;uint16_t writeLenMin;uint16_t writeLenMax;uint16_t *pValueLenVar;
// See if request is regarding a Client Characterisic Configurationif(ATT_BT_UUID_SIZE == pAttr->type.len && GATT_CLIENT_CHAR_CFG_UUID ==*(uint16_t *)pAttr->type.uuid){Log_info3("WriteAttrCB (CCCD): param: %d connHandle: %d %s",Data_Service_findCharParamId(pAttr),connHandle,(uintptr_t)(method ==GATT_LOCAL_WRITE ? "- restoring bonded state" :"- OTA write"));
// Allow notification and indication, but do not check if really allowed per CCCD.status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,offset,GATT_CLIENT_CFG_NOTIFY |GATT_CLIENT_CFG_INDICATE);if(SUCCESS == status && pAppCBs && pAppCBs->pfnCfgChangeCb){pAppCBs->pfnCfgChangeCb(connHandle,Data_Service_findCharParamId(pAttr), len, pValue);}
return(status);}
看一下程序,追踪可以知道的pAppCBs的被注册了
z z46:
回复 Alvin Chen:
我之前也是这么查的
bStatus_t DataService_RegisterAppCBs(DataServiceCBs_t *appCallbacks)
{
if(appCallbacks)
{
pAppCBs = appCallbacks;
Log_info1("Registered callbacks to application. Struct %p",
(uintptr_t)appCallbacks);
return(SUCCESS);
}
else
{
Log_warning0("Null pointer given for app callbacks.");
return(FAILURE);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
projectzero.c中DataService_RegisterAppCBs(&ProjectZero_Data_ServiceCBs);==》》因此pAppCBs 为ProjectZero_Data_ServiceCBs。
定义:
static DataServiceCBs_t ProjectZero_Data_ServiceCBs =
{
.pfnChangeCb = ProjectZero_DataService_ValueChangeCB, // Characteristic value change callback handler
.pfnCfgChangeCb = ProjectZero_DataService_CfgChangeCB, // Noti/ind configuration callback handler
};
///////////////////////////////////////////////////////////////////////////////////////////////
pfnCfgChangeCb :
static void ProjectZero_DataService_CfgChangeCB(uint16_t connHandle,
uint8_t paramID, uint16_t len,
uint8_t *pValue)
{
Log_info1("(CB) Data Svc Char config change paramID(%d). "
"Sending msg to app.", paramID);
pzCharacteristicData_t *pValChange =
ICall_malloc(sizeof(pzCharacteristicData_t) + len);
if(pValChange != NULL)
{
pValChange->svcUUID = DATA_SERVICE_SERV_UUID;
pValChange->paramID = paramID;
memcpy(pValChange->data, pValue, len);
pValChange->dataLen = len;
if(ProjectZero_enqueueMsg(PZ_SERVICE_CFG_EVT, pValChange) != SUCCESS)//此处加入消息队列
{
ICall_freeMsg(pValChange);
}
}
}
///////////////////////////////////////////////////////////////////////////////////
处理队列消息
case PZ_SERVICE_CFG_EVT: /* Message about received CCCD write */
/* Call different handler per service */
switch(pCharData->svcUUID)
{
case BUTTON_SERVICE_SERV_UUID:
ProjectZero_ButtonService_CfgChangeHandler(pCharData);
break;
case DATA_SERVICE_SERV_UUID:
ProjectZero_DataService_CfgChangeHandler(pCharData);
break;
}
break;
////////////////////////////////////////
void ProjectZero_DataService_CfgChangeHandler(pzCharacteristicData_t *pCharData)
{
// Cast received data to uint16, as that's the format for CCCD writes.
uint16_t configValue = *(uint16_t *)pCharData->data;
char *configValString;
// Determine what to tell the user
switch(configValue)
{
case GATT_CFG_NO_OPERATION:
configValString = "Noti/Ind disabled";
break;
case GATT_CLIENT_CFG_NOTIFY:
configValString = "Notifications enabled";
break;
case GATT_CLIENT_CFG_INDICATE:
configValString = "Indications enabled";
break;
default:
configValString = "Unsupported operation";
}
switch(pCharData->paramID)
{
case DS_STREAM_ID:
Log_info3("CCCD Change msg: %s %s: %s",
(uintptr_t)"Data Service",
(uintptr_t)"Stream",
(uintptr_t)configValString);
// ————————-
// Do something useful with configValue here. It tells you whether someone
// wants to know the state of this characteristic.
// …
break;
}
}
抱歉程序太多,但是以上代码里,我仍然没有找到BLE 发射的相关程序啊,而且最后的函只有DS_STREAM_ID这一个case。。。求指导
Alvin Chen:
回复 z z46:
你所指的BLE发送程序是什么?这部分是不开源的,只能通过GATT profile 来操作,读写请求都是通过CB直接操作的,
你仔细看程序Data_Service_ReadAttrCB,通过区分不同的UUID,复制到底层被取走,你能使用发送函数只是类似于:// Try to send notification.GATTServApp_ProcessCharCfg(attrConfig, pAttrVal, needAuth,Data_ServiceAttrTbl,GATT_NUM_ATTRS(Data_ServiceAttrTbl),ds_icall_rsp_task_id,Data_Service_ReadAttrCB);这样的notification或者indication。
z z46:
回复 Alvin Chen:
我查看了Dataservice.c,其中确实有将CBs注册到GATT层的函数。GATTServApp_RegisterService(Data_ServiceAttrTbl, GATT_NUM_ATTRS(Data_ServiceAttrTbl),GATT_MAX_ENCRYPT_KEY_SIZE, &Data_ServiceCBs);
但是GATT层是如何调用这些CBs呢?利用什么事件来触发呢?
以及,另有一件事想和您确认下,APP层的处理(即projectzero.c中)似乎只做了串口打印日志的动作,与GATT层的关联是在dataservice.c中的函数的,请问是这样吗?
Alvin Chen:
回复 z z46:
GATTServApp_RegisterService这种函数是不开源的
GATT 处理都是在对应的service里面操作的。
z z46:
回复 Alvin Chen:
“GATT 处理都是在对应的service里面操作的。"—->service就是指service函数吗,例如Data_Service_ReadAttrCB和Data_Service_WriteAttrCB这两个函数?
z z46:
回复 Alvin Chen:
不要沉啊,仍然在等回答的我
YiKai Chen:
回复 z z46:
建議你讀一下 SimpleLink Academy 蓝牙的部分
Alvin Chen:
回复 z z46:
我们TI编写了一部分Bluetooth的入门简介建议你去看一下:
dev.ti.com/…/