mosquitto/src/handle_connack.c

120 lines
4.2 KiB
C
Raw Normal View History

2014-05-07 22:27:00 +00:00
/*
2018-04-11 14:24:29 +00:00
Copyright (c) 2009-2018 Roger Light <roger@atchoo.org>
2014-05-07 22:27:00 +00:00
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
2014-05-07 22:27:00 +00:00
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
2014-05-07 22:27:00 +00:00
Contributors:
Roger Light - initial implementation and documentation.
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include "mosquitto_broker_internal.h"
2015-04-29 20:37:47 +00:00
#include "memory_mosq.h"
#include "mqtt3_protocol.h"
2015-04-29 20:23:59 +00:00
#include "packet_mosq.h"
2015-04-29 20:37:47 +00:00
#include "send_mosq.h"
#include "util_mosq.h"
2014-05-07 22:27:00 +00:00
2015-05-16 17:43:06 +00:00
int handle__connack(struct mosquitto_db *db, struct mosquitto *context)
2014-05-07 22:27:00 +00:00
{
uint8_t byte;
uint8_t rc;
int i;
char *notification_topic;
int notification_topic_len;
char notification_payload;
if(!context){
return MOSQ_ERR_INVAL;
}
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_DEBUG, "Received CONNACK on connection %s.", context->id);
2015-05-16 13:16:40 +00:00
if(packet__read_byte(&context->in_packet, &byte)) return 1; // Reserved byte, not used
if(packet__read_byte(&context->in_packet, &rc)) return 1;
2014-05-07 22:27:00 +00:00
switch(rc){
case CONNACK_ACCEPTED:
if(context->bridge){
if(context->bridge->notifications){
notification_payload = '1';
if(context->bridge->notification_topic){
if(!context->bridge->notifications_local_only){
if(send__real_publish(context, mosquitto__mid_generate(context),
context->bridge->notification_topic, 1, &notification_payload, 1, true, 0)){
2014-05-07 22:27:00 +00:00
return 1;
}
2014-05-07 22:27:00 +00:00
}
2015-05-16 14:24:24 +00:00
db__messages_easy_queue(db, context, context->bridge->notification_topic, 1, 1, &notification_payload, 1);
2014-05-07 22:27:00 +00:00
}else{
2014-08-19 10:29:24 +00:00
notification_topic_len = strlen(context->bridge->remote_clientid)+strlen("$SYS/broker/connection//state");
notification_topic = mosquitto__malloc(sizeof(char)*(notification_topic_len+1));
2014-05-07 22:27:00 +00:00
if(!notification_topic) return MOSQ_ERR_NOMEM;
2014-08-19 10:29:24 +00:00
snprintf(notification_topic, notification_topic_len+1, "$SYS/broker/connection/%s/state", context->bridge->remote_clientid);
2014-05-07 22:27:00 +00:00
notification_payload = '1';
if(!context->bridge->notifications_local_only){
if(send__real_publish(context, mosquitto__mid_generate(context),
notification_topic, 1, &notification_payload, 1, true, 0)){
2014-05-07 22:27:00 +00:00
mosquitto__free(notification_topic);
return 1;
}
2014-05-07 22:27:00 +00:00
}
2015-05-16 14:24:24 +00:00
db__messages_easy_queue(db, context, notification_topic, 1, 1, &notification_payload, 1);
mosquitto__free(notification_topic);
2014-05-07 22:27:00 +00:00
}
}
for(i=0; i<context->bridge->topic_count; i++){
if(context->bridge->topics[i].direction == bd_in || context->bridge->topics[i].direction == bd_both){
2015-05-16 14:24:24 +00:00
if(send__subscribe(context, NULL, context->bridge->topics[i].remote_topic, context->bridge->topics[i].qos)){
2014-05-07 22:27:00 +00:00
return 1;
}
}else{
if(context->bridge->attempt_unsubscribe){
2015-05-16 14:24:24 +00:00
if(send__unsubscribe(context, NULL, context->bridge->topics[i].remote_topic)){
/* direction = inwards only. This means we should not be subscribed
* to the topic. It is possible that we used to be subscribed to
* this topic so unsubscribe. */
return 1;
}
2014-05-07 22:27:00 +00:00
}
}
}
}
context->state = mosq_cs_connected;
return MOSQ_ERR_SUCCESS;
case CONNACK_REFUSED_PROTOCOL_VERSION:
if(context->bridge){
context->bridge->try_private_accepted = false;
}
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unacceptable protocol version");
2014-05-07 22:27:00 +00:00
return 1;
case CONNACK_REFUSED_IDENTIFIER_REJECTED:
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR, "Connection Refused: identifier rejected");
2014-05-07 22:27:00 +00:00
return 1;
case CONNACK_REFUSED_SERVER_UNAVAILABLE:
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR, "Connection Refused: broker unavailable");
2014-05-07 22:27:00 +00:00
return 1;
case CONNACK_REFUSED_BAD_USERNAME_PASSWORD:
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR, "Connection Refused: broker unavailable");
2014-05-07 22:27:00 +00:00
return 1;
case CONNACK_REFUSED_NOT_AUTHORIZED:
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR, "Connection Refused: not authorised");
2014-05-07 22:27:00 +00:00
return 1;
default:
2015-05-18 07:53:21 +00:00
log__printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unknown reason");
2014-05-07 22:27:00 +00:00
return 1;
}
return 1;
}