forked from u236/homed-service-zigbee
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadapter.h
259 lines (197 loc) · 7.4 KB
/
adapter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#ifndef ADAPTER_H
#define ADAPTER_H
#define RECEIVE_TIMEOUT 20
#define PERMIT_JOIN_TIMEOUT 60000
#define RESET_TIMEOUT 10000
#define RESET_DELAY 100
#define DEFAULT_GROUP 0x0000
#define IKEA_GROUP 0x0385
#define GREEN_POWER_GROUP 0x0B84
#define PROFILE_IPM 0x0101 // Industrial Plant Monitoring
#define PROFILE_HA 0x0104 // Home Automation
#define PROFILE_CBA 0x0105 // Commercial Building Automation
#define PROFILE_TA 0x0107 // Telecom Applications
#define PROFILE_PHHC 0x0108 // Personal Home & Hospital Care
#define PROFILE_AMI 0x0109 // Advanced Metering Initiative
#define PROFILE_GP 0xA1E0 // ZigBee Green Power
#define PROFILE_ZLL 0xC05E // ZigBee Light Link
#define ZDO_DEVICE_ANNOUNCE 0x0013
#define ZDO_NODE_DESCRIPTOR_REQUEST 0x0002
#define ZDO_SIMPLE_DESCRIPTOR_REQUEST 0x0004
#define ZDO_ACTIVE_ENDPOINTS_REQUEST 0x0005
#define ZDO_BIND_REQUEST 0x0021
#define ZDO_UNBIND_REQUEST 0x0022
#define ZDO_LQI_REQUEST 0x0031
#define ZDO_LEAVE_REQUEST 0x0034
#define ADDRESS_MODE_NOT_PRESENT 0x00
#define ADDRESS_MODE_GROUP 0x01
#define ADDRESS_MODE_16_BIT 0x02
#define ADDRESS_MODE_64_BIT 0x03
#define ADDRESS_MODE_BROADCAST 0xFF
#include <QHostAddress>
#include <QQueue>
#include <QSerialPort>
#include <QSettings>
#include <QSharedPointer>
#include <QTcpSocket>
#include <QTimer>
enum class LogicalType
{
Coordinator,
Router,
EndDevice
};
#pragma pack(push, 1)
struct deviceAnnounceStruct
{
quint16 networkAddress;
quint64 ieeeAddress;
quint8 capabilities;
};
struct nodeDescriptorResponseStruct
{
quint8 status;
quint16 networkAddress;
quint8 logicalType;
quint8 apsFlags;
quint8 capabilityFlags;
quint16 manufacturerCode;
quint8 maxBufferSize;
quint16 maxTransferSize;
quint16 serverFlags;
quint16 maxOutTransferSize;
quint8 descriptorCapabilities;
};
struct simpleDescriptorResponseStruct
{
quint8 status;
quint16 networkAddress;
quint8 length;
quint8 endpointId;
quint16 profileId;
quint16 deviceId;
quint8 version;
};
struct activeEndpointsResponseStruct
{
quint8 status;
quint16 networkAddress;
quint8 count;
};
struct lqiResponseStruct
{
quint8 status;
quint8 total;
quint8 index;
quint8 count;
};
struct neighborRecordStruct
{
quint64 extendedPanId;
quint64 ieeeAddress;
quint16 networkAddress;
quint8 options;
quint8 permitJoin;
quint8 depth;
quint8 linkQuality;
};
struct bindRequestStruct
{
quint64 srcAddress;
quint8 srcEndpointId;
quint16 clusterId;
quint8 dstAddressMode;
};
#pragma pack(pop)
class EndpointDataObject;
typedef QSharedPointer <EndpointDataObject> EndpointData;
class EndpointDataObject
{
public:
EndpointDataObject(quint16 profileId = 0, quint16 deviceId = 0) :
m_profileId(profileId), m_deviceId(deviceId) {}
inline quint16 profileId(void) { return m_profileId; }
inline void setProfileId(quint16 value) { m_profileId = value; }
inline quint16 deviceId(void) { return m_deviceId; }
inline void setDeviceId(quint16 value) { m_deviceId = value; }
inline QList <quint16> &inClusters(void) { return m_inClusters; }
inline QList <quint16> &outClusters(void) { return m_outClusters; }
private:
quint16 m_profileId, m_deviceId;
QList <quint16> m_inClusters, m_outClusters;
};
class Adapter : public QObject
{
Q_OBJECT
public:
Adapter(QSettings *config, QObject *parent);
~Adapter(void);
virtual bool unicastRequest(quint8 id, quint16 networkAddress, quint8 srcEndPointId, quint8 dstEndPointId, quint16 clusterId, const QByteArray &payload) = 0;
virtual bool multicastRequest(quint8 id, quint16 groupId, quint8 srcEndPointId, quint8 dstEndPointId, quint16 clusterId, const QByteArray &payload) = 0;
virtual bool unicastInterPanRequest(quint8 id, const QByteArray &ieeeAddress, quint16 clusterId, const QByteArray &payload) = 0;
virtual bool broadcastInterPanRequest(quint8 id, quint16 clusterId, const QByteArray &payload) = 0;
virtual bool setInterPanChannel(quint8 channel) = 0;
virtual void resetInterPanChannel(void) = 0;
inline QString manufacturerName(void) { return m_manufacturerName; }
inline QString modelName(void) { return m_modelName; }
inline QString firmware(void) { return m_firmware; }
inline QByteArray ieeeAddress(void) { return m_ieeeAddress; }
inline quint8 replyStatus(void) { return m_replyStatus; }
inline void setRequestParameters(const QByteArray &value, bool extendedTimeout = true) { m_requestAddress = value; m_extendedTimeout = extendedTimeout; }
void init(void);
bool waitForSignal(const QObject *sender, const char *signal, int tiomeout);
void setPermitJoin(bool enabled);
void togglePermitJoin(void);
virtual bool zdoRequest(quint8 id, quint16 networkAddress, quint16 clusterId, const QByteArray &data = QByteArray());
virtual bool bindRequest(quint8 id, quint16 networkAddress, quint8 endpointId, quint16 clusterId, const QByteArray &address, quint8 dstEndpointId, bool unbind = false);
virtual bool leaveRequest(quint8 id, quint16 networkAddress);
virtual bool lqiRequest(quint8 id, quint16 networkAddress, quint8 index);
protected:
QTimer *m_receiveTimer, *m_resetTimer, *m_permitJoinTimer;
QSerialPort *m_serial;
QTcpSocket *m_socket;
QIODevice *m_device;
bool m_serialError;
QHostAddress m_adddress;
quint16 m_port;
bool m_connected;
QString m_bootPin, m_resetPin, m_reset;
quint16 m_panId;
quint8 m_channel, m_power;
bool m_write, m_portDebug, m_adapterDebug;
QString m_manufacturerName, m_modelName, m_firmware;
QByteArray m_ieeeAddress;
quint8 m_replyStatus;
bool m_permitJoin;
QByteArray m_requestAddress;
bool m_extendedTimeout;
QMap <quint8, EndpointData> m_endpoints;
QList <quint16> m_multicast;
QQueue <QByteArray> m_queue;
void reset(void);
void sendData(const QByteArray &buffer);
private:
virtual void softReset(void) = 0;
virtual void parseData(QByteArray &buffer) = 0;
virtual bool permitJoin(bool enabled) = 0;
private slots:
virtual void handleQueue(void) = 0;
void serialError(QSerialPort::SerialPortError error);
void socketError(QTcpSocket::SocketError error);
void socketConnected(void);
void startTimer(void);
void readyRead(void);
void resetTimeout(void);
void permitJoinTimeout(void);
signals:
void adapterReset(void);
void coordinatorReady(void);
void permitJoinUpdated(bool enabled);
void requestFinished(quint8 id, quint8 status);
void deviceJoined(const QByteArray &ieeeAddress, quint16 networkAddress);
void deviceLeft(const QByteArray &ieeeAddress);
void zdoMessageReveived(quint16 networkAddress, quint16 clusterId, const QByteArray &payload);
void zclMessageReveived(quint16 networkAddress, quint8 endpointId, quint16 clusterId, quint8 linkQuality, const QByteArray &data);
void rawMessageReveived(const QByteArray &ieeeAddress, quint16 clusterId, quint8 linkQuality, const QByteArray &data);
};
#endif