Thread 中讨论的其他器件:CC2640、 CC2650
我们有一个基于 SimplePeripheral 示例的项目。 我们希望能够通过 BLE 读取一些经常变化的值、例如 CC2652的 RTC 的器件时间。 我们希望能够在读取时按需获取数据、而不是不断更新缓冲区以确保这些值在读取时是最新的。 我猜到,正确的方法是在 SimplePeripheral_ReadAttrCB()中返回 blePending,如下所示:
// See if request is regarding the Clock Characteristic Value
if ( ! memcmp(pAttr->type.uuid, MyService_ClockUUID, pAttr->type.len) )
{
if ( offset > MYSERVICE_CLOCK_LEN ) // Prevent malicious ATT ReadBlob offsets.
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
if ( pAppCBs && pAppCBs->pfnReadCb )
pAppCBs->pfnReadCb(connHandle, MYSERVICE_CLOCK_ID); // Call app function from stack task context.
return blePending;
}
}
其中我创建了 pAppCBs->pfnReadCb(),与对 SimplePeripheral_WriteAttrCB()执行应用程序回调的方式相同。 这将为我们的应用程序任务排队一条消息,并由 SimplePeripheral_processAppMsg()处理,后者会调用以下函数:
static void MyService_processValueReadEvt(MyServiceReadCharacteristic_t *pData)
{
switch(pData->paramID)
{
case MYSERVICE_CLOCK_ID:
{
bStatus_t status;
attReadRsp_t clockRsp;
uint16_t len;
clockRsp.pValue = (uint8 *)GATT_bm_alloc( pData->connHandle, ATT_READ_RSP, MYSERVICE_CLOCK_LEN, &len );
if ( clockRsp.pValue != NULL )
{
if (len != MYSERVICE_CLOCK_LEN)
{
GATT_bm_free( (gattMsg_t *)&clockRsp, ATT_READ_RSP );
// TODO: couldn't allocate enough memory, but we still have to tell the BLE stack something to end "blePending", right?
}
else
{
uint32_t time = Seconds_get();
memcpy(clockRsp.pValue, &time, len);
clockRsp.len = len;
status = ATT_ReadRsp(pData->connHandle, &clockRsp);
if ( status != SUCCESS )
{
GATT_bm_free( (gattMsg_t *)&clockRsp, ATT_READ_RSP );
// TODO: we failed to return the data for some reason; does the BLE stack still need us to do anything?
}
}
}
else
{
// TODO: couldn't allocate any memory, but we still have to tell the BLE stack something, right?
}
}
break;
我的第一个问题是:这是正确的方法吗? 我不得不进行一些挖掘以找到 attReadRsp_t 和 ATT_ReadRsp()。 我已经测试过这种方法、但它可以正常工作、因此我知道我至少处于正确的轨道上。
我的第二个问题是:假设上述内容正确、我需要调用什么来代替代码中的注释? 如果我无法分配将读取响应发送回 BLE 堆栈所需的存储器、我假设我仍需要 执行一些操作 、这样它就不会一直处于"待处理"状态、对吧? 如果 ATT_ReadRsp()不成功,我们是否仍然需要做一些事情来防止堆栈等待成功?