SNode.C
Loading...
Searching...
No Matches
SocketContext.cpp
Go to the documentation of this file.
1/*
2 * SNode.C - a slim toolkit for network communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "iot/mqtt-fast/SocketContext.h"
21
22#include "iot/mqtt-fast/ControlPacket.h"
23#include "iot/mqtt-fast/types/Binary.h"
24
25#ifndef DOXYGEN_SHOULD_SKIP_THIS
26
27#include "log/Logger.h"
28
29#include <cstdint>
30#include <iomanip>
31#include <sstream>
32
33#endif // DOXYGEN_SHOULD_SKIP_THIS
34
35namespace iot::mqtt_fast {
36
37 SocketContext::SocketContext(core::socket::stream::SocketConnection* socketConnection)
38 : core::socket::stream::SocketContext(socketConnection)
39 , controlPacketFactory(this) {
40 }
41
42 void SocketContext::sendConnect(const std::string& clientId) {
43 LOG(DEBUG) << "MQTT (fast): Send CONNECT";
44 LOG(DEBUG) << "MQTT (fast): ============";
45
46 send(iot::mqtt_fast::packets::Connect(clientId));
47 }
48
49 void SocketContext::sendConnack(uint8_t returnCode, uint8_t flags) {
50 LOG(DEBUG) << "MQTT (fast): Send CONNACK";
51 LOG(DEBUG) << "MQTT (fast): ============";
52
53 send(iot::mqtt_fast::packets::Connack(returnCode, flags));
54 }
55
56 void SocketContext::sendPublish(const std::string& topic, const std::string& message, bool dup, uint8_t qoS, bool retain) {
57 LOG(DEBUG) << "MQTT (fast): Send PUBLISH";
58 LOG(DEBUG) << "MQTT (fast): ============";
59
60 send(iot::mqtt_fast::packets::Publish(qoS == 0 ? 0 : getPacketIdentifier(), topic, message, dup, qoS, retain));
61 }
62
63 void SocketContext::sendPuback(uint16_t packetIdentifier) {
64 LOG(DEBUG) << "MQTT (fast): Send PUBACK";
65 LOG(DEBUG) << "MQTT (fast): ===========";
66
67 send(iot::mqtt_fast::packets::Puback(packetIdentifier));
68 }
69
70 void SocketContext::sendPubrec(uint16_t packetIdentifier) {
71 LOG(DEBUG) << "MQTT (fast): Send PUBREC";
72 LOG(DEBUG) << "MQTT (fast): ===========";
73
74 send(iot::mqtt_fast::packets::Pubrec(packetIdentifier));
75 }
76
77 void SocketContext::sendPubrel(uint16_t packetIdentifier) {
78 LOG(DEBUG) << "MQTT (fast): Send PUBREL";
79 LOG(DEBUG) << "MQTT (fast): ===========";
80
81 send(iot::mqtt_fast::packets::Pubrel(packetIdentifier));
82 }
83
84 void SocketContext::sendPubcomp(uint16_t packetIdentifier) {
85 LOG(DEBUG) << "MQTT (fast): Send PUBCOMP";
86 LOG(DEBUG) << "MQTT (fast): ============";
87
88 send(iot::mqtt_fast::packets::Pubcomp(packetIdentifier));
89 }
90
91 void SocketContext::sendSubscribe(std::list<iot::mqtt_fast::Topic>& topics) {
92 LOG(DEBUG) << "MQTT (fast): Send SUBSCRIBE";
93 LOG(DEBUG) << "MQTT (fast): ==============";
94
95 send(iot::mqtt_fast::packets::Subscribe(getPacketIdentifier(), topics));
96 }
97
98 void SocketContext::sendSuback(uint16_t packetIdentifier, const std::list<uint8_t>& returnCodes) {
99 LOG(DEBUG) << "MQTT (fast): Send SUBACK";
100 LOG(DEBUG) << "MQTT (fast): ===========";
101
102 send(iot::mqtt_fast::packets::Suback(packetIdentifier, returnCodes));
103 }
104
105 void SocketContext::sendUnsubscribe(const std::list<std::string>& topics) {
106 LOG(DEBUG) << "MQTT (fast): Send UNSUBSCRIBE";
107 LOG(DEBUG) << "MQTT (fast): ================";
108
109 send(iot::mqtt_fast::packets::Unsubscribe(getPacketIdentifier(), topics));
110 }
111
112 void SocketContext::sendUnsuback(uint16_t packetIdentifier) {
113 LOG(DEBUG) << "MQTT (fast): Send UNSUBACK";
114 LOG(DEBUG) << "MQTT (fast): =============";
115
116 send(iot::mqtt_fast::packets::Unsuback(packetIdentifier));
117 }
118
119 void SocketContext::sendPingreq() {
120 LOG(DEBUG) << "MQTT (fast): Send Pingreq";
121 LOG(DEBUG) << "MQTT (fast): ============";
122
123 send(iot::mqtt_fast::packets::Pingreq());
124 }
125
126 void SocketContext::sendPingresp() {
127 LOG(DEBUG) << "MQTT (fast): Send Pingresp";
128 LOG(DEBUG) << "MQTT (fast): =============";
129
130 send(iot::mqtt_fast::packets::Pingresp());
131 }
132
133 void SocketContext::sendDisconnect() {
134 LOG(DEBUG) << "MQTT (fast): Send Disconnect";
135 LOG(DEBUG) << "MQTT (fast): ===============";
136
137 send(iot::mqtt_fast::packets::Disconnect());
138 }
139
140 std::size_t SocketContext::onReceivedFromPeer() {
141 const std::size_t consumed = controlPacketFactory.construct();
142
143 if (controlPacketFactory.isError()) {
144 LOG(ERROR) << "MQTT (fast): SocketContext: Error during ControlPacket construction";
145 close();
146 } else if (controlPacketFactory.isComplete()) {
147 LOG(DEBUG) << "MQTT (fast): ======================================================";
148 LOG(DEBUG) << "MQTT (fast): PacketType: " << static_cast<uint16_t>(controlPacketFactory.getPacketType());
149 LOG(DEBUG) << "MQTT (fast): PacketFlags: " << static_cast<uint16_t>(controlPacketFactory.getPacketFlags());
150 LOG(DEBUG) << "MQTT (fast): RemainingLength: " << static_cast<uint16_t>(controlPacketFactory.getRemainingLength());
151
152 printData(controlPacketFactory.getPacket().getValue());
153
154 switch (controlPacketFactory.getPacketType()) {
155 case MQTT_CONNECT:
156 onConnect(iot::mqtt_fast::packets::Connect(controlPacketFactory));
157 break;
158 case MQTT_CONNACK:
159 onConnack(iot::mqtt_fast::packets::Connack(controlPacketFactory));
160 break;
161 case MQTT_PUBLISH:
162 onPublish(iot::mqtt_fast::packets::Publish(controlPacketFactory));
163 break;
164 case MQTT_PUBACK:
165 onPuback(iot::mqtt_fast::packets::Puback(controlPacketFactory));
166 break;
167 case MQTT_PUBREC:
168 onPubrec(iot::mqtt_fast::packets::Pubrec(controlPacketFactory));
169 break;
170 case MQTT_PUBREL:
171 onPubrel(iot::mqtt_fast::packets::Pubrel(controlPacketFactory));
172 break;
173 case MQTT_PUBCOMP:
174 onPubcomp(iot::mqtt_fast::packets::Pubcomp(controlPacketFactory));
175 break;
176 case MQTT_SUBSCRIBE:
177 onSubscribe(iot::mqtt_fast::packets::Subscribe(controlPacketFactory));
178 break;
179 case MQTT_SUBACK:
180 onSuback(iot::mqtt_fast::packets::Suback(controlPacketFactory));
181 break;
182 case MQTT_UNSUBSCRIBE:
183 onUnsubscribe(iot::mqtt_fast::packets::Unsubscribe(controlPacketFactory));
184 break;
185 case MQTT_UNSUBACK:
186 onUnsuback(iot::mqtt_fast::packets::Unsuback(controlPacketFactory));
187 break;
188 case MQTT_PINGREQ:
189 onPingreq(iot::mqtt_fast::packets::Pingreq(controlPacketFactory));
190 break;
191 case MQTT_PINGRESP:
192 onPingresp(iot::mqtt_fast::packets::Pingresp(controlPacketFactory));
193 break;
194 case MQTT_DISCONNECT:
195 onDisconnect(iot::mqtt_fast::packets::Disconnect(controlPacketFactory));
196 break;
197 default:
198 close();
199 break;
200 }
201
202 controlPacketFactory.reset();
203 }
204
205 return consumed;
206 }
207
208 void SocketContext::send(ControlPacket&& controlPacket) const {
209 send(controlPacket.getPacket());
210 }
211
212 void SocketContext::send(ControlPacket& controlPacket) const {
213 send(controlPacket.getPacket());
214 }
215
216 void SocketContext::send(std::vector<char>&& data) const {
217 printData(data);
218 sendToPeer(data.data(), data.size());
219 }
220
221 void SocketContext::printData(const std::vector<char>& data) {
222 std::stringstream ss;
223
224 ss << "Data: ";
225 unsigned long i = 0;
226 for (char const ch : data) {
227 if (i != 0 && i % 8 == 0 && i + 1 != data.size()) {
228 ss << std::endl;
229 ss << " ";
230 }
231 ++i;
232 ss << "0x" << std::hex << std::setfill('0') << std::setw(2) << static_cast<uint16_t>(static_cast<uint8_t>(ch))
233 << " "; // << " | ";
234 }
235
236 LOG(DEBUG) << ss.str();
237 }
238
239} // namespace iot::mqtt_fast
#define MQTT_CONNACK
Definition Connack.h:35
#define MQTT_CONNECT
Definition Connect.h:36
#define MQTT_DISCONNECT
Definition Disconnect.h:33
#define MQTT_PINGREQ
Definition Pingreq.h:33
#define MQTT_PINGRESP
Definition Pingresp.h:33
#define MQTT_PUBACK
Definition Puback.h:35
#define MQTT_PUBCOMP
Definition Pubcomp.h:35
#define MQTT_PUBLISH
Definition Publish.h:36
#define MQTT_PUBREC
Definition Pubrec.h:35
#define MQTT_PUBREL
Definition Pubrel.h:35
#define MQTT_SUBACK
Definition Suback.h:36
#define MQTT_SUBSCRIBE
Definition Subscribe.h:37
#define MQTT_UNSUBACK
Definition Unsuback.h:35
#define MQTT_UNSUBSCRIBE
Definition Unsubscribe.h:37