this is fork and i will modify for STM32

Fork of AWS-test by Pierre-Marie Ancèle

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aws_iot_mqtt_client_unsubscribe.cpp Source File

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