2014-05-07 22:27:00 +00:00
|
|
|
/*
|
2015-04-19 21:10:59 +00:00
|
|
|
Copyright (c) 2009-2015 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.
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
Contributors:
|
|
|
|
Roger Light - initial implementation and documentation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <mosquitto_broker.h>
|
|
|
|
#include <memory_mosq.h>
|
|
|
|
#include <mqtt3_protocol.h>
|
2015-04-29 20:23:59 +00:00
|
|
|
#include "packet_mosq.h"
|
2014-05-07 22:27:00 +00:00
|
|
|
#include <send_mosq.h>
|
|
|
|
#include <util_mosq.h>
|
|
|
|
|
|
|
|
int mqtt3_handle_connack(struct mosquitto_db *db, struct mosquitto *context)
|
|
|
|
{
|
|
|
|
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-04-19 21:10:59 +00:00
|
|
|
mosquitto__log_printf(NULL, MOSQ_LOG_DEBUG, "Received CONNACK on connection %s.", context->id);
|
|
|
|
if(mosquitto__read_byte(&context->in_packet, &byte)) return 1; // Reserved byte, not used
|
|
|
|
if(mosquitto__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){
|
2015-04-19 21:10:59 +00:00
|
|
|
if(mosquitto__send_real_publish(context, mosquitto__mid_generate(context),
|
2014-05-07 22:27:00 +00:00
|
|
|
context->bridge->notification_topic, 1, ¬ification_payload, 1, true, 0)){
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
mqtt3_db_messages_easy_queue(db, context, context->bridge->notification_topic, 1, 1, ¬ification_payload, 1);
|
|
|
|
}else{
|
2014-08-19 10:29:24 +00:00
|
|
|
notification_topic_len = strlen(context->bridge->remote_clientid)+strlen("$SYS/broker/connection//state");
|
2015-04-19 21:10:59 +00:00
|
|
|
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';
|
2015-04-19 21:10:59 +00:00
|
|
|
if(mosquitto__send_real_publish(context, mosquitto__mid_generate(context),
|
2014-05-07 22:27:00 +00:00
|
|
|
notification_topic, 1, ¬ification_payload, 1, true, 0)){
|
|
|
|
|
2015-04-19 21:10:59 +00:00
|
|
|
mosquitto__free(notification_topic);
|
2014-05-07 22:27:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
mqtt3_db_messages_easy_queue(db, context, notification_topic, 1, 1, ¬ification_payload, 1);
|
2015-04-19 21:10:59 +00:00
|
|
|
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-04-19 21:10:59 +00:00
|
|
|
if(mosquitto__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{
|
2015-01-07 21:50:10 +00:00
|
|
|
if(context->bridge->attempt_unsubscribe){
|
2015-04-19 21:10:59 +00:00
|
|
|
if(mosquitto__send_unsubscribe(context, NULL, context->bridge->topics[i].remote_topic)){
|
2015-01-07 21:50:10 +00:00
|
|
|
/* 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-04-19 21:10:59 +00:00
|
|
|
mosquitto__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-04-19 21:10:59 +00:00
|
|
|
mosquitto__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-04-19 21:10:59 +00:00
|
|
|
mosquitto__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-04-19 21:10:59 +00:00
|
|
|
mosquitto__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-04-19 21:10:59 +00:00
|
|
|
mosquitto__log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: not authorised");
|
2014-05-07 22:27:00 +00:00
|
|
|
return 1;
|
|
|
|
default:
|
2015-04-19 21:10:59 +00:00
|
|
|
mosquitto__log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unknown reason");
|
2014-05-07 22:27:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|