| /* | 
| Copyright (c) 2009-2019 Roger Light <roger@atchoo.org> | 
|   | 
| 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 <assert.h> | 
| #include <stdio.h> | 
| #include <string.h> | 
|   | 
| #ifdef WITH_BROKER | 
| #  include "mosquitto_broker_internal.h" | 
| #endif | 
|   | 
| #include "mosquitto.h" | 
| #include "logging_mosq.h" | 
| #include "memory_mosq.h" | 
| #include "messages_mosq.h" | 
| #include "mqtt_protocol.h" | 
| #include "net_mosq.h" | 
| #include "packet_mosq.h" | 
| #include "property_mosq.h" | 
| #include "read_handle.h" | 
| #include "send_mosq.h" | 
| #include "util_mosq.h" | 
|   | 
|   | 
| int handle__unsuback(struct mosquitto *mosq) | 
| { | 
|     uint16_t mid; | 
|     int rc; | 
|     mosquitto_property *properties = NULL; | 
|   | 
|     assert(mosq); | 
|   | 
|     if(mosq->state != mosq_cs_connected){ | 
|         return MOSQ_ERR_PROTOCOL; | 
|     } | 
|   | 
| #ifdef WITH_BROKER | 
|     log__printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBACK from %s", mosq->id); | 
| #else | 
|     log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received UNSUBACK", mosq->id); | 
| #endif | 
|     rc = packet__read_uint16(&mosq->in_packet, &mid); | 
|     if(rc) return rc; | 
|     if(mid == 0) return MOSQ_ERR_PROTOCOL; | 
|   | 
|     if(mosq->protocol == mosq_p_mqtt5){ | 
|         rc = property__read_all(CMD_UNSUBACK, &mosq->in_packet, &properties); | 
|         if(rc) return rc; | 
|     } | 
|   | 
| #ifdef WITH_BROKER | 
|     /* Immediately free, we don't do anything with Reason String or User Property at the moment */ | 
|     mosquitto_property_free_all(&properties); | 
| #else | 
|     pthread_mutex_lock(&mosq->callback_mutex); | 
|     if(mosq->on_unsubscribe){ | 
|         mosq->in_callback = true; | 
|         mosq->on_unsubscribe(mosq, mosq->userdata, mid); | 
|         mosq->in_callback = false; | 
|     } | 
|     if(mosq->on_unsubscribe_v5){ | 
|         mosq->in_callback = true; | 
|         mosq->on_unsubscribe_v5(mosq, mosq->userdata, mid, properties); | 
|         mosq->in_callback = false; | 
|     } | 
|     pthread_mutex_unlock(&mosq->callback_mutex); | 
|     mosquitto_property_free_all(&properties); | 
| #endif | 
|   | 
|     return MOSQ_ERR_SUCCESS; | 
| } |