/__w/emqttsn/emqttsn/_build/test/cover/aggregate/emqttsn_send.html

1 %%-------------------------------------------------------------------------
2 %% Copyright (c) 2020-2022 EMQ Technologies Co., Ltd. All Rights Reserved.
3 %%
4 %% Licensed under the Apache License, Version 2.0 (the "License");
5 %% you may not use this file except in compliance with the License.
6 %% You may obtain a copy of the License at
7 %%
8 %% http://www.apache.org/licenses/LICENSE-2.0
9 %%
10 %% Unless required by applicable law or agreed to in writing, software
11 %% distributed under the License is distributed on an "AS IS" BASIS,
12 %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 %% See the License for the specific language governing permissions and
14 %% limitations under the License.
15 %%-------------------------------------------------------------------------
16
17 %% @doc low-level API for send any type of standard
18 %% MQTT-SN packet, always used with <i>emqttsn_udp</i>
19 %%
20 %% Caution: If you want to use this module, please
21 %% stop the client from emqttsn if there is any!
22 %%
23 %% @see emqttsn_udp
24 %% @see emqttsn_udp:init_port/0
25 -module(emqttsn_send).
26
27 %% @headerfile "emqttsn.hrl"
28
29 -include_lib("stdlib/include/assert.hrl").
30
31 -include("emqttsn.hrl").
32
33 %% API
34 -export([send_connect/6, send_willtopic/5, send_willmsg/3, send_register/4, send_regack/5,
35 send_subscribe/7, send_unsubscribe/5, send_publish/9, send_puback/5, send_pubrel/3,
36 send_pubrec/3, send_pubcomp/3, send_pub_any/7, send_gwinfo/7, send_disconnect/2,
37 send_asleep/3, send_awake/3, send_pingreq/2, send_pingresp/2, broadcast_searchgw/4]).
38
39 %% @doc Send a MQTT-SN Connect packet
40 %%
41 %% @param Config the client object
42 %% @param Socket the socket object
43 %% @param Will whether need will message for connect
44 %% @param CleanSession whether clean session for client
45 %% @param Duration interval of keep alive timer
46 %% @param ClientId unique name of client
47 %%
48 %% @returns ok | {error, not_owner | inet:posix()}
49 %% @end
50 -spec send_connect(config(),
51 inet:socket(),
52 boolean(),
53 boolean(),
54 non_neg_integer(),
55 string()) ->
56 ok | {error, term()}.
57 send_connect(Config, Socket, Will, CleanSession, Duration, ClientId) ->
58 48 Packet = ?CONNECT_PACKET(Will, CleanSession, Duration, ClientId),
59 48 Bin = emqttsn_frame:serialize(Packet, Config),
60 48 emqttsn_udp:send(Socket, Bin).
61
62 %% @doc Send a MQTT-SN WillTopic packet
63 %%
64 %% @param Config the client object
65 %% @param Socket the socket object
66 %% @param Qos the qos level of will
67 %% @param Retain whether the message is retain
68 %% @param WillTopic the data of will topic
69 %%
70 %% @returns ok | {error, not_owner | inet:posix()}
71 %% @end
72 -spec send_willtopic(config(), inet:socket(), qos(), boolean(), string()) ->
73 ok | {error, term()}.
74 send_willtopic(Config, Socket, Qos, Retain, WillTopic) ->
75 1 Packet = ?WILLTOPIC_PACKET(Qos, Retain, WillTopic),
76 1 Bin = emqttsn_frame:serialize(Packet, Config),
77 1 emqttsn_udp:send(Socket, Bin).
78
79 %% @doc Send a MQTT-SN WillMsg packet
80 %%
81 %% @param Config the client object
82 %% @param Socket the socket object
83 %% @param WillMsg the data of will message
84 %%
85 %% @returns ok | {error, not_owner | inet:posix()}
86 %% @end
87 -spec send_willmsg(config(), inet:socket(), string()) -> ok | {error, term()}.
88 send_willmsg(Config, Socket, WillMsg) ->
89 1 Packet = ?WILLMSG_PACKET(WillMsg),
90 1 Bin = emqttsn_frame:serialize(Packet, Config),
91 1 emqttsn_udp:send(Socket, Bin).
92
93 %% @doc Send a MQTT-SN WillMsg packet
94 %%
95 %% @param Config the client object
96 %% @param Socket the socket object
97 %% @param TopicName topic name to be registered
98 %% @param PacketId the id of packet
99 %%
100 %% @returns ok | {error, not_owner | inet:posix()}
101 %% @end
102 -spec send_register(config(), inet:socket(), string(), packet_id()) ->
103 ok | {error, term()}.
104 send_register(Config, Socket, TopicName, PacketId) ->
105 12 Packet = ?REGISTER_PACKET(PacketId, TopicName),
106 12 Bin = emqttsn_frame:serialize(Packet, Config),
107 12 emqttsn_udp:send(Socket, Bin).
108
109 %% @doc Send a MQTT-SN RegAck packet
110 %%
111 %% @param Config the client object
112 %% @param Socket the socket object
113 %% @param TopicId topic id of packet
114 %% @param ReturnCode return code of request
115 %% @param PacketId the id of packet
116 %%
117 %% @returns ok | {error, not_owner | inet:posix()}
118 %% @end
119 -spec send_regack(config(), inet:socket(), topic_id(), return_code(), packet_id()) ->
120 ok | {error, term()}.
121 send_regack(Config, Socket, TopicId, ReturnCode, PacketId) ->
122
:-(
Packet = ?REGACK_PACKET(TopicId, PacketId, ReturnCode),
123
:-(
Bin = emqttsn_frame:serialize(Packet, Config),
124
:-(
emqttsn_udp:send(Socket, Bin).
125
126 %% @doc Send a MQTT-SN Subscribe packet
127 %%
128 %% @param Config the client object
129 %% @param Socket the socket object
130 %% @param Dup whether it is a duplicated packet
131 %% @param TopicIdType data type of TopicIdOrName param
132 %% @param TopicIdOrName topic id or name to be sent(decided by TopicIdType)
133 %% @param MaxQos max Qos level can be handled of subscribed request
134 %% @param PacketId the id of packet
135 %%
136 %% @returns ok | {error, not_owner | inet:posix()}
137 %% @end
138 -spec send_subscribe(config(),
139 inet:socket(),
140 boolean(),
141 topic_id_type(),
142 topic_id_or_name(),
143 qos(),
144 packet_id()) ->
145 ok | {error, term()}.
146 send_subscribe(Config, Socket, Dup, TopicIdType, TopicIdOrName, MaxQos, PacketId) ->
147 14 Packet =
148 case TopicIdType of
149 ?SHORT_TOPIC_NAME ->
150 12 ?SUBSCRIBE_PACKET(Dup, PacketId, TopicIdOrName, MaxQos);
151 _ ->
152 2 ?SUBSCRIBE_PACKET(Dup, TopicIdType, PacketId, TopicIdOrName, MaxQos)
153 end,
154 14 Bin = emqttsn_frame:serialize(Packet, Config),
155 14 emqttsn_udp:send(Socket, Bin).
156
157 %% @doc Send a MQTT-SN Unsubscribe packet
158 %%
159 %% @param Config the client object
160 %% @param Socket the socket object
161 %% @param TopicIdType data type of TopicIdOrName param
162 %% @param TopicIdOrName topic id or name to be sent(decided by TopicIdType)
163 %% @param PacketId the id of packet
164 %%
165 %% @returns ok | {error, not_owner | inet:posix()}
166 %% @end
167 -spec send_unsubscribe(config(),
168 inet:socket(),
169 topic_id_type(),
170 topic_id_or_name(),
171 packet_id()) ->
172 ok | {error, term()}.
173 send_unsubscribe(Config, Socket, TopicIdType, TopicIdOrName, PacketId) ->
174 7 Packet =
175 case TopicIdType of
176 ?SHORT_TOPIC_NAME ->
177 7 ?UNSUBSCRIBE_PACKET(PacketId, TopicIdOrName);
178 _ ->
179
:-(
?UNSUBSCRIBE_PACKET(TopicIdOrName, PacketId, TopicIdOrName)
180 end,
181 7 Bin = emqttsn_frame:serialize(Packet, Config),
182 7 emqttsn_udp:send(Socket, Bin).
183
184 %% @doc Send a MQTT-SN Publish packet
185 %%
186 %% @param Config the client object
187 %% @param Socket the socket object
188 %% @param Qos the qos level of publish
189 %% @param Dup whether it is a duplicated packet
190 %% @param Retain whether the message is retain
191 %% @param TopicIdType data type of TopicIdOrName param
192 %% @param TopicIdOrName topic id or name to be sent(decided by TopicIdType)
193 %% @param Message message data of publish request
194 %% @param PacketId the id of packet
195 %%
196 %% @returns ok | {error, not_owner | inet:posix()}
197 %% @end
198 -spec send_publish(config(),
199 inet:socket(),
200 qos(),
201 boolean(),
202 boolean(),
203 topic_id_type(),
204 topic_id_or_name(),
205 string(),
206 packet_id()) ->
207 ok | {error, term()}.
208 send_publish(Config,
209 Socket,
210 Qos,
211 Dup,
212 Retain,
213 TopicIdType,
214 TopicIdOrName,
215 Message,
216 PacketId) ->
217 13 ?assert(TopicIdType == ?SHORT_TOPIC_NAME orelse TopicIdType == ?PRE_DEF_TOPIC_ID),
218 13 Packet =
219 case Qos of
220 ?QOS_0 ->
221 4 ?PUBLISH_PACKET(Dup, Retain, TopicIdType, TopicIdOrName, Message);
222 _ ->
223 9 ?PUBLISH_PACKET(Dup, Qos, Retain, TopicIdType, TopicIdOrName, PacketId, Message)
224 end,
225 13 Bin = emqttsn_frame:serialize(Packet, Config),
226 13 emqttsn_udp:send(Socket, Bin).
227
228 %% @doc Send a MQTT-SN PubAck packet
229 %%
230 %% @param Config the client object
231 %% @param Socket the socket object
232 %% @param TopicId topic id of packet
233 %% @param ReturnCode return code of request
234 %% @param PacketId the id of packet
235 %%
236 %% @returns ok | {error, not_owner | inet:posix()}
237 %% @end
238 -spec send_puback(config(), inet:socket(), topic_id(), return_code(), packet_id()) ->
239 ok | {error, term()}.
240 send_puback(Config, Socket, TopicId, ReturnCode, PacketId) ->
241
:-(
Packet = ?PUBACK_PACKET(TopicId, PacketId, ReturnCode),
242
:-(
Bin = emqttsn_frame:serialize(Packet, Config),
243
:-(
emqttsn_udp:send(Socket, Bin).
244
245 %% @doc Send a MQTT-SN PubRel packet
246 %%
247 %% @param Config the client object
248 %% @param Socket the socket object
249 %% @param PacketId the id of packet
250 %%
251 %% @returns ok | {error, not_owner | inet:posix()}
252 %% @end
253 -spec send_pubrel(config(), inet:socket(), packet_id()) -> ok | {error, term()}.
254 send_pubrel(Config, Socket, PacketId) ->
255 1 Packet = ?PUBREL_PACKET(PacketId),
256 1 Bin = emqttsn_frame:serialize(Packet, Config),
257 1 emqttsn_udp:send(Socket, Bin).
258
259 %% @doc Send a MQTT-SN PubRec packet
260 %%
261 %% @param Config the client object
262 %% @param Socket the socket object
263 %% @param PacketId the id of packet
264 %%
265 %% @returns ok | {error, not_owner | inet:posix()}
266 %% @end
267 -spec send_pubrec(config(), inet:socket(), packet_id()) -> ok | {error, term()}.
268 send_pubrec(Config, Socket, PacketId) ->
269
:-(
Packet = ?PUBREC_PACKET(PacketId),
270
:-(
Bin = emqttsn_frame:serialize(Packet, Config),
271
:-(
emqttsn_udp:send(Socket, Bin).
272
273 %% @doc Send a MQTT-SN PubComp packet
274 %%
275 %% @param Config the client object
276 %% @param Socket the socket object
277 %% @param PacketId the id of packet
278 %%
279 %% @returns ok | {error, not_owner | inet:posix()}
280 %% @end
281 -spec send_pubcomp(config(), inet:socket(), packet_id()) -> ok | {error, term()}.
282 send_pubcomp(Config, Socket, PacketId) ->
283
:-(
Packet = ?PUBCOMP_PACKET(PacketId),
284
:-(
Bin = emqttsn_frame:serialize(Packet, Config),
285
:-(
emqttsn_udp:send(Socket, Bin).
286
287 %% @doc Send a MQTT-SN publish packet to any gateway(at Qos -1)
288 %%
289 %% @param Config the client object
290 %% @param Socket the socket object(not need to connect)
291 %% @param Host host of target gateway
292 %% @param Port port of target gateway
293 %% @param TopicIdType data type of TopicIdOrName param
294 %% @param TopicIdOrName topic id or name to be sent(decided by TopicIdType)
295 %% @param Message message data of publish request
296 %% @returns ok | {error, not_owner | inet:posix()}
297 %% @end
298 -spec send_pub_any(config(),
299 inet:socket(),
300 host(),
301 inet:port_number(),
302 topic_id_type(),
303 topic_id_or_name(),
304 string()) ->
305 ok | {error, term()}.
306 send_pub_any(Config, Socket, Host, Port, TopicIdType, TopicIdOrName, Message) ->
307 1 ?assert(TopicIdType == ?SHORT_TOPIC_NAME orelse TopicIdType == ?PRE_DEF_TOPIC_ID),
308 1 Packet = ?PUBLISH_PACKET(TopicIdType, TopicIdOrName, Message),
309 1 Bin = emqttsn_frame:serialize(Packet, Config),
310 1 emqttsn_udp:send_anywhere(Socket, Bin, Host, Port).
311
312 %% @doc Send a MQTT-SN GwInfo packet to any client
313 %%
314 %% @param Config the client object
315 %% @param Socket the socket object
316 %% @param Host host of target client
317 %% @param Port port of target client
318 %% @param _Radius the radius for transmission packet(not implement)
319 %% @param GateWayId the id of responsed gateway
320 %% @param GateWayAdd the host of responsed gateway(without port)
321 %%
322 %% @returns ok | {error, not_owner | inet:posix()}
323 %% @end
324 -spec send_gwinfo(config(),
325 inet:socket(),
326 host(),
327 inet:port_number(),
328 pos_integer(),
329 gw_id(),
330 host()) ->
331 ok | {error, term()}.
332 send_gwinfo(Config, Socket, Host, Port, _Radius, GateWayId, GateWayAdd) ->
333
:-(
Packet = ?GWINFO_PACKET(GateWayId, GateWayAdd),
334
:-(
Bin = emqttsn_frame:serialize(Packet, Config),
335
:-(
emqttsn_udp:send_anywhere(Socket, Bin, Host, Port).
336
337 %% @doc Send a MQTT-SN Disconnect packet
338 %%
339 %% @param Config the client object
340 %% @param Socket the socket object
341 %%
342 %% @returns ok | {error, not_owner | inet:posix()}
343 %% @end
344 -spec send_disconnect(config(), inet:socket()) -> ok | {error, term()}.
345 send_disconnect(Config, Socket) ->
346 25 Packet = ?DISCONNECT_PACKET(),
347 25 Bin = emqttsn_frame:serialize(Packet, Config),
348 25 emqttsn_udp:send(Socket, Bin).
349
350 %% @doc Send a MQTT-SN asleep Disconnect packet
351 %%
352 %% @param Config the client object
353 %% @param Socket the socket object
354 %% @param Interval sleep interval(ms)
355 %%
356 %% @returns ok | {error, not_owner | inet:posix()}
357 %% @end
358 -spec send_asleep(config(), inet:socket(), non_neg_integer()) -> ok | {error, term()}.
359 send_asleep(Config, Socket, Interval) ->
360 1 Packet = ?DISCONNECT_PACKET(Interval),
361 1 Bin = emqttsn_frame:serialize(Packet, Config),
362 1 emqttsn_udp:send(Socket, Bin).
363
364 %% @doc Send a MQTT-SN awake PingReq packet
365 %%
366 %% @param Config the client object
367 %% @param Socket the socket object
368 %% @param ClientId unique name of client
369 %%
370 %% @returns ok | {error, not_owner | inet:posix()}
371 %% @end
372 -spec send_awake(config(), inet:socket(), string()) -> ok | {error, term()}.
373 send_awake(Config, Socket, ClientId) ->
374 1 Packet = ?PINGREQ_PACKET(ClientId),
375 1 Bin = emqttsn_frame:serialize(Packet, Config),
376 1 emqttsn_udp:send(Socket, Bin).
377
378 %% @doc Send a MQTT-SN PingReq packet
379 %%
380 %% @param Config the client object
381 %% @param Socket the socket object
382 %%
383 %% @returns ok | {error, not_owner | inet:posix()}
384 %% @end
385 -spec send_pingreq(config(), inet:socket()) -> ok | {error, term()}.
386 send_pingreq(Config, Socket) ->
387 1 Packet = ?PINGREQ_PACKET(),
388 1 Bin = emqttsn_frame:serialize(Packet, Config),
389 1 emqttsn_udp:send(Socket, Bin).
390
391 %% @doc Send a MQTT-SN PingResp packet
392 %%
393 %% @param Config the client object
394 %% @param Socket the socket object
395 %%
396 %% @returns ok | {error, not_owner | inet:posix()}
397 %% @end
398 -spec send_pingresp(config(), inet:socket()) -> ok | {error, term()}.
399 send_pingresp(Config, Socket) ->
400
:-(
Packet = ?PINGRESP_PACKET(),
401
:-(
Bin = emqttsn_frame:serialize(Packet, Config),
402
:-(
emqttsn_udp:send(Socket, Bin).
403
404 %% @doc Boardcast a MQTT-SN SearchGw packet
405 %%
406 %% @param Config the client object
407 %% @param Socket the socket object
408 %% @param RemotePort the port to broadcast
409 %% @param Radius the radius for transmission packet
410 %%
411 %% @returns ok | {error, not_owner | inet:posix()}
412 %% @end
413 -spec broadcast_searchgw(config(),
414 inet:socket(),
415 inet:port_number(),
416 non_neg_integer()) ->
417 ok | {error, term()}.
418 broadcast_searchgw(Config, Socket, RemotePort, Radius) ->
419 54 Packet = ?SEARCHGW_PACKET(Radius),
420 54 Bin = emqttsn_frame:serialize(Packet, Config),
421 54 emqttsn_udp:broadcast(Socket, Bin, RemotePort).
Line Hits Source