Library for MQTT

Committer:
pavleradojkovic
Date:
Mon Jun 20 16:24:43 2022 +0000
Revision:
0:ba7e439238ab
Inital commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pavleradojkovic 0:ba7e439238ab 1 /*
pavleradojkovic 0:ba7e439238ab 2 * Copyright (c) 2020, ARM Limited, All Rights Reserved
pavleradojkovic 0:ba7e439238ab 3 * SPDX-License-Identifier: Apache-2.0
pavleradojkovic 0:ba7e439238ab 4 *
pavleradojkovic 0:ba7e439238ab 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
pavleradojkovic 0:ba7e439238ab 6 * not use this file except in compliance with the License.
pavleradojkovic 0:ba7e439238ab 7 * You may obtain a copy of the License at
pavleradojkovic 0:ba7e439238ab 8 *
pavleradojkovic 0:ba7e439238ab 9 * http://www.apache.org/licenses/LICENSE-2.0
pavleradojkovic 0:ba7e439238ab 10 *
pavleradojkovic 0:ba7e439238ab 11 * Unless required by applicable law or agreed to in writing, software
pavleradojkovic 0:ba7e439238ab 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
pavleradojkovic 0:ba7e439238ab 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
pavleradojkovic 0:ba7e439238ab 14 * See the License for the specific language governing permissions and
pavleradojkovic 0:ba7e439238ab 15 * limitations under the License.
pavleradojkovic 0:ba7e439238ab 16 */
pavleradojkovic 0:ba7e439238ab 17
pavleradojkovic 0:ba7e439238ab 18 #ifndef _MQTTNETWORK_UTIL_H_
pavleradojkovic 0:ba7e439238ab 19 #define _MQTTNETWORK_UTIL_H_
pavleradojkovic 0:ba7e439238ab 20
pavleradojkovic 0:ba7e439238ab 21 /* MQTT doesn't expect nsapi error values so we translate them */
pavleradojkovic 0:ba7e439238ab 22 static int convert_nsapi_error_to_mqtt_error(int nsapi_error)
pavleradojkovic 0:ba7e439238ab 23 {
pavleradojkovic 0:ba7e439238ab 24 if (nsapi_error == NSAPI_ERROR_WOULD_BLOCK) {
pavleradojkovic 0:ba7e439238ab 25 /* MQTT expects 0 on timeout */
pavleradojkovic 0:ba7e439238ab 26 return 0;
pavleradojkovic 0:ba7e439238ab 27 } else if (nsapi_error == 0) {
pavleradojkovic 0:ba7e439238ab 28 /* MQTT expect -1 on closed sockets */
pavleradojkovic 0:ba7e439238ab 29 return -1;
pavleradojkovic 0:ba7e439238ab 30 }
pavleradojkovic 0:ba7e439238ab 31 return nsapi_error;
pavleradojkovic 0:ba7e439238ab 32 }
pavleradojkovic 0:ba7e439238ab 33
pavleradojkovic 0:ba7e439238ab 34 /** Reads data and returns number of bytes read or a translated error that MQTT expects. This will call
pavleradojkovic 0:ba7e439238ab 35 * read on the socket multiple times until all data is retrieved.
pavleradojkovic 0:ba7e439238ab 36 *
pavleradojkovic 0:ba7e439238ab 37 * @tparam SocketType Socket type like TCPSocket.
pavleradojkovic 0:ba7e439238ab 38 * @param socket Socket to read data from.
pavleradojkovic 0:ba7e439238ab 39 * @param buffer Buffer to store data.
pavleradojkovic 0:ba7e439238ab 40 * @param len Length of expected data.
pavleradojkovic 0:ba7e439238ab 41 * @param timeout Timeout for the operation.
pavleradojkovic 0:ba7e439238ab 42 * @return Always returns the full length if successful or an error.
pavleradojkovic 0:ba7e439238ab 43 */
pavleradojkovic 0:ba7e439238ab 44 template<typename SocketType>
pavleradojkovic 0:ba7e439238ab 45 static int accumulate_mqtt_read(SocketType socket, unsigned char *buffer, int len, int timeout)
pavleradojkovic 0:ba7e439238ab 46 {
pavleradojkovic 0:ba7e439238ab 47 /* TODO: Timout should be applied to whole operation not partial recv */
pavleradojkovic 0:ba7e439238ab 48 socket->set_timeout(timeout);
pavleradojkovic 0:ba7e439238ab 49
pavleradojkovic 0:ba7e439238ab 50 /* MQTT Client expects the full packet so we accumulate until we get all bytes */
pavleradojkovic 0:ba7e439238ab 51 int remaining = len;
pavleradojkovic 0:ba7e439238ab 52 while (remaining) {
pavleradojkovic 0:ba7e439238ab 53 int ret = socket->recv(buffer, remaining);
pavleradojkovic 0:ba7e439238ab 54 if (ret > 0) {
pavleradojkovic 0:ba7e439238ab 55 remaining -= ret;
pavleradojkovic 0:ba7e439238ab 56 buffer += ret;
pavleradojkovic 0:ba7e439238ab 57 } else {
pavleradojkovic 0:ba7e439238ab 58 return convert_nsapi_error_to_mqtt_error(ret);
pavleradojkovic 0:ba7e439238ab 59 }
pavleradojkovic 0:ba7e439238ab 60 }
pavleradojkovic 0:ba7e439238ab 61 return len;
pavleradojkovic 0:ba7e439238ab 62 }
pavleradojkovic 0:ba7e439238ab 63
pavleradojkovic 0:ba7e439238ab 64 /** Sends data and returns number of bytes sent or a translated error that MQTT expects.
pavleradojkovic 0:ba7e439238ab 65 *
pavleradojkovic 0:ba7e439238ab 66 * @tparam SocketType Socket type like TCPSocket.
pavleradojkovic 0:ba7e439238ab 67 * @param socket Socket to send data on.
pavleradojkovic 0:ba7e439238ab 68 * @param buffer Data to send.
pavleradojkovic 0:ba7e439238ab 69 * @param len Length of data.
pavleradojkovic 0:ba7e439238ab 70 * @param timeout Timeout for the operation.
pavleradojkovic 0:ba7e439238ab 71 * @return Always returns the full length if successful or an error.
pavleradojkovic 0:ba7e439238ab 72 */
pavleradojkovic 0:ba7e439238ab 73 template<typename SocketType>
pavleradojkovic 0:ba7e439238ab 74 static int mqtt_write(SocketType socket, unsigned char *buffer, int len, int timeout)
pavleradojkovic 0:ba7e439238ab 75 {
pavleradojkovic 0:ba7e439238ab 76 socket->set_timeout(timeout);
pavleradojkovic 0:ba7e439238ab 77 int ret = socket->send(buffer, len);
pavleradojkovic 0:ba7e439238ab 78 if (ret > 0) {
pavleradojkovic 0:ba7e439238ab 79 return ret;
pavleradojkovic 0:ba7e439238ab 80 } else {
pavleradojkovic 0:ba7e439238ab 81 return convert_nsapi_error_to_mqtt_error(ret);
pavleradojkovic 0:ba7e439238ab 82 }
pavleradojkovic 0:ba7e439238ab 83 }
pavleradojkovic 0:ba7e439238ab 84
pavleradojkovic 0:ba7e439238ab 85 #endif // _MQTTNETWORK_UTIL_H_