2 Copyright (c) 2009-2013 Roger Light <roger@atchoo.org>
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 1. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. Neither the name of mosquitto nor the names of its
14 contributors may be used to endorse or promote products derived from
15 this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE.
33 #include "mosquitto.h"
34 #include "logging_mosq.h"
35 #include "memory_mosq.h"
36 #include "mqtt3_protocol.h"
38 #include "send_mosq.h"
39 #include "util_mosq.h"
42 #include "mosquitto_broker.h"
45 int _mosquitto_send_connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session)
47 struct _mosquitto_packet *packet = NULL;
52 uint8_t version = PROTOCOL_VERSION_v31;
57 packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
58 if(!packet) return MOSQ_ERR_NOMEM;
60 payloadlen = 2+strlen(mosq->id);
63 assert(mosq->will->topic);
65 payloadlen += 2+strlen(mosq->will->topic) + 2+mosq->will->payloadlen;
68 payloadlen += 2+strlen(mosq->username);
70 payloadlen += 2+strlen(mosq->password);
74 packet->command = CONNECT;
75 packet->remaining_length = 12+payloadlen;
76 rc = _mosquitto_packet_alloc(packet);
78 _mosquitto_free(packet);
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){
90 _mosquitto_write_byte(packet, version);
91 byte = (clean_session&0x1)<<1;
93 byte = byte | ((mosq->will->retain&0x1)<<5) | ((mosq->will->qos&0x3)<<3) | ((will&0x1)<<2);
101 _mosquitto_write_byte(packet, byte);
102 _mosquitto_write_uint16(packet, keepalive);
105 _mosquitto_write_string(packet, mosq->id, strlen(mosq->id));
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);
111 _mosquitto_write_string(packet, mosq->username, strlen(mosq->username));
113 _mosquitto_write_string(packet, mosq->password, strlen(mosq->password));
117 mosq->keepalive = keepalive;
120 _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending CONNECT", mosq->id);
123 _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending CONNECT", mosq->id);
125 return _mosquitto_packet_queue(mosq, packet);
128 int _mosquitto_send_disconnect(struct mosquitto *mosq)
133 _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending DISCONNECT", mosq->id);
136 _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending DISCONNECT", mosq->id);
138 return _mosquitto_send_simple_command(mosq, DISCONNECT);
141 int _mosquitto_send_subscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic, uint8_t topic_qos)
143 /* FIXME - only deals with a single topic */
144 struct _mosquitto_packet *packet = NULL;
152 packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
153 if(!packet) return MOSQ_ERR_NOMEM;
155 packetlen = 2 + 2+strlen(topic) + 1;
157 packet->command = SUBSCRIBE | (dup<<3) | (1<<1);
158 packet->remaining_length = packetlen;
159 rc = _mosquitto_packet_alloc(packet);
161 _mosquitto_free(packet);
165 /* Variable header */
166 local_mid = _mosquitto_mid_generate(mosq);
167 if(mid) *mid = (int)local_mid;
168 _mosquitto_write_uint16(packet, local_mid);
171 _mosquitto_write_string(packet, topic, strlen(topic));
172 _mosquitto_write_byte(packet, topic_qos);
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);
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);
182 return _mosquitto_packet_queue(mosq, packet);
186 int _mosquitto_send_unsubscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic)
188 /* FIXME - only deals with a single topic */
189 struct _mosquitto_packet *packet = NULL;
197 packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet));
198 if(!packet) return MOSQ_ERR_NOMEM;
200 packetlen = 2 + 2+strlen(topic);
202 packet->command = UNSUBSCRIBE | (dup<<3) | (1<<1);
203 packet->remaining_length = packetlen;
204 rc = _mosquitto_packet_alloc(packet);
206 _mosquitto_free(packet);
210 /* Variable header */
211 local_mid = _mosquitto_mid_generate(mosq);
212 if(mid) *mid = (int)local_mid;
213 _mosquitto_write_uint16(packet, local_mid);
216 _mosquitto_write_string(packet, topic, strlen(topic));
220 _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic);
223 _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic);
225 return _mosquitto_packet_queue(mosq, packet);