UNPKG

5.22 kBtext/x-cView Raw
1/*
2Copyright (c) 2009-2013 Roger Light <roger@atchoo.org>
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
81. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
102. 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.
133. 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.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <config.h>
31#include <stdio.h>
32#include <string.h>
33
34#include <mosquitto_broker.h>
35#include <memory_mosq.h>
36#include <mqtt3_protocol.h>
37#include <send_mosq.h>
38#include <util_mosq.h>
39
40int mqtt3_handle_connack(struct mosquitto_db *db, struct mosquitto *context)
41{
42 uint8_t byte;
43 uint8_t rc;
44 int i;
45 char *notification_topic;
46 int notification_topic_len;
47 char notification_payload;
48
49 if(!context){
50 return MOSQ_ERR_INVAL;
51 }
52#ifdef WITH_STRICT_PROTOCOL
53 if(context->in_packet.remaining_length != 2){
54 return MOSQ_ERR_PROTOCOL;
55 }
56#endif
57 _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received CONNACK on connection %s.", context->id);
58 if(_mosquitto_read_byte(&context->in_packet, &byte)) return 1; // Reserved byte, not used
59 if(_mosquitto_read_byte(&context->in_packet, &rc)) return 1;
60 switch(rc){
61 case CONNACK_ACCEPTED:
62 if(context->bridge){
63 if(context->bridge->notifications){
64 notification_payload = '1';
65 if(context->bridge->notification_topic){
66 if(_mosquitto_send_real_publish(context, _mosquitto_mid_generate(context),
67 context->bridge->notification_topic, 1, &notification_payload, 1, true, 0)){
68
69 return 1;
70 }
71 mqtt3_db_messages_easy_queue(db, context, context->bridge->notification_topic, 1, 1, &notification_payload, 1);
72 }else{
73 notification_topic_len = strlen(context->id)+strlen("$SYS/broker/connection//state");
74 notification_topic = _mosquitto_malloc(sizeof(char)*(notification_topic_len+1));
75 if(!notification_topic) return MOSQ_ERR_NOMEM;
76
77 snprintf(notification_topic, notification_topic_len+1, "$SYS/broker/connection/%s/state", context->id);
78 notification_payload = '1';
79 if(_mosquitto_send_real_publish(context, _mosquitto_mid_generate(context),
80 notification_topic, 1, &notification_payload, 1, true, 0)){
81
82 _mosquitto_free(notification_topic);
83 return 1;
84 }
85 mqtt3_db_messages_easy_queue(db, context, notification_topic, 1, 1, &notification_payload, 1);
86 _mosquitto_free(notification_topic);
87 }
88 }
89 for(i=0; i<context->bridge->topic_count; i++){
90 if(context->bridge->topics[i].direction == bd_in || context->bridge->topics[i].direction == bd_both){
91 if(_mosquitto_send_subscribe(context, NULL, false, context->bridge->topics[i].remote_topic, context->bridge->topics[i].qos)){
92 return 1;
93 }
94 }else{
95 if(_mosquitto_send_unsubscribe(context, NULL, false, context->bridge->topics[i].remote_topic)){
96 /* direction = inwards only. This means we should not be subscribed
97 * to the topic. It is possible that we used to be subscribed to
98 * this topic so unsubscribe. */
99 return 1;
100 }
101 }
102 }
103 }
104 context->state = mosq_cs_connected;
105 return MOSQ_ERR_SUCCESS;
106 case CONNACK_REFUSED_PROTOCOL_VERSION:
107 if(context->bridge){
108 context->bridge->try_private_accepted = false;
109 }
110 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unacceptable protocol version");
111 return 1;
112 case CONNACK_REFUSED_IDENTIFIER_REJECTED:
113 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: identifier rejected");
114 return 1;
115 case CONNACK_REFUSED_SERVER_UNAVAILABLE:
116 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: broker unavailable");
117 return 1;
118 case CONNACK_REFUSED_BAD_USERNAME_PASSWORD:
119 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: broker unavailable");
120 return 1;
121 case CONNACK_REFUSED_NOT_AUTHORIZED:
122 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: not authorised");
123 return 1;
124 default:
125 _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unknown reason");
126 return 1;
127 }
128 return 1;
129}
130