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 | #include <assert.h>
|
31 | #include <string.h>
|
32 |
|
33 | #include "mosquitto.h"
|
34 | #include "logging_mosq.h"
|
35 | #include "memory_mosq.h"
|
36 | #include "mqtt3_protocol.h"
|
37 | #include "net_mosq.h"
|
38 | #include "send_mosq.h"
|
39 | #include "util_mosq.h"
|
40 |
|
41 | #ifdef WITH_BROKER
|
42 | #include "mosquitto_broker.h"
|
43 | #endif
|
44 |
|
45 | int _mosquitto_send_connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session)
|
46 | {
|
47 | struct _mosquitto_packet *packet = NULL;
|
48 | int payloadlen;
|
49 | uint8_t will = 0;
|
50 | uint8_t byte;
|
51 | int rc;
|
52 | uint8_t version = PROTOCOL_VERSION_v31;
|
53 |
|
54 | assert(mosq);
|
55 | assert(mosq->id);
|
56 |
|
57 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
|
58 | if(!packet) return MOSQ_ERR_NOMEM;
|
59 |
|
60 | payloadlen = 2+strlen(mosq->id);
|
61 | if(mosq->will){
|
62 | will = 1;
|
63 | assert(mosq->will->topic);
|
64 |
|
65 | payloadlen += 2+strlen(mosq->will->topic) + 2+mosq->will->payloadlen;
|
66 | }
|
67 | if(mosq->username){
|
68 | payloadlen += 2+strlen(mosq->username);
|
69 | if(mosq->password){
|
70 | payloadlen += 2+strlen(mosq->password);
|
71 | }
|
72 | }
|
73 |
|
74 | packet->command = CONNECT;
|
75 | packet->remaining_length = 12+payloadlen;
|
76 | rc = _mosquitto_packet_alloc(packet);
|
77 | if(rc){
|
78 | _mosquitto_free(packet);
|
79 | return rc;
|
80 | }
|
81 |
|
82 |
|
83 | _mosquitto_write_string(packet, PROTOCOL_NAME_v31, strlen(PROTOCOL_NAME_v31));
|
84 | #if defined(WITH_BROKER) && defined(WITH_BRIDGE)
|
85 | if(mosq->bridge && mosq->bridge->try_private && mosq->bridge->try_private_accepted){
|
86 | version |= 0x80;
|
87 | }else{
|
88 | }
|
89 | #endif
|
90 | _mosquitto_write_byte(packet, version);
|
91 | byte = (clean_session&0x1)<<1;
|
92 | if(will){
|
93 | byte = byte | ((mosq->will->retain&0x1)<<5) | ((mosq->will->qos&0x3)<<3) | ((will&0x1)<<2);
|
94 | }
|
95 | if(mosq->username){
|
96 | byte = byte | 0x1<<7;
|
97 | if(mosq->password){
|
98 | byte = byte | 0x1<<6;
|
99 | }
|
100 | }
|
101 | _mosquitto_write_byte(packet, byte);
|
102 | _mosquitto_write_uint16(packet, keepalive);
|
103 |
|
104 |
|
105 | _mosquitto_write_string(packet, mosq->id, strlen(mosq->id));
|
106 | if(will){
|
107 | _mosquitto_write_string(packet, mosq->will->topic, strlen(mosq->will->topic));
|
108 | _mosquitto_write_string(packet, (const char *)mosq->will->payload, mosq->will->payloadlen);
|
109 | }
|
110 | if(mosq->username){
|
111 | _mosquitto_write_string(packet, mosq->username, strlen(mosq->username));
|
112 | if(mosq->password){
|
113 | _mosquitto_write_string(packet, mosq->password, strlen(mosq->password));
|
114 | }
|
115 | }
|
116 |
|
117 | mosq->keepalive = keepalive;
|
118 | #ifdef WITH_BROKER
|
119 | # ifdef WITH_BRIDGE
|
120 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending CONNECT", mosq->id);
|
121 | # endif
|
122 | #else
|
123 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending CONNECT", mosq->id);
|
124 | #endif
|
125 | return _mosquitto_packet_queue(mosq, packet);
|
126 | }
|
127 |
|
128 | int _mosquitto_send_disconnect(struct mosquitto *mosq)
|
129 | {
|
130 | assert(mosq);
|
131 | #ifdef WITH_BROKER
|
132 | # ifdef WITH_BRIDGE
|
133 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending DISCONNECT", mosq->id);
|
134 | # endif
|
135 | #else
|
136 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending DISCONNECT", mosq->id);
|
137 | #endif
|
138 | return _mosquitto_send_simple_command(mosq, DISCONNECT);
|
139 | }
|
140 |
|
141 | int _mosquitto_send_subscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic, uint8_t topic_qos)
|
142 | {
|
143 |
|
144 | struct _mosquitto_packet *packet = NULL;
|
145 | uint32_t packetlen;
|
146 | uint16_t local_mid;
|
147 | int rc;
|
148 |
|
149 | assert(mosq);
|
150 | assert(topic);
|
151 |
|
152 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
|
153 | if(!packet) return MOSQ_ERR_NOMEM;
|
154 |
|
155 | packetlen = 2 + 2+strlen(topic) + 1;
|
156 |
|
157 | packet->command = SUBSCRIBE | (dup<<3) | (1<<1);
|
158 | packet->remaining_length = packetlen;
|
159 | rc = _mosquitto_packet_alloc(packet);
|
160 | if(rc){
|
161 | _mosquitto_free(packet);
|
162 | return rc;
|
163 | }
|
164 |
|
165 |
|
166 | local_mid = _mosquitto_mid_generate(mosq);
|
167 | if(mid) *mid = (int)local_mid;
|
168 | _mosquitto_write_uint16(packet, local_mid);
|
169 |
|
170 |
|
171 | _mosquitto_write_string(packet, topic, strlen(topic));
|
172 | _mosquitto_write_byte(packet, topic_qos);
|
173 |
|
174 | #ifdef WITH_BROKER
|
175 | # ifdef WITH_BRIDGE
|
176 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending SUBSCRIBE (Mid: %d, Topic: %s, QoS: %d)", mosq->id, local_mid, topic, topic_qos);
|
177 | # endif
|
178 | #else
|
179 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending SUBSCRIBE (Mid: %d, Topic: %s, QoS: %d)", mosq->id, local_mid, topic, topic_qos);
|
180 | #endif
|
181 |
|
182 | return _mosquitto_packet_queue(mosq, packet);
|
183 | }
|
184 |
|
185 |
|
186 | int _mosquitto_send_unsubscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic)
|
187 | {
|
188 |
|
189 | struct _mosquitto_packet *packet = NULL;
|
190 | uint32_t packetlen;
|
191 | uint16_t local_mid;
|
192 | int rc;
|
193 |
|
194 | assert(mosq);
|
195 | assert(topic);
|
196 |
|
197 | packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
|
198 | if(!packet) return MOSQ_ERR_NOMEM;
|
199 |
|
200 | packetlen = 2 + 2+strlen(topic);
|
201 |
|
202 | packet->command = UNSUBSCRIBE | (dup<<3) | (1<<1);
|
203 | packet->remaining_length = packetlen;
|
204 | rc = _mosquitto_packet_alloc(packet);
|
205 | if(rc){
|
206 | _mosquitto_free(packet);
|
207 | return rc;
|
208 | }
|
209 |
|
210 |
|
211 | local_mid = _mosquitto_mid_generate(mosq);
|
212 | if(mid) *mid = (int)local_mid;
|
213 | _mosquitto_write_uint16(packet, local_mid);
|
214 |
|
215 |
|
216 | _mosquitto_write_string(packet, topic, strlen(topic));
|
217 |
|
218 | #ifdef WITH_BROKER
|
219 | # ifdef WITH_BRIDGE
|
220 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic);
|
221 | # endif
|
222 | #else
|
223 | _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic);
|
224 | #endif
|
225 | return _mosquitto_packet_queue(mosq, packet);
|
226 | }
|
227 |
|