- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我的问题是:
Livolo 开关有自己的 Zigbee 门。我想用 CC2531 USB 加密狗从 zigbee2mqtt 连接它们。通常它可以工作,但是当我打开/关闭开关按钮(在物理设备上)时,开关发送了不正确的 ZCL 包。
我绝对是微 Controller 编程和 Zigbee 架构方面的新手。所以我希望有人能帮助我并回答这些问题:
我使用 Z-STACK-HOME 1.2.2a 固件并按照此处所述进行编译: https://github.com/Koenkk/Z-Stack-firmware/blob/master/coordinator/Z-Stack_Home_1.2/COMPILE.md
// Malformed ZCL package
// header
0x7c, // [0111 1100]
// 01 - frame type = "Command is specific or local to a cluster"
// 1 - manufacturer spec = manufacturer code present
// 1 - direction = "from server to client"
// 1 - disable default response
// 100 - reserved
0xd2, 0x15, // manufacturer
0xd8, // sequence
0x00, // read attrs command
// endpoint adress
0x12, 0x0f, 0x05, 0x18, 0x00, 0x4b, 0x12, 0x00,
0x22, 0x00, // ????? need more data from another switches
0x03 // 0x00|0x01|0x02|0x03 - switch state
更新:我认为,我可以在 afIncomingData 函数中拦截 AF.c 文件中的消息并在 afBuildMSGIncoming 中修复。
所以现在我希望有人可以帮助我确定正确的消息格式。可以处理标准 ZCL parcer。
void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,
NLDE_Signal_t *sig, uint8 nwkSeqNum, uint8 SecurityUse,
uint32 timestamp, uint8 radius )
{
endPointDesc_t *epDesc = NULL;
epList_t *pList = epList;
#if !defined ( APS_NO_GROUPS )
uint8 grpEp = APS_GROUPS_EP_NOT_FOUND;
#endif
if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
{
#if !defined ( APS_NO_GROUPS )
// Find the first endpoint for this group
grpEp = aps_FindGroupForEndpoint( aff->GroupID, APS_GROUPS_FIND_FIRST );
if ( grpEp == APS_GROUPS_EP_NOT_FOUND ) {
// No endpoint found, default to endpoint 1.
// In the original source code there is a return here.
// This prevent the messags from being forwarded.
// For our use-case we want to capture all messages.
// Even if the coordinator is not in the group.
epDesc = afFindEndPointDesc( 1 );
}
else {
epDesc = afFindEndPointDesc( grpEp );
}
if ( epDesc == NULL )
return; // Endpoint descriptor not found
pList = afFindEndPointDescList( epDesc->endPoint );
#else
return; // Not supported
#endif
}
else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
{
// Set the list
if ( pList != NULL )
{
epDesc = pList->epDesc;
}
}
else if ( aff->DstEndPoint == 10 || aff->DstEndPoint == 11 ) {
if ( (epDesc = afFindEndPointDesc( 1 )) )
{
pList = afFindEndPointDescList( epDesc->endPoint );
}
}
else if ( (epDesc = afFindEndPointDesc( aff->DstEndPoint )) )
{
pList = afFindEndPointDescList( epDesc->endPoint );
}
while ( epDesc )
{
uint16 epProfileID = 0xFFFE; // Invalid Profile ID
if ( pList->pfnDescCB )
{
uint16 *pID = (uint16 *)(pList->pfnDescCB(
AF_DESCRIPTOR_PROFILE_ID, epDesc->endPoint ));
if ( pID )
{
epProfileID = *pID;
osal_mem_free( pID );
}
}
else if ( epDesc->simpleDesc )
{
epProfileID = epDesc->simpleDesc->AppProfId;
}
// First part of verification is to make sure that:
// the local Endpoint ProfileID matches the received ProfileID OR
// the message is specifically send to ZDO (this excludes the broadcast endpoint) OR
// if the Wildcard ProfileID is received the message should not be sent to ZDO endpoint
if ( (aff->ProfileID == epProfileID) ||
((epDesc->endPoint == ZDO_EP) && (aff->ProfileID == ZDO_PROFILE_ID)) ||
((epDesc->endPoint != ZDO_EP) && ( aff->ProfileID == ZDO_WILDCARD_PROFILE_ID )) )
{
// Save original endpoint
uint8 endpoint = aff->DstEndPoint;
// overwrite with descriptor's endpoint
aff->DstEndPoint = epDesc->endPoint;
afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig,
nwkSeqNum, SecurityUse, timestamp, radius );
// Restore with original endpoint
aff->DstEndPoint = endpoint;
}
if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
{
#if !defined ( APS_NO_GROUPS )
// Find the next endpoint for this group
grpEp = aps_FindGroupForEndpoint( aff->GroupID, grpEp );
if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
return; // No endpoint found
epDesc = afFindEndPointDesc( grpEp );
if ( epDesc == NULL )
return; // Endpoint descriptor not found
pList = afFindEndPointDescList( epDesc->endPoint );
#else
return;
#endif
}
else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
{
pList = pList->nextDesc;
if ( pList )
epDesc = pList->epDesc;
else
epDesc = NULL;
}
else
epDesc = NULL;
}
}
static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
zAddrType_t *SrcAddress, uint16 SrcPanId, NLDE_Signal_t *sig,
uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp, uint8 radius )
{
afIncomingMSGPacket_t *MSGpkt;
const uint8 len = sizeof( afIncomingMSGPacket_t ) + aff->asduLength;
uint8 *asdu = aff->asdu;
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_allocate( len );
if ( MSGpkt == NULL )
{
return;
}
MSGpkt->hdr.event = AF_INCOMING_MSG_CMD;
MSGpkt->groupId = aff->GroupID;
MSGpkt->clusterId = aff->ClusterID;
afCopyAddress( &MSGpkt->srcAddr, SrcAddress );
MSGpkt->srcAddr.endPoint = aff->SrcEndPoint;
MSGpkt->endPoint = epDesc->endPoint;
MSGpkt->wasBroadcast = aff->wasBroadcast;
MSGpkt->LinkQuality = sig->LinkQuality;
MSGpkt->correlation = sig->correlation;
MSGpkt->rssi = sig->rssi;
MSGpkt->SecurityUse = SecurityUse;
MSGpkt->timestamp = timestamp;
MSGpkt->nwkSeqNum = nwkSeqNum;
MSGpkt->macSrcAddr = aff->macSrcAddr;
MSGpkt->macDestAddr = aff->macDestAddr;
MSGpkt->srcAddr.panId = SrcPanId;
MSGpkt->cmd.TransSeqNumber = 0;
MSGpkt->cmd.DataLength = aff->asduLength;
MSGpkt->radius = radius;
if ( MSGpkt->cmd.DataLength )
{
MSGpkt->cmd.Data = (uint8 *)(MSGpkt + 1);
osal_memcpy( MSGpkt->cmd.Data, asdu, MSGpkt->cmd.DataLength );
}
else
{
MSGpkt->cmd.Data = NULL;
}
#if defined ( MT_AF_CB_FUNC )
// If ZDO or SAPI have registered for this endpoint, dont intercept it here
if (AFCB_CHECK(CB_ID_AF_DATA_IND, *(epDesc->task_id)))
{
MT_AfIncomingMsg( (void *)MSGpkt );
// Release the memory.
osal_msg_deallocate( (void *)MSGpkt );
}
else
#endif
{
// Send message through task message.
osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );
}
}
最佳答案
我认为您没有正确解码帧控制字节。查看我编写的一些代码,我将其解释如下:
0x7c, // [0111 1100]
// 011 - reserved
// 1 - disable default response
// 1 - direction = "from server to client"
// 1 - manufacturer spec = manufacturer code present
// 00 - frame type = "Command acts across entire profile"
这是基于旧的 ZCL 规范(大约 2008 年?),也许保留位在规范的更高版本中具有某种意义。
我相信制造商特定位表明这不是标准 Zigbee 命令(读取属性)。如果它是读取属性,我认为它后面应该有偶数个字节(16 位属性 ID)。
该帧的源端点和目标端点、配置文件 ID 和集群 ID 是什么?
更新:看起来你可以修改 afIncomingData()
来查看 aff
的字段来识别这个确切的消息类型(帧控制、端点、集群、配置文件),然后手它交给您自己的函数进行处理(并在必要时做出响应)。
但我还会查看有关 MT_AF_CB_FUNC
和 MT_AfIncomingMsg()
的文档,看看这是否是识别您要处理的帧的“官方”方式在您自己的代码中。
关于c - CC253x 固件的非标准 ZCL 封装支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57925570/
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclStatus类的一些代码示例,展示了ZclStatus类的具体用法。这些代码示例主要来源于Github/Stacko
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclAttribute类的一些代码示例,展示了ZclAttribute类的具体用法。这些代码示例主要来源于Github/
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclCluster类的一些代码示例,展示了ZclCluster类的具体用法。这些代码示例主要来源于Github/Stac
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclTransactionMatcher类的一些代码示例,展示了ZclTransactionMatcher类的具体用法。
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclCommand类的一些代码示例,展示了ZclCommand类的具体用法。这些代码示例主要来源于Github/Stac
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclHeader类的一些代码示例,展示了ZclHeader类的具体用法。这些代码示例主要来源于Github/Stacko
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclFieldDeserializer类的一些代码示例,展示了ZclFieldDeserializer类的具体用法。这些
我的问题是: Livolo 开关有自己的 Zigbee 门。我想用 CC2531 USB 加密狗从 zigbee2mqtt 连接它们。通常它可以工作,但是当我打开/关闭开关按钮(在物理设备上)时,开关
本文整理了Java中com.zsmartsystems.zigbee.zcl.protocol.ZclDataType类的一些代码示例,展示了ZclDataType类的具体用法。这些代码示例主要来源于
本文整理了Java中com.zsmartsystems.zigbee.zcl.clusters.ZclLevelControlCluster类的一些代码示例,展示了ZclLevelControlClu
本文整理了Java中com.zsmartsystems.zigbee.zcl.protocol.ZclClusterType类的一些代码示例,展示了ZclClusterType类的具体用法。这些代码示
本文整理了Java中com.zsmartsystems.zigbee.zcl.clusters.ZclOnOffCluster类的一些代码示例,展示了ZclOnOffCluster类的具体用法。这些代
本文整理了Java中com.zsmartsystems.zigbee.zcl.clusters.ZclOtaUpgradeCluster类的一些代码示例,展示了ZclOtaUpgradeCluster
本文整理了Java中com.zsmartsystems.zigbee.zcl.clusters.ZclBasicCluster类的一些代码示例,展示了ZclBasicCluster类的具体用法。这些代
本文整理了Java中com.zsmartsystems.zigbee.zcl.clusters.ZclRelativeHumidityMeasurementCluster类的一些代码示例,展示了Zcl
本文整理了Java中com.zsmartsystems.zigbee.zcl.clusters.ZclColorControlCluster类的一些代码示例,展示了ZclColorControlClu
本文整理了Java中com.zsmartsystems.zigbee.zcl.clusters.ZclOccupancySensingCluster类的一些代码示例,展示了ZclOccupancySe
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclStatus.getStatus()方法的一些代码示例,展示了ZclStatus.getStatus()的具体用法。
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclStatus.getId()方法的一些代码示例,展示了ZclStatus.getId()的具体用法。这些代码示例主要
本文整理了Java中com.zsmartsystems.zigbee.zcl.ZclAttribute.isLastValueCurrent()方法的一些代码示例,展示了ZclAttribute.is
我是一名优秀的程序员,十分优秀!