-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathBt_MqttSnClient.hpp
188 lines (147 loc) · 5.56 KB
/
Bt_MqttSnClient.hpp
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
//*************************************************************************************************
//
// BITTAILOR.CH - BtMqttSn, an Arduino library for MQTT-SN over nRF24L01+
//
//-------------------------------------------------------------------------------------------------
//
// Bt::MqttSnClient
//
//*************************************************************************************************
#ifndef INC__Bt_MqttSnClient__hpp
#define INC__Bt_MqttSnClient__hpp
#include <stdio.h>
#include <string.h>
#include "Bt_MqttSnConfiguration.hpp"
#include "Bt_I_RfPacketSocket.hpp"
namespace Bt {
class MqttSnClient
{
public:
enum State {
DISCONNECTED,
ACTIVE,
ASLEEP,
AWAKE,
LOST,
};
typedef void (*Callback)(const char* iTopic, const char* iData);
enum { MAX_LENGTH_CLIENT_ID = 23 };
enum { MAX_LENGTH_TOPIC_NAME = I_RfPacketSocket::PAYLOAD_CAPACITY - 7 };
enum { MAX_LENGTH_DATA = I_RfPacketSocket::PAYLOAD_CAPACITY - 7 };
MqttSnClient(I_RfPacketSocket& iSocket,
uint8_t iGatewayNodeId,
const char* iClientId,
Callback iCallback = 0);
~MqttSnClient();
bool loop();
bool connect(uint16_t iKeepAliveTimerDuration);
bool disconnect();
bool registerTopic(const char* iTopic);
bool publish(const char* iTopic, const char* iMessage, bool iRetain = false);
bool publish(const char* iTopic, const uint8_t* iData, size_t iSize, bool iRetain = false);
bool subscribe(const char* iTopic);
bool sleep(uint16_t iSleepDuration);
bool receivePendingMessages();
bool wakeUp();
private:
class Topic {
public:
Topic() : mRegistered(false), mId(0), mName(){}
bool define(uint16_t iId, const char* iName) {
if(strlen(iName) > MAX_LENGTH_TOPIC_NAME) {
BT_LOG_WARNING_AND_PARAMETER("topic name too long: ", iName);
return false;
}
mRegistered = true;
mId = iId;
strncpy(mName,iName,sizeof(mName));
return true;
}
void clear() {
mRegistered = false;
mId = 0;
mName[0] = 0;
}
bool isRegistred() const { return mRegistered; }
uint16_t id() const { return mId; }
const char* name() const { return mName; }
bool matches(const char* iName) const { return strcmp(mName, iName) == 0; }
bool matches(uint16_t iId) const { return mId == iId; }
private:
bool mRegistered;
uint16_t mId;
char mName[MAX_LENGTH_TOPIC_NAME + 1];
};
class Topics {
public:
bool add(uint16_t iId, const char* iName) {
Topic* freeTopic = nextFree();
if(freeTopic == 0) {
BT_LOG_WARNING("no free topic storage");
return false;
}
return freeTopic->define(iId, iName);
}
void clear() {
for (size_t i = 0 ; i < BT_MQTTSN_MAX_NUMBER_OF_REGISTERED_TOPICS ; i++) {
mTopics[i].clear();
}
}
const Topic* findTopic(const char* iName) {
for (size_t i = 0 ; i < BT_MQTTSN_MAX_NUMBER_OF_REGISTERED_TOPICS ; i++) {
if(mTopics[i].isRegistred() && mTopics[i].matches(iName) ) {
return &mTopics[i];
}
}
return 0;
}
const Topic* findTopic(uint16_t iId) {
for (size_t i = 0 ; i < BT_MQTTSN_MAX_NUMBER_OF_REGISTERED_TOPICS ; i++) {
if(mTopics[i].isRegistred() && mTopics[i].matches(iId) ) {
return &mTopics[i];
}
}
return 0;
}
private:
Topic* nextFree() {
for (size_t i = 0 ; i < BT_MQTTSN_MAX_NUMBER_OF_REGISTERED_TOPICS ; i++) {
if(!mTopics[i].isRegistred()) {
return &mTopics[i];
}
}
return 0;
}
Topic mTopics[BT_MQTTSN_MAX_NUMBER_OF_REGISTERED_TOPICS];
};
// Constructor to prohibit copy construction.
MqttSnClient(const MqttSnClient&);
// Operator= to prohibit copy assignment
MqttSnClient& operator=(const MqttSnClient&);
bool pollLoop(uint8_t* oBuffer, uint8_t msgType);
bool handleLoop(uint8_t* oBuffer, uint8_t msgType);
bool reveiveLoop(uint8_t* oBuffer);
void handleInternal(uint8_t* iBuffer);
void handlePublish(uint8_t* iBuffer);
void handleRegister(uint8_t* iBuffer);
void handlePingRequest(uint8_t* iBuffer);
void handlePingResponse(uint8_t* iBuffer);
bool send(uint8_t* iPayload, size_t iSize);
void changeState(State iCurrentState) {
BT_LOG_INFO_AND_PARAMETER("state change from : ", mCurrentState);
BT_LOG_INFO_AND_PARAMETER(" to : ", iCurrentState);
mCurrentState = iCurrentState;
}
I_RfPacketSocket* mSocket;
uint8_t mGatewayNodeId;
char mClientId[MAX_LENGTH_CLIENT_ID + 1];
Topics mTopics;
uint16_t mMsgIdCounter;
Callback mCallback;
unsigned long mKeepAliveTimerDuration;
unsigned long mLastSendActivity;
unsigned long mLastReveiveActivity;
State mCurrentState;
};
} // namespace Bt
#endif // INC__Bt_MqttSnClient__hpp