Программная система управления устройствами в беспроводной сети
Заказать уникальную дипломную работу- 90 90 страниц
- 9 + 9 источников
- Добавлена 11.07.2023
- Содержание
- Часть работы
- Список литературы
1 АНАЛИЗ ТЕХНИЧЕСКИХ ТРЕБОВАНИЙ И УТОЧНЕНИЕ СПЕЦИФИКАЦИЙ
1.1 Анализ задания и выбор технологии, языка и среды разработки
1.2 Анализ технологий разработки средств связи устройств в беспроводной сети
1.3 Анализ методов управления устройствами в беспроводной сети
1.4 Анализ вариантов использования
2 ПРОЕКТИРОВАНИЕ СТРУКТУРЫ И КОМПОНЕНТОВ ПРОГРАММНОГО ПРОДУКТА
2.1 Проектирование алгоритма работы приложения
2.2 Проектирование структуры приложения
2.3 Разработка программной структуры приложения, разработка API
2.4 Компоновка приложения
2.5 Реализация приложения
3 Выбор стратегии тестирования и разработка тестов
3.1 Анализ возможных методов тестирования
3.2 Проведение тестирования функционирования приложения
ЗАКЛЮЧЕНИЕ
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
ПРИЛОЖЕНИЕ А Техническое задание
ПРИЛОЖЕНИЕ Б Код программы
ПРИЛОЖЕНИЕ В Руководство пользователя
ПРИЛОЖЕНИЕ Г Графическая часть дипломного проекта
strcmp(cfgPubType, "boolean")){strcpy(application_message, "false"); }else if (!strcmp(cfgPubType, "json")){ */snprintf(application_message, sizeof(application_message), "{\"DeviceTypeAlias\":\"LOCK\", \"DeviceType\":\"6\", \"state\":\"locked\", \"timestamp\":\"%lu\", \"heartbit\":\"true\", \"RFAddress\":\"%08X\", \"LastActivity\":\"%s\"}", (long)timer, devID, tm); //} int i = findTaskForDevice(devID); //assume that device = lock and there is only open cmd from external if (i >= 0) removeDeviceTask(i); //publish_mqtt((void *) mqtt_listener, application_message, topic_pub); queuePushMessage(getMqttQueue(mqtt_listener), topic_pub, application_message, TRUE); //Support HOMEBRIDGEsnprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockCurrentState\", \"value\":\"1\"}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE); // }else if (r == LOCK_DEVICE_CMD_OPEN){ //publish_mqtt((void *) mqtt_listener, "CLOSED", topic_pub) LOG(LOG_LEVEL_TRACE,"Got LOCK_DEVICE_CMD_OPEN code cfgPubType=%s\r\n", cfgPubType); //if (!strcmp(cfgPubType, "boolean")){ // strcpy(application_message, "false"); //}else if (!strcmp(cfgPubType, "json")){snprintf(application_message, sizeof(application_message), "{\"DeviceTypeAlias\":\"LOCK\", \"DeviceType\":\"6\", \"state\":\"unlocked\", \"timestamp\":\"%lu\", \"RFAddress\":\"%08X\", \"LastActivity\":\"%s\"}", (long)timer, devID, tm); //snprintf(application_message, sizeof(application_message), "{\"state\":\"unlocked\", \"timestamp\":\"%lu\", \"RFAddress\":\"%08X\"}", (long)timer, devID); //} //lastUnlockedtime = timer;homebridgeLockState.lastOpenTime = timer; LOG(LOG_LEVEL_TRACE,"Going to publish mqtt msg %s to %s...", application_message, topic_pub); //publish_mqtt((void *) mqtt_listener, application_message, topic_pub);queuePushMessage(getMqttQueue(mqtt_listener), topic_pub, application_message, TRUE); LOG(LOG_LEVEL_TRACE,"done.\r\n"); //Support HOMEBRIDGE if (homebridgeLockState.LockTargetState == 0 && homebridgeLockState.LockCurrentState != homebridgeLockState.LockTargetState){snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockCurrentState\", \"value\": 0}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, FALSE);homebridgeLockState.LockCurrentState = 0; }else{snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockTargetState\", \"value\": 0}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE);snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockCurrentState\", \"value\": 0}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, FALSE);homebridgeLockState.LockTargetState = 0;homebridgeLockState.LockCurrentState = 0; } // LOG(LOG_LEVEL_TRACE,"Removing task..."); int i = findTaskForDevice(devID); //assume that device = lock and there is only open cmd from external if (i >= 0) removeDeviceTask(i); LOG(LOG_LEVEL_TRACE,"done.\r\n"); LOG(LOG_LEVEL_TRACE,"LOCK OPEN REGISTERED, task removed\r\n"); }else if (r == LOCK_DEVICE_CMD_BELLPRESSED){ //publish_mqtt((void *) mqtt_listener, "CLOSED", topic_pub) LOG(LOG_LEVEL_TRACE,"Got LOCK_DEVICE_CMD_BELLPRESSED code cfgPubType=%s\r\n", cfgPubType);snprintf(application_message, sizeof(application_message), "{\"DeviceTypeAlias\":\"LOCK\", \"DeviceType\":\"6\", \"state\":\"bell\", \"timestamp\":\"%lu\", \"RFAddress\":\"%08X\", \"LastActivity\":\"%s\"}", (long)timer, devID, tm); queuePushMessage(getMqttQueue(mqtt_listener), topic_pub, application_message, TRUE); LOG(LOG_LEVEL_TRACE,"done.\r\n"); }else if (r == LOCK_DEVICE_CMD_MAGNETON){ LOG(LOG_LEVEL_DEBUG, "DOOR IS CLOSED\r\n"); //if (!strcmp(cfgPubType, "boolean")){ // strcpy(application_message, "false"); //}else if (!strcmp(cfgPubType, "json")){snprintf(application_message, sizeof(application_message), "{\"DeviceTypeAlias\":\"LOCK\", \"DeviceType\":\"6\", \"state\":\"closed\", \"timestamp\":\"%lu\", \"RFAddress\":\"%08X\", \"LastActivity\":\"%s\"}", (long)timer, devID, tm); //snprintf(application_message, sizeof(application_message), "{\"state\":\"closed\", \"timestamp\":\"%lu\", \"RFAddress\":\"%08X\"}", (long)timer, devID); //} //publish_mqtt((void *) mqtt_listener, application_message, topic_pub);queuePushMessage(getMqttQueue(mqtt_listener), topic_pub, application_message, TRUE); }else if (r == LOCK_DEVICE_CMD_MAGNETOFF){ LOG(LOG_LEVEL_DEBUG, "DOOR IS OPENED\r\n"); //if (!strcmp(cfgPubType, "boolean")){ // strcpy(application_message, "true"); //}else if (!strcmp(cfgPubType, "json")){snprintf(application_message, sizeof(application_message), "{\"DeviceTypeAlias\":\"LOCK\", \"DeviceType\":\"6\", \"state\":\"opened\", \"timestamp\":\"%lu\", \"RFAddress\":\"%08X\", \"LastActivity\":\"%s\"}", (long)timer, devID, tm); //snprintf(application_message, sizeof(application_message), "{\"state\":\"opened\", \"timestamp\":\"%lu\", \"RFAddress\":\"%08X\"}", (long)timer, devID); //} //publish_mqtt((void *) mqtt_listener, application_message, topic_pub);queuePushMessage(getMqttQueue(mqtt_listener), topic_pub, application_message, TRUE); }else if (r == LOCK_DEVICE_CMD_CARDREAD){ LOG(LOG_LEVEL_DEBUG, "CARD READ\r\n"); if (strlen(application_message) > 0) { //publish_mqtt((void *) mqtt_listener, application_message, topic_pub);queuePushMessage(getMqttQueue(mqtt_listener), topic_pub, application_message, TRUE); } } } long t12 = getNanoSeconds(); LOG(LOG_LEVEL_DEBUG, "Finished processing. Reset buffers. Timing: Processing = %luqueuePush = %lu\r\n", t11-t10, t12-t11);memset(tmp,0, 256);memset(application_message, 0, JSON_MESSAGE_BUFFER_SIZE);rdlen = 0;block_size = 0; LOG(LOG_LEVEL_DEBUG, "Ready to read next package\r\n********************************************\r\n"); //fd = open_cc1101(); //workaround???? /* if (SPImode){ LOG(LOG_LEVEL_TRACE, "Before SPI reset loop end\n"); resetMode_cc1101(); LOG(LOG_LEVEL_TRACE, "After SPI reset loop end\n"); } */ } } else if (rdlen < 0) { LOG(LOG_LEVEL_ERROR,"Error from read: %d: %s\n", rdlen, strerror(errno)); break; } long t2 = getNanoSeconds(); if (t2-t0 > maxT2_T0) maxT2_T0 = t2-t0; if (t1-t0 > maxT1_T0) maxT1_T0 = t1-t0; if (t2-t1 > maxT2_T1) maxT2_T1 = t2-t1; if (t11-t1 > maxT11_T1) maxT11_T1 = t11-t1;usleep(SPImode ? 50000U : 100000U); //usleep(SPImode ? 500U : 20000U); }else{usleep(SPImode ? 50000U : 100000U); //usleep(SPImode ? 500U : 20000U);checkAndRetryCryptoSessions(fd); }time_t timer; time(&timer); if ((homebridgeLockState.lastOpenTime > 0) && ((timer - homebridgeLockState.lastOpenTime) > DEFAULT_LOCK_TIMEOUT_SEC)){ //Support HOMEBRIDGE LOG(LOG_LEVEL_DEBUG, "\nCLOSE AUTOMATICALLY ON TIMEOUT\n\n"); char application_message[JSON_MESSAGE_BUFFER_SIZE]={0}; if (homebridgeLockState.LockTargetState == 0){snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockTargetState\", \"value\": 1}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE);snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockCurrentState\", \"value\": 1}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, FALSE); } if (homebridgeLockState.LockCurrentState == 0){snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockCurrentState\", \"value\": 1}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE); } homebridgeLockState.LockTargetState = 1;homebridgeLockState.LockCurrentState = 1;homebridgeLockState.lastOpenTime = -1; /* //queuePushMessage(getMqttQueue(mqtt_listener), "/sergey.ponomarenko@revolta-engineering.ru/AGK_MQTTGate_2048703094/cmd/homebridge/to/get", "{\"name\":\"Door_A6EF3A70\"}", TRUE);snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockTargetState\", \"value\": 1}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE); //queuePushMessage(getMqttQueue(mqtt_listener), "/sergey.ponomarenko@revolta-engineering.ru/AGK_MQTTGate_2048703094/cmd/homebridge/to/get", "{\"name\":\"Door_A6EF3A70\"}", TRUE);snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockCurrentState\", \"value\": 1}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE); //queuePushMessage(getMqttQueue(mqtt_listener), "/sergey.ponomarenko@revolta-engineering.ru/AGK_MQTTGate_2048703094/cmd/homebridge/to/get", "{\"name\":\"Door_A6EF3A70\"}", TRUE);snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockTargetState\", \"value\": 1}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE); //queuePushMessage(getMqttQueue(mqtt_listener), "/sergey.ponomarenko@revolta-engineering.ru/AGK_MQTTGate_2048703094/cmd/homebridge/to/get", "{\"name\":\"Door_A6EF3A70\"}", TRUE);snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockCurrentState\", \"value\": 1}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE); //queuePushMessage(getMqttQueue(mqtt_listener), "/sergey.ponomarenko@revolta-engineering.ru/AGK_MQTTGate_2048703094/cmd/homebridge/to/get", "{\"name\":\"Door_A6EF3A70\"}", TRUE);snprintf(application_message, sizeof(application_message), "{\"name\":\"Door_%08X\", \"service_name\":\"MyFlatDoor\", \"characteristic\":\"LockTargetState\", \"value\": 1}", devID); queuePushMessage(getMqttQueue(mqtt_listener), homebridge_topic_pub, application_message, TRUE);queuePushMessage(getMqttQueue(mqtt_listener), "/sergey.ponomarenko@revolta-engineering.ru/AGK_MQTTGate_2048703094/cmd/homebridge/to/get", "{\"name\":\"Door_A6EF3A70\"}", FALSE); */ //lastUnlockedtime = -1; } } while (1); LOG(LOG_LEVEL_ERROR, "QMODULE !!!! MAIN thread finished !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n");unsubscribe_mqtt(mqtt_listener);}Код модуля mqtt.h#ifndef __MQTT_H__#define __MQTT_H__/*MIT LicenseCopyright(c) 2018 Liam BindlePermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files(the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions :The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THESOFTWARE.*/#include \#include
. * * @example simple_publisher.c * A simple program to that publishes the current time whenever ENTER is pressed. * * Usage: * \code{.sh} * ./bin/simple_publisher [address [port [topic]]] * \endcode * * Where \c address is the address of the MQTT broker, \c port is the port number the * MQTT broker is running on, and \c topic is the name of the topic to publish with. Note * that all these arguments are optional and the defaults are \c address = \c "test.mosquitto.org", * \c port = \c "1883", and \c topic = "datetime". * * @example simple_subscriber.c * A simple program that subscribes to a single topic and prints all updates that are received. * * Usage: * \code{.sh} * ./bin/simple_subscriber [address [port [topic]]] * \endcode * * Where \c address is the address of the MQTT broker, \c port is the port number the * MQTT broker is running on, and \c topic is the name of the topic subscribe to. Note * that all these arguments are optional and the defaults are \c address = \c "test.mosquitto.org", * \c port = \c "1883", and \c topic = "datetime". * * @example reconnect_subscriber.c * Same program as \ref simple_subscriber.c, but using the automatic reconnect functionality. * * @example bio_publisher.c * Same program as \ref simple_publisher.c, but uses a unencrypted BIO socket. * * @example openssl_publisher.c * Same program as \ref simple_publisher.c, but over an encrypted connection using OpenSSL. * * Usage: * \code{.sh} * ./bin/openssl_publisherca_file [address [port [topic]]] * \endcode * * * @defgroup api API * @brief Documentation of everything you need to know to use the MQTT-C client. * * This module contains everything you need to know to use MQTT-C in your application. * For usage examples see: * - @ref simple_publisher.c * - @ref simple_subscriber.c * - @ref reconnect_subscriber.c * - @ref bio_publisher.c * - @ref openssl_publisher.c * * @note MQTT-C can be used in both single-threaded and multi-threaded applications. All * the functions in \ref api are thread-safe. * * @defgroup packers Control Packet Serialization * @brief Developer documentation of the functions and datastructures used for serializing MQTT * control packets. * * @defgroup unpackers Control Packet Deserialization * @brief Developer documentation of the functions and datastructures used for deserializing MQTT * control packets. * * @defgroup details Utilities * @brief Developer documentation for the utilities used to implement the MQTT-C client. * * @note To deserialize a packet from a buffer use \ref mqtt_unpack_response (it's the only * function you need). */ /** * @brief An enumeration of the MQTT control packet types. * @ingroup unpackers * * @see * MQTT v3.1.1: MQTT Control Packet Types * */enumMQTTControlPacketType { MQTT_CONTROL_CONNECT=1u, MQTT_CONTROL_CONNACK=2u, MQTT_CONTROL_PUBLISH=3u, MQTT_CONTROL_PUBACK=4u, MQTT_CONTROL_PUBREC=5u, MQTT_CONTROL_PUBREL=6u, MQTT_CONTROL_PUBCOMP=7u, MQTT_CONTROL_SUBSCRIBE=8u, MQTT_CONTROL_SUBACK=9u, MQTT_CONTROL_UNSUBSCRIBE=10u, MQTT_CONTROL_UNSUBACK=11u, MQTT_CONTROL_PINGREQ=12u, MQTT_CONTROL_PINGRESP=13u, MQTT_CONTROL_DISCONNECT=14u};/** * @brief The fixed header of an MQTT control packet. * @ingroup unpackers * * @see * MQTT v3.1.1: Fixed Header * */struct mqtt_fixed_header { /** The type of packet. */enumMQTTControlPacketTypecontrol_type; /** The packets control flags.*/ uint8_t control_flags: 4; /** The remaining size of the packet in bytes (i.e. the size of variable header and payload).*/ uint32_t remaining_length;};/** * @brief The protocol identifier for MQTT v3.1.1. * @ingroup packers * * @see * MQTT v3.1.1: CONNECT Variable Header. * */#define MQTT_PROTOCOL_LEVEL 0x04/** * @brief A macro used to declare the enumMQTTErrors and associated * error messages (the members of the num) at the same time. */#define __ALL_MQTT_ERRORS(MQTT_ERROR) \ MQTT_ERROR(MQTT_ERROR_NULLPTR) \ MQTT_ERROR(MQTT_ERROR_CONTROL_FORBIDDEN_TYPE) \ MQTT_ERROR(MQTT_ERROR_CONTROL_INVALID_FLAGS) \ MQTT_ERROR(MQTT_ERROR_CONTROL_WRONG_TYPE) \ MQTT_ERROR(MQTT_ERROR_CONNECT_NULL_CLIENT_ID) \ MQTT_ERROR(MQTT_ERROR_CONNECT_NULL_WILL_MESSAGE) \ MQTT_ERROR(MQTT_ERROR_CONNECT_FORBIDDEN_WILL_QOS) \ MQTT_ERROR(MQTT_ERROR_CONNACK_FORBIDDEN_FLAGS) \ MQTT_ERROR(MQTT_ERROR_CONNACK_FORBIDDEN_CODE) \ MQTT_ERROR(MQTT_ERROR_PUBLISH_FORBIDDEN_QOS) \ MQTT_ERROR(MQTT_ERROR_SUBSCRIBE_TOO_MANY_TOPICS) \ MQTT_ERROR(MQTT_ERROR_MALFORMED_RESPONSE) \ MQTT_ERROR(MQTT_ERROR_UNSUBSCRIBE_TOO_MANY_TOPICS) \ MQTT_ERROR(MQTT_ERROR_RESPONSE_INVALID_CONTROL_TYPE) \ MQTT_ERROR(MQTT_ERROR_CONNECT_NOT_CALLED) \ MQTT_ERROR(MQTT_ERROR_SEND_BUFFER_IS_FULL) \ MQTT_ERROR(MQTT_ERROR_SOCKET_ERROR) \ MQTT_ERROR(MQTT_ERROR_MALFORMED_REQUEST) \ MQTT_ERROR(MQTT_ERROR_RECV_BUFFER_TOO_SMALL) \ MQTT_ERROR(MQTT_ERROR_ACK_OF_UNKNOWN) \ MQTT_ERROR(MQTT_ERROR_NOT_IMPLEMENTED) \ MQTT_ERROR(MQTT_ERROR_CONNECTION_REFUSED) \ MQTT_ERROR(MQTT_ERROR_SUBSCRIBE_FAILED) \ MQTT_ERROR(MQTT_ERROR_CONNECTION_CLOSED) \ MQTT_ERROR(MQTT_ERROR_INITIAL_RECONNECT) \ MQTT_ERROR(MQTT_ERROR_INVALID_REMAINING_LENGTH)/* todo: add more connection refused errors *//** * @brief A macro used to generate the enumMQTTErrors from * \ref __ALL_MQTT_ERRORS * @see __ALL_MQTT_ERRORS*/#define GENERATE_ENUM(ENUM) ENUM,/** * @brief A macro used to generate the error messages associated with * MQTTErrors from \ref __ALL_MQTT_ERRORS * @see __ALL_MQTT_ERRORS*/#define GENERATE_STRING(STRING) #STRING,/** * @brief An enumeration of error codes. Error messages can be retrieved by calling \ref mqtt_error_str. * @ingroup api * * @see mqtt_error_str */enumMQTTErrors { MQTT_ERROR_UNKNOWN=INT_MIN, __ALL_MQTT_ERRORS(GENERATE_ENUM) MQTT_OK = 1};/** * @brief Returns an error message for error code, \p error. * @ingroup api * * @param[in] error the error code. * * @returns The associated error message. */const char* mqtt_error_str(enumMQTTErrors error);/** * @brief Pack a MQTT string, given a c-string \p str. * * @param[out] buf the buffer that the MQTT string will be written to. * @param[in] str the c-string to be written to \p buf. * * @warning This function provides no error checking. * * @returns strlen(str) + 2*/ssize_t __mqtt_pack_str(uint8_t *buf, const char* str);/** @brief A macro to get the MQTT string length from a c-string. */#define __mqtt_packed_cstrlen(x) (2 + strlen(x))/* RESPONSES *//** * @brief An enumeration of the return codes returned in a CONNACK packet. * @ingroup unpackers * * @see * MQTT v3.1.1: CONNACK return codes. * */enumMQTTConnackReturnCode { MQTT_CONNACK_ACCEPTED = 0u, MQTT_CONNACK_REFUSED_PROTOCOL_VERSION = 1u, MQTT_CONNACK_REFUSED_IDENTIFIER_REJECTED = 2u, MQTT_CONNACK_REFUSED_SERVER_UNAVAILABLE = 3u, MQTT_CONNACK_REFUSED_BAD_USER_NAME_OR_PASSWORD = 4u, MQTT_CONNACK_REFUSED_NOT_AUTHORIZED = 5u};/** * @brief A connection response datastructure. * @ingroup unpackers * * @see * MQTT v3.1.1: CONNACK - Acknowledgement connection response. * */struct mqtt_response_connack { /** * @brief Allows client and broker to check if they have a consistent view about whether there is * already a stored session state. */ uint8_t session_present_flag; /** * @brief The return code of the connection request. * * @see MQTTConnackReturnCode */enumMQTTConnackReturnCodereturn_code;}; /** * @brief A publish packet received from the broker. * @ingroup unpackers * * A publish packet is received from the broker when a client publishes to a topic that the * \em {local client} is subscribed to. * * @see * MQTT v3.1.1: PUBLISH - Publish Message. * */struct mqtt_response_publish { /** * @brief The DUP flag. DUP flag is 0 if its the first attempt to send this publish packet. A DUP flag * of 1 means that this might be a re-delivery of the packet. */ uint8_t dup_flag; /** * @brief The quality of service level. * * @see * MQTT v3.1.1: QoS Definitions * */ uint8_t qos_level; /** @brief The retain flag of this publish message. */ uint8_t retain_flag; /** @brief Size of the topic name (number of characters). */ uint16_t topic_name_size; /** * @brief The topic name. * @note topic_name is not null terminated. Therefore topic_name_size must be used to get the * string length. */ const void* topic_name; /** @brief The publish message's packet ID. */ uint16_t packet_id; /** @brief The publish message's application message.*/ const void* application_message; /** @brief The size of the application message in bytes. */size_tapplication_message_size;};/** * @brief A publish acknowledgement for messages that were published with QoS level 1. * @ingroup unpackers * * @see * MQTT v3.1.1: PUBACK - Publish Acknowledgement. * * */struct mqtt_response_puback { /** @brief The published messages packet ID. */ uint16_t packet_id;};/** * @brief The response packet to a PUBLISH packet with QoS level 2. * @ingroup unpackers * * @see * MQTT v3.1.1: PUBREC - Publish Received. * * */struct mqtt_response_pubrec { /** @brief The published messages packet ID. */ uint16_t packet_id;};/** * @brief The response to a PUBREC packet. * @ingroup unpackers * * @see * MQTT v3.1.1: PUBREL - Publish Release. * * */struct mqtt_response_pubrel { /** @brief The published messages packet ID. */ uint16_t packet_id;};/** * @brief The response to a PUBREL packet. * @ingroup unpackers * * @see * MQTT v3.1.1: PUBCOMP - Publish Complete. * * */struct mqtt_response_pubcomp { /** T@brief he published messages packet ID. */ uint16_t packet_id;};/** * @brief An enumeration of subscription acknowledgement return codes. * @ingroup unpackers * * @see * MQTT v3.1.1: SUBACK Return Codes. * */enumMQTTSubackReturnCodes { MQTT_SUBACK_SUCCESS_MAX_QOS_0 = 0u, MQTT_SUBACK_SUCCESS_MAX_QOS_1 = 1u, MQTT_SUBACK_SUCCESS_MAX_QOS_2 = 2u, MQTT_SUBACK_FAILURE = 128u};/** * @brief The response to a subscription request. * @ingroup unpackers * * @see * MQTT v3.1.1: SUBACK - Subscription Acknowledgement. * */struct mqtt_response_suback { /** @brief The published messages packet ID. */ uint16_t packet_id; /** * Array of return codes corresponding to the requested subscribe topics. * * @see MQTTSubackReturnCodes */ const uint8_t *return_codes; /** The number of return codes. */size_tnum_return_codes;};/** * @brief The brokers response to a UNSUBSCRIBE request. * @ingroup unpackers * * @see * MQTT v3.1.1: UNSUBACK - Unsubscribe Acknowledgement. * */struct mqtt_response_unsuback { /** @brief The published messages packet ID. */ uint16_t packet_id;};/** * @brief The response to a ping request. * @ingroup unpackers * * @note This response contains no members. * * @see * MQTT v3.1.1: PINGRESP - Ping Response. * */struct mqtt_response_pingresp { int dummy;};/** * @brief A struct used to deserialize/interpret an incoming packet from the broker. * @ingroup unpackers */struct mqtt_response { /** @brief The mqtt_fixed_header of the deserialized packet. */ struct mqtt_fixed_headerfixed_header; /** * @brief A union of the possible responses from the broker. * * @note The fixed_header contains the control type. This control type corresponds to the * member of this union that should be accessed. For example if * fixed_header#control_type == \c MQTT_CONTROL_PUBLISH then * decoded#publish should be accessed. */ union { struct mqtt_response_connackconnack; struct mqtt_response_publish publish; struct mqtt_response_pubackpuback; struct mqtt_response_pubrecpubrec; struct mqtt_response_pubrelpubrel; struct mqtt_response_pubcomppubcomp; struct mqtt_response_subacksuback; struct mqtt_response_unsubackunsuback; struct mqtt_response_pingresppingresp; } decoded;};/** * @brief Deserialize the contents of \p buf into an mqtt_fixed_header object. * @ingroup unpackers * * @note This function performs complete error checking and a positive return value * means the entire mqtt_response can be deserialized from \p buf. * * @param[out] response the response who's \ref mqtt_response.fixed_header will be initialized. * @param[in] buf the buffer. * @param[in] bufsz the total number of bytes in the buffer. * * @returns The number of bytes that were consumed, or 0 if the buffer does not contain enough * bytes to parse the packet, or a negative value if there was a protocol violation. */ssize_tmqtt_unpack_fixed_header(struct mqtt_response *response, const uint8_t *buf, size_tbufsz);/** * @brief Deserialize a CONNACK response from \p buf. * @ingroup unpackers * * @pre \ref mqtt_unpack_fixed_header must have returned a positive value and the control packet type * must be \c MQTT_CONTROL_CONNACK. * * @param[out] mqtt_response the mqtt_response that will be initialized. * @param[in] buf the buffer that contains the variable header and payload of the packet. The * first byte of \p buf should be the first byte of the variable header. * * @relates mqtt_response_connack * * @returns The number of bytes that were consumed, or 0 if the buffer does not contain enough * bytes to parse the packet, or a negative value if there was a protocol violation. */ssize_tmqtt_unpack_connack_response (struct mqtt_response *mqtt_response, const uint8_t *buf);…..#endif
2 Сэмюэл, Грингард Интернет вещей. Будущее уже здесь / Грингард Сэмюэл. - М.: Альпина Паблишер, 2020
3 Simonsen K. Programming languages - C [электронный ресурс] // open-std.org Дата обновления 03.05.2013. URL: http://www.open-std.org/JTC1/SC22/WG14/www/standards (дата обращения 20.05.2021)
4 Hamelin A. С++ [электронный ресурс] // isocpp.org Дата обновления 14.06.2021. URL: https://isocpp.org/ (дата обращения 20.05.2021)
5 Совельев А. Unix shell [электронный ресурс] // oppennet.ru Дата обновления 14.11.2015. URL: https://www.opennet.ru/docs/shell/shell.html (дата обращения 20.05.2021)
6 How to setup a Mosquitto MQTT broker with TLS/SSL protection using self-signed certificates and connect it to Mongoose Os [Электронный ресурс]. – Режим доступа: https://github.com/SugarFreeOrbit/MosquittoMQTT (03.08.2020)
7 MQTT Конечное устройство Базовая станция Raspberry [Электронный ресурс] - Режим доступа: https://miem.hse.ru/data/2019/12/15/1523020186/Malakhov_I_30_05.pptx
8 Teach, learn, and make with the Raspberry Pi Foundation [Электронный ресурс] - Режим доступа: https://www.raspberrypi.org/
9 Основы программирования на Raspberry Pi [Электронный ресурс] - Режим доступа: https://api-2d3d-cad.com/microcomputer-programming-basics/