From be86c44846dc4882bac926a5cf7ec43229e636c6 Mon Sep 17 00:00:00 2001 From: Daniel Tartavel Date: Mon, 24 Apr 2023 21:57:35 +0200 Subject: [PATCH] serial fonctional --- docs/Stack_zigbee_3.ods | Bin 30867 -> 28837 bytes docs/properties.txt | 115 ++++++ library.h | 2 + responseClasses.h | 27 +- zigateBackend.cpp | 66 +-- zigateBackend.h | 192 ++++----- zigateInit.cpp | 872 ++++++++++++++++++---------------------- zigatecmd.cpp | 4 +- zigbeemanager.pro | 4 +- zigbeemanager.pro.user | 430 -------------------- 10 files changed, 671 insertions(+), 1041 deletions(-) create mode 100644 docs/properties.txt delete mode 100644 zigbeemanager.pro.user diff --git a/docs/Stack_zigbee_3.ods b/docs/Stack_zigbee_3.ods index e53ad9a4b192ca526ccdcaa68e533fe92a6c6d76..48f5c602d8f72331d64132cf1a859d6c1b1d8db6 100644 GIT binary patch delta 23843 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 P + #define DEBUG 1 #define INFO 2 #define WARNING 3 diff --git a/responseClasses.h b/responseClasses.h index c8e58b8..5f37568 100644 --- a/responseClasses.h +++ b/responseClasses.h @@ -5,6 +5,18 @@ #include #include #include +#include + +//void (*propertyManager)(QByteArray); + +class Response +{ + public: + QByteArray code; + QByteArray datas; + QString description; + void manager(Response *); +}; class ResponseProperties { @@ -14,16 +26,13 @@ class ResponseProperties QString description; QMap > properties; QMap > propertyDetail; - QFunctionPointer manager; + QHash propertyManagerList; + void (*manager)(Response *); }; -class Response -{ - public: - QByteArray code; - QByteArray datas; - QString description; - QFunctionPointer manager; -}; +void infoOutput(Response *); +void defaultManager(Response *); +//void (*manager)(Response *); +void macCapabilityManager(QByteArray); #endif // RESPONSECLASSES_H diff --git a/zigateBackend.cpp b/zigateBackend.cpp index f2f593b..16fd212 100644 --- a/zigateBackend.cpp +++ b/zigateBackend.cpp @@ -1,5 +1,4 @@ -#include "main.h" -#include "responseClasses.h" +#include "zigateBackend.h" #include using namespace std; @@ -35,6 +34,8 @@ ZigateBackend::~ZigateBackend() { } + + QByteArray ZigateBackend::checksum(QByteArray msgType, QByteArray length, QByteArray datas) { quint16 temp = 0; @@ -150,14 +151,14 @@ int ZigateBackend::interpretResult(QByteArray payload) quint8 crctmp = 0; uint i = 0; int datasResultLength = 0; - ResponseProperties * responseObject = nullptr; + Response responseObject; QByteArray type; uint ln; quint8 crc; QByteArray datasResult; QByteArray quality; QByteArray payloadD; - + uint typeA; payloadD = unTranscode(payload); length = payloadD.count(); @@ -166,39 +167,44 @@ int ZigateBackend::interpretResult(QByteArray payload) crctmp = 0; //type de message type = payloadD.mid(0, 2); - crctmp = crctmp ^ payloadD.at(0) ^ payloadD.at(1); ln = payloadD.mid(2, 2).toHex().toUInt(nullptr, 16); - crctmp = crctmp ^ payloadD.at(2) ^ payloadD.at(3); - //acquisition du CRC - crc = payloadD.at(4); - //datasResult - datasResult = ""; - for(i=0;idatas = datasResult; - responseObject->manager(); + datasResult += payloadD.at(5+i); + crctmp ^= payloadD.at(5+i); + } + quality = payloadD.right(1); + + datasResultLength = datasResult.count(); + + //verification du CRC + if (crc == crctmp) + { + if (responseListIndex[type.toHex()]->manager != nullptr) + { + responseObject.code = type; + responseObject.datas = datasResult; + // responseObject.properties = responseListIndex[type]->properties + responseListIndex[type.toHex()]->manager(&responseObject); + + }else + { + cout << "unknown command or command not implemented :" << type.toHex().toStdString() << endl; + } }else { - cout << "unknown command" << endl; + tab=-2; } - }else - { - tab=-2; } - payloadD.remove(0,i+6); + payloadD.remove(0,ln+6); length = payloadD.count(); } return tab; diff --git a/zigateBackend.h b/zigateBackend.h index ab4e05e..1a66d5f 100644 --- a/zigateBackend.h +++ b/zigateBackend.h @@ -1,43 +1,109 @@ #ifndef ZIGATEBACKEND_H #define ZIGATEBACKEND_H -#include "main.h" +#define DEVICE_ANNOUNCE "004D" +#define STATUS_RETURNED "8000" +#define LOG_MESSAGE "8001" +#define DATA_INDICATION "8002" +#define CLUSTERS_LIST "8003" +#define ATTRIBUTES_LIST "8004" +#define COMMANDS_LIST "8005" +#define STATUS "8006" +#define STATUS2 "8007" +#define VERSION_LIST "8010" +#define PERMIT_JOIN "8014" +#define NETWORK_JOINED_FORMED "8024" +#define BIND_RESPONSE "8030" +#define UNBIND_RESPONSE "8031" +#define NETWORK_ADDRESS "8040" +#define IEEE_ADDRESS "8041" +#define NODE_DESCRIPTOR "8042" +#define SIMPLE_DESCRIPTOR "8043" +#define POWER_DESCRIPTOR "8044" +#define ACTIVE_ENDPOINT "8045" +#define MATCH_DESCRIPTOR "8046" +#define USER_DESCRIPTOR_NOTIFY "802B" +#define USER_DESCRIPTOR "802C" +#define MANAGEMENT_LEAVE "8047" +#define LEAVE_INDICATION "8048" +#define MANAGEMENT_NETWORK_UPDATE "804A" +#define SYSTEM_SERVER_DISCOVERY "804B" +#define MANAGEMENT_LQI "804E" +#define ATTRIBUTE_DISCOVERY "8140" +#define HEARTBEAT "8008" +#define NETWORK_STATE "8009" +#define ACK_DATA "8011" +#define DATA_CONFIRM "8012" +#define DEVICES_LIST "8015" +#define TIME_SERVER "8017" +#define AUTHENTICATE_RESPONSE "8028" +#define PDM_EVENT "8035" +#define PERMIT_JOINING "8049" +#define PDM_CHILD_TABLE_SIZE "8052" +#define ADD_GROUP "8060" +#define VIEW_GROUP "8061" +#define GROUP_MEMBERSHIP "8062" +#define REMOVE_GROUP "8063" +#define LEVEL_UPDATE "8085" +#define ON_OFF "8095" +#define VIEW_SCENE "80A0" +#define ADD_SCENE "80A1" +#define REMOVE_SCENE "80A2" +#define REMOVE_ALL_SCENE "80A3" +#define STORE_SCENE "80A4" +#define SCENE_MEMBERSHIP "80A6" +#define SCENES_UPDATE "80A7" +#define READ_INDIVIDUAL_ATTRIBUTE "8100" +#define DEFAULT_RESPONSE "8101" +#define REPORT_INDIVIDUAL_ATTRIBUTE "8102" +#define WRITE_ATTRIBUTE "8110" +#define CONFIGURE_REPORTING "8120" +#define READ_REPORT_CONFIG "8122" +#define COMPLEX_DESCRIPTOR "8531" +#define ROUTER_DISCOVERY "8701" +#define APS_DATA_CONFIRM_FAIL "8702" +#define EXTENDED_ERROR "9999" + +#include "library.h" #include "serial.inc.h" #include #include #include #include "responseClasses.h" -void deviceAnnounceManager(); -void commandReturnStatusManager(); -void logMessageManager(); -void dataIndicationManager(); -void clustersListManager(); -void attributesListManager(); -void commandsListManager(); -void statusManager(); -void status2Manager(); -void versionListManager(); -void permitJoinManager(); -void networkJoinedFormedManager(); -void bindResponseManager(); -void unbindResponseManager(); -void networkAddressManager(); -void iEEEAddressManager(); -void nodeDescriptorManager(); -void simpleDescriptorManager(); -void powerDescriptorManager(); -void activeEndpointManager(); -void matchDescriptorManager(); -void userDescriptorNotifyManager(); -void userDescriptorManager(); -void complexDescriptorManager(); -void managementLeaveManager(); -void leaveIndicationManager(); -void managementNetworkUpdateManager(); -void systemServerDiscoveryManager(); -void managementLQIManager(); -void attributeDiscoveryManager(); +//void deviceAnnounceManager(Response *); +//void commandReturnStatusManager(Response *); +//void logMessageManager(Response *); +//void dataIndicationManager(Response *); +void clustersListManager(Response *); +//void attributesListManager(Response *); +//void commandsListManager(Response *); +//void statusManager(Response *); +//void status2Manager(Response *); +//void versionListManager(Response *); +//void permitJoinManager(Response *); +//void networkJoinedFormedManager(Response *); +//void bindResponseManager(Response *); +//void unbindResponseManager(Response *); +//void networkAddressManager(Response *); +void iEEEAddressManager(Response *); +void nodeDescriptorManager(Response *); +void simpleDescriptorManager(Response *); +//void powerDescriptorManager(Response *); +//void activeEndpointManager(Response *); +//void matchDescriptorManager(Response *); +//void userDescriptorNotifyManager(Response *); +//void userDescriptorManager(Response *); +//void complexDescriptorManager(Response *); +//void managementLeaveManager(Response *); +//void leaveIndicationManager(Response *); +//void managementNetworkUpdateManager(Response *); +//void systemServerDiscoveryManager(Response *); +//void managementLQIManager(Response *); +//void attributeDiscoveryManager(Response *); +void deviceListManager(Response *); +void networkAddressManager(Response *); +void dataIndicationManager(Response *); class ZigbeeMgr; @@ -152,7 +218,6 @@ class ZigateBackend : public ZigbeeMgr {"iASZoneEnrollResponse", {"0400", "0007", ""}}, {"rawApsDataRequest", {"0530", "000D", ""}} }; - QHash responseListIndex; QList responseListCode @@ -256,66 +321,5 @@ class ZigateBackend : public ZigbeeMgr }; }; -#define DEVICE_ANNOUNCE "004D" -#define STATUS_RETURNED "8000" -#define LOG_MESSAGE "8001" -#define DATA_INDICATION "8002" -#define CLUSTERS_LIST "8003" -#define ATTRIBUTES_LIST "8004" -#define COMMANDS_LIST "8005" -#define STATUS "8006" -#define STATUS2 "8007" -#define VERSION_LIST "8010" -#define PERMIT_JOIN "8014" -#define NETWORK_JOINED_FORMED "8024" -#define BIND_RESPONSE "8030" -#define UNBIND_RESPONSE "8031" -#define NETWORK_ADDRESS "8040" -#define IEEE_ADDRESS "8041" -#define NODE_DESCRIPTOR "8042" -#define SIMPLE_DESCRIPTOR "8043" -#define POWER_DESCRIPTOR "8044" -#define ACTIVE_ENDPOINT "8045" -#define MATCH_DESCRIPTOR "8046" -#define USER_DESCRIPTOR_NOTIFY "802B" -#define USER_DESCRIPTOR "802C" -#define MANAGEMENT_LEAVE "8047" -#define LEAVE_INDICATION "8048" -#define MANAGEMENT_NETWORK_UPDATE "804A" -#define SYSTEM_SERVER_DISCOVERY "804B" -#define MANAGEMENT_LQI "804E" -#define ATTRIBUTE_DISCOVERY "8140" -#define HEARTBEAT "8008" -#define NETWORK_STATE "8009" -#define ACK_DATA "8011" -#define DATA_CONFIRM "8012" -#define DEVICES_LIST "8015" -#define TIME_SERVER "8017" -#define AUTHENTICATE_RESPONSE "8028" -#define PDM_EVENT "8035" -#define PERMIT_JOINING "8049" -#define PDM_CHILD_TABLE_SIZE "8052" -#define ADD_GROUP "8060" -#define VIEW_GROUP "8061" -#define GROUP_MEMBERSHIP "8062" -#define REMOVE_GROUP "8063" -#define LEVEL_UPDATE "8085" -#define ON_OFF "8095" -#define VIEW_SCENE "80A0" -#define ADD_SCENE "80A1" -#define REMOVE_SCENE "80A2" -#define REMOVE_ALL_SCENE "80A3" -#define STORE_SCENE "80A4" -#define SCENE_MEMBERSHIP "80A6" -#define SCENES_UPDATE "80A7" -#define READ_INDIVIDUAL_ATTRIBUTE "8100" -#define DEFAULT_RESPONSE "8101" -#define REPORT_INDIVIDUAL_ATTRIBUTE "8102" -#define WRITE_ATTRIBUTE "8110" -#define CONFIGURE_REPORTING "8120" -#define READ_REPORT_CONFIG "8122" -#define COMPLEX_DESCRIPTOR "8531" -#define ROUTER_DISCOVERY "8701" -#define APS_DATA_CONFIRM_FAIL "8702" -#define EXTENDED_ERROR "9999" + #endif // ZIGATEBACKEND_H diff --git a/zigateInit.cpp b/zigateInit.cpp index cce0e6a..618c615 100644 --- a/zigateInit.cpp +++ b/zigateInit.cpp @@ -1,8 +1,8 @@ -#include "responseClasses.h" #include "zigateBackend.h" #include extern ZigateBackend zigateBkd; +extern QHash responseListIndex; using namespace std; @@ -15,6 +15,7 @@ bool ZigateBackend::initBackend() foreach (var, responseListCode) { temp = new ResponseProperties(); + temp->manager = &defaultManager; responseListIndex.insert(var, temp) ; } @@ -26,12 +27,15 @@ bool ZigateBackend::initBackend() // {rang, {designation, nbyte, isvalue}} // isvalue = 0 => display value // = 1 => is array of bits - // = 2 => is index in string list + // = 2 => is index of string in list + // = 3 => launch a subroutine pointed by propertyManagerList + // = 4 => is a list of objects {0, {"Short address", 2, 0}}, // uint16_t {1, {"IEEE address", 4, 0}}, // uint64_t - {2, {"MAC capability", 1, 1}} + {2, {"MAC capability", 1, 3}} }; - temp->manager = &deviceAnnounceManager; + temp->propertyManagerList[2] = &macCapabilityManager; + temp->manager = &defaultManager; temp->propertyDetail[2] = { {1, "Alternate PAN Coordinator"}, @@ -60,9 +64,9 @@ bool ZigateBackend::initBackend() {0, {"Status", 1, 2}}, // {1, {"Sequence number", 1, 0}}, // {2, {"Packet Type", 2, 0}}, // - {3, {"Optional additional error information", -1, 0}} // + {3, {"Optional additional error information", -1, 5}} // }; - temp->manager = &commandReturnStatusManager; + temp->manager = &defaultManager; temp->propertyDetail[0] = { {0, "Success"}, @@ -74,15 +78,15 @@ bool ZigateBackend::initBackend() {-1, "Failed"} }; // ***************************************************************************** - // * Status : - // * 0 = Success - // * 1 = Incorrect parameters - // * 2 = Unhandled command - // * 3 = Command failed - // * 4 = Busy (Node is carrying out a lengthy operation and is currently unable to handle the incoming command) - // * 5 = Stack already started (no new configuration accepted) - // * 128 – 244 = Failed (ZigBee event codes) - // * Packet Type: The value of the initiating command request. + // // Status : + // // 0 = Success + // // 1 = Incorrect parameters + // // 2 = Unhandled command + // // 3 = Command failed + // // 4 = Busy (Node is carrying out a lengthy operation and is currently unable to handle the incoming command) + // // 5 = Stack already started (no new configuration accepted) + // // 128 – 244 = Failed (ZigBee event codes) + // // Packet Type: The value of the initiating command request. // ****************************************************************************** temp = responseListIndex["8001"]; @@ -90,42 +94,62 @@ bool ZigateBackend::initBackend() temp->description = "Log message"; temp->properties = { - {0, {"Log level", 1}}, // uint8_t - {1, {"Log message", -1}} // string + {0, {"Log level", 1, 2}}, // uint8_t + {1, {"Log message", -1, 5}} // string }; - temp->manager = &logMessageManager; - + temp->manager = &defaultManager; + temp->propertyDetail[0] = + { + {0, "Emergency"}, + {1, "Alert"}, + {2, "Critical"}, + {3, "Error"}, + {4, "Warning"}, + {5, "Notice"}, + {6, "Information"}, + {7, "Debug"} + }; + // ********************************************************************************* + // 0 = Emergency + // 1 = Alert + // 2 = Critical + // 3 = Error + // 4 = Warning + // 5 = Notice + // 6 = Information + // 7 = Debug + // ********************************************************************************* temp = responseListIndex["8002"]; temp->code = QByteArray::fromHex("8002"); temp->description = "Data indication"; temp->properties = { - {0, {"status", 1}}, // uint8_t - {1, {"Profile ID", 2}}, // uint16_t - {2, {"Cluster ID", 2}}, // uint16_t - {3, {"Source endpoint", 1}}, // uint8_t - {4, {"Destination endpoint", 1}}, // uint8_t - {5, {"Source address mode", 1}}, // uint8_t - {6, {"Source address", 2}}, // uint16_t or uint64_t - {7, {"Destination address mode", 1}}, // uint8_t + {0, {"status", 1, 1}}, // uint8_t + {1, {"Profile ID", 2, 0}}, // uint16_t + {2, {"Cluster ID", 2, 0}}, // uint16_t + {3, {"Source endpoint", 1, 0}}, // uint8_t + {4, {"Destination endpoint", 1, 0}}, // uint8_t + {5, {"Source address mode", 1, 0}}, // uint8_t TODO + {6, {"Source address", 2, 0}}, // uint16_t or uint64_t + {7, {"Destination address mode", 0}}, // uint8_t TODO {8, {"Destination address", 2}}, // uint16_t or uint64_t {9, {"Payload size", 1}}, // uint8_t {10, {"Payload", -1}} // data each element is uint8_t }; - temp->manager = &dataIndicationManager; + temp->manager = &defaultManager; //dataIndicationManager temp = responseListIndex["8003"]; temp->code = QByteArray::fromHex("8003"); temp->description = "list of object's clusters"; temp->properties = { - {0, {"Source endpoint", 1}}, // uint8_t - {1, {"Profile ID", 2}}, // uint16_t - {2, {"Cluster list", 0}}, // data each entry is uint16_t - {3, {"Source endpoint", 1}}, // uint8_t - {4, {"Profile ID", 2}}, // uint16_t - {5, {"Cluster ID", 2}}, // uint16_t - {6, {"Attribute list", 2}} // data each entry is uint16_t + {0, {"Source endpoint", 1, 0}}, // uint8_t + {1, {"Profile ID", 2, 0}}, // uint16_t + {2, {"Cluster list", 0, 0}}, // data each entry is uint16_t + {3, {"Source endpoint", 1, 0}}, // uint8_t + {4, {"Profile ID", 2, 0}}, // uint16_t + {5, {"Cluster ID", 2, 0}}, // uint16_t + {6, {"Attribute list", 2 ,0}} // data each entry is uint16_t }; temp->manager = &clustersListManager; @@ -134,243 +158,274 @@ bool ZigateBackend::initBackend() temp->description = "list of object's attributes"; temp->properties = { - {0, {"Source endpoint", 1}}, // uint8_t - {1, {"Profile ID", 2}}, // uint16_t - {2, {"Cluster ID", 2}}, // uint16_t - {3, {"Attribute list", 2}} // data each entry is uint16_t> + {0, {"Source endpoint", 1, 0}}, // uint8_t + {1, {"Profile ID", 2, 0}}, // uint16_t + {2, {"Cluster ID", 2, 0}}, // uint16_t + {3, {"Attribute list", 2, 0}} // data each entry is uint16_t> }; - temp->manager = &attributesListManager; + temp->manager = &defaultManager; //TODO temp = responseListIndex["8005"]; temp->code = QByteArray::fromHex("8005"); temp->description = "List of object's commands"; temp->properties = { - {0, {"Source endpoint", 1}}, // uint8_t - {1, {"Profile ID", 1}}, // uint16_t - {2, {"Cluster ID", 1}}, // uint16_t - {3, {"Command ID list", -1}} // data each entry is uint8_t + {0, {"Source endpoint", 1, 0}}, // uint8_t + {1, {"Profile ID", 1, 0}}, // uint16_t + {2, {"Cluster ID", 1, 0}}, // uint16_t + {3, {"Command ID list", -1, 0}} // data each entry is uint8_t }; - temp->manager = &commandsListManager; + temp->manager = &defaultManager; //TODO temp = responseListIndex["8006"]; temp->code = QByteArray::fromHex("8006"); - temp->description = "Status"; + temp->description = "Status after restart"; temp->properties = { - {0, {"Status", 1}} + {0, {"Status after restart: ", 1, 2}} }; - temp->manager = &statusManager; + temp->manager = &defaultManager; + temp->propertyDetail[0] = + { + {0, "Startup"}, + {1, "NFN_START"}, + {2, "RUNNING"}, + }; + // ***************************************************************************** + // 0 - STARTUP + // 2 - NFN_START + // 6 - RUNNING + // The node is provisioned from previous restart. + // ***************************************************************************** temp = responseListIndex["8007"]; temp->code = QByteArray::fromHex("8007"); - temp->description = "Status"; + temp->description = "Status after start"; temp->properties = { - {0, {"Status", 1}} + {0, {"Status after start: ", 1, 2}} + }; + temp->manager = &defaultManager; + temp->propertyDetail[0] = + { + {0, "Startup"}, + {1, "NFN_START"}, + {2, "RUNNING"}, }; - temp->manager = &statusManager; - temp = responseListIndex["8008"]; temp->code = QByteArray::fromHex("8008"); temp->description = "HeartBeat"; temp->properties = { - {0, {"UTC time :", 4}} + {0, {"UTC time :", 4, 0}} }; - temp->manager = &hearbeatManager; + temp->manager = &defaultManager; temp = responseListIndex["8009"]; temp->code = QByteArray::fromHex("8009"); temp->description = "Network state"; temp->properties = { - {0, {"Short Address: ", 2}}, - {1, {"Extended Address: ", 8}}, - {2, {"PAN ID: ", 2}}, - {3, {"Extended PAN ID: ", 8}}, - {4, {"Channel: ", 8}} + {0, {"Short Address: ", 2, 0}}, + {1, {"Extended Address: ", 8, 0}}, + {2, {"PAN ID: ", 2, 0}}, + {3, {"Extended PAN ID: ", 8, 0}}, + {4, {"Channel: ", 8, 0}} }; - temp->manager = &networkStateManager; + temp->manager = &defaultManager; temp = responseListIndex["8010"]; temp->code = QByteArray::fromHex("8010"); temp->description = "Version List"; temp->properties = { - {0, {"Major version number", 2}}, // uint16_t - {1, {"Installer version number", 2}} // uint16_t + {0, {"Major version number", 2, 0}}, // uint16_t + {1, {"Installer version number", 2, 0}} // uint16_t }; - temp->manager = &versionListManager; + temp->manager = &defaultManager; temp = responseListIndex["8011"]; temp->code = QByteArray::fromHex("8011"); temp->description = "Ack Data"; temp->properties = { - {0, {"Status: ", 1}}, - {1, {"Destination address: ", 2}}, - {2, {"Destination endpoint: ", 1}}, - {3, {"Cluster ID :", 2}} + {0, {"Status: ", 1, 0}}, + {1, {"Destination address: ", 2, 0}}, + {2, {"Destination endpoint: ", 1, 0}}, + {3, {"Cluster ID :", 2, 0}} }; - temp->manager = &ackDataManager; + temp->manager = &defaultManager; temp = responseListIndex["8012"]; temp->code = QByteArray::fromHex("8012"); temp->description = "DATA_CONFIRM"; temp->properties = { - {0, {"Status: ", 1}}, - {1, {"Source Endpoint: ", 1}}, - {2, {"Destination endpoint: ", 1}}, - {3, {"Destination Address mode:", 1}}, - {4, {"Destination IEEE address: ", 8}}, - {5, {"APS Sequence number: ", 1}} + {0, {"Status: ", 1, }}, + {1, {"Source Endpoint: ", 1, 0}}, + {2, {"Destination endpoint: ", 1, 0}}, + {3, {"Destination Address mode:", 1, 0}}, + {4, {"Destination IEEE address: ", 8, 0}}, + {5, {"APS Sequence number: ", 1, 0}} }; - temp->manager = &dataConfirmManager; + temp->manager = &defaultManager; temp = responseListIndex["8014"]; temp->code = QByteArray::fromHex("8014"); temp->description = "Permit join status response"; temp->properties = { - {0, {"Status", 1}} // bool_t + {0, {"Status", 1, 2}} // bool_t + }; + temp->manager = &defaultManager; + temp->propertyDetail[0] = + { + {0, "Off"}, + {1, "On"} }; - temp->manager = &permitJoinManager; temp = responseListIndex["8015"]; temp->code = QByteArray::fromHex("8015"); temp->description = "Device list"; temp->properties = { - {0, {"Status", 1}} // bool_t + {0, {"Device List", 1, 4}} // bool_t }; - temp->manager = &permitJoinManager; + temp->manager = &deviceListManager; temp = responseListIndex["8017"]; temp->code = QByteArray::fromHex("8017"); temp->description = "Time server"; temp->properties = { - {0, {"ID: ", 1}}, - {1, {"Short address: ", 2}}, - {2, {"IEEE address: ", 8}}, - {3, {"Power source: ", 1}}, - {4, {"LinkQuality : ", 1}} - }; - temp->manager = &permitJoinManager; - temp->propertyDetail[3] = - { - {0, "Battery"}, - {1, "AC Power"} + {0, {"UTC Time: ", 1, 0}} // from 2000-01-01 00:00:00 }; + temp->manager = &defaultManager; temp = responseListIndex["8024"]; temp->code = QByteArray::fromHex("8024"); temp->description = "Network joined/formed"; temp->properties = { - {0, {"Status", 1}}, // uint8_t - {1, {"Short address", 2}}, // uint16_t - {2, {"Extended address", 4}}, // uint64_t - {3, {"Channel", 1}} // uint8_t + {0, {"Status", 1, 2}}, // uint8_t + {1, {"Short address", 2, 0}}, // uint16_t + {2, {"Extended address", 4, 0}}, // uint64_t + {3, {"Channel", 1, 0}} // uint8_t }; - temp->manager = &networkJoinedFormedManager; - - temp = responseListIndex["8024"]; - temp->code = QByteArray::fromHex("8024"); - temp->description = "Network joined/formed"; - temp->properties = - { - {0, {"Status", 1}}, // uint8_t - {1, {"Short address", 2}}, // uint16_t - {2, {"Extended address", 4}}, // uint64_t - {3, {"Channel", 1}} // uint8_t + temp->manager = &defaultManager; + temp->propertyDetail[0] = + { + {0, "Joined"}, + {1, "Formed new network"}, + {-1, "Failed"} }; - temp->manager = &networkJoinedFormedManager; temp = responseListIndex["8028"]; temp->code = QByteArray::fromHex("8028"); temp->description = "Authenticate response"; temp->properties = { - {0, {"IEEE address of the Gateway: ", 8}}, - {1, {"Encrypted Key: ", 16}}, - {2, {"MIC: ", 4}}, - {3, {"IEEE address of the initiating node: ", 8}}, - {4, {"Active Key Sequence number: ", 1}}, - {5, {"Channel: ", 1}}, - {6, {"Short PAN Id: ", 2}}, - {7, {"Extended PAN ID: ", 8}}, + {0, {"IEEE address of the Gateway: ", 8, 0}}, + {1, {"Encrypted Key: ", 16, 0}}, + {2, {"MIC: ", 4, 0}}, + {3, {"IEEE address of the initiating node: ", 8, 0}}, + {4, {"Active Key Sequence number: ", 1, 0}}, + {5, {"Channel: ", 1, 0}}, + {6, {"Short PAN Id: ", 2, 0}}, + {7, {"Extended PAN ID: ", 8, 0}}, }; - temp->manager = &authenticateResponse; + temp->manager = &defaultManager; temp = responseListIndex["802B"]; temp->code = QByteArray::fromHex("802B"); temp->description = "User Descriptor Notify"; temp->properties = { - {0, {"Sequence number", 1}}, // uin8_t - {1, {"Status", 1}}, // uint8_t - {2, {"Network address of interest", 2}} // uint16_t + {0, {"Sequence number", 1, 0}}, // uin8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"Network address of interest", 2, 0}} // uint16_t }; - temp->manager = &userDescriptorNotifyManager; + temp->manager = &defaultManager; temp = responseListIndex["802C"]; temp->code = QByteArray::fromHex("802C"); temp->description = "User Descriptor Response"; temp->properties = { - {0, {"Sequence number", 1}}, // uin8_t - {1, {"Status", 1}}, // uint8_t - {2, {"Network address of interest", 2}}, // uint16_6 - {3, {"Length", 1}}, // uint8_t + {0, {"Sequence number", 1, 0}}, // uin8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"Network address of interest", 2, 0}}, // uint16_6 + {3, {"Length", 1, 0}}, // uint8_t {4, {"Data", -1}} // uint8_t stream }; - temp->manager = &userDescriptorManager; + temp->manager = &defaultManager; temp = responseListIndex["8030"]; temp->code = QByteArray::fromHex("8030"); temp->description = "Bind response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"Status", 1}} // uint8_t + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"Status", 1}}, // uint8_t + {2, {"Source address mode: ", 1, 0}}, // uint8_t> (only from v3.1a) + {3, {"Source Address: ", 2, 0}} // uint16_t> (only from v3.1a) }; - temp->manager = &bindResponseManager; + temp->manager = &defaultManager; temp = responseListIndex["8031"]; temp->code = QByteArray::fromHex("8031"); temp->description = "Unbind response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"Status", 1}} // uint8_t + {0, {"Sequence number", 1}}, // uint8_t + {1, {"Status", 1}}, // uint8_t + {2, {"Source address mode: ", 1, 0}}, // uint8_t> (only from v3.1a) + {3, {"Source Address: ", 2, 0}} // uint16_t> (only from v3.1a) + }; - temp->manager = &unbindResponseManager; + temp->manager = &defaultManager; temp = responseListIndex["8035"]; temp->code = QByteArray::fromHex("8035"); temp->description = "PDM event"; temp->properties = { - {0, {"Event status: ", 1}}, // uint8_t - {1, {"record ID: ", 4}} // uint8_t + {0, {"Event status: ", 1, 2}}, // uint8_t + {1, {"record ID: ", 4, 0}} // uint8_t + }; + temp->manager = &defaultManager; + temp->propertyDetail[0] = + { + {0, "E_PDM_SYSTEM_EVENT_WEAR_COUNT_TRIGGER_VALUE_REACHED"}, + {1, "E_PDM_SYSTEM_EVENT_DESCRIPTOR_SAVE_FAILED"}, + {1, "E_PDM_SYSTEM_EVENT_PDM_NOT_ENOUGH_SPACE"}, + {1, "E_PDM_SYSTEM_EVENT_LARGEST_RECORD_FULL_SAVE_NO_LONGER_POSSIBLE"}, + {1, "E_PDM_SYSTEM_EVENT_SEGMENT_DATA_CHECKSUM_FAIL"}, + {1, "E_PDM_SYSTEM_EVENT_SEGMENT_SAVE_OK"}, + {1, "E_PDM_SYSTEM_EVENT_EEPROM_SEGMENT_HEADER_REPAIRED"}, + {1, "E_PDM_SYSTEM_EVENT_SYSTEM_INTERNAL_BUFFER_WEAR_COUNT_SWAP"}, + {1, "E_PDM_SYSTEM_EVENT_SYSTEM_DUPLICATE_FILE_SEGMENT_DETECTED"}, + {1, "E_PDM_SYSTEM_EVENT_SYSTEM_ERROR"}, + {1, "E_PDM_SYSTEM_EVENT_SEGMENT_PREWRITE"}, + {1, "E_PDM_SYSTEM_EVENT_SEGMENT_POSTWRITE"}, + {1, "E_PDM_SYSTEM_EVENT_SEQUENCE_DUPLICATE_DETECTED"}, + {1, "E_PDM_SYSTEM_EVENT_SEQUENCE_VERIFY_FAIL"}, + {1, "E_PDM_SYSTEM_EVENT_PDM_SMART_SAVE"}, + {1, "E_PDM_SYSTEM_EVENT_PDM_FULL_SAVE"} }; - temp->manager = &pdmEventManager; temp = responseListIndex["8040"]; temp->code = QByteArray::fromHex("8040"); temp->description = "Network Address response"; temp->properties = { - {0, {"Sequence number", 1}}, // uin8_t - {1, {"Status", 1}}, // uint8_t - {2, {"IEEE address", 4}}, // uint64_t - {3, {"Short address", 2}}, // uint16_t - {4, {"Number of associated devices", 1}}, // uint8_t - {5, {"Start index", 1}}, // uint8_t - {6, {"Device list", -1}} // data each entry is uint16_t> + {0, {"Sequence number", 1, 0}}, // uin8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"IEEE address", 4, 0}}, // uint64_t + {3, {"Short address", 2, 0}}, // uint16_t + {4, {"Number of associated devices", 1, 0}}, // uint8_t + {5, {"Start index", 1, 0}}, // uint8_t + {6, {"Device list", -1, 4}} // data each entry is uint16_t> }; temp->manager = &networkAddressManager; @@ -379,13 +434,13 @@ bool ZigateBackend::initBackend() temp->description = "IEEE Address response"; temp->properties = { - {0, {"Sequence number", 1}}, // uin8_t - {1, {"Status", 1}}, // uint8_t - {2, {"IEEE address", 4}}, // uint64_t - {3, {"Short address", 2}}, // uint16_t - {4, {"Number of associated devices", 1}}, // uint8_t - {5, {"Start index", 1}}, // uint8_t - {6, {"Device list", -1}} // data each entry is uint16_t + {0, {"Sequence number", 1, 0}}, // uin8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"IEEE address", 4, 0}}, // uint64_t + {3, {"Short address", 2, 0}}, // uint16_t + {4, {"Number of associated devices", 1, 0}}, // uint8_t + {5, {"Start index", 1, 0}}, // uint8_t + {6, {"Device list", -1, 4}} // data each entry is uint16_t }; temp->manager = &iEEEAddressManager; @@ -394,16 +449,16 @@ bool ZigateBackend::initBackend() temp->description = "Node Descriptor response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"Network address", 2}}, // uint16_t - {2, {"Manufacturer code", 2}}, // uint16_t - {3, {"Max Rx Size", 2}}, // uint16_t - {4, {"Max Tx Size", 2}}, // uint16_t - {5, {"Server mask", 2}}, // uint16_t - {6, {"Descriptor capability", 1}}, // uint8_t - {7, {"Mac flags", 1}}, // uint8_t - {8, {"Max buffer size", 1}}, // uint8_t - {9, {"Bit fields", 2}} // uint16_t + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"Network address", 2, 0}}, // uint16_t + {2, {"Manufacturer code", 2, 0}}, // uint16_t + {3, {"Max Rx Size", 2, 0}}, // uint16_t + {4, {"Max Tx Size", 2, 0}}, // uint16_t + {5, {"Server mask", 2, 0}}, // uint16_t + {6, {"Descriptor capability", 1, 0}}, // uint8_t + {7, {"Mac flags", 1, 0}}, // uint8_t + {8, {"Max buffer size", 1, 0}}, // uint8_t + {9, {"Bit fields", 2, -1}} // uint16_t }; temp->manager = &nodeDescriptorManager; @@ -412,274 +467,261 @@ bool ZigateBackend::initBackend() temp->description = "Simple Descriptor response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"Status", 1}}, // uint8_t - {2, {"NwkAddress", 2}}, // uint16_t - {3, {"Length", 1}}, // uint8_t - {4, {"Endpoint", 1}}, // uint8_t - {5, {"Profile", 2}}, // uint16_t - {6, {"Device id", 2}}, // uint16_t - {7, {"Bit fields", 1}}, // uint8_t - {8, {"InClusterCount", 1}}, // uint8_t - {9, {"In cluster list", 0}}, // data each entry is uint16_t> - {10, {"Out Cluster Count", 1}}, // uint8_t - {11, {"Out cluster list", -1}} // data each entry is uint16_t + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"NwkAddress", 2, 0}}, // uint16_t + {3, {"Length", 1, 0}}, // uint8_t + {4, {"Endpoint", 1, 0}}, // uint8_t + {5, {"Profile", 2, 0}}, // uint16_t + {6, {"Device id", 2, 0}}, // uint16_t + {7, {"Bit fields", 1, 0}}, // uint8_t + {8, {"InClusterCount", 1, 0}}, // uint8_t + {9, {"In cluster list", 0, 0}}, // data each entry is uint16_t> + {10, {"Out Cluster Count", 1, 0}}, // uint8_t + {11, {"Out cluster list", -1, 0}} // data each entry is uint16_t }; - temp->manager = &simpleDescriptorManager; + temp->manager = &defaultManager; //TODO temp = responseListIndex["8044"]; temp->code = QByteArray::fromHex("8044"); temp->description = "Power Descriptor response"; temp->properties = { - {0, {"Sequence number", 1}}, // uin8_t - {1, {"Status", 1}}, // uint8_t - {2, {"bit field", 2}} // uint16_t + {0, {"Sequence number", 1, 0}}, // uin8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"bit field", 2, }} // uint16_t }; - temp->manager = &powerDescriptorManager; + temp->manager = &defaultManager; + // ****************************************** + // 0 to 3: current power mode + // 4 to 7: available power source + // 8 to 11: current power source + // 12 to 15: current power source level + // ****************************************** temp = responseListIndex["8045"]; temp->code = QByteArray::fromHex("8045"); temp->description = "Active Endpoint response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"Status", 1}}, // uint8_t - {2, {"Address", 2}}, // uint16_t - {3, {"Endpoint count", 1}}, // uint8_t - {4, {"Active endpoint list", -1}} // each data element of the type uint8_t + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"Address", 2, 0}}, // uint16_t + {3, {"Endpoint count", 1, 0}}, // uint8_t + {4, {"Active endpoint list", -1, 0}} // each data element of the type uint8_t }; - temp->manager = &activeEndpointManager; + temp->manager = &defaultManager; temp = responseListIndex["8046"]; temp->code = QByteArray::fromHex("8046"); temp->description = "Match Descriptor response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"Status", 1}}, // uint8_t - {2, {"Network address", 2}}, // uint16_t - {3, {"Length of list", 1}}, // uint8_t - {4, {"Match list", -1}} // data each entry is uint8_t + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"Network address", 2, 0}}, // uint16_t + {3, {"Length of list", 1, 0}}, // uint8_t + {4, {"Match list", -1, 0}} // data each entry is uint8_t }; - temp->manager = &matchDescriptorManager; + temp->manager = &defaultManager; temp = responseListIndex["8047"]; temp->code = QByteArray::fromHex("8047"); temp->description = "Management Leave response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"Status", 1}} // uint8_t + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"Status", 1, 0}} // uint8_t }; - temp->manager = &managementLeaveManager; + temp->manager = &defaultManager; temp = responseListIndex["8048"]; temp->code = QByteArray::fromHex("8048"); temp->description = "Leave indication"; temp->properties = { - {0, {"Extended address", 4}}, // uint64_t - {1, {"Rejoin status", 1}} // uint8_t + {0, {"Extended address", 4, 0}}, // uint64_t + {1, {"Rejoin status", 1, 0}} // uint8_t }; - temp->manager = &leaveIndicationManager; + temp->manager = &defaultManager; temp = responseListIndex["8049"]; temp->code = QByteArray::fromHex("8049"); temp->description = "PDM child table size"; temp->properties = { - {0, {"Number of child: ", 1}} // data each entry is uint8_t + {0, {"Number of child: ", 1, 0}} // data each entry is uint8_t }; - temp->manager = &pdmChildTableSizeManager; + temp->manager = &defaultManager; temp = responseListIndex["804A"]; temp->code = QByteArray::fromHex("804A"); temp->description = "Management Network Update response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"Status", 1}}, // uint8_t - {2, {"Total transmission", 2}}, // uint16_t - {3, {"Transmission failures", 2}}, // uint16_t - {4, {"Scanned channels", 4}}, // uint32_t - {5, {"Scanned channel list count", 1}}, // uint8_t - {6, {"Channel list", -1}} // list each element is uint8_t + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"Status", 1, 0}}, // uint8_t + {2, {"Total transmission", 2, 0}}, // uint16_t + {3, {"Transmission failures", 2, 0}}, // uint16_t + {4, {"Scanned channels", 4, 0}}, // uint32_t + {5, {"Scanned channel list count", 1, 0}}, // uint8_t + {6, {"Channel list", -1, 0}} // list each element is uint8_t }; - temp->manager = &managementNetworkUpdateManager; + temp->manager = &defaultManager; temp = responseListIndex["804B"]; temp->code = QByteArray::fromHex("804B"); temp->description = "System Server Discovery response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"status", 1}}, // uint8_t - {2, {"Server mask", 2}} // uint16_t + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"status", 1, 0}}, // uint8_t + {2, {"Server mask", 2, 0}} // uint16_t }; - temp->manager = &systemServerDiscoveryManager; + temp->manager = &defaultManager; temp = responseListIndex["804E"]; temp->code = QByteArray::fromHex("804E"); temp->description = "Management LQI response"; temp->properties = { - {0, {"Sequence number", 1}}, // uint8_t - {1, {"status", 1}}, // uint8_t - {2, {"Neighbour Table Entries ", 1}}, // uint8_t - {3, {"Neighbour Table List Count ", 1}}, // uint8_t - {4, {"Start Index ", 1}}, // uint8_t - {5, {"List of Entries elements described below", -1}} + {0, {"Sequence number", 1, 0}}, // uint8_t + {1, {"status", 1, 0}}, // uint8_t + {2, {"Neighbour Table Entries ", 1, 0}}, // uint8_t + {3, {"Neighbour Table List Count ", 1, 0}}, // uint8_t + {4, {"Start Index ", 1, 0}}, // uint8_t + {5, {"List of Entries elements described below", -1, 0}} }; - temp->manager = &managementLQIManager; + temp->manager = &defaultManager; temp = responseListIndex["8060"]; temp->code = QByteArray::fromHex("8060"); temp->description = "Add group"; temp->properties = { - {0, {"Sequence number: ", 1}}, - {1, {"Endpoint: ", 1}}, - {2, {"Cluster id: ", 2}}, - {3, {"Status: ", 1}}, //(added only from 3.0f version) - {4, {"Group id :", 2}}, //(added only from 3.0f version) - {5, {"Source Address: ", 2}}, //(added only from 3.0f version) - {6, {"Number of child: ", 1}} // data each entry is uint8_t + {0, {"Sequence number: ", 1, 0}}, + {1, {"Endpoint: ", 1, 0}}, + {2, {"Cluster id: ", 2, 0}}, + {3, {"Status: ", 1, 0}}, //(added only from 3.0f version) + {4, {"Group id :", 2, 0}}, //(added only from 3.0f version) + {5, {"Source Address: ", 2, 0}}, //(added only from 3.0f version) + {6, {"Number of child: ", 1, 0}} // data each entry is uint8_t }; - temp->manager = &addGroupManager; + temp->manager = &defaultManager; temp = responseListIndex["8061"]; temp->code = QByteArray::fromHex("8061"); temp->description = "View group"; temp->properties = { - {0, {"Sequence number: ", 1}}, - {1, {"Endpoint: ", 1}}, - {2, {"Cluster id: ", 2}}, - {3, {"Status: ", 1}}, //(added only from 3.0f version) - {4, {"Group id :", 2}}, //(added only from 3.0f version) - {5, {"Source Address: ", 2}} //(added only from 3.0f version) - }; // data each entry is uint8_t - temp->manager = &viewGroupManager; + {0, {"Sequence number: ", 1, 0}}, + {1, {"Endpoint: ", 1, 0}}, + {2, {"Cluster id: ", 2, 0}}, + {3, {"Status: ", 1, 0}}, //(added only from 3.0f version) + {4, {"Group id :", 2, 0}}, //(added only from 3.0f version) + {5, {"Source Address: ", 2, 0}} //(added only from 3.0f version) + }; + temp->manager = &defaultManager; temp = responseListIndex["8062"]; temp->code = QByteArray::fromHex("8062"); temp->description = "Group membership"; temp->properties = { - {0, {"Sequence number: ", 1}}, - {1, {"Endpoint: ", 1}}, - {2, {"Cluster id: ", 2}}, - {3, {"Source Address:", 2}}, //(added only from 3.0d version) - {4, {"Capacity: ", 1}}, - {5, {"Group count: ", 1}}, - {6, {"List of Group id: ", 2}}, //list each data item uint16_t> - {7, {"Source Addr: ", 2}} //(added only from 3.0f version) + {0, {"Sequence number: ", 1, 0}}, + {1, {"Endpoint: ", 1, 0}}, + {2, {"Cluster id: ", 2, 0}}, + {3, {"Source Address:", 2, 0}}, //(added only from 3.0d version) + {4, {"Capacity: ", 1, 0}}, + {5, {"Group count: ", 1, 0}}, + {6, {"List of Group id: ", 2, 0}}, //list each data item uint16_t> + {7, {"Source Addr: ", 2, 0}} //(added only from 3.0f version) }; - temp->manager = &groupMemberShipManager; + temp->manager = &defaultManager; temp = responseListIndex["8063"]; temp->code = QByteArray::fromHex("8063"); temp->description = "Remove group"; temp->properties = { - {0, {"Sequence number: ", 1}}, - {1, {"Endpoint: ", 1}}, - {2, {"Cluster id: ", 2}}, - {3, {"Source Address:", 2}}, //(added only from 3.0d version) - {4, {"Status: ", 1}}, - {5, {"Group ID: ", 2}} + {0, {"Sequence number: ", 1, 0}}, + {1, {"Endpoint: ", 1, 0}}, + {2, {"Cluster id: ", 2, 0}}, + {3, {"Source Address:", 2, 0}}, //(added only from 3.0d version) + {4, {"Status: ", 1, 0}}, + {5, {"Group ID: ", 2, 0}} }; - temp->manager = &removeGroupManager; + temp->manager = &defaultManager; temp = responseListIndex["8085"]; temp->code = QByteArray::fromHex("8085"); temp->description = "Level update"; temp->properties = { - {0, {"Sequence number: ", 1}}, - {1, {"Endpoint: ", 1}}, - {2, {"Cluster id: ", 2}}, - {3, {"Source Address mode:", 1}}, //(added only from 3.0d version) - {4, {"Source Address:", 2}}, //(added only from 3.0d version) - {5, {"Status: ", 1}} + {0, {"Sequence number: ", 1, 0}}, + {1, {"Endpoint: ", 1, 0}}, + {2, {"Cluster id: ", 2, 0}}, + {3, {"Source Address mode:", 1, 0}}, //(added only from 3.0d version) + {4, {"Source Address:", 2, 0}}, //(added only from 3.0d version) + {5, {"Status: ", 1, 0}} }; - temp->manager = &levelUpdateManager; + temp->manager = &defaultManager; temp = responseListIndex["8095"]; temp->code = QByteArray::fromHex("8095"); temp->description = "On/Off"; temp->properties = { - {0, {"Sequence number: ", 1}}, - {1, {"Endpoint: ", 1}}, - {2, {"Cluster id: ", 2}}, - {3, {"Source Address mode:", 1}}, //(added only from 3.0d version) - {4, {"Source Address:", 2}}, //(added only from 3.0d version) - {5, {"Status: ", 1}} + {0, {"Sequence number: ", 1, 0}}, + {1, {"Endpoint: ", 1, 0}}, + {2, {"Cluster id: ", 2, 0}}, + {3, {"Source Address mode:", 1, 0}}, //(added only from 3.0d version) + {4, {"Source Address:", 2, 0}}, //(added only from 3.0d version) + {5, {"Status: ", 1, 0}} }; - temp->manager = &onOffManager; - - - - + temp->manager = &defaultManager; temp = responseListIndex["8140"]; temp->code = QByteArray::fromHex("8140"); temp->description = "Attribute Discovery response"; temp->properties = { - {0, {"Complete", 1}}, // uint8_t - {1, {"Attribute type", 1}}, // uint8_t - {2, {"Attribute id", 2}} // uint16_t + {0, {"Complete", 1, 0}}, // uint8_t + {1, {"Attribute type", 1, 0}}, // uint8_t + {2, {"Attribute id", 2, 0}} // uint16_t }; - temp->manager = &attributeDiscoveryManager; + temp->manager = &defaultManager; resetCoordinator(); return returnCode; } -void infoOutput(ResponseProperties object) +void infoOutput(Response *object) { - cout << object.code.toHex().toStdString() << " : " << object.description.toStdString() << endl; + cout << object->code.toHex().toStdString() << " : " << object->description.toStdString() << endl; } -void defaultManager() -{ - infoOutput(zigateBkd.responseListIndex("")); -} - -void deviceAnnounceManager() -{ - infoOutput(zigateBkd.responseListIndex("")); -} - -void commandReturnStatusManager() +void defaultManager(Response *responseObject) { int nbyte; int isValue; int offset = 0; - QByteArray datas = commandReturnStatus.datas; + QByteArray datas = responseObject->datas; QByteArray result; - QMap >::iterator i = commandReturnStatus.properties.begin(); + QByteArray code = responseObject->code.toHex(); + + cout << responseObject->code.toStdString() << endl; + QMap >::iterator i = zigateBkd.responseListIndex[code]->properties.begin(); QList propertyList; QMap propertyDetail; QMap var; - infoOutput(commandReturnStatus); - /* - * {"Status", 1}, // - {"Sequence number", 1}, // - {"Packet Type", 2}, // - {"Optional additional error information", -1} // - */ - //keys = commandReturnStatus.properties.keys(); - - while (i != commandReturnStatus.properties.end()) + infoOutput(responseObject); + while (i != zigateBkd.responseListIndex[code]->properties.end()) { propertyList = i.value(); - propertyDetail = commandReturnStatus.propertyDetail.value(i.key()); + propertyDetail = zigateBkd.responseListIndex[code]->propertyDetail.value(i.key()); cout << propertyList.at(0).toString().toStdString() << ": "; nbyte = propertyList.at(1).toInt(); isValue = propertyList.at(2).toInt(); @@ -690,13 +732,14 @@ void commandReturnStatusManager() { case 0: cout << result.toHex().toStdString() << endl; - break; + break; case 1: - /*foreach (var, propertyDetail) - { + cout << result.toHex().toStdString() << endl; + //foreach (var, propertyDetail) + //{ - }*/ - break; + //} + break; case 2: if (propertyDetail.contains(result.toUInt())) { @@ -705,97 +748,42 @@ void commandReturnStatusManager() { cout << propertyDetail.value(-1).toStdString() << endl; } - break; - } - - - - -/* - switch (i.key()) - { - case 0: - switch (result.toUInt()) - { - case 0: - cout << "Success" << endl; - break; - case 1: - cout << "Incorrect Parameters" << endl; - break; - case 2: - cout << "Unhandled Command" << endl; - break; - case 3: - cout << "Command Failed" << endl; - break; - case 4: - cout << "Busy (Node is carrying out a lengthy operation and is currently unable to handle the incoming command)" << endl; - break; - case 5: - cout << "Stack Already Started (no new configuration accepted)" << endl;; - break; - default: - { - cout << "ZigBee Error Code : " << result.toHex().toStdString(); - } - break; - } - break; - case 1: - cout << "SQN : " << result.toHex().toStdString() << endl;; - break; - case 2: - cout << result.toHex().toStdString() << " - The value of the initiating command request" << endl; break; case 3: - cout << result.toHex().toStdString() << endl; + zigateBkd.responseListIndex[responseObject->code]->propertyManagerList[i.key()](result); break; - }*/ + case 4: + cout << "Liste" << endl; + break; + case 5: + cout << result.toStdString() << endl; + break; + } i++; } - - /* - } - echo "SQN: : ".substr($payload,6,2)."\n"; - - if (hexdec(substr($payload,0,4)) > 2) - { - echo " Message: "; - echo hex2str(substr($payload,8,strlen($payload)-2))."\n"; - } - break;*/ } - -void logMessageManager() +void macCapabilityManager(QByteArray mac) { - infoOutput(logMessage); - + cout << "macCapabilityManger" << mac.toStdString() << endl; } - -/***************************************************************************** - * Log Level : - * Use the Linux / Unix log levels - * 0 = Emergency - * 1 = Alert - * 2 = Critical - * 3 = Error - * 4 = Warning - * 5 = Notice - * 6 = Information - * 7 = Debug - ******************************************************************************/ -void dataIndicationManager() +/* void deviceAnnounceManager() { - infoOutput(dataIndication); + infoOutput(responseListIndex("")); } +*/ -void clustersListManager() +void dataIndicationManager(Response * response) { - infoOutput(clustersList); + infoOutput(response); } +void clustersListManager(Response * response) +{ + infoOutput(response); +} + +/* void attributesListManager() { infoOutput(attributesList); @@ -810,32 +798,20 @@ void statusManager() { infoOutput(status); } -/***************************************************************************** -* 0 - STARTUP -* 2 - NFN_START -* 6 - RUNNING -* The node is provisioned from previous restart. -******************************************************************************/ -/*void status2Manager() +void status2Manager() { } -***************************************************************************** -* 0 - STARTUP -* 2 - NFN_START -* 6 - RUNNING -* The node is not yet provisioned. -******************************************************************************/ void versionListManager() { infoOutput(versionList); } -/***************************************************************************** -* 0 - Off -* 1 - On -******************************************************************************/ +// **************************************************************************** +// 0 - Off +// 1 - On +// ******************************************************************************* void permitJoinManager() { @@ -846,13 +822,22 @@ void networkJoinedFormedManager() { infoOutput(networkJoinedFormed); } -/***************************************************************************** -* Status: -* 0 = Joined existing network -* 1 = Formed new network -* 128 – 244 = Failed (ZigBee event codes) -******************************************************************************/ +*/ +void deviceListManager(Response * response) +{ + infoOutput(response); + // ************************************************************** + // + // + // + // + // 0 – battery 1- AC power + // 1-255 + // ************************************************************** + } + +/* void bindResponseManager() { infoOutput(bindResponse); @@ -862,76 +847,34 @@ void unbindResponseManager() { infoOutput(unbindResponse); } +*/ -void networkAddressManager() +void networkAddressManager(Response * response) { - infoOutput(networkAddress); + infoOutput(response); } -void iEEEAddressManager() + +void iEEEAddressManager(Response * response) { - infoOutput(iEEEAddress); + infoOutput(response); } -void nodeDescriptorManager() +void nodeDescriptorManager(Response * response) { - infoOutput(nodeDescriptor); + infoOutput(response); } -/***************************************************************************** -* Bitfields: -* Logical type (bits 0-2 -* 0 - Coordinator -* 1 - Router -* 2 - End Device) -* Complex descriptor available (bit 3) -* User descriptor available (bit 4) -* Reserved (bit 5-7) -* APS flags (bit 8-10 – currently 0) -* Frequency band(11-15 set to 3 (2.4Ghz)) -* Server mask bits: -* 0 - Primary trust center -* 1 - Back up trust center -* 2 - Primary binding cache -* 3 - Backup binding cache -* 4 - Primary discovery cache -* 5 - Backup discovery cache -* 6 - Network manager -* 7 to15 - Reserved -* MAC capability -* Bit 0 - Alternate PAN Coordinator -* Bit 1 - Device Type -* Bit 2 - Power source -* Bit 3 - Receiver On when Idle -* Bit 4-5 - Reserved -* Bit 6 - Security capability -* Bit 7 - Allocate Address -* Descriptor capability: -* 0 - extended Active endpoint list available -* 1 - Extended simple descriptor list available -* 2 to 7 - Reserved -******************************************************************************/ -void simpleDescriptorManager() +void simpleDescriptorManager(Response * response) { - infoOutput(simpleDescriptor); + infoOutput(response); } -/***************************************************************************** -* Bit fields: -* Device version: 4 bits (bits 0-4) -* Reserved: 4 bits (bits4-7) -******************************************************************************/ +/* void powerDescriptorManager() { infoOutput(powerDescriptor); } -/***************************************************************************** -* Bit fields -* 0 to 3: current power mode -* 4 to 7: available power source -* 8 to 11: current power source -* 12 to 15: current power source level -******************************************************************************/ void activeEndpointManager() { @@ -977,38 +920,17 @@ void systemServerDiscoveryManager() { infoOutput(systemServerDiscovery); } -/******************************** -* Bitmask according to spec". * -********************************/ +// ********************************* // +// Bitmask according to spec". // +// ********************************* // void managementLQIManager() { infoOutput(managementLQI); } -/***************************************************************************** - * Note: If Neighbour Table list count is 0, there are no elements in the list. - * NWK Address : uint16_t - * Extended PAN ID : uint64_t - * IEEE Address : uint64_t - * Depth : uint_t - * Link Quality : uint8_t - * Bit map of attributes Described below: uint8_t - * bit 0-1 Device Type - * (0-Coordinator 1-Router 2-End Device) - * bit 2-3 Permit Join status - * (1- On 0-Off) - * bit 4-5 Relationship - * (0-Parent 1-Child 2-Sibling) - * bit 6-7 Rx On When Idle status - * (1-On 0-Off) - ******************************************************************************/ void attributeDiscoveryManager() { infoOutput(attributeDiscovery); } -/***************************************************************************** -* Complete: -* 0 – more attributes to follow -* 1 – this was the last attribute -******************************************************************************/ +*/ diff --git a/zigatecmd.cpp b/zigatecmd.cpp index c8b9a64..62896a3 100644 --- a/zigatecmd.cpp +++ b/zigatecmd.cpp @@ -1,4 +1,4 @@ -#include "main.h" +#include "zigateBackend.h" using namespace std; @@ -11,6 +11,8 @@ bool ZigateBackend::resetCoordinator() getResponse(); getResponse(); getResponse(); + getResponse(); + getResponse(); cout << "***************************************************" << endl; sleep(10); return returnCode; diff --git a/zigbeemanager.pro b/zigbeemanager.pro index 92e0023..4edee0f 100644 --- a/zigbeemanager.pro +++ b/zigbeemanager.pro @@ -26,7 +26,7 @@ else: unix:!android: target.path = /usr/bin HEADERS += \ library.h \ main.h \ + zigateBackend.h \ responseClasses.h \ serial.inc.h \ - version.h \ - zigateBackend.h + version.h diff --git a/zigbeemanager.pro.user b/zigbeemanager.pro.user deleted file mode 100644 index 3b8b43e..0000000 --- a/zigbeemanager.pro.user +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - EnvironmentId - {a3117c94-e673-4dca-aa4c-050bbea034fe} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - false - true - false - 1 - true - true - 0 - 8 - true - false - 1 - true - true - true - *.md, *.MD, Makefile - true - true - true - - - - ProjectExplorer.Project.PluginSettings - - - true - false - true - true - true - true - - - 0 - true - - true - true - Builtin.DefaultTidyAndClazy - 2 - - - - true - - - true - - - - - ProjectExplorer.Project.Target.0 - - Desktop - Qt 5.15.7 (qt5) - Qt 5.15.7 (qt5) - {a8a6d767-5e05-45c7-b70b-532f99112b6a} - 0 - 0 - 0 - - 0 - /home/daniel/develop/zigbeemanager/../build-zigbeemanager-Qt_5_15_7_qt5-Debug - /home/daniel/develop/build-zigbeemanager-Qt_5_15_7_qt5-Debug - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - - - /home/daniel/develop/zigbeemanager/../build-zigbeemanager-Qt_5_15_7_qt5-Release - /home/daniel/develop/build-zigbeemanager-Qt_5_15_7_qt5-Release - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - - - 0 - /home/daniel/develop/zigbeemanager/../build-zigbeemanager-Qt_5_15_7_qt5-Profile - /home/daniel/develop/build-zigbeemanager-Qt_5_15_7_qt5-Profile - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - 0 - - 3 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - true - - 2 - - zigbeemanager - Qt4ProjectManager.Qt4RunConfiguration:/home/daniel/develop/zigbeemanager/zigbeemanager.pro - /home/daniel/develop/zigbeemanager/zigbeemanager.pro - false - true - true - false - true - /home/daniel/develop/build-zigbeemanager-Qt_5_15_7_qt5-Debug - - 1 - - - - ProjectExplorer.Project.Target.1 - - Desktop - Desktop - Desktop - {893f9ca6-0efa-4c08-a4a6-5a818f60a8a0} - 0 - 0 - 0 - - 0 - /home/daniel/develop/zigbeemanager/../build-zigbeemanager-Desktop-Debug - /home/daniel/develop/build-zigbeemanager-Desktop-Debug - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - - - /home/daniel/develop/zigbeemanager/../build-zigbeemanager-Desktop-Release - /home/daniel/develop/build-zigbeemanager-Desktop-Release - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - - - 0 - /home/daniel/develop/zigbeemanager/../build-zigbeemanager-Desktop-Profile - /home/daniel/develop/build-zigbeemanager-Desktop-Profile - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - 0 - - 3 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - true - - 2 - - ProjectExplorer.CustomExecutableRunConfiguration - - false - true - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 2 - - - ProjectExplorer.Project.Updater.FileVersion - 22 - - - Version - 22 - -