Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of AWS-test by
aws_iot_mqtt_client_unsubscribe.cpp
00001 /* 00002 * Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"). 00005 * You may not use this file except in compliance with the License. 00006 * A copy of the License is located at 00007 * 00008 * http://aws.amazon.com/apache2.0 00009 * 00010 * or in the "license" file accompanying this file. This file is distributed 00011 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 00012 * express or implied. See the License for the specific language governing 00013 * permissions and limitations under the License. 00014 */ 00015 00016 // Based on Eclipse Paho. 00017 /******************************************************************************* 00018 * Copyright (c) 2014 IBM Corp. 00019 * 00020 * All rights reserved. This program and the accompanying materials 00021 * are made available under the terms of the Eclipse Public License v1.0 00022 * and Eclipse Distribution License v1.0 which accompany this distribution. 00023 * 00024 * The Eclipse Public License is available at 00025 * http://www.eclipse.org/legal/epl-v10.html 00026 * and the Eclipse Distribution License is available at 00027 * http://www.eclipse.org/org/documents/edl-v10.php. 00028 * 00029 * Contributors: 00030 * Ian Craggs - initial API and implementation and/or initial documentation 00031 *******************************************************************************/ 00032 00033 /** 00034 * @file aws_iot_mqtt_client_unsubscribe.c 00035 * @brief MQTT client unsubscribe API definitions 00036 */ 00037 00038 #ifdef __cplusplus 00039 extern "C" { 00040 #endif 00041 00042 #include "aws_iot_mqtt_client_common_internal.h" 00043 00044 /** 00045 * Serializes the supplied unsubscribe data into the supplied buffer, ready for sending 00046 * @param pTxBuf the raw buffer data, of the correct length determined by the remaining length field 00047 * @param txBufLen the length in bytes of the data in the supplied buffer 00048 * @param dup integer - the MQTT dup flag 00049 * @param packetId integer - the MQTT packet identifier 00050 * @param count - number of members in the topicFilters array 00051 * @param pTopicNameList - array of topic filter names 00052 * @param pTopicNameLenList - array of length of topic filter names in pTopicNameList 00053 * @param pSerializedLen - the length of the serialized data 00054 * @return IoT_Error_t indicating function execution status 00055 */ 00056 static IoT_Error_t _aws_iot_mqtt_serialize_unsubscribe(unsigned char *pTxBuf, size_t txBufLen, 00057 uint8_t dup, uint16_t packetId, 00058 uint32_t count, const char **pTopicNameList, 00059 uint16_t *pTopicNameLenList, uint32_t *pSerializedLen) { 00060 unsigned char *ptr = pTxBuf; 00061 uint32_t i = 0; 00062 uint32_t rem_len = 2; /* packetId */ 00063 IoT_Error_t rc; 00064 MQTTHeader header = {0}; 00065 00066 FUNC_ENTRY; 00067 00068 for(i = 0; i < count; ++i) { 00069 rem_len += (uint32_t) (pTopicNameLenList[i] + 2); /* topic + length */ 00070 } 00071 00072 if(aws_iot_mqtt_internal_get_final_packet_length_from_remaining_length(rem_len) > txBufLen) { 00073 FUNC_EXIT_RC(MQTT_TX_BUFFER_TOO_SHORT_ERROR); 00074 } 00075 00076 rc = aws_iot_mqtt_internal_init_header(&header, UNSUBSCRIBE, QOS1, dup, 0); 00077 if(IOT_SUCCESS != rc) { 00078 FUNC_EXIT_RC(rc); 00079 } 00080 aws_iot_mqtt_internal_write_char(&ptr, header.byte); /* write header */ 00081 00082 ptr += aws_iot_mqtt_internal_write_len_to_buffer(ptr, rem_len); /* write remaining length */ 00083 00084 aws_iot_mqtt_internal_write_uint_16(&ptr, packetId); 00085 00086 for(i = 0; i < count; ++i) { 00087 aws_iot_mqtt_internal_write_utf8_string(&ptr, pTopicNameList[i], pTopicNameLenList[i]); 00088 } 00089 00090 *pSerializedLen = (uint32_t) (ptr - pTxBuf); 00091 00092 FUNC_EXIT_RC(IOT_SUCCESS); 00093 } 00094 00095 00096 /** 00097 * Deserializes the supplied (wire) buffer into unsuback data 00098 * @param pPacketId returned integer - the MQTT packet identifier 00099 * @param pRxBuf the raw buffer data, of the correct length determined by the remaining length field 00100 * @param rxBufLen the length in bytes of the data in the supplied buffer 00101 * @return IoT_Error_t indicating function execution status 00102 */ 00103 static IoT_Error_t _aws_iot_mqtt_deserialize_unsuback(uint16_t *pPacketId, unsigned char *pRxBuf, size_t rxBufLen) { 00104 unsigned char type = 0; 00105 unsigned char dup = 0; 00106 IoT_Error_t rc; 00107 00108 FUNC_ENTRY; 00109 00110 rc = aws_iot_mqtt_internal_deserialize_ack(&type, &dup, pPacketId, pRxBuf, rxBufLen); 00111 if(IOT_SUCCESS == rc && UNSUBACK != type) { 00112 rc = IOT_FAILURE; 00113 } 00114 00115 FUNC_EXIT_RC(rc); 00116 } 00117 00118 /** 00119 * @brief Unsubscribe to an MQTT topic. 00120 * 00121 * Called to send an unsubscribe message to the broker requesting removal of a subscription 00122 * to an MQTT topic. 00123 * @note Call is blocking. The call returns after the receipt of the UNSUBACK control packet. 00124 * This is the internal function which is called by the unsubscribe API to perform the operation. 00125 * Not meant to be called directly as it doesn't do validations or client state changes 00126 * 00127 * @param pClient Reference to the IoT Client 00128 * @param pTopicName Topic Name to publish to 00129 * @param topicNameLen Length of the topic name 00130 * 00131 * @return An IoT Error Type defining successful/failed unsubscribe call 00132 */ 00133 static IoT_Error_t _aws_iot_mqtt_internal_unsubscribe(AWS_IoT_Client *pClient, const char *pTopicFilter, 00134 uint16_t topicFilterLen) { 00135 /* No NULL checks because this is a static internal function */ 00136 00137 TimerAWS timer; 00138 00139 uint16_t packet_id; 00140 uint32_t serializedLen = 0; 00141 uint32_t i = 0; 00142 IoT_Error_t rc; 00143 bool subscriptionExists = false; 00144 00145 FUNC_ENTRY; 00146 00147 /* Remove from message handler array */ 00148 for(i = 0; i < AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS; ++i) { 00149 if(pClient->clientData.messageHandlers[i].topicName != NULL && 00150 (strcmp(pClient->clientData.messageHandlers[i].topicName, pTopicFilter) == 0)) { 00151 subscriptionExists = true; 00152 } 00153 } 00154 00155 if(false == subscriptionExists) { 00156 FUNC_EXIT_RC(IOT_FAILURE); 00157 } 00158 00159 init_timer(&timer); 00160 countdown_ms(&timer, pClient->clientData.commandTimeoutMs); 00161 00162 rc = _aws_iot_mqtt_serialize_unsubscribe(pClient->clientData.writeBuf, pClient->clientData.writeBufSize, 0, 00163 aws_iot_mqtt_get_next_packet_id(pClient), 1, &pTopicFilter, 00164 &topicFilterLen, &serializedLen); 00165 if(IOT_SUCCESS != rc) { 00166 FUNC_EXIT_RC(rc); 00167 } 00168 00169 /* send the unsubscribe packet */ 00170 rc = aws_iot_mqtt_internal_send_packet(pClient, serializedLen, &timer); 00171 if(IOT_SUCCESS != rc) { 00172 FUNC_EXIT_RC(rc); 00173 } 00174 00175 rc = aws_iot_mqtt_internal_wait_for_read(pClient, UNSUBACK, &timer); 00176 if(IOT_SUCCESS != rc) { 00177 FUNC_EXIT_RC(rc); 00178 } 00179 00180 rc = _aws_iot_mqtt_deserialize_unsuback(&packet_id, pClient->clientData.readBuf, pClient->clientData.readBufSize); 00181 if(IOT_SUCCESS != rc) { 00182 FUNC_EXIT_RC(rc); 00183 } 00184 00185 /* Remove from message handler array */ 00186 for(i = 0; i < AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS; ++i) { 00187 if(pClient->clientData.messageHandlers[i].topicName != NULL && 00188 (strcmp(pClient->clientData.messageHandlers[i].topicName, pTopicFilter) == 0)) { 00189 pClient->clientData.messageHandlers[i].topicName = NULL; 00190 /* We don't want to break here, in case the same topic is registered 00191 * with 2 callbacks. Unlikely scenario */ 00192 } 00193 } 00194 00195 FUNC_EXIT_RC(IOT_SUCCESS); 00196 } 00197 00198 /** 00199 * @brief Unsubscribe to an MQTT topic. 00200 * 00201 * Called to send an unsubscribe message to the broker requesting removal of a subscription 00202 * to an MQTT topic. 00203 * @note Call is blocking. The call returns after the receipt of the UNSUBACK control packet. 00204 * This is the outer function which does the validations and calls the internal unsubscribe above 00205 * to perform the actual operation. It is also responsible for client state changes 00206 * 00207 * @param pClient Reference to the IoT Client 00208 * @param pTopicName Topic Name to publish to 00209 * @param topicNameLen Length of the topic name 00210 * 00211 * @return An IoT Error Type defining successful/failed unsubscribe call 00212 */ 00213 IoT_Error_t aws_iot_mqtt_unsubscribe(AWS_IoT_Client *pClient, const char *pTopicFilter, uint16_t topicFilterLen) { 00214 IoT_Error_t rc, unsubRc; 00215 ClientState clientState; 00216 00217 if(NULL == pClient || NULL == pTopicFilter) { 00218 return NULL_VALUE_ERROR; 00219 } 00220 00221 if(!aws_iot_mqtt_is_client_connected(pClient)) { 00222 return NETWORK_DISCONNECTED_ERROR; 00223 } 00224 00225 clientState = aws_iot_mqtt_get_client_state(pClient); 00226 if(CLIENT_STATE_CONNECTED_IDLE != clientState && CLIENT_STATE_CONNECTED_WAIT_FOR_CB_RETURN != clientState) { 00227 return MQTT_CLIENT_NOT_IDLE_ERROR; 00228 } 00229 00230 rc = aws_iot_mqtt_set_client_state(pClient, clientState, CLIENT_STATE_CONNECTED_UNSUBSCRIBE_IN_PROGRESS); 00231 if(IOT_SUCCESS != rc) { 00232 rc = aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTED_UNSUBSCRIBE_IN_PROGRESS, clientState); 00233 return rc; 00234 } 00235 00236 unsubRc = _aws_iot_mqtt_internal_unsubscribe(pClient, pTopicFilter, topicFilterLen); 00237 00238 rc = aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTED_UNSUBSCRIBE_IN_PROGRESS, clientState); 00239 if(IOT_SUCCESS == unsubRc && IOT_SUCCESS != rc) { 00240 unsubRc = rc; 00241 } 00242 00243 return unsubRc; 00244 } 00245 00246 #ifdef __cplusplus 00247 } 00248 #endif 00249
Generated on Tue Jul 12 2022 11:16:37 by
