mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 12:46:34 +00:00
Merge pull request #8862 from s-hadinger/zigbee_july_5
Zigbee EZSP support for bindings and groups
This commit is contained in:
commit
d612d2b62e
@ -461,6 +461,7 @@ enum EZSP_ZDO {
|
|||||||
// Network Management Server Services Requests
|
// Network Management Server Services Requests
|
||||||
ZDO_Mgmt_Lqi_req = 0x0031,
|
ZDO_Mgmt_Lqi_req = 0x0031,
|
||||||
ZDO_Mgmt_Rtg_req = 0x0032,
|
ZDO_Mgmt_Rtg_req = 0x0032,
|
||||||
|
ZDO_Mgmt_Bind_req = 0x0033,
|
||||||
ZDO_Mgmt_Leave_req = 0x0034,
|
ZDO_Mgmt_Leave_req = 0x0034,
|
||||||
ZDO_Mgmt_Permit_Joining_req = 0x0036,
|
ZDO_Mgmt_Permit_Joining_req = 0x0036,
|
||||||
ZDO_Mgmt_NWK_Update_req = 0x0038,
|
ZDO_Mgmt_NWK_Update_req = 0x0038,
|
||||||
@ -496,6 +497,7 @@ enum EZSP_ZDO {
|
|||||||
// Network Management Server Services Responses
|
// Network Management Server Services Responses
|
||||||
ZDO_Mgmt_Lqi_rsp = 0x8031,
|
ZDO_Mgmt_Lqi_rsp = 0x8031,
|
||||||
ZDO_Mgmt_Rtg_rsp = 0x8032,
|
ZDO_Mgmt_Rtg_rsp = 0x8032,
|
||||||
|
ZDO_Mgmt_Bind_rsp = 0x8033,
|
||||||
ZDO_Mgmt_Leave_rsp = 0x8034,
|
ZDO_Mgmt_Leave_rsp = 0x8034,
|
||||||
ZDO_Mgmt_Permit_Joining_rsp = 0x8036,
|
ZDO_Mgmt_Permit_Joining_rsp = 0x8036,
|
||||||
ZDO_Mgmt_NWK_Update_rsp = 0x8038,
|
ZDO_Mgmt_NWK_Update_rsp = 0x8038,
|
||||||
@ -1106,6 +1108,34 @@ typedef struct Z_StatusLine {
|
|||||||
const char * status_msg;
|
const char * status_msg;
|
||||||
} Z_StatusLine;
|
} Z_StatusLine;
|
||||||
|
|
||||||
|
|
||||||
|
// ZDP Enumeration, see Zigbee spec 2.4.5
|
||||||
|
String getZDPStatusMessage(uint8_t status) {
|
||||||
|
static const char StatusMsg[] PROGMEM = "SUCCESS|INV_REQUESTTYPE|DEVICE_NOT_FOUND|INVALID_EP|NOT_ACTIVE|NOT_SUPPORTED"
|
||||||
|
"|TIMEOUT|NO_MATCH|NO_ENTRY|NO_DESCRIPTOR|INSUFFICIENT_SPACE|NOT_PERMITTED"
|
||||||
|
"|TABLE_FULL|NOT_AUTHORIZED|DEVICE_BINDING_TABLE_FULL"
|
||||||
|
;
|
||||||
|
static const uint8_t StatusIdx[] PROGMEM = { 0x00, 0x80, 0x81, 0x82, 0x83, 0x84,
|
||||||
|
0x85, 0x86, 0x88, 0x89, 0x8A, 0x8B,
|
||||||
|
0x8C, 0x8D, 0x8E };
|
||||||
|
|
||||||
|
char msg[32];
|
||||||
|
int32_t idx = -1;
|
||||||
|
for (uint32_t i = 0; i < sizeof(StatusIdx); i++) {
|
||||||
|
if (status == pgm_read_byte(&StatusIdx[i])) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idx >= 0) {
|
||||||
|
GetTextIndexed(msg, sizeof(msg), idx, StatusMsg);
|
||||||
|
} else {
|
||||||
|
*msg = 0x00; // empty string
|
||||||
|
}
|
||||||
|
return String(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Undocumented Zigbee ZCL code here: https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/Zigbee-Error-Codes-in-the-Log
|
// Undocumented Zigbee ZCL code here: https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/Zigbee-Error-Codes-in-the-Log
|
||||||
String getZigbeeStatusMessage(uint8_t status) {
|
String getZigbeeStatusMessage(uint8_t status) {
|
||||||
static const char StatusMsg[] PROGMEM = "SUCCESS|FAILURE|NOT_AUTHORIZED|RESERVED_FIELD_NOT_ZERO|MALFORMED_COMMAND|UNSUP_CLUSTER_COMMAND|UNSUP_GENERAL_COMMAND"
|
static const char StatusMsg[] PROGMEM = "SUCCESS|FAILURE|NOT_AUTHORIZED|RESERVED_FIELD_NOT_ZERO|MALFORMED_COMMAND|UNSUP_CLUSTER_COMMAND|UNSUP_GENERAL_COMMAND"
|
||||||
|
@ -670,9 +670,17 @@ int32_t ZNP_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) {
|
|||||||
//
|
//
|
||||||
// Handle Bind Rsp incoming message
|
// Handle Bind Rsp incoming message
|
||||||
//
|
//
|
||||||
int32_t ZNP_BindRsp(int32_t res, const class SBuffer &buf) {
|
int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) {
|
||||||
|
#ifdef USE_ZIGBEE_ZNP
|
||||||
Z_ShortAddress nwkAddr = buf.get16(2);
|
Z_ShortAddress nwkAddr = buf.get16(2);
|
||||||
uint8_t status = buf.get8(4);
|
uint8_t status = buf.get8(4);
|
||||||
|
String msg = getZigbeeStatusMessage(status);
|
||||||
|
#endif // USE_ZIGBEE_ZNP
|
||||||
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
|
uint8_t status = buf.get8(0);
|
||||||
|
Z_ShortAddress nwkAddr = buf.get16(buf.len()-2); // last 2 bytes
|
||||||
|
String msg = getZDPStatusMessage(status);
|
||||||
|
#endif // USE_ZIGBEE_EZSP
|
||||||
|
|
||||||
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
||||||
|
|
||||||
@ -682,7 +690,7 @@ int32_t ZNP_BindRsp(int32_t res, const class SBuffer &buf) {
|
|||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
||||||
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
||||||
"}}"), status, getZigbeeStatusMessage(status).c_str());
|
"}}"), status, msg.c_str());
|
||||||
|
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
@ -693,9 +701,17 @@ int32_t ZNP_BindRsp(int32_t res, const class SBuffer &buf) {
|
|||||||
//
|
//
|
||||||
// Handle Unbind Rsp incoming message
|
// Handle Unbind Rsp incoming message
|
||||||
//
|
//
|
||||||
int32_t ZNP_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
||||||
|
#ifdef USE_ZIGBEE_ZNP
|
||||||
Z_ShortAddress nwkAddr = buf.get16(2);
|
Z_ShortAddress nwkAddr = buf.get16(2);
|
||||||
uint8_t status = buf.get8(4);
|
uint8_t status = buf.get8(4);
|
||||||
|
String msg = getZigbeeStatusMessage(status);
|
||||||
|
#endif // USE_ZIGBEE_ZNP
|
||||||
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
|
uint8_t status = buf.get8(0);
|
||||||
|
Z_ShortAddress nwkAddr = buf.get16(buf.len()-2); // last 2 bytes
|
||||||
|
String msg = getZDPStatusMessage(status);
|
||||||
|
#endif // USE_ZIGBEE_EZSP
|
||||||
|
|
||||||
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
||||||
|
|
||||||
@ -703,8 +719,9 @@ int32_t ZNP_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
|||||||
if (friendlyName) {
|
if (friendlyName) {
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName);
|
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName);
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
||||||
"}}"), status, getZigbeeStatusMessage(status).c_str());
|
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
||||||
|
"}}"), status, msg.c_str());
|
||||||
|
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
@ -714,12 +731,23 @@ int32_t ZNP_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
|||||||
//
|
//
|
||||||
// Handle MgMt Bind Rsp incoming message
|
// Handle MgMt Bind Rsp incoming message
|
||||||
//
|
//
|
||||||
int32_t ZNP_MgmtBindRsp(int32_t res, const class SBuffer &buf) {
|
int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) {
|
||||||
|
#ifdef USE_ZIGBEE_ZNP
|
||||||
uint16_t shortaddr = buf.get16(2);
|
uint16_t shortaddr = buf.get16(2);
|
||||||
uint8_t status = buf.get8(4);
|
uint8_t status = buf.get8(4);
|
||||||
uint8_t bind_total = buf.get8(5);
|
uint8_t bind_total = buf.get8(5);
|
||||||
uint8_t bind_start = buf.get8(6);
|
uint8_t bind_start = buf.get8(6);
|
||||||
uint8_t bind_len = buf.get8(7);
|
uint8_t bind_len = buf.get8(7);
|
||||||
|
const size_t prefix_len = 8;
|
||||||
|
#endif // USE_ZIGBEE_ZNP
|
||||||
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
|
uint16_t shortaddr = buf.get16(buf.len()-2);
|
||||||
|
uint8_t status = buf.get8(0);
|
||||||
|
uint8_t bind_total = buf.get8(1);
|
||||||
|
uint8_t bind_start = buf.get8(2);
|
||||||
|
uint8_t bind_len = buf.get8(3);
|
||||||
|
const size_t prefix_len = 4;
|
||||||
|
#endif // USE_ZIGBEE_EZSP
|
||||||
|
|
||||||
const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr);
|
const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr);
|
||||||
|
|
||||||
@ -733,7 +761,7 @@ int32_t ZNP_MgmtBindRsp(int32_t res, const class SBuffer &buf) {
|
|||||||
",\"Bindings\":["
|
",\"Bindings\":["
|
||||||
), status, getZigbeeStatusMessage(status).c_str(), bind_total);
|
), status, getZigbeeStatusMessage(status).c_str(), bind_total);
|
||||||
|
|
||||||
uint32_t idx = 8;
|
uint32_t idx = prefix_len;
|
||||||
for (uint32_t i = 0; i < bind_len; i++) {
|
for (uint32_t i = 0; i < bind_len; i++) {
|
||||||
if (idx + 14 > buf.len()) { break; } // overflow, frame size is between 14 and 21
|
if (idx + 14 > buf.len()) { break; } // overflow, frame size is between 14 and 21
|
||||||
|
|
||||||
@ -791,7 +819,8 @@ void Z_SendIEEEAddrReq(uint16_t shortaddr) {
|
|||||||
ZigbeeZNPSend(IEEEAddrReq, sizeof(IEEEAddrReq));
|
ZigbeeZNPSend(IEEEAddrReq, sizeof(IEEEAddrReq));
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_ZIGBEE_EZSP
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
// TODO
|
uint8_t IEEEAddrReq[] = { Z_B0(shortaddr), Z_B1(shortaddr), 0x00, 0x00 };
|
||||||
|
EZ_SendZDO(shortaddr, ZDO_IEEE_addr_req, IEEEAddrReq, sizeof(IEEEAddrReq));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -991,25 +1020,31 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) {
|
|||||||
uint8_t linkquality = buf.get8(14);
|
uint8_t linkquality = buf.get8(14);
|
||||||
// uint8_t linkrsssi = buf.get8(15); // probably not used as there is no equivalent in Z-Stack
|
// uint8_t linkrsssi = buf.get8(15); // probably not used as there is no equivalent in Z-Stack
|
||||||
uint16_t srcaddr = buf.get16(16);
|
uint16_t srcaddr = buf.get16(16);
|
||||||
uint8_t bindingindex = buf.get8(18); // TODO not sure we need this one as a coordinator
|
// uint8_t bindingindex = buf.get8(18); // not sure we need this one as a coordinator
|
||||||
uint8_t addressindex = buf.get8(19); // TODO not sure how to handle this one
|
// uint8_t addressindex = buf.get8(19); // not sure how to handle this one
|
||||||
// offset 20 is len, and buffer starts at offset 21
|
// offset 20 is len, and buffer starts at offset 21
|
||||||
|
|
||||||
|
|
||||||
if ((0x0000 == profileid) && (0x00 == srcendpoint)) {
|
if ((0x0000 == profileid) && (0x00 == srcendpoint)) {
|
||||||
// ZDO request
|
// ZDO request
|
||||||
// Since ZDO messages start with a sequence number, we skip it
|
// Since ZDO messages start with a sequence number, we skip it
|
||||||
SBuffer zdo_buf = buf.subBuffer(22, buf.get8(20) - 1);
|
// but we add the source address in the last 2 bytes
|
||||||
|
SBuffer zdo_buf(buf.get8(20) - 1 + 2);
|
||||||
|
zdo_buf.addBuffer(buf.buf(22), buf.get8(20) - 1);
|
||||||
|
zdo_buf.add16(srcaddr);
|
||||||
switch (clusterid) {
|
switch (clusterid) {
|
||||||
case ZDO_Device_annce:
|
case ZDO_Device_annce:
|
||||||
return Z_ReceiveEndDeviceAnnonce(res, zdo_buf);
|
return Z_ReceiveEndDeviceAnnonce(res, zdo_buf);
|
||||||
break;
|
|
||||||
case ZDO_Active_EP_rsp:
|
case ZDO_Active_EP_rsp:
|
||||||
return Z_ReceiveActiveEp(res, zdo_buf);
|
return Z_ReceiveActiveEp(res, zdo_buf);
|
||||||
break;
|
|
||||||
case ZDO_IEEE_addr_rsp:
|
case ZDO_IEEE_addr_rsp:
|
||||||
return Z_ReceiveIEEEAddr(res, zdo_buf);
|
return Z_ReceiveIEEEAddr(res, zdo_buf);
|
||||||
break;
|
case ZDO_Bind_rsp:
|
||||||
|
return Z_BindRsp(res, zdo_buf);
|
||||||
|
case ZDO_Unbind_rsp:
|
||||||
|
return Z_UnbindRsp(res, zdo_buf);
|
||||||
|
case ZDO_Mgmt_Bind_rsp:
|
||||||
|
return Z_MgmtBindRsp(res, zdo_buf);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bool defer_attributes = false; // do we defer attributes reporting to coalesce
|
bool defer_attributes = false; // do we defer attributes reporting to coalesce
|
||||||
@ -1130,15 +1165,6 @@ int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Callback for loading Zigbee configuration from Flash, called by the state machine
|
|
||||||
//
|
|
||||||
int32_t Z_Reset_Device(uint8_t value) {
|
|
||||||
// TODO - GPIO is hardwired to GPIO4
|
|
||||||
digitalWrite(4, value ? HIGH : LOW);
|
|
||||||
return 0; // continue
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // USE_ZIGBEE_ZNP
|
#endif // USE_ZIGBEE_ZNP
|
||||||
|
|
||||||
|
|
||||||
@ -1189,9 +1215,9 @@ const Z_Dispatcher Z_DispatchTable[] PROGMEM = {
|
|||||||
{ { Z_AREQ | Z_ZDO, ZDO_NODE_DESC_RSP }, &ZNP_ReceiveNodeDesc }, // 4582
|
{ { Z_AREQ | Z_ZDO, ZDO_NODE_DESC_RSP }, &ZNP_ReceiveNodeDesc }, // 4582
|
||||||
{ { Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP }, &Z_ReceiveActiveEp }, // 4585
|
{ { Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP }, &Z_ReceiveActiveEp }, // 4585
|
||||||
{ { Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP }, &Z_ReceiveIEEEAddr }, // 4581
|
{ { Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP }, &Z_ReceiveIEEEAddr }, // 4581
|
||||||
{ { Z_AREQ | Z_ZDO, ZDO_BIND_RSP }, &ZNP_BindRsp }, // 45A1
|
{ { Z_AREQ | Z_ZDO, ZDO_BIND_RSP }, &Z_BindRsp }, // 45A1
|
||||||
{ { Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP }, &ZNP_UnbindRsp }, // 45A2
|
{ { Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP }, &Z_UnbindRsp }, // 45A2
|
||||||
{ { Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP }, &ZNP_MgmtBindRsp }, // 45B3
|
{ { Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP }, &Z_MgmtBindRsp }, // 45B3
|
||||||
};
|
};
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -718,33 +718,61 @@ void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterI
|
|||||||
#ifdef USE_ZIGBEE_EZSP
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
SBuffer buf(32+len);
|
SBuffer buf(32+len);
|
||||||
|
|
||||||
buf.add16(EZSP_sendUnicast); // 3400
|
if (BAD_SHORTADDR != shortaddr) {
|
||||||
buf.add8(EMBER_OUTGOING_DIRECT); // 00
|
// send unicast message to an address
|
||||||
buf.add16(shortaddr); // dest addr
|
buf.add16(EZSP_sendUnicast); // 3400
|
||||||
// ApsFrame
|
buf.add8(EMBER_OUTGOING_DIRECT); // 00
|
||||||
buf.add16(Z_PROF_HA); // Home Automation profile
|
buf.add16(shortaddr); // dest addr
|
||||||
buf.add16(clusterId); // cluster
|
// ApsFrame
|
||||||
buf.add8(0x01); // srcEp
|
buf.add16(Z_PROF_HA); // Home Automation profile
|
||||||
buf.add8(endpoint); // dstEp
|
buf.add16(clusterId); // cluster
|
||||||
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
|
buf.add8(0x01); // srcEp
|
||||||
buf.add16(groupaddr); // groupId
|
buf.add8(endpoint); // dstEp
|
||||||
buf.add8(transacId);
|
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
|
||||||
// end of ApsFrame
|
buf.add16(groupaddr); // groupId
|
||||||
buf.add8(0x01); // tag TODO
|
buf.add8(transacId);
|
||||||
|
// end of ApsFrame
|
||||||
|
buf.add8(0x01); // tag TODO
|
||||||
|
|
||||||
buf.add8(3 + len + (manuf ? 2 : 0));
|
buf.add8(3 + len + (manuf ? 2 : 0));
|
||||||
buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field
|
buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field
|
||||||
if (manuf) {
|
if (manuf) {
|
||||||
buf.add16(manuf); // add Manuf Id if not null
|
buf.add16(manuf); // add Manuf Id if not null
|
||||||
}
|
}
|
||||||
buf.add8(transacId); // Transaction Sequance Number
|
buf.add8(transacId); // Transaction Sequance Number
|
||||||
buf.add8(cmdId);
|
buf.add8(cmdId);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
buf.addBuffer(msg, len); // add the payload
|
buf.addBuffer(msg, len); // add the payload
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// send broadcast group address, aka groupcast
|
||||||
|
buf.add16(EZSP_sendMulticast); // 3800
|
||||||
|
// ApsFrame
|
||||||
|
buf.add16(Z_PROF_HA); // Home Automation profile
|
||||||
|
buf.add16(clusterId); // cluster
|
||||||
|
buf.add8(0x01); // srcEp
|
||||||
|
buf.add8(endpoint); // broadcast endpoint for groupcast
|
||||||
|
buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame
|
||||||
|
buf.add16(groupaddr); // groupId
|
||||||
|
buf.add8(transacId);
|
||||||
|
// end of ApsFrame
|
||||||
|
buf.add8(0); // hops, 0x00 = EMBER_MAX_HOPS
|
||||||
|
buf.add8(7); // nonMemberRadius, 7 = infinite
|
||||||
|
buf.add8(0x01); // tag TODO
|
||||||
|
|
||||||
|
buf.add8(3 + len + (manuf ? 2 : 0));
|
||||||
|
buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field
|
||||||
|
if (manuf) {
|
||||||
|
buf.add16(manuf); // add Manuf Id if not null
|
||||||
|
}
|
||||||
|
buf.add8(transacId); // Transaction Sequance Number
|
||||||
|
buf.add8(cmdId);
|
||||||
|
if (len > 0) {
|
||||||
|
buf.addBuffer(msg, len); // add the payload
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true);
|
ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true);
|
||||||
|
|
||||||
#endif // USE_ZIGBEE_EZSP
|
#endif // USE_ZIGBEE_EZSP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,6 +713,25 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind
|
|||||||
ZigbeeZNPSend(buf.getBuffer(), buf.len());
|
ZigbeeZNPSend(buf.getBuffer(), buf.len());
|
||||||
#endif // USE_ZIGBEE_ZNP
|
#endif // USE_ZIGBEE_ZNP
|
||||||
|
|
||||||
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
|
SBuffer buf(24);
|
||||||
|
|
||||||
|
// ZDO message payload (see Zigbee spec 2.4.3.2.2)
|
||||||
|
buf.add64(srcLongAddr);
|
||||||
|
buf.add8(endpoint);
|
||||||
|
buf.add16(cluster);
|
||||||
|
if (dstLongAddr) {
|
||||||
|
buf.add8(Z_Addr_IEEEAddress); // DstAddrMode - 0x03 = ADDRESS_64_BIT
|
||||||
|
buf.add64(dstLongAddr);
|
||||||
|
buf.add8(toendpoint);
|
||||||
|
} else {
|
||||||
|
buf.add8(Z_Addr_Group); // DstAddrMode - 0x01 = GROUP_ADDRESS
|
||||||
|
buf.add16(toGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
EZ_SendZDO(srcDevice, unbind ? ZDO_UNBIND_REQ : ZDO_BIND_REQ, buf.buf(), buf.len());
|
||||||
|
#endif // USE_ZIGBEE_EZSP
|
||||||
|
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,6 +767,14 @@ void CmndZbBindState(void) {
|
|||||||
ZigbeeZNPSend(buf.getBuffer(), buf.len());
|
ZigbeeZNPSend(buf.getBuffer(), buf.len());
|
||||||
#endif // USE_ZIGBEE_ZNP
|
#endif // USE_ZIGBEE_ZNP
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
|
// ZDO message payload (see Zigbee spec 2.4.3.3.4)
|
||||||
|
uint8_t buf[] = { 0x00 }; // index = 0
|
||||||
|
|
||||||
|
EZ_SendZDO(shortaddr, ZDO_Mgmt_Bind_req, buf, sizeof(buf));
|
||||||
|
#endif // USE_ZIGBEE_EZSP
|
||||||
|
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user