mirror of https://github.com/arendst/Tasmota.git
Merge pull request #8469 from s-hadinger/zigbee_non_zero_addr2
Zigbee allow zero shortaddr
This commit is contained in:
commit
b797a2ce1f
|
@ -24,6 +24,8 @@
|
||||||
typedef uint64_t Z_IEEEAddress;
|
typedef uint64_t Z_IEEEAddress;
|
||||||
typedef uint16_t Z_ShortAddress;
|
typedef uint16_t Z_ShortAddress;
|
||||||
|
|
||||||
|
const uint16_t BAD_SHORTADDR = 0xFFFE;
|
||||||
|
|
||||||
enum ZnpCommandType {
|
enum ZnpCommandType {
|
||||||
Z_POLL = 0x00,
|
Z_POLL = 0x00,
|
||||||
Z_SREQ = 0x20,
|
Z_SREQ = 0x20,
|
||||||
|
|
|
@ -103,7 +103,7 @@ public:
|
||||||
// Probe the existence of device keys
|
// Probe the existence of device keys
|
||||||
// Results:
|
// Results:
|
||||||
// - 0x0000 = not found
|
// - 0x0000 = not found
|
||||||
// - 0xFFFF = bad parameter
|
// - BAD_SHORTADDR = bad parameter
|
||||||
// - 0x<shortaddr> = the device's short address
|
// - 0x<shortaddr> = the device's short address
|
||||||
uint16_t isKnownShortAddr(uint16_t shortaddr) const;
|
uint16_t isKnownShortAddr(uint16_t shortaddr) const;
|
||||||
uint16_t isKnownLongAddr(uint64_t longaddr) const;
|
uint16_t isKnownLongAddr(uint64_t longaddr) const;
|
||||||
|
@ -295,18 +295,16 @@ void Z_Devices::freeDeviceEntry(Z_Device *device) {
|
||||||
// Scan all devices to find a corresponding shortaddr
|
// Scan all devices to find a corresponding shortaddr
|
||||||
// Looks info device.shortaddr entry
|
// Looks info device.shortaddr entry
|
||||||
// In:
|
// In:
|
||||||
// shortaddr (non null)
|
// shortaddr (not BAD_SHORTADDR)
|
||||||
// Out:
|
// Out:
|
||||||
// index in _devices of entry, -1 if not found
|
// index in _devices of entry, -1 if not found
|
||||||
//
|
//
|
||||||
int32_t Z_Devices::findShortAddr(uint16_t shortaddr) const {
|
int32_t Z_Devices::findShortAddr(uint16_t shortaddr) const {
|
||||||
if (!shortaddr) { return -1; } // does not make sense to look for 0x0000 shortaddr (localhost)
|
if (BAD_SHORTADDR == shortaddr) { return -1; } // does not make sense to look for BAD_SHORTADDR shortaddr (broadcast)
|
||||||
int32_t found = 0;
|
int32_t found = 0;
|
||||||
if (shortaddr) {
|
for (auto &elem : _devices) {
|
||||||
for (auto &elem : _devices) {
|
if (elem->shortaddr == shortaddr) { return found; }
|
||||||
if (elem->shortaddr == shortaddr) { return found; }
|
found++;
|
||||||
found++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -321,11 +319,9 @@ int32_t Z_Devices::findShortAddr(uint16_t shortaddr) const {
|
||||||
int32_t Z_Devices::findLongAddr(uint64_t longaddr) const {
|
int32_t Z_Devices::findLongAddr(uint64_t longaddr) const {
|
||||||
if (!longaddr) { return -1; }
|
if (!longaddr) { return -1; }
|
||||||
int32_t found = 0;
|
int32_t found = 0;
|
||||||
if (longaddr) {
|
for (auto &elem : _devices) {
|
||||||
for (auto &elem : _devices) {
|
if (elem->longaddr == longaddr) { return found; }
|
||||||
if (elem->longaddr == longaddr) { return found; }
|
found++;
|
||||||
found++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +354,7 @@ uint16_t Z_Devices::isKnownShortAddr(uint16_t shortaddr) const {
|
||||||
if (found >= 0) {
|
if (found >= 0) {
|
||||||
return shortaddr;
|
return shortaddr;
|
||||||
} else {
|
} else {
|
||||||
return 0; // unknown
|
return BAD_SHORTADDR; // unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +364,7 @@ uint16_t Z_Devices::isKnownLongAddr(uint64_t longaddr) const {
|
||||||
const Z_Device & device = devicesAt(found);
|
const Z_Device & device = devicesAt(found);
|
||||||
return device.shortaddr; // can be zero, if not yet registered
|
return device.shortaddr; // can be zero, if not yet registered
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return BAD_SHORTADDR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,18 +373,18 @@ uint16_t Z_Devices::isKnownIndex(uint32_t index) const {
|
||||||
const Z_Device & device = devicesAt(index);
|
const Z_Device & device = devicesAt(index);
|
||||||
return device.shortaddr;
|
return device.shortaddr;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return BAD_SHORTADDR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Z_Devices::isKnownFriendlyName(const char * name) const {
|
uint16_t Z_Devices::isKnownFriendlyName(const char * name) const {
|
||||||
if ((!name) || (0 == strlen(name))) { return 0xFFFF; } // Error
|
if ((!name) || (0 == strlen(name))) { return BAD_SHORTADDR; } // Error
|
||||||
int32_t found = findFriendlyName(name);
|
int32_t found = findFriendlyName(name);
|
||||||
if (found >= 0) {
|
if (found >= 0) {
|
||||||
const Z_Device & device = devicesAt(found);
|
const Z_Device & device = devicesAt(found);
|
||||||
return device.shortaddr; // can be zero, if not yet registered
|
return device.shortaddr; // can be zero, if not yet registered
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return BAD_SHORTADDR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,10 +394,10 @@ uint64_t Z_Devices::getDeviceLongAddr(uint16_t shortaddr) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// We have a seen a shortaddr on the network, get the corresponding
|
// We have a seen a shortaddr on the network, get the corresponding device object
|
||||||
//
|
//
|
||||||
Z_Device & Z_Devices::getShortAddr(uint16_t shortaddr) {
|
Z_Device & Z_Devices::getShortAddr(uint16_t shortaddr) {
|
||||||
if (!shortaddr) { return *(Z_Device*) nullptr; } // this is not legal
|
if (BAD_SHORTADDR == shortaddr) { return *(Z_Device*) nullptr; } // this is not legal
|
||||||
int32_t found = findShortAddr(shortaddr);
|
int32_t found = findShortAddr(shortaddr);
|
||||||
if (found >= 0) {
|
if (found >= 0) {
|
||||||
return *(_devices[found]);
|
return *(_devices[found]);
|
||||||
|
@ -411,7 +407,7 @@ Z_Device & Z_Devices::getShortAddr(uint16_t shortaddr) {
|
||||||
}
|
}
|
||||||
// Same version but Const
|
// Same version but Const
|
||||||
const Z_Device & Z_Devices::getShortAddrConst(uint16_t shortaddr) const {
|
const Z_Device & Z_Devices::getShortAddrConst(uint16_t shortaddr) const {
|
||||||
if (!shortaddr) { return *(Z_Device*) nullptr; } // this is not legal
|
if (BAD_SHORTADDR == shortaddr) { return *(Z_Device*) nullptr; } // this is not legal
|
||||||
int32_t found = findShortAddr(shortaddr);
|
int32_t found = findShortAddr(shortaddr);
|
||||||
if (found >= 0) {
|
if (found >= 0) {
|
||||||
return *(_devices[found]);
|
return *(_devices[found]);
|
||||||
|
@ -471,7 +467,7 @@ void Z_Devices::updateDevice(uint16_t shortaddr, uint64_t longaddr) {
|
||||||
dirty();
|
dirty();
|
||||||
} else {
|
} else {
|
||||||
// neither short/lonf addr are found.
|
// neither short/lonf addr are found.
|
||||||
if (shortaddr || longaddr) {
|
if ((BAD_SHORTADDR != shortaddr) || longaddr) {
|
||||||
createDeviceEntry(shortaddr, longaddr);
|
createDeviceEntry(shortaddr, longaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,7 +477,6 @@ void Z_Devices::updateDevice(uint16_t shortaddr, uint64_t longaddr) {
|
||||||
// Clear all endpoints
|
// Clear all endpoints
|
||||||
//
|
//
|
||||||
void Z_Devices::clearEndpoints(uint16_t shortaddr) {
|
void Z_Devices::clearEndpoints(uint16_t shortaddr) {
|
||||||
if (!shortaddr) { return; }
|
|
||||||
Z_Device &device = getShortAddr(shortaddr);
|
Z_Device &device = getShortAddr(shortaddr);
|
||||||
if (&device == nullptr) { return; } // don't crash if not found
|
if (&device == nullptr) { return; } // don't crash if not found
|
||||||
|
|
||||||
|
@ -495,7 +490,6 @@ void Z_Devices::clearEndpoints(uint16_t shortaddr) {
|
||||||
// Add an endpoint to a shortaddr
|
// Add an endpoint to a shortaddr
|
||||||
//
|
//
|
||||||
void Z_Devices::addEndpoint(uint16_t shortaddr, uint8_t endpoint) {
|
void Z_Devices::addEndpoint(uint16_t shortaddr, uint8_t endpoint) {
|
||||||
if (!shortaddr) { return; }
|
|
||||||
if (0x00 == endpoint) { return; }
|
if (0x00 == endpoint) { return; }
|
||||||
Z_Device &device = getShortAddr(shortaddr);
|
Z_Device &device = getShortAddr(shortaddr);
|
||||||
if (&device == nullptr) { return; } // don't crash if not found
|
if (&device == nullptr) { return; } // don't crash if not found
|
||||||
|
@ -922,7 +916,7 @@ uint16_t Z_Devices::parseDeviceParam(const char * param, bool short_must_be_know
|
||||||
char dataBuf[param_len + 1];
|
char dataBuf[param_len + 1];
|
||||||
strcpy(dataBuf, param);
|
strcpy(dataBuf, param);
|
||||||
RemoveSpace(dataBuf);
|
RemoveSpace(dataBuf);
|
||||||
uint16_t shortaddr = 0;
|
uint16_t shortaddr = BAD_SHORTADDR; // start with unknown
|
||||||
|
|
||||||
if (strlen(dataBuf) < 4) {
|
if (strlen(dataBuf) < 4) {
|
||||||
// simple number 0..99
|
// simple number 0..99
|
||||||
|
@ -1018,8 +1012,8 @@ String Z_Devices::dump(uint32_t dump_mode, uint16_t status_shortaddr) const {
|
||||||
uint16_t shortaddr = device.shortaddr;
|
uint16_t shortaddr = device.shortaddr;
|
||||||
char hex[22];
|
char hex[22];
|
||||||
|
|
||||||
// ignore non-current device, if specified device is non-zero
|
// ignore non-current device, if device specified
|
||||||
if ((status_shortaddr) && (status_shortaddr != shortaddr)) { continue; }
|
if ((BAD_SHORTADDR != status_shortaddr) && (status_shortaddr != shortaddr)) { continue; }
|
||||||
|
|
||||||
JsonObject& dev = devices.createNestedObject();
|
JsonObject& dev = devices.createNestedObject();
|
||||||
|
|
||||||
|
|
|
@ -66,41 +66,6 @@ public:
|
||||||
const static uint32_t ZIGB_NAME = 0x3167697A; // 'zig1' little endian
|
const static uint32_t ZIGB_NAME = 0x3167697A; // 'zig1' little endian
|
||||||
const static size_t Z_MAX_FLASH = z_block_len - sizeof(z_flashdata_t); // 2040
|
const static size_t Z_MAX_FLASH = z_block_len - sizeof(z_flashdata_t); // 2040
|
||||||
|
|
||||||
// encoding for the most commonly 32 clusters, used for binary encoding
|
|
||||||
const uint16_t Z_ClusterNumber[] PROGMEM = {
|
|
||||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
|
||||||
0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
|
|
||||||
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
|
|
||||||
0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
|
|
||||||
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
|
|
||||||
0x0100, 0x0101, 0x0102,
|
|
||||||
0x0201, 0x0202, 0x0203, 0x0204,
|
|
||||||
0x0300, 0x0301,
|
|
||||||
0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
|
|
||||||
0x0500, 0x0501, 0x0502,
|
|
||||||
0x0700, 0x0701, 0x0702,
|
|
||||||
0x0B00, 0x0B01, 0x0B02, 0x0B03, 0x0B04, 0x0B05,
|
|
||||||
0x1000,
|
|
||||||
0xFC0F,
|
|
||||||
};
|
|
||||||
|
|
||||||
// convert a 1 byte cluster code to the actual cluster number
|
|
||||||
uint16_t fromClusterCode(uint8_t c) {
|
|
||||||
if (c >= ARRAY_SIZE(Z_ClusterNumber)) {
|
|
||||||
return 0xFFFF; // invalid
|
|
||||||
}
|
|
||||||
return pgm_read_word(&Z_ClusterNumber[c]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert a cluster number to 1 byte, or 0xFF if not in table
|
|
||||||
uint8_t toClusterCode(uint16_t c) {
|
|
||||||
for (uint32_t i = 0; i < ARRAY_SIZE(Z_ClusterNumber); i++) {
|
|
||||||
if (c == pgm_read_word(&Z_ClusterNumber[i])) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0xFF; // not found
|
|
||||||
}
|
|
||||||
|
|
||||||
class SBuffer hibernateDevice(const struct Z_Device &device) {
|
class SBuffer hibernateDevice(const struct Z_Device &device) {
|
||||||
SBuffer buf(128);
|
SBuffer buf(128);
|
||||||
|
@ -202,18 +167,8 @@ void hydrateDevices(const SBuffer &buf) {
|
||||||
for (uint32_t i = 0; (i < num_devices) && (k < buf_len); i++) {
|
for (uint32_t i = 0; (i < num_devices) && (k < buf_len); i++) {
|
||||||
uint32_t dev_record_len = buf.get8(k);
|
uint32_t dev_record_len = buf.get8(k);
|
||||||
|
|
||||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Device %d Before Memory = %d // DIFF %d // record_len %d"), i, ESP_getFreeHeap(), before - ESP_getFreeHeap(), dev_record_len);
|
|
||||||
// before = ESP_getFreeHeap();
|
|
||||||
|
|
||||||
SBuffer buf_d = buf.subBuffer(k, dev_record_len);
|
SBuffer buf_d = buf.subBuffer(k, dev_record_len);
|
||||||
|
|
||||||
// char *hex_char = (char*) malloc((dev_record_len * 2) + 2);
|
|
||||||
// if (hex_char) {
|
|
||||||
// AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "/// SUB %s"),
|
|
||||||
// ToHex_P(buf_d.getBuffer(), dev_record_len, hex_char, (dev_record_len * 2) + 2));
|
|
||||||
// free(hex_char);
|
|
||||||
// }
|
|
||||||
|
|
||||||
uint32_t d = 1; // index in device buffer
|
uint32_t d = 1; // index in device buffer
|
||||||
uint16_t shortaddr = buf_d.get16(d); d += 2;
|
uint16_t shortaddr = buf_d.get16(d); d += 2;
|
||||||
uint64_t longaddr = buf_d.get64(d); d += 8;
|
uint64_t longaddr = buf_d.get64(d); d += 8;
|
||||||
|
|
|
@ -79,16 +79,6 @@ uint8_t Z_getDatatypeLen(uint8_t t) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedef struct Z_DataTypeMapping {
|
|
||||||
// uint8_t datatype;
|
|
||||||
// uint8_t len; // len in bytes and add 0x80 if DISCRETE
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const Z_DataTypeMapping Z_types[] PROGMEM = {
|
|
||||||
// { Znodata, 0 },
|
|
||||||
// { Zdata8, 0 },
|
|
||||||
// };
|
|
||||||
|
|
||||||
typedef union ZCLHeaderFrameControl_t {
|
typedef union ZCLHeaderFrameControl_t {
|
||||||
struct {
|
struct {
|
||||||
uint8_t frame_type : 2; // 00 = across entire profile, 01 = cluster specific
|
uint8_t frame_type : 2; // 00 = across entire profile, 01 = cluster specific
|
||||||
|
@ -572,6 +562,9 @@ typedef struct Z_AttributeConverter {
|
||||||
Z_AttrConverter func;
|
Z_AttrConverter func;
|
||||||
} Z_AttributeConverter;
|
} Z_AttributeConverter;
|
||||||
|
|
||||||
|
// Cluster numbers are store in 8 bits format to save space,
|
||||||
|
// the following tables allows the conversion from 8 bits index Cx...
|
||||||
|
// to the 16 bits actual cluster number
|
||||||
enum Cx_cluster_short {
|
enum Cx_cluster_short {
|
||||||
Cx0000, Cx0001, Cx0002, Cx0003, Cx0004, Cx0005, Cx0006, Cx0007,
|
Cx0000, Cx0001, Cx0002, Cx0003, Cx0004, Cx0005, Cx0006, Cx0007,
|
||||||
Cx0008, Cx0009, Cx000A, Cx000B, Cx000C, Cx000D, Cx000E, Cx000F,
|
Cx0008, Cx0009, Cx000A, Cx000B, Cx000C, Cx000D, Cx000E, Cx000F,
|
||||||
|
|
|
@ -177,6 +177,9 @@ int32_t Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clus
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (attrs) {
|
if (attrs) {
|
||||||
|
if (groupaddr) {
|
||||||
|
shortaddr = BAD_SHORTADDR; // if group address, don't send to device
|
||||||
|
}
|
||||||
ZigbeeZCLSend_Raw(shortaddr, groupaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, 0, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(shortaddr));
|
ZigbeeZCLSend_Raw(shortaddr, groupaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, 0, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(shortaddr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +187,7 @@ int32_t Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clus
|
||||||
|
|
||||||
// This callback is registered after a an attribute read command was made to a light, and fires if we don't get any response after 1000 ms
|
// This callback is registered after a an attribute read command was made to a light, and fires if we don't get any response after 1000 ms
|
||||||
int32_t Z_Unreachable(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
|
int32_t Z_Unreachable(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
|
||||||
if (shortaddr) {
|
if (BAD_SHORTADDR != shortaddr) {
|
||||||
zigbee_devices.setReachable(shortaddr, false); // mark device as reachable
|
zigbee_devices.setReachable(shortaddr, false); // mark device as reachable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +211,7 @@ void zigbeeSetCommandTimer(uint16_t shortaddr, uint16_t groupaddr, uint16_t clus
|
||||||
}
|
}
|
||||||
if (wait_ms) {
|
if (wait_ms) {
|
||||||
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms, cluster, endpoint, Z_CAT_NONE, 0 /* value */, &Z_ReadAttrCallback);
|
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms, cluster, endpoint, Z_CAT_NONE, 0 /* value */, &Z_ReadAttrCallback);
|
||||||
if (shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group
|
if (BAD_SHORTADDR != shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group
|
||||||
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms + Z_CAT_REACHABILITY_TIMEOUT, cluster, endpoint, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
|
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms + Z_CAT_REACHABILITY_TIMEOUT, cluster, endpoint, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,12 +317,12 @@ void sendHueUpdate(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uin
|
||||||
}
|
}
|
||||||
if (z_cat >= 0) {
|
if (z_cat >= 0) {
|
||||||
uint8_t endpoint = 0;
|
uint8_t endpoint = 0;
|
||||||
if (shortaddr) {
|
if (BAD_SHORTADDR != shortaddr) {
|
||||||
endpoint = zigbee_devices.findFirstEndpoint(shortaddr);
|
endpoint = zigbee_devices.findFirstEndpoint(shortaddr);
|
||||||
}
|
}
|
||||||
if ((!shortaddr) || (endpoint)) { // send if group address or endpoint is known
|
if ((BAD_SHORTADDR == shortaddr) || (endpoint)) { // send if group address or endpoint is known
|
||||||
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms, cluster, endpoint, z_cat, 0 /* value */, &Z_ReadAttrCallback);
|
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms, cluster, endpoint, z_cat, 0 /* value */, &Z_ReadAttrCallback);
|
||||||
if (shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group
|
if (BAD_SHORTADDR != shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group
|
||||||
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms + Z_CAT_REACHABILITY_TIMEOUT, cluster, endpoint, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
|
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms + Z_CAT_REACHABILITY_TIMEOUT, cluster, endpoint, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -584,18 +584,6 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
|
||||||
ZI_WAIT_RECV(1000, ZBS_LOGTYPE_DEVICE) // it should be coordinator
|
ZI_WAIT_RECV(1000, ZBS_LOGTYPE_DEVICE) // it should be coordinator
|
||||||
|
|
||||||
ZI_GOTO(ZIGBEE_LABEL_START_ROUTER)
|
ZI_GOTO(ZIGBEE_LABEL_START_ROUTER)
|
||||||
// Device and Router code is common from now
|
|
||||||
// ZI_LABEL(ZIGBEE_LABEL_START_DEVICE) // Init as a router
|
|
||||||
// ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredDevice)
|
|
||||||
// ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT)
|
|
||||||
// ZI_SEND(ZBS_AF_REGISTER_ALL) // Z_AF register for endpoint 01, profile 0x0104 Home Automation
|
|
||||||
// ZI_WAIT_RECV(1000, ZBR_AF_REGISTER)
|
|
||||||
// ZI_SEND(ZBS_STARTUPFROMAPP) // start router
|
|
||||||
// ZI_WAIT_RECV(2000, ZBR_STARTUPFROMAPP) // wait for sync ack of command
|
|
||||||
// ZI_WAIT_UNTIL_FUNC(0xFFFF, AREQ_STARTUPFROMAPP, &Z_ReceiveStateChange) // wait forever for async message that coordinator started
|
|
||||||
// ZI_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo
|
|
||||||
// ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &Z_ReceiveDeviceInfo)
|
|
||||||
// ZI_GOTO(ZIGBEE_LABEL_READY)
|
|
||||||
|
|
||||||
ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_DEVICE) // Factory reset for router
|
ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_DEVICE) // Factory reset for router
|
||||||
ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting)
|
ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting)
|
||||||
|
@ -608,25 +596,12 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
|
||||||
ZI_WAIT_RECV(1000, ZBR_W_OK)
|
ZI_WAIT_RECV(1000, ZBR_W_OK)
|
||||||
ZI_GOTO(ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST)
|
ZI_GOTO(ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST)
|
||||||
|
|
||||||
// ZI_SEND(ZBS_W_ALL_PAN) // write universal PAN ID = 0xFFFF
|
// Error: version of Z-Stack is not supported
|
||||||
// ZI_WAIT_RECV(1000, ZBR_W_OK)
|
|
||||||
// ZI_SEND(ZBS_W_ALL_CHANN) // write Allows all CHANNELS = 0x07FFF800, 11-26
|
|
||||||
// ZI_WAIT_RECV(1000, ZBR_W_OK)
|
|
||||||
|
|
||||||
// // Now mark the device as ready, writing 0x55 in memory slot 0x0F00
|
|
||||||
// ZI_SEND(ZBS_WNV_INITZNPHC) // Init NV ZNP Has Configured
|
|
||||||
// ZI_WAIT_RECV_FUNC(1000, ZBR_WNV_INIT_OK, &Z_CheckNVWrite)
|
|
||||||
// ZI_SEND(ZBS_WNV_ZNPHC) // Write NV ZNP Has Configured
|
|
||||||
// ZI_WAIT_RECV(1000, ZBR_WNV_OK)
|
|
||||||
|
|
||||||
// ZI_GOTO(ZIGBEE_LABEL_START_ROUTER)
|
|
||||||
// ZI_GOTO(ZIGBEE_LABEL_START_DEVICE)
|
|
||||||
|
|
||||||
|
|
||||||
ZI_LABEL(ZIGBEE_LABEL_UNSUPPORTED_VERSION)
|
ZI_LABEL(ZIGBEE_LABEL_UNSUPPORTED_VERSION)
|
||||||
ZI_MQTT_STATE(ZIGBEE_STATUS_UNSUPPORTED_VERSION, kZNP12)
|
ZI_MQTT_STATE(ZIGBEE_STATUS_UNSUPPORTED_VERSION, kZNP12)
|
||||||
ZI_GOTO(ZIGBEE_LABEL_ABORT)
|
ZI_GOTO(ZIGBEE_LABEL_ABORT)
|
||||||
|
|
||||||
|
// Abort state machine, general error
|
||||||
ZI_LABEL(ZIGBEE_LABEL_ABORT) // Label 99: abort
|
ZI_LABEL(ZIGBEE_LABEL_ABORT) // Label 99: abort
|
||||||
ZI_MQTT_STATE(ZIGBEE_STATUS_ABORT, kAbort)
|
ZI_MQTT_STATE(ZIGBEE_STATUS_ABORT, kAbort)
|
||||||
ZI_LOG(LOG_LEVEL_ERROR, kZigbeeAbort)
|
ZI_LOG(LOG_LEVEL_ERROR, kZigbeeAbort)
|
||||||
|
|
|
@ -52,7 +52,7 @@ int32_t Z_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) {
|
||||||
ZIGBEE_STATUS_CC_INFO, hex, short_adr, device_type, device_state,
|
ZIGBEE_STATUS_CC_INFO, hex, short_adr, device_type, device_state,
|
||||||
device_associated);
|
device_associated);
|
||||||
|
|
||||||
if (device_associated > 0) {
|
if (device_associated > 0) { // If there are devices registered in CC2530, print the list
|
||||||
uint idx = 16;
|
uint idx = 16;
|
||||||
ResponseAppend_P(PSTR(",\"AssocDevicesList\":["));
|
ResponseAppend_P(PSTR(",\"AssocDevicesList\":["));
|
||||||
for (uint32_t i = 0; i < device_associated; i++) {
|
for (uint32_t i = 0; i < device_associated; i++) {
|
||||||
|
@ -87,18 +87,20 @@ int32_t Z_Reboot(int32_t res, class SBuffer &buf) {
|
||||||
// print information about the reboot of device
|
// print information about the reboot of device
|
||||||
// 4180.02.02.00.02.06.03
|
// 4180.02.02.00.02.06.03
|
||||||
//
|
//
|
||||||
static const char Z_RebootReason[] PROGMEM = "Power-up|External|Watchdog";
|
|
||||||
|
|
||||||
uint8_t reason = buf.get8(2);
|
uint8_t reason = buf.get8(2);
|
||||||
uint8_t transport_rev = buf.get8(3);
|
uint8_t transport_rev = buf.get8(3);
|
||||||
uint8_t product_id = buf.get8(4);
|
uint8_t product_id = buf.get8(4);
|
||||||
uint8_t major_rel = buf.get8(5);
|
uint8_t major_rel = buf.get8(5);
|
||||||
uint8_t minor_rel = buf.get8(6);
|
uint8_t minor_rel = buf.get8(6);
|
||||||
uint8_t hw_rev = buf.get8(7);
|
uint8_t hw_rev = buf.get8(7);
|
||||||
char reason_str[12];
|
const char *reason_str;
|
||||||
|
|
||||||
if (reason > 3) { reason = 3; }
|
switch (reason) {
|
||||||
GetTextIndexed(reason_str, sizeof(reason_str), reason, Z_RebootReason);
|
case 0: reason_str = PSTR("Power-up"); break;
|
||||||
|
case 1: reason_str = PSTR("External"); break;
|
||||||
|
case 2: reason_str = PSTR("Watchdog"); break;
|
||||||
|
default: reason_str = PSTR("Unknown"); break;
|
||||||
|
}
|
||||||
|
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
|
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
|
||||||
"\"Status\":%d,\"Message\":\"CC2530 booted\",\"RestartReason\":\"%s\""
|
"\"Status\":%d,\"Message\":\"CC2530 booted\",\"RestartReason\":\"%s\""
|
||||||
|
@ -201,7 +203,6 @@ int32_t Z_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Z_DeviceType[] = { "Coordinator", "Router", "End Device", "Unknown" };
|
|
||||||
int32_t Z_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) {
|
int32_t Z_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) {
|
||||||
// Received ZDO_NODE_DESC_RSP
|
// Received ZDO_NODE_DESC_RSP
|
||||||
Z_ShortAddress srcAddr = buf.get16(2);
|
Z_ShortAddress srcAddr = buf.get16(2);
|
||||||
|
@ -217,15 +218,22 @@ int32_t Z_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) {
|
||||||
uint16_t maxOutTransferSize = buf.get16(17);
|
uint16_t maxOutTransferSize = buf.get16(17);
|
||||||
uint8_t descriptorCapabilities = buf.get8(19);
|
uint8_t descriptorCapabilities = buf.get8(19);
|
||||||
|
|
||||||
|
|
||||||
if (0 == status) {
|
if (0 == status) {
|
||||||
uint8_t deviceType = logicalType & 0x7; // 0=coordinator, 1=router, 2=end device
|
uint8_t deviceType = logicalType & 0x7; // 0=coordinator, 1=router, 2=end device
|
||||||
if (deviceType > 3) { deviceType = 3; }
|
const char * deviceTypeStr;
|
||||||
|
switch (deviceType) {
|
||||||
|
case 0: deviceTypeStr = PSTR("Coordinator"); break;
|
||||||
|
case 1: deviceTypeStr = PSTR("Router"); break;
|
||||||
|
case 2: deviceTypeStr = PSTR("Device"); break;
|
||||||
|
default: deviceTypeStr = PSTR("Unknown"); break;
|
||||||
|
}
|
||||||
bool complexDescriptorAvailable = (logicalType & 0x08) ? 1 : 0;
|
bool complexDescriptorAvailable = (logicalType & 0x08) ? 1 : 0;
|
||||||
|
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
|
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
|
||||||
"\"Status\":%d,\"NodeType\":\"%s\",\"ComplexDesc\":%s}}"),
|
"\"Status\":%d,\"NodeType\":\"%s\",\"ComplexDesc\":%s}}"),
|
||||||
ZIGBEE_STATUS_NODE_DESC, Z_DeviceType[deviceType],
|
ZIGBEE_STATUS_NODE_DESC, deviceTypeStr,
|
||||||
complexDescriptorAvailable ? "true" : "false"
|
complexDescriptorAvailable ? PSTR("true") : PSTR("false")
|
||||||
);
|
);
|
||||||
|
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
||||||
|
@ -282,15 +290,13 @@ int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) {
|
||||||
Uint64toHex(ieeeAddr, hex, 64);
|
Uint64toHex(ieeeAddr, hex, 64);
|
||||||
// Ping response
|
// Ping response
|
||||||
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
||||||
|
|
||||||
|
Response_P(PSTR("{\"" D_JSON_ZIGBEE_PING "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""
|
||||||
|
",\"" D_JSON_ZIGBEE_IEEE "\":\"0x%s\""), nwkAddr, hex);
|
||||||
if (friendlyName) {
|
if (friendlyName) {
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_PING "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""
|
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName);
|
||||||
",\"" D_JSON_ZIGBEE_IEEE "\":\"0x%s\""
|
|
||||||
",\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), nwkAddr, hex, friendlyName);
|
|
||||||
} else {
|
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_PING "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""
|
|
||||||
",\"" D_JSON_ZIGBEE_IEEE "\":\"0x%s\""
|
|
||||||
"}}"), nwkAddr, hex);
|
|
||||||
}
|
}
|
||||||
|
ResponseAppend_P(PSTR("\"}}"));
|
||||||
|
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
|
@ -398,9 +404,9 @@ int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) {
|
||||||
"\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\""
|
"\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\""
|
||||||
",\"PowerSource\":%s,\"ReceiveWhenIdle\":%s,\"Security\":%s}}"),
|
",\"PowerSource\":%s,\"ReceiveWhenIdle\":%s,\"Security\":%s}}"),
|
||||||
ZIGBEE_STATUS_DEVICE_ANNOUNCE, hex, nwkAddr,
|
ZIGBEE_STATUS_DEVICE_ANNOUNCE, hex, nwkAddr,
|
||||||
(capabilities & 0x04) ? "true" : "false",
|
(capabilities & 0x04) ? PSTR("true") : PSTR("false"),
|
||||||
(capabilities & 0x08) ? "true" : "false",
|
(capabilities & 0x08) ? PSTR("true") : PSTR("false"),
|
||||||
(capabilities & 0x40) ? "true" : "false"
|
(capabilities & 0x40) ? PSTR("true") : PSTR("false")
|
||||||
);
|
);
|
||||||
// query the state of the bulb (for Alexa)
|
// query the state of the bulb (for Alexa)
|
||||||
uint32_t wait_ms = 2000; // wait for 2s
|
uint32_t wait_ms = 2000; // wait for 2s
|
||||||
|
@ -444,18 +450,15 @@ int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) {
|
||||||
uint8_t status = buf.get8(4);
|
uint8_t status = buf.get8(4);
|
||||||
|
|
||||||
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
||||||
|
|
||||||
|
Response_P(PSTR("{\"" D_JSON_ZIGBEE_BIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), nwkAddr);
|
||||||
if (friendlyName) {
|
if (friendlyName) {
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_BIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""
|
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName);
|
||||||
",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""
|
|
||||||
",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
|
||||||
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
|
||||||
"}}"), nwkAddr, friendlyName, status, getZigbeeStatusMessage(status).c_str());
|
|
||||||
} else {
|
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_BIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""
|
|
||||||
",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
|
||||||
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
|
||||||
"}}"), nwkAddr, status, getZigbeeStatusMessage(status).c_str());
|
|
||||||
}
|
}
|
||||||
|
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
||||||
|
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
||||||
|
"}}"), status, getZigbeeStatusMessage(status).c_str());
|
||||||
|
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
|
|
||||||
|
@ -470,18 +473,14 @@ int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) {
|
||||||
uint8_t status = buf.get8(4);
|
uint8_t status = buf.get8(4);
|
||||||
|
|
||||||
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr);
|
||||||
|
|
||||||
|
Response_P(PSTR("{\"" D_JSON_ZIGBEE_UNBIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), nwkAddr);
|
||||||
if (friendlyName) {
|
if (friendlyName) {
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_UNBIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""
|
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName);
|
||||||
",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""
|
|
||||||
",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
|
||||||
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
|
||||||
"}}"), nwkAddr, friendlyName, status, getZigbeeStatusMessage(status).c_str());
|
|
||||||
} else {
|
|
||||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_UNBIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""
|
|
||||||
",\"" D_JSON_ZIGBEE_STATUS "\":%d"
|
|
||||||
",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
|
||||||
"}}"), nwkAddr, status, getZigbeeStatusMessage(status).c_str());
|
|
||||||
}
|
}
|
||||||
|
ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\""
|
||||||
|
"}}"), status, getZigbeeStatusMessage(status).c_str());
|
||||||
|
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
|
|
||||||
|
@ -506,7 +505,6 @@ int32_t Z_MgmtBindRsp(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\""
|
||||||
",\"BindingsTotal\":%d"
|
",\"BindingsTotal\":%d"
|
||||||
//",\"BindingsStart\":%d"
|
|
||||||
",\"Bindings\":["
|
",\"Bindings\":["
|
||||||
), status, getZigbeeStatusMessage(status).c_str(), bind_total);
|
), status, getZigbeeStatusMessage(status).c_str(), bind_total);
|
||||||
|
|
||||||
|
@ -631,7 +629,7 @@ int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu
|
||||||
int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) {
|
int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) {
|
||||||
uint16_t groupid = buf.get16(2);
|
uint16_t groupid = buf.get16(2);
|
||||||
uint16_t clusterid = buf.get16(4);
|
uint16_t clusterid = buf.get16(4);
|
||||||
Z_ShortAddress srcaddr = buf.get16(6);
|
uint16_t srcaddr = buf.get16(6);
|
||||||
uint8_t srcendpoint = buf.get8(8);
|
uint8_t srcendpoint = buf.get8(8);
|
||||||
uint8_t dstendpoint = buf.get8(9);
|
uint8_t dstendpoint = buf.get8(9);
|
||||||
uint8_t wasbroadcast = buf.get8(10);
|
uint8_t wasbroadcast = buf.get8(10);
|
||||||
|
|
|
@ -147,7 +147,7 @@ void ZigbeeInputLoop(void)
|
||||||
// Initialize internal structures
|
// Initialize internal structures
|
||||||
void ZigbeeInit(void)
|
void ZigbeeInit(void)
|
||||||
{
|
{
|
||||||
// Check if settings if Flash are set
|
// Check if settings in Flash are set
|
||||||
if (0 == Settings.zb_channel) {
|
if (0 == Settings.zb_channel) {
|
||||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Initializing Zigbee parameters from defaults"));
|
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Initializing Zigbee parameters from defaults"));
|
||||||
Settings.zb_ext_panid = USE_ZIGBEE_EXTPANID;
|
Settings.zb_ext_panid = USE_ZIGBEE_EXTPANID;
|
||||||
|
@ -314,7 +314,7 @@ void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterI
|
||||||
SBuffer buf(32+len);
|
SBuffer buf(32+len);
|
||||||
buf.add8(Z_SREQ | Z_AF); // 24
|
buf.add8(Z_SREQ | Z_AF); // 24
|
||||||
buf.add8(AF_DATA_REQUEST_EXT); // 02
|
buf.add8(AF_DATA_REQUEST_EXT); // 02
|
||||||
if (0x0000 == shortaddr) { // if no shortaddr we assume group address
|
if (BAD_SHORTADDR == shortaddr) { // if no shortaddr we assume group address
|
||||||
buf.add8(Z_Addr_Group); // 01
|
buf.add8(Z_Addr_Group); // 01
|
||||||
buf.add64(groupaddr); // group address, only 2 LSB, upper 6 MSB are discarded
|
buf.add64(groupaddr); // group address, only 2 LSB, upper 6 MSB are discarded
|
||||||
buf.add8(0xFF); // dest endpoint is not used for group addresses
|
buf.add8(0xFF); // dest endpoint is not used for group addresses
|
||||||
|
@ -372,7 +372,7 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((0 == endpoint) && (shortaddr)) {
|
if ((0 == endpoint) && (BAD_SHORTADDR != shortaddr)) {
|
||||||
// endpoint is not specified, let's try to find it from shortAddr, unless it's a group address
|
// endpoint is not specified, let's try to find it from shortAddr, unless it's a group address
|
||||||
endpoint = zigbee_devices.findFirstEndpoint(shortaddr);
|
endpoint = zigbee_devices.findFirstEndpoint(shortaddr);
|
||||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: guessing endpoint 0x%02X"), endpoint);
|
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: guessing endpoint 0x%02X"), endpoint);
|
||||||
|
@ -380,7 +380,7 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint,
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: shortaddr 0x%04X, groupaddr 0x%04X, cluster 0x%04X, endpoint 0x%02X, cmd 0x%02X, data %s"),
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: shortaddr 0x%04X, groupaddr 0x%04X, cluster 0x%04X, endpoint 0x%02X, cmd 0x%02X, data %s"),
|
||||||
shortaddr, groupaddr, cluster, endpoint, cmd, param);
|
shortaddr, groupaddr, cluster, endpoint, cmd, param);
|
||||||
|
|
||||||
if ((0 == endpoint) && (shortaddr)) { // endpoint null is ok for group address
|
if ((0 == endpoint) && (BAD_SHORTADDR != shortaddr)) { // endpoint null is ok for group address
|
||||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbSend: unspecified endpoint"));
|
AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbSend: unspecified endpoint"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -415,7 +415,7 @@ void CmndZbSend(void) {
|
||||||
|
|
||||||
// params
|
// params
|
||||||
static char delim[] = ", "; // delimiters for parameters
|
static char delim[] = ", "; // delimiters for parameters
|
||||||
uint16_t device = 0x0000; // 0x0000 is local, so considered invalid
|
uint16_t device = BAD_SHORTADDR; // 0x0000 is local, so considered invalid
|
||||||
uint16_t groupaddr = 0x0000; // group address
|
uint16_t groupaddr = 0x0000; // group address
|
||||||
uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint
|
uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint
|
||||||
uint16_t manuf = 0x0000; // Manuf Id in ZCL frame
|
uint16_t manuf = 0x0000; // Manuf Id in ZCL frame
|
||||||
|
@ -430,9 +430,9 @@ void CmndZbSend(void) {
|
||||||
const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device"));
|
const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device"));
|
||||||
if (nullptr != &val_device) {
|
if (nullptr != &val_device) {
|
||||||
device = zigbee_devices.parseDeviceParam(val_device.as<char*>());
|
device = zigbee_devices.parseDeviceParam(val_device.as<char*>());
|
||||||
if (0xFFFF == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
if (BAD_SHORTADDR == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
||||||
}
|
}
|
||||||
if (0x0000 == device) { // if not found, check if we have a group
|
if (BAD_SHORTADDR == device) { // if not found, check if we have a group
|
||||||
const JsonVariant &val_group = getCaseInsensitive(json, PSTR("Group"));
|
const JsonVariant &val_group = getCaseInsensitive(json, PSTR("Group"));
|
||||||
if (nullptr != &val_group) {
|
if (nullptr != &val_group) {
|
||||||
groupaddr = strToUInt(val_group);
|
groupaddr = strToUInt(val_group);
|
||||||
|
@ -571,8 +571,8 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind
|
||||||
|
|
||||||
// params
|
// params
|
||||||
// static char delim[] = ", "; // delimiters for parameters
|
// static char delim[] = ", "; // delimiters for parameters
|
||||||
uint16_t srcDevice = 0xFFFF; // 0xFFFF is broadcast, so considered invalid
|
uint16_t srcDevice = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid
|
||||||
uint16_t dstDevice = 0xFFFF; // 0xFFFF is broadcast, so considered invalid
|
uint16_t dstDevice = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid
|
||||||
uint64_t dstLongAddr = 0;
|
uint64_t dstLongAddr = 0;
|
||||||
uint8_t endpoint = 0x00; // 0x00 is invalid for the src endpoint
|
uint8_t endpoint = 0x00; // 0x00 is invalid for the src endpoint
|
||||||
uint8_t toendpoint = 0x00; // 0x00 is invalid for the dst endpoint
|
uint8_t toendpoint = 0x00; // 0x00 is invalid for the dst endpoint
|
||||||
|
@ -585,9 +585,8 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind
|
||||||
const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device"));
|
const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device"));
|
||||||
if (nullptr != &val_device) {
|
if (nullptr != &val_device) {
|
||||||
srcDevice = zigbee_devices.parseDeviceParam(val_device.as<char*>());
|
srcDevice = zigbee_devices.parseDeviceParam(val_device.as<char*>());
|
||||||
if (0xFFFF == srcDevice) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
|
||||||
}
|
}
|
||||||
if ((nullptr == &val_device) || (0x0000 == srcDevice)) { ResponseCmndChar_P(PSTR("Unknown source device")); return; }
|
if ((nullptr == &val_device) || (BAD_SHORTADDR == srcDevice)) { ResponseCmndChar_P(PSTR("Unknown source device")); return; }
|
||||||
// check if IEEE address is known
|
// check if IEEE address is known
|
||||||
uint64_t srcLongAddr = zigbee_devices.getDeviceLongAddr(srcDevice);
|
uint64_t srcLongAddr = zigbee_devices.getDeviceLongAddr(srcDevice);
|
||||||
if (0 == srcLongAddr) { ResponseCmndChar_P(PSTR("Unknown source IEEE address")); return; }
|
if (0 == srcLongAddr) { ResponseCmndChar_P(PSTR("Unknown source IEEE address")); return; }
|
||||||
|
@ -605,7 +604,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind
|
||||||
const JsonVariant &dst_device = getCaseInsensitive(json, PSTR("ToDevice"));
|
const JsonVariant &dst_device = getCaseInsensitive(json, PSTR("ToDevice"));
|
||||||
if (nullptr != &dst_device) {
|
if (nullptr != &dst_device) {
|
||||||
dstDevice = zigbee_devices.parseDeviceParam(dst_device.as<char*>());
|
dstDevice = zigbee_devices.parseDeviceParam(dst_device.as<char*>());
|
||||||
if (0xFFFF == dstDevice) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
if (BAD_SHORTADDR == dstDevice) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
||||||
if (0x0000 == dstDevice) {
|
if (0x0000 == dstDevice) {
|
||||||
dstLongAddr = localIEEEAddr;
|
dstLongAddr = localIEEEAddr;
|
||||||
} else {
|
} else {
|
||||||
|
@ -622,8 +621,8 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind
|
||||||
if (nullptr != &to_group) { toGroup = strToUInt(to_group); }
|
if (nullptr != &to_group) { toGroup = strToUInt(to_group); }
|
||||||
|
|
||||||
// make sure we don't have conflicting parameters
|
// make sure we don't have conflicting parameters
|
||||||
if (toGroup && dstLongAddr) { ResponseCmndChar_P(PSTR("Cannot have both \"ToDevice\" and \"ToGroup\"")); return; }
|
if (&to_group && dstLongAddr) { ResponseCmndChar_P(PSTR("Cannot have both \"ToDevice\" and \"ToGroup\"")); return; }
|
||||||
if (!toGroup && !dstLongAddr) { ResponseCmndChar_P(PSTR("Missing \"ToDevice\" or \"ToGroup\"")); return; }
|
if (!&to_group && !dstLongAddr) { ResponseCmndChar_P(PSTR("Missing \"ToDevice\" or \"ToGroup\"")); return; }
|
||||||
|
|
||||||
SBuffer buf(34);
|
SBuffer buf(34);
|
||||||
buf.add8(Z_SREQ | Z_ZDO);
|
buf.add8(Z_SREQ | Z_ZDO);
|
||||||
|
@ -670,8 +669,7 @@ void CmndZbUnbind(void) {
|
||||||
void CmndZbBindState(void) {
|
void CmndZbBindState(void) {
|
||||||
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
||||||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
||||||
if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||||
if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
|
||||||
|
|
||||||
SBuffer buf(10);
|
SBuffer buf(10);
|
||||||
buf.add8(Z_SREQ | Z_ZDO); // 25
|
buf.add8(Z_SREQ | Z_ZDO); // 25
|
||||||
|
@ -695,8 +693,7 @@ void CmndZbProbe(void) {
|
||||||
void CmndZbProbeOrPing(boolean probe) {
|
void CmndZbProbeOrPing(boolean probe) {
|
||||||
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
||||||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
||||||
if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||||
if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
|
||||||
|
|
||||||
// everything is good, we can send the command
|
// everything is good, we can send the command
|
||||||
Z_SendIEEEAddrReq(shortaddr);
|
Z_SendIEEEAddrReq(shortaddr);
|
||||||
|
@ -731,8 +728,7 @@ void CmndZbName(void) {
|
||||||
|
|
||||||
// parse first part, <device_id>
|
// parse first part, <device_id>
|
||||||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered
|
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered
|
||||||
if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||||
if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
|
||||||
|
|
||||||
if (p == nullptr) {
|
if (p == nullptr) {
|
||||||
const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr);
|
const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr);
|
||||||
|
@ -763,8 +759,7 @@ void CmndZbModelId(void) {
|
||||||
|
|
||||||
// parse first part, <device_id>
|
// parse first part, <device_id>
|
||||||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered
|
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered
|
||||||
if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||||
if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
|
||||||
|
|
||||||
if (p == nullptr) {
|
if (p == nullptr) {
|
||||||
const char * modelId = zigbee_devices.getModelId(shortaddr);
|
const char * modelId = zigbee_devices.getModelId(shortaddr);
|
||||||
|
@ -793,8 +788,7 @@ void CmndZbLight(void) {
|
||||||
|
|
||||||
// parse first part, <device_id>
|
// parse first part, <device_id>
|
||||||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered
|
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered
|
||||||
if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||||
if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
int8_t bulbtype = strtol(p, nullptr, 10);
|
int8_t bulbtype = strtol(p, nullptr, 10);
|
||||||
|
@ -817,8 +811,7 @@ void CmndZbLight(void) {
|
||||||
void CmndZbForget(void) {
|
void CmndZbForget(void) {
|
||||||
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
||||||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
||||||
if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||||
if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
|
||||||
|
|
||||||
// everything is good, we can send the command
|
// everything is good, we can send the command
|
||||||
if (zigbee_devices.removeDevice(shortaddr)) {
|
if (zigbee_devices.removeDevice(shortaddr)) {
|
||||||
|
@ -906,7 +899,7 @@ void CmndZbRead(void) {
|
||||||
if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; }
|
if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; }
|
||||||
|
|
||||||
// params
|
// params
|
||||||
uint16_t device = 0xFFFF; // 0xFFFF is braodcast, so considered valid
|
uint16_t device = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid
|
||||||
uint16_t groupaddr = 0x0000; // if 0x0000 ignore group adress
|
uint16_t groupaddr = 0x0000; // if 0x0000 ignore group adress
|
||||||
uint16_t cluster = 0x0000; // default to general cluster
|
uint16_t cluster = 0x0000; // default to general cluster
|
||||||
uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint
|
uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint
|
||||||
|
@ -917,9 +910,9 @@ void CmndZbRead(void) {
|
||||||
const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device"));
|
const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device"));
|
||||||
if (nullptr != &val_device) {
|
if (nullptr != &val_device) {
|
||||||
device = zigbee_devices.parseDeviceParam(val_device.as<char*>());
|
device = zigbee_devices.parseDeviceParam(val_device.as<char*>());
|
||||||
if (0xFFFF == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
if (BAD_SHORTADDR == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
||||||
}
|
}
|
||||||
if (0x0000 == device) { // if not found, check if we have a group
|
if (BAD_SHORTADDR == device) { // if not found, check if we have a group
|
||||||
const JsonVariant &val_group = getCaseInsensitive(json, PSTR("Group"));
|
const JsonVariant &val_group = getCaseInsensitive(json, PSTR("Group"));
|
||||||
if (nullptr != &val_group) {
|
if (nullptr != &val_group) {
|
||||||
groupaddr = strToUInt(val_group);
|
groupaddr = strToUInt(val_group);
|
||||||
|
@ -960,9 +953,9 @@ void CmndZbRead(void) {
|
||||||
|
|
||||||
if ((0 == endpoint) && (device)) { // try to compute the endpoint
|
if ((0 == endpoint) && (device)) { // try to compute the endpoint
|
||||||
endpoint = zigbee_devices.findFirstEndpoint(device);
|
endpoint = zigbee_devices.findFirstEndpoint(device);
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: guessing endpoint 0x%02X"), endpoint);
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbRead: guessing endpoint 0x%02X"), endpoint);
|
||||||
}
|
}
|
||||||
if (0x0000 == device) {
|
if (BAD_SHORTADDR == device) {
|
||||||
endpoint = 0xFF; // endpoint not used for group addresses
|
endpoint = 0xFF; // endpoint not used for group addresses
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,9 +1005,8 @@ void CmndZbStatus(void) {
|
||||||
if (ZigbeeSerial) {
|
if (ZigbeeSerial) {
|
||||||
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
|
||||||
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data);
|
||||||
if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; }
|
|
||||||
if (XdrvMailbox.payload > 0) {
|
if (XdrvMailbox.payload > 0) {
|
||||||
if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
String dump = zigbee_devices.dump(XdrvMailbox.index, shortaddr);
|
String dump = zigbee_devices.dump(XdrvMailbox.index, shortaddr);
|
||||||
|
|
Loading…
Reference in New Issue