├── .gitignore ├── CLIENTS ├── CMakeLists.txt ├── MQTT.CON ├── README.md ├── TOPICS.PRE ├── cmake-build-debug ├── .gitignore └── DB │ └── TOPICS.PRE ├── doc ├── CoreClassDiagram.png ├── GeneralClassDiagram.png ├── LinuxClassDiagram.png └── Testcases.ods └── src ├── CoreImpl.cpp ├── CoreImpl.h ├── CoreInterface.h ├── Gateway.cpp ├── Gateway.h ├── Implementation ├── Arduino.cpp ├── Arduino.h ├── ArduinoLogger.cpp ├── ArduinoLogger.h ├── ArduinoSystem.cpp ├── ArduinoSystem.h ├── SDLinuxFake.cpp ├── SDLinuxFake.h ├── SDPersistentImpl.h ├── SD_table_entries.h ├── UdpSocketImpl.cpp ├── UdpSocketImpl.h └── paho │ ├── CMakeLists.txt │ ├── PahoMqttMessageHandler.cpp │ ├── PahoMqttMessageHandler.h │ ├── Readme.md │ └── pahomqttembeddedc │ ├── .cproject │ ├── .project │ ├── .settings │ ├── org.eclipse.cdt.core.prefs │ └── org.eclipse.cdt.ui.prefs │ ├── CONTRIBUTING.md │ ├── Debug │ ├── makefile │ ├── objects.mk │ ├── sources.mk │ └── src │ │ ├── MQTTDeserializeConnect.d │ │ └── subdir.mk │ ├── MQTTClient-C │ ├── samples │ │ └── linux │ │ │ ├── build.sh │ │ │ └── stdoutsub.c │ └── src │ │ ├── FreeRTOS │ │ ├── MQTTFreeRTOS.c │ │ └── MQTTFreeRTOS.h │ │ ├── MQTTClient.c │ │ ├── MQTTClient.h │ │ ├── cc3200 │ │ ├── MQTTCC3200.c │ │ └── MQTTCC3200.h │ │ ├── linux │ │ ├── MQTTLinux.c │ │ └── MQTTLinux.h │ │ └── samples │ │ └── FreeRTOS │ │ └── MQTTEcho.c │ ├── MQTTClient │ ├── CMakeLists.txt │ ├── samples │ │ ├── arduino │ │ │ └── Hello │ │ │ │ └── Hello.ino │ │ └── linux │ │ │ ├── CMakeLists.txt │ │ │ ├── build.sh │ │ │ ├── hello │ │ │ ├── hello.cpp │ │ │ ├── main.cpp │ │ │ ├── stdoutsub │ │ │ └── stdoutsub.cpp │ └── src │ │ ├── FP.h │ │ ├── MQTTClient.h │ │ ├── MQTTLogging.h │ │ ├── arduino │ │ ├── CMakeLists.txt │ │ ├── Countdown.h │ │ ├── IPStack.h │ │ └── WifiIPStack.h │ │ ├── linux │ │ ├── CMakeLists.txt │ │ └── linux.cpp │ │ └── mbed │ │ ├── MQTTEthernet.h │ │ └── MQTTSocket.h │ ├── MQTTPacket │ ├── CMakeLists.txt │ ├── samples │ │ ├── build │ │ ├── null.c │ │ ├── pub0sub1.c │ │ ├── pub0sub1_nb.c │ │ ├── qos0pub.c │ │ ├── transport.c │ │ └── transport.h │ ├── src │ │ ├── MQTTConnect.h │ │ ├── MQTTConnectClient.c │ │ ├── MQTTConnectServer.c │ │ ├── MQTTDeserializePublish.c │ │ ├── MQTTFormat.c │ │ ├── MQTTFormat.h │ │ ├── MQTTPacket.c │ │ ├── MQTTPacket.h │ │ ├── MQTTPublish.h │ │ ├── MQTTSerializePublish.c │ │ ├── MQTTSubscribe.h │ │ ├── MQTTSubscribeClient.c │ │ ├── MQTTSubscribeServer.c │ │ ├── MQTTUnsubscribe.h │ │ ├── MQTTUnsubscribeClient.c │ │ ├── MQTTUnsubscribeServer.c │ │ └── StackTrace.h │ └── test │ │ ├── build_test │ │ └── test1.c │ ├── Makefile │ ├── README.md │ ├── about.html │ ├── edl-v10 │ ├── epl-v10 │ └── notice.html ├── LoggerInterface.h ├── MqttMessageHandlerInterface.cpp ├── MqttMessageHandlerInterface.h ├── MqttSnMessageHandler.cpp ├── MqttSnMessageHandler.h ├── PersistentInterface.cpp ├── PersistentInterface.h ├── SocketInterface.cpp ├── SocketInterface.h ├── System.h ├── core_defines.h ├── global_defines.h ├── main.cpp └── mqttsn_messages.h /.gitignore: -------------------------------------------------------------------------------- 1 | idea/* 2 | .idea/* 3 | -------------------------------------------------------------------------------- /CLIENTS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3ler/arduino-mqtt-sn-gateway/e5d1d7778945387e80e14fdc4a7e3cc1fe45c5c7/CLIENTS -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6) 2 | project(arduino-mqtt-sn-gateway) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | file(GLOB GLOBAL_SOURCES *) 7 | 8 | include_directories(src/Implementation) 9 | include_directories(src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/linux) 10 | include_directories(src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/) 11 | include_directories(src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src) 12 | 13 | add_subdirectory(src/Implementation/paho) 14 | 15 | set(INTERFACE_FILES 16 | src/core_defines.h 17 | src/CoreImpl.cpp 18 | src/CoreImpl.h 19 | src/CoreInterface.h 20 | src/Gateway.cpp 21 | src/Gateway.h 22 | src/global_defines.h 23 | src/LoggerInterface.h 24 | src/MqttMessageHandlerInterface.cpp 25 | src/MqttMessageHandlerInterface.h 26 | src/mqttsn_messages.h 27 | src/MqttSnMessageHandler.cpp 28 | src/MqttSnMessageHandler.h 29 | src/PersistentInterface.cpp 30 | src/PersistentInterface.h 31 | src/SocketInterface.cpp 32 | src/SocketInterface.h 33 | 34 | src/Implementation/Arduino.cpp 35 | src/Implementation/Arduino.h 36 | 37 | src/Implementation/ArduinoLogger.cpp 38 | src/Implementation/ArduinoLogger.h 39 | 40 | src/Implementation/ArduinoSystem.cpp 41 | src/Implementation/ArduinoSystem.h 42 | 43 | src/Implementation/SDLinuxFake.cpp 44 | src/Implementation/SDLinuxFake.h 45 | 46 | src/Implementation/UdpSocketImpl.cpp 47 | src/Implementation/UdpSocketImpl.h 48 | 49 | src/Implementation/paho/PahoMqttMessageHandler.h 50 | src/Implementation/paho/PahoMqttMessageHandler.cpp 51 | ) 52 | 53 | file(GLOB PAHO_SOURCE_FILES 54 | src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/*.c 55 | src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/*.h 56 | src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/*.cpp 57 | src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/*.h 58 | src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/linux/*.cpp 59 | src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/linux/*.h 60 | ) 61 | 62 | set(SOURCE_FILES src/main.cpp ${GLOBAL_SOURCES} ${INTERFACE_FILES} ${PAHO_SOURCE_FILES}) 63 | add_executable(arduino-mqtt-sn-gateway ${SOURCE_FILES}) -------------------------------------------------------------------------------- /MQTT.CON: -------------------------------------------------------------------------------- 1 | brokeraddress 127.0.0.1 2 | brokerport 1883 3 | clientid mqtt-sn linux gateway 4 | willtopic /mqtt/sn/gateway 5 | willmessage /mqtt-sn linux gateway offline 6 | willqos 1 7 | willretain 0 8 | gatewayid 2 -------------------------------------------------------------------------------- /TOPICS.PRE: -------------------------------------------------------------------------------- 1 | 50 mqtt/sn/some/predefined/topic 2 | 20 mqtt/sn/another/predefined/topic -------------------------------------------------------------------------------- /cmake-build-debug/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !DB/MQTT.CON 3 | !DB/TOPICS.PRE 4 | -------------------------------------------------------------------------------- /cmake-build-debug/DB/TOPICS.PRE: -------------------------------------------------------------------------------- 1 | 50 mqtt/sn/some/predefined/topic 2 | 20 mqtt/sn/another/predefined/topic -------------------------------------------------------------------------------- /doc/CoreClassDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3ler/arduino-mqtt-sn-gateway/e5d1d7778945387e80e14fdc4a7e3cc1fe45c5c7/doc/CoreClassDiagram.png -------------------------------------------------------------------------------- /doc/GeneralClassDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3ler/arduino-mqtt-sn-gateway/e5d1d7778945387e80e14fdc4a7e3cc1fe45c5c7/doc/GeneralClassDiagram.png -------------------------------------------------------------------------------- /doc/LinuxClassDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3ler/arduino-mqtt-sn-gateway/e5d1d7778945387e80e14fdc4a7e3cc1fe45c5c7/doc/LinuxClassDiagram.png -------------------------------------------------------------------------------- /doc/Testcases.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3ler/arduino-mqtt-sn-gateway/e5d1d7778945387e80e14fdc4a7e3cc1fe45c5c7/doc/Testcases.ods -------------------------------------------------------------------------------- /src/CoreImpl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 01.01.17. 3 | // 4 | 5 | #ifndef MQTTSNGATEWAY_COREIMPL1_H 6 | #define MQTTSNGATEWAY_COREIMPL1_H 7 | 8 | 9 | #include "CoreInterface.h" 10 | 11 | class CoreImpl : public Core{ 12 | private: 13 | PersistentInterface *persistent = nullptr; 14 | MqttMessageHandlerInterface *mqtt = nullptr; 15 | MqttSnMessageHandler *mqttsn = nullptr; 16 | LoggerInterface *logger = nullptr; 17 | System *system = nullptr; 18 | 19 | 20 | public: 21 | virtual bool begin(); 22 | 23 | virtual void setPersistent(PersistentInterface *persistent); 24 | 25 | virtual void setMqttMessageHandler(MqttMessageHandlerInterface *mqtt); 26 | 27 | virtual void setMqttSnMessageHandler(MqttSnMessageHandler *mqttsn); 28 | 29 | virtual void setLogger(LoggerInterface *logger); 30 | 31 | virtual void setSystem(System *system); 32 | 33 | virtual void loop(); 34 | 35 | virtual CORE_RESULT 36 | add_client(const char *client_id, uint16_t duration, bool clean_session,device_address *address); 37 | 38 | virtual CORE_RESULT remove_will(device_address *address); 39 | 40 | virtual CORE_RESULT add_will_topic(device_address *address, char *will_topic, bool retain, uint8_t qos); 41 | 42 | virtual CORE_RESULT add_will_msg(device_address *address, uint8_t *will_msg, uint8_t will_msg_len); 43 | 44 | virtual CORE_RESULT await_message(device_address *address, message_type type); 45 | 46 | virtual CORE_RESULT register_topic(device_address *address, char *topic_name, uint16_t *new_topic_id); 47 | 48 | virtual CORE_RESULT 49 | notify_regack_arrived(device_address *address, uint16_t topic_id, uint16_t msg_id, return_code_t return_code); 50 | 51 | virtual CORE_RESULT 52 | publish(device_address *address, const uint8_t *data, uint16_t data_len, uint16_t msg_id, uint16_t topic_id, 53 | bool short_topic, bool retain, int8_t qos, bool dup, uint16_t *new_topic_id); 54 | 55 | virtual CORE_RESULT 56 | add_subscription(device_address *address, uint16_t topic_id, uint16_t msg_id, bool short_topic, uint8_t qos, 57 | bool dup,uint16_t* new_topic_id, uint8_t* granted_qos); 58 | 59 | virtual CORE_RESULT 60 | delete_subscription(device_address *address, uint16_t topic_id, uint16_t msg_id, bool short_topic, bool dup); 61 | 62 | virtual CORE_RESULT delete_subscription(device_address *address, char *topic_name, uint16_t msg_id, bool dup); 63 | 64 | virtual CORE_RESULT set_disconnected(device_address *address); 65 | 66 | virtual CORE_RESULT set_asleep(device_address *address, uint16_t duration); 67 | 68 | virtual CORE_RESULT set_asleep(device_address *address); 69 | 70 | virtual CORE_RESULT 71 | notify_puback_arrived(device_address *address, uint16_t msg_id, uint16_t topic_id, return_code_t return_code); 72 | 73 | virtual CORE_RESULT set_awake(device_address *address); 74 | 75 | virtual CORE_RESULT get_gateway_id(uint8_t *gateway_id); 76 | 77 | virtual CORE_RESULT notify_mqttsn_disconnected(); 78 | 79 | virtual CORE_RESULT notify_mqtt_disconnected(); 80 | 81 | virtual CORE_RESULT publish(char *topic_name, uint8_t *data, uint32_t data_length, bool retain); 82 | 83 | virtual CORE_RESULT get_mqtt_config(uint8_t *server_ip, uint16_t *server_port, char *client_id); 84 | 85 | virtual CORE_RESULT get_mqtt_login_config(char *username, char *password); 86 | 87 | virtual CORE_RESULT get_mqtt_will(char *will_topic, char *will_msg, uint8_t *will_qos, bool *will_retain); 88 | 89 | virtual CORE_RESULT notify_mqtt_connected(); 90 | 91 | virtual CORE_RESULT notify_mqttsn_connected(); 92 | private: 93 | void remove_client_subscriptions(const char *client_id); 94 | void process_mqttsn_offline_procedure(); 95 | void process_mqtt_offline_procedure(); 96 | 97 | void set_all_clients_lost(); 98 | 99 | void handle_timeout(const CLIENT_STATUS &status, uint32_t duration, uint32_t elapsed_time, char *client_id, 100 | device_address &address, 101 | uint32_t &timeout); 102 | 103 | void handle_receive_mqtt_publish_for_client(const char *topic_name, uint8_t *data, uint32_t data_length, 104 | device_address &address, 105 | bool retain); 106 | 107 | void handle_client_publishes(CLIENT_STATUS status, const char *client_id, device_address *address); 108 | 109 | void append_device_address(device_address *pAddress); 110 | }; 111 | 112 | 113 | #endif //MQTTSNGATEWAY_COREIMPL1_H 114 | -------------------------------------------------------------------------------- /src/CoreInterface.h: -------------------------------------------------------------------------------- 1 | #ifndef GATEWAY_CORE_H 2 | #define GATEWAY_CORE_H 3 | 4 | #include "core_defines.h" 5 | #include "global_defines.h" 6 | #include "mqttsn_messages.h" 7 | #include "PersistentInterface.h" 8 | #include "MqttMessageHandlerInterface.h" 9 | #include "MqttSnMessageHandler.h" 10 | #include "System.h" 11 | 12 | /** 13 | * Core message return Zero on an unexpected error 14 | */ 15 | 16 | class MqttMessageHandlerInterface; 17 | 18 | class PersistentInterface; 19 | 20 | class MqttSnMessageHandler; 21 | 22 | 23 | class Core { 24 | public: 25 | virtual ~Core() {}; 26 | 27 | /** 28 | * Starts the database and initializes internal variables. 29 | * This mainly for comformances with other Arduino libraries. 30 | */ 31 | virtual bool begin()=0; 32 | 33 | virtual void setPersistent(PersistentInterface *persistent)=0; 34 | 35 | virtual void setMqttMessageHandler(MqttMessageHandlerInterface *mqtt)=0; 36 | 37 | virtual void setMqttSnMessageHandler(MqttSnMessageHandler *mqttsn)=0; 38 | 39 | virtual void setLogger(LoggerInterface *logger)=0; 40 | 41 | virtual void setSystem(System* system)=0; 42 | 43 | virtual void loop() = 0; 44 | 45 | /** 46 | * Adds a new Mqtt-SN client to the database. 47 | * Identification of the client is done by the client_id. 48 | * Creates a new client in the database if not already exist. 49 | * If the clean_session is true it will first remove an existing client out of the databse, before adding the new client. 50 | * 51 | * @param client_id by which the client is uniquely identified 52 | * @param duration time period in seconds until the client is lost or removed 53 | * @param clean_session remove existing client with client_id if exist 54 | * @param address by which the client can be addresses if no socket is supported 55 | * @return 56 | * - SUCCESS if everything went fine 57 | * - FULL if no more space for further clients is available 58 | * - ZERO for any other errors 59 | */ 60 | virtual CORE_RESULT add_client(const char *client_id, uint16_t duration, bool clean_session, 61 | device_address *address) =0; 62 | 63 | virtual CORE_RESULT remove_will(device_address *address)=0; 64 | 65 | virtual CORE_RESULT add_will_topic(device_address *address, char *will_topic, bool retain, uint8_t qos)=0; 66 | 67 | virtual CORE_RESULT add_will_msg(device_address *address, uint8_t *will_msg, uint8_t will_msg_len)=0; 68 | 69 | virtual CORE_RESULT await_message(device_address *address, message_type type)=0; 70 | 71 | virtual CORE_RESULT register_topic(device_address *address, char *topic_name, uint16_t *p_topic_id)=0; 72 | 73 | virtual CORE_RESULT 74 | notify_regack_arrived(device_address *address, uint16_t topic_id, uint16_t msg_id, return_code_t return_code)=0; 75 | 76 | /** 77 | * 78 | * @param address 79 | * @param data 80 | * @param data_len 81 | * @param msg_id 82 | * @param topic_id 83 | * @param short_topic 84 | * @param retain 85 | * @param qos 86 | * @param dup 87 | * @param new_topic_id 88 | * @return 89 | * - SUCCESS if everything went fine 90 | * - CLIENTNONEXISTENCE if the client is not connected 91 | * - TOPICIDNONEXISTENCE if the give topic_id does not exist 92 | * - ZERO for any other error 93 | */ 94 | virtual CORE_RESULT 95 | publish(device_address *address, const uint8_t *data, uint16_t data_len, uint16_t msg_id, uint16_t topic_id, 96 | bool short_topic, 97 | bool retain, int8_t qos, bool dup, uint16_t *new_topic_id)=0; 98 | 99 | virtual CORE_RESULT add_subscription(device_address *address, uint16_t topic_id, uint16_t msg_id, bool short_topic, uint8_t qos, bool dup,uint16_t* new_topic_id,uint8_t* granted_qos) = 0; 100 | 101 | virtual CORE_RESULT 102 | delete_subscription(device_address *address, uint16_t topic_id, uint16_t msg_id, bool short_topic, bool dup)=0; 103 | 104 | virtual CORE_RESULT 105 | delete_subscription(device_address *address, char* topic_name, uint16_t msg_id, bool dup)=0; 106 | 107 | virtual CORE_RESULT set_disconnected(device_address *address)=0; 108 | 109 | virtual CORE_RESULT set_asleep(device_address *address, uint16_t duration)=0; 110 | 111 | virtual CORE_RESULT set_asleep(device_address *address)=0; 112 | 113 | virtual CORE_RESULT 114 | notify_puback_arrived(device_address *address, uint16_t msg_id, uint16_t topic_id, return_code_t return_code)=0; 115 | 116 | virtual CORE_RESULT set_awake(device_address *address) = 0; 117 | 118 | 119 | 120 | virtual CORE_RESULT publish(char *topic_name, uint8_t *data, uint32_t data_length, bool retain) = 0; 121 | 122 | public: // gateway configuration 123 | 124 | virtual CORE_RESULT get_gateway_id(uint8_t* gateway_id)=0; 125 | 126 | virtual CORE_RESULT get_mqtt_config(uint8_t *server_ip, uint16_t *server_port, char *client_id) = 0; 127 | 128 | virtual CORE_RESULT get_mqtt_login_config(char *username, char *password) = 0; 129 | 130 | virtual CORE_RESULT get_mqtt_will(char *will_topic, char *will_msg, uint8_t *will_qos, bool *will_retain) = 0; 131 | 132 | public: // gateway connection status 133 | 134 | virtual CORE_RESULT notify_mqttsn_disconnected()=0; 135 | 136 | virtual CORE_RESULT notify_mqtt_disconnected()=0; 137 | 138 | virtual CORE_RESULT notify_mqtt_connected() = 0; 139 | 140 | virtual CORE_RESULT notify_mqttsn_connected() = 0; 141 | }; 142 | 143 | 144 | #endif //GATEWAY_DATABASE_H 145 | -------------------------------------------------------------------------------- /src/Gateway.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 22.12.16. 3 | // 4 | 5 | #include "Gateway.h" 6 | -------------------------------------------------------------------------------- /src/Gateway.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 22.12.16. 3 | // 4 | 5 | #ifndef GATEWAY_GATEWAY_H 6 | #define GATEWAY_GATEWAY_H 7 | 8 | 9 | #include "PersistentInterface.h" 10 | #include "CoreInterface.h" 11 | #include "CoreImpl.h" 12 | 13 | class Gateway { 14 | public: 15 | bool initialized = false; 16 | PersistentInterface *persistentInterface = nullptr; 17 | CoreImpl coreInterface; 18 | MqttMessageHandlerInterface *mqttInterface = nullptr; 19 | MqttSnMessageHandler mqttsnInterface; 20 | SocketInterface *socketInterface = nullptr; 21 | LoggerInterface *logger; 22 | System *system; 23 | public: 24 | 25 | bool begin() { 26 | if (persistentInterface != nullptr && 27 | mqttInterface != nullptr && 28 | socketInterface != nullptr) { 29 | 30 | /* -- connect components -- */ 31 | 32 | // Socket 33 | socketInterface->setMqttSnMessageHandler(&mqttsnInterface); 34 | socketInterface->setLogger(logger); 35 | 36 | // Mqtt-SN 37 | mqttsnInterface.setSocket(socketInterface); 38 | mqttsnInterface.setCore(&coreInterface); 39 | mqttsnInterface.setLogger(logger); 40 | 41 | // Mqtt 42 | mqttInterface->setCore(&coreInterface); 43 | mqttInterface->setLogger(logger); 44 | 45 | // Persistent 46 | persistentInterface->setCore(&coreInterface); 47 | persistentInterface->setLogger(logger); 48 | 49 | // Core 50 | coreInterface.setPersistent(persistentInterface); 51 | coreInterface.setMqttMessageHandler(mqttInterface); 52 | coreInterface.setMqttSnMessageHandler(&mqttsnInterface); 53 | coreInterface.setLogger(logger); 54 | coreInterface.setSystem(system); 55 | 56 | if (logger->begin()) { 57 | initialized = coreInterface.begin(); 58 | } 59 | return initialized; 60 | } else { 61 | return false; 62 | } 63 | } 64 | 65 | void setPersistentInterface(PersistentInterface *persistentInterface) { 66 | Gateway::persistentInterface = persistentInterface; 67 | } 68 | 69 | void setMqttInterface(MqttMessageHandlerInterface *mqttInterface) { 70 | Gateway::mqttInterface = mqttInterface; 71 | } 72 | 73 | void setSocketInterface(SocketInterface *socketInterface) { 74 | Gateway::socketInterface = socketInterface; 75 | } 76 | 77 | void setLoggerInterface(LoggerInterface *logger){ 78 | Gateway::logger = logger; 79 | } 80 | 81 | void setSystemInterface(System *system){ 82 | Gateway::system = system; 83 | } 84 | 85 | 86 | void loop() { 87 | if (initialized) { 88 | mqttInterface->loop(); 89 | socketInterface->loop(); 90 | coreInterface.loop(); 91 | } 92 | } 93 | 94 | 95 | 96 | }; 97 | 98 | 99 | #endif //GATEWAY_GATEWAY_H 100 | -------------------------------------------------------------------------------- /src/Implementation/Arduino.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Arduino.h" 4 | 5 | void SerialMock::begin(uint64_t) { 6 | 7 | } 8 | 9 | void SerialMock::println() { 10 | std::cout << std::endl; 11 | } 12 | 13 | void SerialMock::print(const char toPrint) { 14 | std::cout << toPrint<< std::flush; 15 | } 16 | 17 | void SerialMock::println(const char toPrint) { 18 | std::cout << toPrint << std::endl; 19 | } 20 | 21 | void SerialMock::print(const char *toPrint) { 22 | std::cout << toPrint << std::flush; 23 | } 24 | 25 | void SerialMock::println(const char *toPrint) { 26 | std::cout << toPrint << std::endl; 27 | } 28 | 29 | // DATABASE_ARDUINO_TIMERS_H 30 | void delay(uint64_t time) { 31 | struct timespec tim; 32 | uint64_t seconds = (uint64_t) time / 1000; 33 | tim.tv_sec = seconds; 34 | uint64_t nseconds = (time - seconds * 1000) * (uint64_t) 1000000000L; 35 | tim.tv_nsec = nseconds; 36 | nanosleep(&tim, (struct timespec *) NULL); 37 | return; 38 | } 39 | 40 | int64_t timerValue = 0; 41 | bool timerValueCalled = false; 42 | 43 | int64_t millis() { 44 | if (!timerValueCalled) { 45 | std::chrono::milliseconds ms = std::chrono::duration_cast( 46 | std::chrono::system_clock::now().time_since_epoch() 47 | ); 48 | timerValue = ms.count(); 49 | timerValueCalled = true; 50 | return 0; 51 | } 52 | std::chrono::milliseconds ms = std::chrono::duration_cast( 53 | std::chrono::system_clock::now().time_since_epoch() 54 | ); 55 | int64_t diff = ms.count() - timerValue; 56 | if (diff > UINT32_MAX) { 57 | // overflow 58 | timerValue = diff - UINT32_MAX; 59 | return timerValue; 60 | } 61 | return diff; 62 | } 63 | 64 | void yield() { } 65 | 66 | int64_t random(int64_t min, int64_t max) { 67 | return rand() % max + min; 68 | } 69 | 70 | void randomSeed(uint16_t seed) { 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/Implementation/Arduino.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 28.05.16. 3 | // 4 | 5 | #ifndef DATABASE_ARDUINO_H 6 | #define DATABASE_ARDUINO_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #if defined(ARDUINO) 14 | #else 15 | #ifndef DATABASE_ARDUINO_TIMERS_H 16 | #define DATABASE_ARDUINO_TIMERS_H 17 | 18 | #include 19 | 20 | extern void delay(uint64_t time); 21 | 22 | extern int64_t millis(); 23 | 24 | extern void yield(); 25 | 26 | extern int64_t random(int64_t min, int64_t max); 27 | 28 | extern int64_t random(int64_t min, int64_t max); 29 | 30 | extern void randomSeed(uint16_t seed); 31 | 32 | #endif // DATABASE_ARDUINO_TIMERS_H 33 | #endif 34 | 35 | class SerialMock { 36 | 37 | public: 38 | void begin(uint64_t); 39 | 40 | void println(); 41 | // char 42 | void print(const char toPrint); 43 | 44 | void println(const char toPrint); 45 | 46 | void print(const char *toPrint); 47 | 48 | void println(const char *toPrint); 49 | }; 50 | 51 | #endif //DATABASE_ARDUINO_H 52 | -------------------------------------------------------------------------------- /src/Implementation/ArduinoLogger.cpp: -------------------------------------------------------------------------------- 1 | #include "ArduinoLogger.h" 2 | 3 | bool ArduinoLogger::begin(){ 4 | return true; 5 | } 6 | 7 | void ArduinoLogger::set_log_lvl(uint8_t log_lvl){ 8 | this->current_log_lvl = log_lvl; 9 | } 10 | 11 | 12 | void ArduinoLogger::log(char *msg, uint8_t log_lvl) { 13 | log((const char *) msg, log_lvl); 14 | } 15 | 16 | 17 | void ArduinoLogger::log(const char *msg, uint8_t log_lvl) { 18 | if (log_lvl > current_log_lvl) { 19 | return; 20 | } 21 | Serial.println(); 22 | char millis_buffer[26]; 23 | sprintf(millis_buffer, "%Ld", millis()); 24 | Serial.print(millis_buffer); 25 | Serial.print(": "); 26 | Serial.print(msg);} 27 | 28 | 29 | void ArduinoLogger::start_log(char *msg, uint8_t log_lvl) { 30 | start_log((const char *) msg, log_lvl); 31 | } 32 | 33 | 34 | void ArduinoLogger::start_log(const char *msg, uint8_t log_lvl) { 35 | last_started_log_lvl = log_lvl; 36 | if (last_started_log_lvl > current_log_lvl) { 37 | return; 38 | } 39 | Serial.println(); 40 | char millis_buffer[26]; 41 | sprintf(millis_buffer, "%Ld", millis()); 42 | Serial.print(millis_buffer); 43 | Serial.print(": "); 44 | Serial.print(msg); 45 | } 46 | 47 | void ArduinoLogger::set_current_log_lvl(uint8_t log_lvl){ 48 | last_started_log_lvl = log_lvl; 49 | } 50 | 51 | 52 | void ArduinoLogger::append_log(char *msg) { 53 | append_log((const char *) msg); 54 | } 55 | 56 | void ArduinoLogger::append_log(const char *msg) { 57 | if (last_started_log_lvl > current_log_lvl) { 58 | return; 59 | } 60 | Serial.print(msg); 61 | } 62 | -------------------------------------------------------------------------------- /src/Implementation/ArduinoLogger.h: -------------------------------------------------------------------------------- 1 | #ifndef ESPARDUINOMQTTSNGATEWAY_ARDUINOLOGGER_H 2 | #define ESPARDUINOMQTTSNGATEWAY_ARDUINOLOGGER_H 3 | 4 | #include "../LoggerInterface.h" 5 | #include "Arduino.h" 6 | #include 7 | 8 | 9 | class ArduinoLogger : public LoggerInterface { 10 | private: 11 | uint8_t current_log_lvl = 2; 12 | uint8_t last_started_log_lvl = UINT8_MAX; 13 | SerialMock Serial; 14 | 15 | public: 16 | 17 | /** 18 | * Initializes logger 19 | * @return if logger is successfully initialized or not 20 | */ 21 | virtual bool begin() override; 22 | 23 | /** 24 | * Set the logging level only message with log_lvl smaller or equal then the set logging level will be logged. 25 | * The default level is 2, only message with log_lvl 2,1 and 0 are printed. 26 | * Note: 27 | * Logging level shall indicate how detailed the loggin output is. Higher means more detailled. 28 | * A logging level 0 shall only be used for fatal errors inside the Gateway and will be always logged. 29 | * @param log_lvl 30 | */ 31 | void set_log_lvl(uint8_t log_lvl) override; 32 | 33 | 34 | /** 35 | * logs a single line with timestamp or whatever at the beginning. 36 | * @param msg to be logged 37 | */ 38 | void log(char *msg, uint8_t log_lvl) override ; 39 | 40 | /** 41 | * logs a single line with timestamp or whatever at the beginning. 42 | * @param msg to be logged 43 | */ 44 | void log(const char *msg, uint8_t log_lvl) override; 45 | 46 | /** 47 | * logs a line can be appended with append_log 48 | * @param msg 49 | */ 50 | void start_log(char *msg, uint8_t log_lvl) override; 51 | 52 | /** 53 | * logs a line can be appended with append_log 54 | * @param msg 55 | */ 56 | void start_log(const char *msg, uint8_t log_lvl) override; 57 | 58 | 59 | /** 60 | * sets the log lvl for log message to be printed 61 | * @param msg 62 | */ 63 | void set_current_log_lvl(uint8_t log_lvl) override; 64 | 65 | /** 66 | * append message to the last log message 67 | * @param msg to be appended 68 | */ 69 | void append_log(char *msg) override; 70 | 71 | /** 72 | * append message to the last log message 73 | * @param msg to be appended 74 | */ 75 | void append_log(const char *msg) override; 76 | 77 | }; 78 | 79 | 80 | #endif //ESPARDUINOMQTTSNGATEWAY_ARDUINOLOGGER_H 81 | -------------------------------------------------------------------------------- /src/Implementation/ArduinoSystem.cpp: -------------------------------------------------------------------------------- 1 | #include "ArduinoSystem.h" 2 | 3 | void ArduinoSystem::set_heartbeat(uint32_t period) { 4 | this->heartbeat_period = period; 5 | } 6 | 7 | uint32_t ArduinoSystem::get_heartbeat() { 8 | return this->heartbeat_period; 9 | } 10 | 11 | 12 | bool ArduinoSystem::has_beaten() { 13 | uint32_t current = millis(); 14 | if (current - heartbeat_current > heartbeat_period) { 15 | this->heartbeat_current = current; 16 | return true; 17 | } 18 | return false; 19 | } 20 | 21 | uint32_t ArduinoSystem::get_elapsed_time() { 22 | uint32_t current = millis(); 23 | uint32_t elapsed_time = current - elapsed_current; 24 | elapsed_current = current; 25 | return elapsed_time; 26 | } 27 | 28 | void ArduinoSystem::sleep(uint32_t duration) { 29 | delay(duration); 30 | } 31 | 32 | void ArduinoSystem::exit() { 33 | throw std::exception(); 34 | #if defined(ESP8266) 35 | ESP.reset(); 36 | #endif 37 | 38 | } -------------------------------------------------------------------------------- /src/Implementation/ArduinoSystem.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 08.01.17. 3 | // 4 | 5 | #ifndef ESPARDUINOMQTTSNGATEWAY_ARDUINOSYSTEM_H 6 | #define ESPARDUINOMQTTSNGATEWAY_ARDUINOSYSTEM_H 7 | 8 | #include "../System.h" 9 | #include 10 | 11 | class ArduinoSystem : public System{ 12 | private: 13 | uint32_t heartbeat_period = 10000; 14 | uint32_t heartbeat_current=0; 15 | uint32_t elapsed_current=0; 16 | public: 17 | /** 18 | * Sets the heartbeat value where the System perform regular checks. 19 | * Default value is a period of 30 000 ms 20 | * @param period 21 | */ 22 | virtual void set_heartbeat(uint32_t period); 23 | 24 | /** 25 | * Gets the heartbeat value where the System perform regular checks. 26 | * Default value is a period of 30 000 ms 27 | */ 28 | virtual uint32_t get_heartbeat(); 29 | 30 | /** 31 | * Checks if the heartbeat is timed out. 32 | * @return true if the heartbeat value was reached, false otherwise. 33 | */ 34 | virtual bool has_beaten(); 35 | 36 | /** 37 | * Get the elapsed time between two calls of this function. 38 | * @return the elapsed time between two calls 39 | */ 40 | virtual uint32_t get_elapsed_time(); 41 | 42 | /** 43 | * Lets the execution sleep for some seconds. 44 | */ 45 | virtual void sleep(uint32_t duration); 46 | 47 | /** 48 | * Stop/exit the whole program or restart it if you want to. 49 | */ 50 | virtual void exit(); 51 | }; 52 | 53 | 54 | #endif //ESPARDUINOMQTTSNGATEWAY_ARDUINOSYSTEM_H 55 | -------------------------------------------------------------------------------- /src/Implementation/SDLinuxFake.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "SDLinuxFake.h" 4 | 5 | 6 | 7 | bool SDLinuxFake::begin(uint8_t csPin/* = SD_CHIP_SELECT_PIN*/) { 8 | _begin = true; 9 | std::system(("mkdir --parents " + _rootPath).c_str()); 10 | return true; 11 | } 12 | 13 | 14 | void SDLinuxFake::setRootPath(std::string rootPath) { 15 | _rootPath = rootPath; 16 | } 17 | 18 | 19 | SDLinuxFake::~SDLinuxFake() { 20 | } 21 | 22 | 23 | FileLinuxFake SDLinuxFake::open(const char *filename, uint8_t mode) { 24 | std::string fullPath = _rootPath+ "/" + filename; 25 | std::system(("touch " + fullPath).c_str()); 26 | 27 | return FileLinuxFake(fullPath.c_str(), filename, (bool)mode); 28 | } 29 | 30 | 31 | FileLinuxFake::FileLinuxFake() { 32 | 33 | } 34 | 35 | 36 | FileLinuxFake::FileLinuxFake(const char *fullPath, const char *name, bool rw) { 37 | _full_path = fullPath; 38 | strcpy(_name, name); 39 | _read = rw; 40 | } 41 | 42 | bool SDLinuxFake::exists(const char *filepath) { 43 | std::string full_path = _rootPath + filepath; 44 | struct stat buffer; 45 | return (stat(full_path.c_str(), &buffer) == 0); 46 | } 47 | 48 | bool SDLinuxFake::remove(const char *filepath) { 49 | return !std::remove(filepath); 50 | } 51 | 52 | 53 | 54 | void FileLinuxFake::close() { 55 | _closed = true; 56 | } 57 | 58 | 59 | size_t FileLinuxFake::write(const uint8_t *buf, size_t size) { 60 | if (_closed) { 61 | return 0; 62 | } 63 | if (_read) { 64 | return 0; 65 | } 66 | // open file 67 | std::fstream _file; 68 | _file.open(_full_path); 69 | _file.seekg(_position); 70 | for (uint16_t i = 0; i < size; i++) { 71 | _file << *buf++; 72 | } 73 | _position += size; 74 | _file.close(); 75 | return size; 76 | } 77 | 78 | size_t FileLinuxFake::write(const char *buf, size_t size) { 79 | if (_closed) { 80 | return 0; 81 | } 82 | if (_read) { 83 | return 0; 84 | } 85 | // open file 86 | std::fstream _file; 87 | _file.open(_full_path); 88 | _file.seekg(_position); 89 | for (uint16_t i = 0; i < size; i++) { 90 | _file << *buf++; 91 | } 92 | _position += size; 93 | _file.close(); 94 | return size; 95 | } 96 | 97 | void FileLinuxFake::flush() { 98 | 99 | } 100 | 101 | int FileLinuxFake::read(void *buf, uint16_t nbyte) { 102 | if(!_read){ 103 | return 0; 104 | } 105 | std::fstream _file; 106 | _file.open(_full_path); 107 | _file.seekg(_position); 108 | _file.read((char *) buf, nbyte); 109 | if (_file.rdstate() == std::ios_base::eofbit) { 110 | long read_bytes = _file.gcount(); 111 | _position += read_bytes; 112 | _file.close(); 113 | return read_bytes; 114 | } else if (_file.rdstate() == std::ios_base::failbit) { 115 | return 0; 116 | } else if (_file.rdstate() == std::ios_base::badbit) { 117 | return 0; 118 | } 119 | long read_bytes = _file.gcount(); 120 | _position += read_bytes; 121 | _file.close(); 122 | return read_bytes; 123 | } 124 | 125 | bool FileLinuxFake::seek(uint32_t pos) { 126 | _position = pos; 127 | return true; 128 | } 129 | 130 | int FileLinuxFake::read() { 131 | if(!_read){ 132 | return 0; 133 | } 134 | std::fstream _file; 135 | _file.open(_full_path); 136 | _file.seekg(_position,std::fstream::beg); 137 | int c = _file.get(); 138 | if (_file.rdstate() == std::ios_base::eofbit) { 139 | long read_bytes = _file.gcount(); 140 | _position += read_bytes; 141 | _file.close(); 142 | return c; 143 | } else if (_file.rdstate() == std::ios_base::failbit) { 144 | return 0; 145 | } else if (_file.rdstate() == std::ios_base::badbit) { 146 | return 0; 147 | } 148 | long read_bytes = _file.gcount(); 149 | _position += read_bytes; 150 | _file.close(); 151 | return c; 152 | } 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /src/Implementation/SDLinuxFake.h: -------------------------------------------------------------------------------- 1 | #ifndef DATABASE_SD_H 2 | #define DATABASE_SD_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define O_READ std::ios::in 12 | #define O_WRITE std::ios::out 13 | 14 | //#define O_CREAT 255 15 | 16 | //#define O_RDONLY O_READ 17 | 18 | #define FILE_READ 1 19 | #define FILE_WRITE 0 20 | //#define FILE_WRITE (O_READ | O_WRITE | O_CREAT) 21 | 22 | /** 23 | * Fake implementation using the same function signatures as the File classes from the Arduino SD Library. 24 | */ 25 | class FileLinuxFake { 26 | private: 27 | char _name[13]; // our name 28 | std::string _full_path; 29 | uint32_t _length; 30 | bool _read; 31 | long _position=0; 32 | bool _closed = false; 33 | 34 | public: 35 | ~FileLinuxFake(){ }; 36 | FileLinuxFake(const char *fullPath, const char *name, bool rw); // wraps an underlying SdFile 37 | FileLinuxFake(); 38 | 39 | size_t write(const uint8_t *buf, size_t size); 40 | size_t write(const char *buf, size_t size); 41 | int read(void *buf, uint16_t nybte); 42 | int read(); 43 | void flush(); 44 | bool seek(uint32_t pos); 45 | void close(); 46 | 47 | }; 48 | class SDLinuxFake { 49 | public: 50 | std::string _rootPath ; 51 | private: 52 | bool _begin = false; 53 | public: 54 | ~SDLinuxFake(); 55 | 56 | void setRootPath(std::string rootPath); 57 | 58 | 59 | bool begin(uint8_t csPin/* = SD_CHIP_SELECT_PIN*/); 60 | 61 | FileLinuxFake open(const char *filename, uint8_t mode = FILE_READ); 62 | 63 | bool exists(const char *filepath); 64 | 65 | // Delete the file. 66 | bool remove(const char *filepath); 67 | 68 | 69 | private: 70 | friend class FileLinuxFake; 71 | // friend boolean callback_openPath(SdFile&, const char *, boolean, void *); 72 | }; 73 | 74 | 75 | #endif //DATABASE_SD_H 76 | -------------------------------------------------------------------------------- /src/Implementation/SD_table_entries.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 18.12.16. 3 | // 4 | 5 | #ifndef GATEWAY_SD_TABLE_ENTRIES_H 6 | #define GATEWAY_SD_TABLE_ENTRIES_H 7 | 8 | #include 9 | #include 10 | #include "../global_defines.h" 11 | #include "../mqttsn_messages.h" 12 | #include "../core_defines.h" 13 | 14 | struct entry_mqtt_subscription{ 15 | uint32_t client_subscription_count; 16 | char topic_name[255]; 17 | }; 18 | 19 | struct entry_will { 20 | char willtopic[255]; 21 | char willmsg[255]; 22 | uint8_t willmsg_length; 23 | uint8_t qos; 24 | bool retain; 25 | }; 26 | 27 | struct entry_subscription{ 28 | uint16_t topic_id; 29 | uint8_t qos; 30 | char topic_name[255]; 31 | 32 | }; 33 | 34 | struct entry_registration{ 35 | uint16_t topic_id; 36 | char topic_name[255]; 37 | bool known; 38 | }; 39 | 40 | struct entry_publish{ 41 | uint8_t msg[255]; 42 | uint8_t msg_length; 43 | uint16_t topic_id; 44 | uint8_t qos; 45 | bool retain; 46 | bool dup; 47 | uint16_t msg_id; 48 | uint16_t publish_id; 49 | uint32_t retransmition_timeout; // not used atm 50 | }; 51 | 52 | //TODO remove pragma and test 53 | #pragma pack(push, 1) 54 | struct entry_client { 55 | char client_id[24]; 56 | char file_number[9]; 57 | device_address client_address; 58 | CLIENT_STATUS client_status; 59 | uint32_t duration; // changed 60 | uint32_t timeout; 61 | uint16_t await_message_id; 62 | message_type await_message; 63 | }; 64 | #pragma pack(pop) 65 | 66 | #endif //GATEWAY_SD_TABLE_ENTRIES_H 67 | -------------------------------------------------------------------------------- /src/Implementation/UdpSocketImpl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 23.12.16. 3 | // 4 | 5 | #ifndef GATEWAY_UDPSOCKETIMPL_H 6 | #define GATEWAY_UDPSOCKETIMPL_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "../SocketInterface.h" 18 | 19 | #define BUFLEN 255 //Max length of buffer 20 | #define PORT 8888 //The port on which to listen for incoming data 21 | 22 | /** 23 | * This is a example implementation for the SocketInterface based on Linux UDP Sockets. 24 | * This can be used as a reference implementation. 25 | */ 26 | class UdpSocketImpl : public SocketInterface{ 27 | public: 28 | struct sockaddr_in si_me, si_other; 29 | 30 | int s, i, recv_len; 31 | socklen_t slen = sizeof(si_other); 32 | char buf[BUFLEN]; 33 | 34 | MqttSnMessageHandler *mqttsn = nullptr; 35 | device_address own_address; 36 | device_address broadcast_address; 37 | 38 | LoggerInterface *logger; 39 | public: 40 | bool begin(); 41 | 42 | void setMqttSnMessageHandler(MqttSnMessageHandler *mqttSnMessageHandler) override; 43 | 44 | void setLogger(LoggerInterface *logger) override; 45 | 46 | device_address *getBroadcastAddress() override; 47 | 48 | device_address *getAddress() override; 49 | 50 | uint8_t getMaximumMessageLength() override; 51 | 52 | bool send(device_address *destination, uint8_t *bytes, uint16_t bytes_len) override; 53 | 54 | bool send(device_address *destination, uint8_t *bytes, uint16_t bytes_len, uint8_t signal_strength) override; 55 | 56 | bool loop() override; 57 | 58 | device_address getDevice_address(sockaddr_in *addr) const; 59 | 60 | uint32_t getIp_address(device_address *address) const; 61 | 62 | uint16_t getPort(device_address *address) const; 63 | 64 | void disconnect(); 65 | 66 | 67 | }; 68 | 69 | 70 | #endif //GATEWAY_UDPSOCKETIMPL_H 71 | -------------------------------------------------------------------------------- /src/Implementation/paho/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | include_directories(pahomqttembeddedc/MQTTClient/src/linux) 4 | include_directories(pahomqttembeddedc/MQTTClient/src/) 5 | include_directories(pahomqttembeddedc/MQTTPacket/src) 6 | 7 | file(GLOB PAHO_SOURCE_FILES 8 | pahomqttembeddedc/MQTTPacket/src/*.c 9 | pahomqttembeddedc/MQTTPacket/src/*.h 10 | pahomqttembeddedc/MQTTClient/src/*.cpp 11 | pahomqttembeddedc/MQTTClient/src/*.h 12 | pahomqttembeddedc/MQTTClient/src/linux/*.cpp 13 | pahomqttembeddedc/MQTTClient/src/linux/*.h 14 | ) 15 | 16 | 17 | set(SOURCE_FILES PahoMqttMessageHandler.h PahoMqttMessageHandler.cpp) 18 | add_library(PahoLinuxMqttMessageHandler ${SOURCE_FILES} ${PAHO_SOURCE_FILES} ) 19 | 20 | -------------------------------------------------------------------------------- /src/Implementation/paho/PahoMqttMessageHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef GATEWAY_PAHOMQTTMESSAGEHANDLER_H 2 | #define GATEWAY_PAHOMQTTMESSAGEHANDLER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../../CoreInterface.h" 8 | 9 | class PahoMqttMessageHandler : public MqttMessageHandlerInterface{ 10 | private: 11 | 12 | public: 13 | virtual bool begin(); 14 | 15 | virtual void setCore(Core *core); 16 | 17 | virtual void setLogger(LoggerInterface *logger); 18 | 19 | virtual void setServer(uint8_t *ip, uint16_t port); 20 | 21 | virtual void setServer(const char* hostname, uint16_t port); 22 | 23 | virtual bool connect(const char *id); 24 | 25 | virtual bool connect(const char *id, const char *user, const char *pass); 26 | 27 | virtual bool 28 | connect(const char *id, const char *willTopic, uint8_t willQos, bool willRetain, const uint8_t *willMessage, 29 | const uint16_t willMessageLength); 30 | 31 | virtual bool 32 | connect(const char *id, const char *user, const char *pass, const char *willTopic, uint8_t willQos, bool willRetain, 33 | const uint8_t *willMessage, const uint16_t willMessageLength); 34 | 35 | virtual void disconnect(); 36 | 37 | virtual bool publish(const char *topic, const uint8_t *payload, uint16_t plength, uint8_t qos, bool retained); 38 | 39 | virtual bool subscribe(const char *topic, uint8_t qos); 40 | 41 | virtual bool unsubscribe(const char *topic); 42 | 43 | virtual bool receive_publish(char *topic, uint8_t *payload, uint32_t length); 44 | 45 | virtual bool loop(); 46 | 47 | IPStack ipstack; 48 | MQTT::Client *client; 49 | const char *hostname = nullptr; 50 | uint16_t port = 0; 51 | private: 52 | Core *core = nullptr; 53 | bool getConfigAndConnect() ; 54 | int64_t ip_address = -1; 55 | LoggerInterface *logger; 56 | }; 57 | 58 | 59 | #endif //GATEWAY_PAHOMQTTMESSAGEHANDLER_H 60 | -------------------------------------------------------------------------------- /src/Implementation/paho/Readme.md: -------------------------------------------------------------------------------- 1 | if nothing is in this directoy: 2 | git clone https://github.com/eclipse/paho.mqtt.embedded-c.git 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | embedded-C 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/.settings/org.eclipse.cdt.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | formatter_profile=org.eclipse.cdt.ui.default.allman_profile 3 | formatter_settings_version=1 4 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Paho 2 | 3 | Thanks for your interest in this project! 4 | 5 | You can contribute bugfixes and new features by sending pull requests through GitHub. 6 | 7 | ## Legal 8 | 9 | In order for your contribution to be accepted, it must comply with the Eclipse Foundation IP policy. 10 | 11 | Please read the [Eclipse Foundation policy on accepting contributions via Git](http://wiki.eclipse.org/Development_Resources/Contributing_via_Git). 12 | 13 | 1. Sign the [Eclipse CLA](http://www.eclipse.org/legal/CLA.php) 14 | 1. Register for an Eclipse Foundation User ID. You can register [here](https://dev.eclipse.org/site_login/createaccount.php). 15 | 2. Log into the [Projects Portal](https://projects.eclipse.org/), and click on the '[Eclipse CLA](https://projects.eclipse.org/user/sign/cla)' link. 16 | 2. Go to your [account settings](https://dev.eclipse.org/site_login/myaccount.php#open_tab_accountsettings) and add your GitHub username to your account. 17 | 3. Make sure that you _sign-off_ your Git commits in the following format: 18 | ``` Signed-off-by: John Smith ``` This is usually at the bottom of the commit message. You can automate this by adding the '-s' flag when you make the commits. e.g. ```git commit -s -m "Adding a cool feature"``` 19 | 4. Ensure that the email address that you make your commits with is the same one you used to sign up to the Eclipse Foundation website with. 20 | 21 | ## Contributing a change 22 | 23 | 1. [Fork the repository on GitHub](https://github.com/eclipse/paho.mqtt.embedded-c/fork) 24 | 2. Clone the forked repository onto your computer: ``` git clone https://github.com//paho.mqtt.embedded-c.git ``` 25 | 3. Create a new branch from the latest ```develop``` branch with ```git checkout -b YOUR_BRANCH_NAME origin/develop``` 26 | 4. Make your changes 27 | 5. If developing a new feature, make sure to include JUnit tests. 28 | 6. Ensure that all new and existing tests pass. 29 | 7. Commit the changes into the branch: ``` git commit -s ``` Make sure that your commit message is meaningful and describes your changes correctly. 30 | 8. If you have a lot of commits for the change, squash them into a single / few commits. 31 | 9. Push the changes in your branch to your forked repository. 32 | 10. Finally, go to [https://github.com/eclipse/paho.mqtt.embedded-c](https://github.com/eclipse/paho.mqtt.embedded-c) and create a pull request from your "YOUR_BRANCH_NAME" branch to the ```develop``` one to request review and merge of the commits in your pushed branch. 33 | 34 | 35 | What happens next depends on the content of the patch. If it is 100% authored 36 | by the contributor and is less than 1000 lines (and meets the needs of the 37 | project), then it can be pulled into the main repository. If not, more steps 38 | are required. These are detailed in the 39 | [legal process poster](http://www.eclipse.org/legal/EclipseLegalProcessPoster.pdf). 40 | 41 | 42 | 43 | ## Developer resources: 44 | 45 | 46 | Information regarding source code management, builds, coding standards, and more. 47 | 48 | - [https://projects.eclipse.org/projects/iot.paho/developer](https://projects.eclipse.org/projects/iot.paho/developer) 49 | 50 | Contact: 51 | -------- 52 | 53 | Contact the project developers via the project's development 54 | [mailing list](https://dev.eclipse.org/mailman/listinfo/paho-dev). 55 | 56 | Search for bugs: 57 | ---------------- 58 | 59 | This project uses GitHub Issues here: [github.com/eclipse/paho.mqtt.embedded-c/issues](https://github.com/eclipse/paho.mqtt.embedded-c/issues) to track ongoing development and issues. 60 | 61 | Create a new bug: 62 | ----------------- 63 | 64 | Be sure to search for existing bugs before you create another one. Remember that contributions are always welcome! 65 | 66 | - [Create new Paho bug](https://github.com/eclipse/paho.mqtt.embedded-c/issues) 67 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/Debug/makefile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | -include ../makefile.init 6 | 7 | RM := rm -rf 8 | 9 | # All of the sources participating in the build are defined here 10 | -include sources.mk 11 | -include MQTTPacket/src/subdir.mk 12 | -include MQTTPacket/samples/subdir.mk 13 | -include subdir.mk 14 | -include objects.mk 15 | 16 | ifneq ($(MAKECMDGOALS),clean) 17 | ifneq ($(strip $(C_DEPS)),) 18 | -include $(C_DEPS) 19 | endif 20 | endif 21 | 22 | -include ../makefile.defs 23 | 24 | # Add inputs and outputs from these tool invocations to the build variables 25 | 26 | # All Target 27 | all: libembedded-C.so 28 | 29 | # Tool invocations 30 | libembedded-C.so: $(OBJS) $(USER_OBJS) 31 | @echo 'Building target: $@' 32 | @echo 'Invoking: GCC C Linker' 33 | gcc -shared -o "libembedded-C.so" $(OBJS) $(USER_OBJS) $(LIBS) 34 | @echo 'Finished building target: $@' 35 | @echo ' ' 36 | 37 | # Other Targets 38 | clean: 39 | -$(RM) $(C_DEPS)$(LIBRARIES)$(OBJS) libembedded-C.so 40 | -@echo ' ' 41 | 42 | .PHONY: all clean dependents 43 | .SECONDARY: 44 | 45 | -include ../makefile.targets 46 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/Debug/objects.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | USER_OBJS := 6 | 7 | LIBS := 8 | 9 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/Debug/sources.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | ASM_SRCS := 6 | OBJ_SRCS := 7 | S_UPPER_SRCS := 8 | C_SRCS := 9 | O_SRCS := 10 | C_DEPS := 11 | LIBRARIES := 12 | OBJS := 13 | 14 | # Every subdirectory with source files must be described here 15 | SUBDIRS := \ 16 | MQTTPacket/src \ 17 | MQTTPacket/samples \ 18 | 19 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/Debug/src/MQTTDeserializeConnect.d: -------------------------------------------------------------------------------- 1 | src/MQTTDeserializeConnect.d src/MQTTDeserializeConnect.o: \ 2 | ../src/MQTTDeserializeConnect.c ../src/StackTrace.h 3 | 4 | ../src/StackTrace.h: 5 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/Debug/src/subdir.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | # Add inputs and outputs from these tool invocations to the build variables 6 | C_SRCS += \ 7 | ../src/MQTTConnectClient.c \ 8 | ../src/MQTTConnectServer.c \ 9 | ../src/MQTTDeserializePublish.c \ 10 | ../src/MQTTPacket.c \ 11 | ../src/MQTTSerializePublish.c \ 12 | ../src/MQTTSubscribeClient.c \ 13 | ../src/MQTTSubscribeServer.c \ 14 | ../src/MQTTUnsubscribeClient.c \ 15 | ../src/MQTTUnsubscribeServer.c 16 | 17 | C_DEPS += \ 18 | ./src/MQTTConnectClient.d \ 19 | ./src/MQTTConnectServer.d \ 20 | ./src/MQTTDeserializePublish.d \ 21 | ./src/MQTTPacket.d \ 22 | ./src/MQTTSerializePublish.d \ 23 | ./src/MQTTSubscribeClient.d \ 24 | ./src/MQTTSubscribeServer.d \ 25 | ./src/MQTTUnsubscribeClient.d \ 26 | ./src/MQTTUnsubscribeServer.d 27 | 28 | OBJS += \ 29 | ./src/MQTTConnectClient.o \ 30 | ./src/MQTTConnectServer.o \ 31 | ./src/MQTTDeserializePublish.o \ 32 | ./src/MQTTPacket.o \ 33 | ./src/MQTTSerializePublish.o \ 34 | ./src/MQTTSubscribeClient.o \ 35 | ./src/MQTTSubscribeServer.o \ 36 | ./src/MQTTUnsubscribeClient.o \ 37 | ./src/MQTTUnsubscribeServer.o 38 | 39 | 40 | # Each subdirectory must supply rules for building sources it contributes 41 | src/%.o: ../src/%.c 42 | @echo 'Building file: $<' 43 | @echo 'Invoking: GCC C Compiler' 44 | gcc -I"/home/icraggs/work/paho/org.eclipse.paho.mqtt.embedded-c/src" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" 45 | @echo 'Finished building: $<' 46 | @echo ' ' 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/samples/linux/build.sh: -------------------------------------------------------------------------------- 1 | cp ../../src/MQTTClient.c . 2 | sed -e 's/""/"MQTTLinux.h"/g' ../../src/MQTTClient.h > MQTTClient.h 3 | gcc stdoutsub.c -I ../../src -I ../../src/linux -I ../../../MQTTPacket/src MQTTClient.c ../../src/linux/MQTTLinux.c ../../../MQTTPacket/src/MQTTFormat.c ../../../MQTTPacket/src/MQTTPacket.c ../../../MQTTPacket/src/MQTTDeserializePublish.c ../../../MQTTPacket/src/MQTTConnectClient.c ../../../MQTTPacket/src/MQTTSubscribeClient.c ../../../MQTTPacket/src/MQTTSerializePublish.c -o stdoutsub ../../../MQTTPacket/src/MQTTConnectServer.c ../../../MQTTPacket/src/MQTTSubscribeServer.c ../../../MQTTPacket/src/MQTTUnsubscribeServer.c ../../../MQTTPacket/src/MQTTUnsubscribeClient.c -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/samples/linux/stdoutsub.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012, 2013 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial contribution 15 | * Ian Craggs - change delimiter option from char to string 16 | * Al Stockdill-Mander - Version using the embedded C client 17 | *******************************************************************************/ 18 | 19 | /* 20 | 21 | stdout subscriber 22 | 23 | compulsory parameters: 24 | 25 | topic to subscribe to 26 | 27 | defaulted parameters: 28 | 29 | --host localhost 30 | --port 1883 31 | --qos 2 32 | --delimiter \n 33 | --clientid stdout_subscriber 34 | 35 | --userid none 36 | --password none 37 | 38 | for example: 39 | 40 | stdoutsub topic/of/interest --host iot.eclipse.org 41 | 42 | */ 43 | #include 44 | #include "MQTTClient.h" 45 | 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | 52 | 53 | volatile int toStop = 0; 54 | 55 | 56 | void usage() 57 | { 58 | printf("MQTT stdout subscriber\n"); 59 | printf("Usage: stdoutsub topicname , where options are:\n"); 60 | printf(" --host (default is localhost)\n"); 61 | printf(" --port (default is 1883)\n"); 62 | printf(" --qos (default is 2)\n"); 63 | printf(" --delimiter (default is \\n)\n"); 64 | printf(" --clientid (default is hostname+timestamp)\n"); 65 | printf(" --username none\n"); 66 | printf(" --password none\n"); 67 | printf(" --showtopics (default is on if the topic has a wildcard, else off)\n"); 68 | exit(-1); 69 | } 70 | 71 | 72 | void cfinish(int sig) 73 | { 74 | signal(SIGINT, NULL); 75 | toStop = 1; 76 | } 77 | 78 | 79 | struct opts_struct 80 | { 81 | char* clientid; 82 | int nodelimiter; 83 | char* delimiter; 84 | enum QoS qos; 85 | char* username; 86 | char* password; 87 | char* host; 88 | int port; 89 | int showtopics; 90 | } opts = 91 | { 92 | (char*)"stdout-subscriber", 0, (char*)"\n", QOS2, NULL, NULL, (char*)"localhost", 1883, 0 93 | }; 94 | 95 | 96 | void getopts(int argc, char** argv) 97 | { 98 | int count = 2; 99 | 100 | while (count < argc) 101 | { 102 | if (strcmp(argv[count], "--qos") == 0) 103 | { 104 | if (++count < argc) 105 | { 106 | if (strcmp(argv[count], "0") == 0) 107 | opts.qos = QOS0; 108 | else if (strcmp(argv[count], "1") == 0) 109 | opts.qos = QOS1; 110 | else if (strcmp(argv[count], "2") == 0) 111 | opts.qos = QOS2; 112 | else 113 | usage(); 114 | } 115 | else 116 | usage(); 117 | } 118 | else if (strcmp(argv[count], "--host") == 0) 119 | { 120 | if (++count < argc) 121 | opts.host = argv[count]; 122 | else 123 | usage(); 124 | } 125 | else if (strcmp(argv[count], "--port") == 0) 126 | { 127 | if (++count < argc) 128 | opts.port = atoi(argv[count]); 129 | else 130 | usage(); 131 | } 132 | else if (strcmp(argv[count], "--clientid") == 0) 133 | { 134 | if (++count < argc) 135 | opts.clientid = argv[count]; 136 | else 137 | usage(); 138 | } 139 | else if (strcmp(argv[count], "--username") == 0) 140 | { 141 | if (++count < argc) 142 | opts.username = argv[count]; 143 | else 144 | usage(); 145 | } 146 | else if (strcmp(argv[count], "--password") == 0) 147 | { 148 | if (++count < argc) 149 | opts.password = argv[count]; 150 | else 151 | usage(); 152 | } 153 | else if (strcmp(argv[count], "--delimiter") == 0) 154 | { 155 | if (++count < argc) 156 | opts.delimiter = argv[count]; 157 | else 158 | opts.nodelimiter = 1; 159 | } 160 | else if (strcmp(argv[count], "--showtopics") == 0) 161 | { 162 | if (++count < argc) 163 | { 164 | if (strcmp(argv[count], "on") == 0) 165 | opts.showtopics = 1; 166 | else if (strcmp(argv[count], "off") == 0) 167 | opts.showtopics = 0; 168 | else 169 | usage(); 170 | } 171 | else 172 | usage(); 173 | } 174 | count++; 175 | } 176 | 177 | } 178 | 179 | 180 | void messageArrived(MessageData* md) 181 | { 182 | MQTTMessage* message = md->message; 183 | 184 | if (opts.showtopics) 185 | printf("%.*s\t", md->topicName->lenstring.len, md->topicName->lenstring.data); 186 | if (opts.nodelimiter) 187 | printf("%.*s", (int)message->payloadlen, (char*)message->payload); 188 | else 189 | printf("%.*s%s", (int)message->payloadlen, (char*)message->payload, opts.delimiter); 190 | //fflush(stdout); 191 | } 192 | 193 | 194 | int main(int argc, char** argv) 195 | { 196 | int rc = 0; 197 | unsigned char buf[100]; 198 | unsigned char readbuf[100]; 199 | 200 | if (argc < 2) 201 | usage(); 202 | 203 | char* topic = argv[1]; 204 | 205 | if (strchr(topic, '#') || strchr(topic, '+')) 206 | opts.showtopics = 1; 207 | if (opts.showtopics) 208 | printf("topic is %s\n", topic); 209 | 210 | getopts(argc, argv); 211 | 212 | Network n; 213 | Client c; 214 | 215 | signal(SIGINT, cfinish); 216 | signal(SIGTERM, cfinish); 217 | 218 | NewNetwork(&n); 219 | ConnectNetwork(&n, opts.host, opts.port); 220 | MQTTClient(&c, &n, 1000, buf, 100, readbuf, 100); 221 | 222 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 223 | data.willFlag = 0; 224 | data.MQTTVersion = 3; 225 | data.clientID.cstring = opts.clientid; 226 | data.username.cstring = opts.username; 227 | data.password.cstring = opts.password; 228 | 229 | data.keepAliveInterval = 10; 230 | data.cleansession = 1; 231 | printf("Connecting to %s %d\n", opts.host, opts.port); 232 | 233 | rc = MQTTConnect(&c, &data); 234 | printf("Connected %d\n", rc); 235 | 236 | printf("Subscribing to %s\n", topic); 237 | rc = MQTTSubscribe(&c, topic, opts.qos, messageArrived); 238 | printf("Subscribed %d\n", rc); 239 | 240 | while (!toStop) 241 | { 242 | MQTTYield(&c, 1000); 243 | } 244 | 245 | printf("Stopping\n"); 246 | 247 | MQTTDisconnect(&c); 248 | n.disconnect(&n); 249 | 250 | return 0; 251 | } 252 | 253 | 254 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/src/FreeRTOS/MQTTFreeRTOS.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, 2015 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Allan Stockdill-Mander - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #if !defined(MQTTFreeRTOS_H) 18 | #define MQTTFreeRTOS_H 19 | 20 | #include "FreeRTOS.h" 21 | #include "FreeRTOS_Sockets.h" 22 | #include "FreeRTOS_IP.h" 23 | #include "semphr.h" 24 | #include "task.h" 25 | 26 | typedef struct Timer 27 | { 28 | TickType_t xTicksToWait; 29 | TimeOut_t xTimeOut; 30 | } Timer; 31 | 32 | typedef struct Network Network; 33 | 34 | struct Network 35 | { 36 | xSocket_t my_socket; 37 | int (*mqttread) (Network*, unsigned char*, int, int); 38 | int (*mqttwrite) (Network*, unsigned char*, int, int); 39 | void (*disconnect) (Network*); 40 | }; 41 | 42 | void TimerInit(Timer*); 43 | char TimerIsExpired(Timer*); 44 | void TimerCountdownMS(Timer*, unsigned int); 45 | void TimerCountdown(Timer*, unsigned int); 46 | int TimerLeftMS(Timer*); 47 | 48 | typedef struct Mutex 49 | { 50 | SemaphoreHandle_t sem; 51 | } Mutex; 52 | 53 | void MutexInit(Mutex*); 54 | int MutexLock(Mutex*); 55 | int MutexUnlock(Mutex*); 56 | 57 | typedef struct Thread 58 | { 59 | TaskHandle_t task; 60 | } Thread; 61 | 62 | int ThreadStart(Thread*, void (*fn)(void*), void* arg); 63 | 64 | int FreeRTOS_read(Network*, unsigned char*, int, int); 65 | int FreeRTOS_write(Network*, unsigned char*, int, int); 66 | void FreeRTOS_disconnect(Network*); 67 | 68 | void NetworkInit(Network*); 69 | int NetworkConnect(Network*, char*, int); 70 | /*int NetworkConnectTLS(Network*, char*, int, SlSockSecureFiles_t*, unsigned char, unsigned int, char);*/ 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/src/MQTTClient.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, 2015 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation 15 | * Ian Craggs - documentation and platform specific header 16 | *******************************************************************************/ 17 | 18 | #if !defined(__MQTT_CLIENT_C_) 19 | #define __MQTT_CLIENT_C_ 20 | 21 | #if defined(__cplusplus) 22 | extern "C" { 23 | #endif 24 | 25 | #if defined(WIN32_DLL) || defined(WIN64_DLL) 26 | #define DLLImport __declspec(dllimport) 27 | #define DLLExport __declspec(dllexport) 28 | #elif defined(LINUX_SO) 29 | #define DLLImport extern 30 | #define DLLExport __attribute__ ((visibility ("default"))) 31 | #else 32 | #define DLLImport 33 | #define DLLExport 34 | #endif 35 | 36 | #include "MQTTPacket.h" 37 | #include "stdio.h" 38 | 39 | #if defined(MQTTCLIENT_PLATFORM_HEADER) 40 | /* The following sequence of macros converts the MQTTCLIENT_PLATFORM_HEADER value 41 | * into a string constant suitable for use with include. 42 | */ 43 | #define xstr(s) str(s) 44 | #define str(s) #s 45 | #include xstr(MQTTCLIENT_PLATFORM_HEADER) 46 | #endif 47 | 48 | #define MAX_PACKET_ID 65535 /* according to the MQTT specification - do not change! */ 49 | 50 | #if !defined(MAX_MESSAGE_HANDLERS) 51 | #define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */ 52 | #endif 53 | 54 | enum QoS { QOS0, QOS1, QOS2 }; 55 | 56 | /* all failure return codes must be negative */ 57 | enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1, SUCCESS = 0 }; 58 | 59 | /* The Platform specific header must define the Network and Timer structures and functions 60 | * which operate on them. 61 | * 62 | typedef struct Network 63 | { 64 | int (*mqttread)(Network*, unsigned char* read_buffer, int, int); 65 | int (*mqttwrite)(Network*, unsigned char* send_buffer, int, int); 66 | } Network;*/ 67 | 68 | /* The Timer structure must be defined in the platform specific header, 69 | * and have the following functions to operate on it. */ 70 | extern void TimerInit(Timer*); 71 | extern char TimerIsExpired(Timer*); 72 | extern void TimerCountdownMS(Timer*, unsigned int); 73 | extern void TimerCountdown(Timer*, unsigned int); 74 | extern int TimerLeftMS(Timer*); 75 | 76 | typedef struct MQTTMessage 77 | { 78 | enum QoS qos; 79 | unsigned char retained; 80 | unsigned char dup; 81 | unsigned short id; 82 | void *payload; 83 | size_t payloadlen; 84 | } MQTTMessage; 85 | 86 | typedef struct MessageData 87 | { 88 | MQTTMessage* message; 89 | MQTTString* topicName; 90 | } MessageData; 91 | 92 | typedef void (*messageHandler)(MessageData*); 93 | 94 | typedef struct MQTTClient 95 | { 96 | unsigned int next_packetid, 97 | command_timeout_ms; 98 | size_t buf_size, 99 | readbuf_size; 100 | unsigned char *buf, 101 | *readbuf; 102 | unsigned int keepAliveInterval; 103 | char ping_outstanding; 104 | int isconnected; 105 | 106 | struct MessageHandlers 107 | { 108 | const char* topicFilter; 109 | void (*fp) (MessageData*); 110 | } messageHandlers[MAX_MESSAGE_HANDLERS]; /* Message handlers are indexed by subscription topic */ 111 | 112 | void (*defaultMessageHandler) (MessageData*); 113 | 114 | Network* ipstack; 115 | Timer ping_timer; 116 | #if defined(MQTT_TASK) 117 | Mutex mutex; 118 | Thread thread; 119 | #endif 120 | } MQTTClient; 121 | 122 | #define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0} 123 | 124 | 125 | /** 126 | * Create an MQTT client object 127 | * @param client 128 | * @param network 129 | * @param command_timeout_ms 130 | * @param 131 | */ 132 | DLLExport void MQTTClientInit(MQTTClient* client, Network* network, unsigned int command_timeout_ms, 133 | unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size); 134 | 135 | /** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack 136 | * The nework object must be connected to the network endpoint before calling this 137 | * @param options - connect options 138 | * @return success code 139 | */ 140 | DLLExport int MQTTConnect(MQTTClient* client, MQTTPacket_connectData* options); 141 | 142 | /** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs 143 | * @param client - the client object to use 144 | * @param topic - the topic to publish to 145 | * @param message - the message to send 146 | * @return success code 147 | */ 148 | DLLExport int MQTTPublish(MQTTClient* client, const char*, MQTTMessage*); 149 | 150 | /** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning. 151 | * @param client - the client object to use 152 | * @param topicFilter - the topic filter to subscribe to 153 | * @param message - the message to send 154 | * @return success code 155 | */ 156 | DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler); 157 | 158 | /** MQTT Subscribe - send an MQTT unsubscribe packet and wait for unsuback before returning. 159 | * @param client - the client object to use 160 | * @param topicFilter - the topic filter to unsubscribe from 161 | * @return success code 162 | */ 163 | DLLExport int MQTTUnsubscribe(MQTTClient* client, const char* topicFilter); 164 | 165 | /** MQTT Disconnect - send an MQTT disconnect packet and close the connection 166 | * @param client - the client object to use 167 | * @return success code 168 | */ 169 | DLLExport int MQTTDisconnect(MQTTClient* client); 170 | 171 | /** MQTT Yield - MQTT background 172 | * @param client - the client object to use 173 | * @param time - the time, in milliseconds, to yield for 174 | * @return success code 175 | */ 176 | DLLExport int MQTTYield(MQTTClient* client, int time); 177 | 178 | #if defined(MQTT_TASK) 179 | /** MQTT start background thread for a client. After this, MQTTYield should not be called. 180 | * @param client - the client object to use 181 | * @return success code 182 | */ 183 | DLLExport int MQTTStartTask(MQTTClient* client); 184 | #endif 185 | 186 | #if defined(__cplusplus) 187 | } 188 | #endif 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/src/cc3200/MQTTCC3200.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Allan Stockdill-Mander - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTCC3200.h" 18 | 19 | unsigned long MilliTimer; 20 | 21 | void SysTickIntHandler(void) { 22 | MilliTimer++; 23 | } 24 | 25 | char expired(Timer* timer) { 26 | long left = timer->end_time - MilliTimer; 27 | return (left < 0); 28 | } 29 | 30 | 31 | void countdown_ms(Timer* timer, unsigned int timeout) { 32 | timer->end_time = MilliTimer + timeout; 33 | } 34 | 35 | 36 | void countdown(Timer* timer, unsigned int timeout) { 37 | timer->end_time = MilliTimer + (timeout * 1000); 38 | } 39 | 40 | 41 | int left_ms(Timer* timer) { 42 | long left = timer->end_time - MilliTimer; 43 | return (left < 0) ? 0 : left; 44 | } 45 | 46 | 47 | void InitTimer(Timer* timer) { 48 | timer->end_time = 0; 49 | } 50 | 51 | 52 | int cc3200_read(Network* n, unsigned char* buffer, int len, int timeout_ms) { 53 | SlTimeval_t timeVal; 54 | SlFdSet_t fdset; 55 | int rc = 0; 56 | int recvLen = 0; 57 | 58 | SL_FD_ZERO(&fdset); 59 | SL_FD_SET(n->my_socket, &fdset); 60 | 61 | timeVal.tv_sec = 0; 62 | timeVal.tv_usec = timeout_ms * 1000; 63 | if (sl_Select(n->my_socket + 1, &fdset, NULL, NULL, &timeVal) == 1) { 64 | do { 65 | rc = sl_Recv(n->my_socket, buffer + recvLen, len - recvLen, 0); 66 | recvLen += rc; 67 | } while(recvLen < len); 68 | } 69 | return recvLen; 70 | } 71 | 72 | 73 | int cc3200_write(Network* n, unsigned char* buffer, int len, int timeout_ms) { 74 | SlTimeval_t timeVal; 75 | SlFdSet_t fdset; 76 | int rc = 0; 77 | int readySock; 78 | 79 | SL_FD_ZERO(&fdset); 80 | SL_FD_SET(n->my_socket, &fdset); 81 | 82 | timeVal.tv_sec = 0; 83 | timeVal.tv_usec = timeout_ms * 1000; 84 | do { 85 | readySock = sl_Select(n->my_socket + 1, NULL, &fdset, NULL, &timeVal); 86 | } while(readySock != 1); 87 | rc = sl_Send(n->my_socket, buffer, len, 0); 88 | return rc; 89 | } 90 | 91 | 92 | void cc3200_disconnect(Network* n) { 93 | sl_Close(n->my_socket); 94 | } 95 | 96 | 97 | void NewNetwork(Network* n) { 98 | n->my_socket = 0; 99 | n->mqttread = cc3200_read; 100 | n->mqttwrite = cc3200_write; 101 | n->disconnect = cc3200_disconnect; 102 | } 103 | 104 | int TLSConnectNetwork(Network *n, char* addr, int port, SlSockSecureFiles_t* certificates, unsigned char sec_method, unsigned int cipher, char server_verify) { 105 | SlSockAddrIn_t sAddr; 106 | int addrSize; 107 | int retVal; 108 | unsigned long ipAddress; 109 | 110 | retVal = sl_NetAppDnsGetHostByName(addr, strlen(addr), &ipAddress, AF_INET); 111 | if (retVal < 0) { 112 | return -1; 113 | } 114 | 115 | sAddr.sin_family = AF_INET; 116 | sAddr.sin_port = sl_Htons((unsigned short)port); 117 | sAddr.sin_addr.s_addr = sl_Htonl(ipAddress); 118 | 119 | addrSize = sizeof(SlSockAddrIn_t); 120 | 121 | n->my_socket = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, SL_SEC_SOCKET); 122 | if (n->my_socket < 0) { 123 | return -1; 124 | } 125 | 126 | SlSockSecureMethod method; 127 | method.secureMethod = sec_method; 128 | retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECMETHOD, &method, sizeof(method)); 129 | if (retVal < 0) { 130 | return retVal; 131 | } 132 | 133 | SlSockSecureMask mask; 134 | mask.secureMask = cipher; 135 | retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_MASK, &mask, sizeof(mask)); 136 | if (retVal < 0) { 137 | return retVal; 138 | } 139 | 140 | if (certificates != NULL) { 141 | retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_FILES, certificates->secureFiles, sizeof(SlSockSecureFiles_t)); 142 | if(retVal < 0) 143 | { 144 | return retVal; 145 | } 146 | } 147 | 148 | retVal = sl_Connect(n->my_socket, ( SlSockAddr_t *)&sAddr, addrSize); 149 | if( retVal < 0 ) { 150 | if (server_verify || retVal != -453) { 151 | sl_Close(n->my_socket); 152 | return retVal; 153 | } 154 | } 155 | 156 | SysTickIntRegister(SysTickIntHandler); 157 | SysTickPeriodSet(80000); 158 | SysTickEnable(); 159 | 160 | return retVal; 161 | } 162 | 163 | int ConnectNetwork(Network* n, char* addr, int port) 164 | { 165 | SlSockAddrIn_t sAddr; 166 | int addrSize; 167 | int retVal; 168 | unsigned long ipAddress; 169 | 170 | sl_NetAppDnsGetHostByName(addr, strlen(addr), &ipAddress, AF_INET); 171 | 172 | sAddr.sin_family = AF_INET; 173 | sAddr.sin_port = sl_Htons((unsigned short)port); 174 | sAddr.sin_addr.s_addr = sl_Htonl(ipAddress); 175 | 176 | addrSize = sizeof(SlSockAddrIn_t); 177 | 178 | n->my_socket = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); 179 | if( n->my_socket < 0 ) { 180 | // error 181 | return -1; 182 | } 183 | 184 | retVal = sl_Connect(n->my_socket, ( SlSockAddr_t *)&sAddr, addrSize); 185 | if( retVal < 0 ) { 186 | // error 187 | sl_Close(n->my_socket); 188 | return retVal; 189 | } 190 | 191 | SysTickIntRegister(SysTickIntHandler); 192 | SysTickPeriodSet(80000); 193 | SysTickEnable(); 194 | 195 | return retVal; 196 | } 197 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/src/cc3200/MQTTCC3200.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Allan Stockdill-Mander - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #ifndef __MQTT_CC3200_ 18 | #define __MQTT_CC3200_ 19 | 20 | #include "simplelink.h" 21 | #include "netapp.h" 22 | #include "socket.h" 23 | #include "hw_types.h" 24 | #include "systick.h" 25 | 26 | typedef struct Timer Timer; 27 | 28 | struct Timer { 29 | unsigned long systick_period; 30 | unsigned long end_time; 31 | }; 32 | 33 | typedef struct Network Network; 34 | 35 | struct Network 36 | { 37 | int my_socket; 38 | int (*mqttread) (Network*, unsigned char*, int, int); 39 | int (*mqttwrite) (Network*, unsigned char*, int, int); 40 | void (*disconnect) (Network*); 41 | }; 42 | 43 | char expired(Timer*); 44 | void countdown_ms(Timer*, unsigned int); 45 | void countdown(Timer*, unsigned int); 46 | int left_ms(Timer*); 47 | 48 | void InitTimer(Timer*); 49 | 50 | int cc3200_read(Network*, unsigned char*, int, int); 51 | int cc3200_write(Network*, unsigned char*, int, int); 52 | void cc3200_disconnect(Network*); 53 | void NewNetwork(Network*); 54 | 55 | int ConnectNetwork(Network*, char*, int); 56 | int TLSConnectNetwork(Network*, char*, int, SlSockSecureFiles_t*, unsigned char, unsigned int, char); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/src/linux/MQTTLinux.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Allan Stockdill-Mander - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTLinux.h" 18 | 19 | void TimerInit(Timer* timer) 20 | { 21 | timer->end_time = (struct timeval){0, 0}; 22 | } 23 | 24 | char TimerIsExpired(Timer* timer) 25 | { 26 | struct timeval now, res; 27 | gettimeofday(&now, NULL); 28 | timersub(&timer->end_time, &now, &res); 29 | return res.tv_sec < 0 || (res.tv_sec == 0 && res.tv_usec <= 0); 30 | } 31 | 32 | 33 | void TimerCountdownMS(Timer* timer, unsigned int timeout) 34 | { 35 | struct timeval now; 36 | gettimeofday(&now, NULL); 37 | struct timeval interval = {timeout / 1000, (timeout % 1000) * 1000}; 38 | timeradd(&now, &interval, &timer->end_time); 39 | } 40 | 41 | 42 | void TimerCountdown(Timer* timer, unsigned int timeout) 43 | { 44 | struct timeval now; 45 | gettimeofday(&now, NULL); 46 | struct timeval interval = {timeout, 0}; 47 | timeradd(&now, &interval, &timer->end_time); 48 | } 49 | 50 | 51 | int TimerLeftMS(Timer* timer) 52 | { 53 | struct timeval now, res; 54 | gettimeofday(&now, NULL); 55 | timersub(&timer->end_time, &now, &res); 56 | //printf("left %d ms\n", (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000); 57 | return (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000; 58 | } 59 | 60 | 61 | int linux_read(Network* n, unsigned char* buffer, int len, int timeout_ms) 62 | { 63 | struct timeval interval = {timeout_ms / 1000, (timeout_ms % 1000) * 1000}; 64 | if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 0)) 65 | { 66 | interval.tv_sec = 0; 67 | interval.tv_usec = 100; 68 | } 69 | 70 | setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&interval, sizeof(struct timeval)); 71 | 72 | int bytes = 0; 73 | while (bytes < len) 74 | { 75 | int rc = recv(n->my_socket, &buffer[bytes], (size_t)(len - bytes), 0); 76 | if (rc == -1) 77 | { 78 | if (errno != ENOTCONN && errno != ECONNRESET) 79 | { 80 | bytes = -1; 81 | break; 82 | } 83 | } 84 | else 85 | bytes += rc; 86 | } 87 | return bytes; 88 | } 89 | 90 | 91 | int linux_write(Network* n, unsigned char* buffer, int len, int timeout_ms) 92 | { 93 | struct timeval tv; 94 | 95 | tv.tv_sec = 0; /* 30 Secs Timeout */ 96 | tv.tv_usec = timeout_ms * 1000; // Not init'ing this can cause strange errors 97 | 98 | setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); 99 | int rc = write(n->my_socket, buffer, len); 100 | return rc; 101 | } 102 | 103 | 104 | void NetworkInit(Network* n) 105 | { 106 | n->my_socket = 0; 107 | n->mqttread = linux_read; 108 | n->mqttwrite = linux_write; 109 | } 110 | 111 | 112 | int NetworkConnect(Network* n, char* addr, int port) 113 | { 114 | int type = SOCK_STREAM; 115 | struct sockaddr_in address; 116 | int rc = -1; 117 | sa_family_t family = AF_INET; 118 | struct addrinfo *result = NULL; 119 | struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL}; 120 | 121 | if ((rc = getaddrinfo(addr, NULL, &hints, &result)) == 0) 122 | { 123 | struct addrinfo* res = result; 124 | 125 | /* prefer ip4 addresses */ 126 | while (res) 127 | { 128 | if (res->ai_family == AF_INET) 129 | { 130 | result = res; 131 | break; 132 | } 133 | res = res->ai_next; 134 | } 135 | 136 | if (result->ai_family == AF_INET) 137 | { 138 | address.sin_port = htons(port); 139 | address.sin_family = family = AF_INET; 140 | address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr; 141 | } 142 | else 143 | rc = -1; 144 | 145 | freeaddrinfo(result); 146 | } 147 | 148 | if (rc == 0) 149 | { 150 | n->my_socket = socket(family, type, 0); 151 | if (n->my_socket != -1) 152 | rc = connect(n->my_socket, (struct sockaddr*)&address, sizeof(address)); 153 | } 154 | 155 | return rc; 156 | } 157 | 158 | 159 | void NetworkDisconnect(Network* n) 160 | { 161 | close(n->my_socket); 162 | } 163 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/src/linux/MQTTLinux.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Allan Stockdill-Mander - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #if !defined(__MQTT_LINUX_) 18 | #define __MQTT_LINUX_ 19 | 20 | #if defined(WIN32_DLL) || defined(WIN64_DLL) 21 | #define DLLImport __declspec(dllimport) 22 | #define DLLExport __declspec(dllexport) 23 | #elif defined(LINUX_SO) 24 | #define DLLImport extern 25 | #define DLLExport __attribute__ ((visibility ("default"))) 26 | #else 27 | #define DLLImport 28 | #define DLLExport 29 | #endif 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include 46 | #include 47 | #include 48 | 49 | typedef struct Timer 50 | { 51 | struct timeval end_time; 52 | } Timer; 53 | 54 | void TimerInit(Timer*); 55 | char TimerIsExpired(Timer*); 56 | void TimerCountdownMS(Timer*, unsigned int); 57 | void TimerCountdown(Timer*, unsigned int); 58 | int TimerLeftMS(Timer*); 59 | 60 | typedef struct Network 61 | { 62 | int my_socket; 63 | int (*mqttread) (struct Network*, unsigned char*, int, int); 64 | int (*mqttwrite) (struct Network*, unsigned char*, int, int); 65 | } Network; 66 | 67 | int linux_read(Network*, unsigned char*, int, int); 68 | int linux_write(Network*, unsigned char*, int, int); 69 | 70 | DLLExport void NetworkInit(Network*); 71 | DLLExport int NetworkConnect(Network*, char*, int); 72 | DLLExport void NetworkDisconnect(Network*); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient-C/src/samples/FreeRTOS/MQTTEcho.c: -------------------------------------------------------------------------------- 1 | /* Standard includes. */ 2 | #include 3 | #include 4 | #include 5 | 6 | /* FreeRTOS includes. */ 7 | #include "FreeRTOS.h" 8 | #include "task.h" 9 | #include "queue.h" 10 | 11 | /* FreeRTOS+TCP includes. */ 12 | #include "FreeRTOS_IP.h" 13 | #include "FreeRTOS_Sockets.h" 14 | 15 | #define MQTT_TASK 1 16 | #include "MQTTClient.h" 17 | 18 | 19 | void messageArrived(MessageData* data) 20 | { 21 | printf("Message arrived on topic %.*s: %.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data, 22 | data->message->payloadlen, data->message->payload); 23 | } 24 | 25 | static void prvMQTTEchoTask(void *pvParameters) 26 | { 27 | /* connect to m2m.eclipse.org, subscribe to a topic, send and receive messages regularly every 1 sec */ 28 | MQTTClient client; 29 | Network network; 30 | unsigned char sendbuf[80], readbuf[80]; 31 | int rc = 0, 32 | count = 0; 33 | MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer; 34 | 35 | pvParameters = 0; 36 | NetworkInit(&network); 37 | MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf)); 38 | 39 | char* address = "iot.eclipse.org"; 40 | if ((rc = NetworkConnect(&network, address, 1883)) != 0) 41 | printf("Return code from network connect is %d\n", rc); 42 | 43 | #if defined(MQTT_TASK) 44 | if ((rc = MQTTStartTask(&client)) != pdPASS) 45 | printf("Return code from start tasks is %d\n", rc); 46 | #endif 47 | 48 | connectData.MQTTVersion = 3; 49 | connectData.clientID.cstring = "FreeRTOS_sample"; 50 | 51 | if ((rc = MQTTConnect(&client, &connectData)) != 0) 52 | printf("Return code from MQTT connect is %d\n", rc); 53 | else 54 | printf("MQTT Connected\n"); 55 | 56 | if ((rc = MQTTSubscribe(&client, "FreeRTOS/sample/#", 2, messageArrived)) != 0) 57 | printf("Return code from MQTT subscribe is %d\n", rc); 58 | 59 | while (++count) 60 | { 61 | MQTTMessage message; 62 | char payload[30]; 63 | 64 | message.qos = 1; 65 | message.retained = 0; 66 | message.payload = payload; 67 | sprintf(payload, "message number %d", count); 68 | message.payloadlen = strlen(payload); 69 | 70 | if ((rc = MQTTPublish(&client, "FreeRTOS/sample/a", &message)) != 0) 71 | printf("Return code from MQTT publish is %d\n", rc); 72 | #if !defined(MQTT_TASK) 73 | if ((rc = MQTTYield(&client, 1000)) != 0) 74 | printf("Return code from yield is %d\n", rc); 75 | #endif 76 | } 77 | 78 | /* do not return */ 79 | } 80 | 81 | 82 | void vStartMQTTTasks(uint16_t usTaskStackSize, UBaseType_t uxTaskPriority) 83 | { 84 | BaseType_t x = 0L; 85 | 86 | xTaskCreate(prvMQTTEchoTask, /* The function that implements the task. */ 87 | "MQTTEcho0", /* Just a text name for the task to aid debugging. */ 88 | usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */ 89 | (void *)x, /* The task parameter, not used in this case. */ 90 | uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */ 91 | NULL); /* The task handle is not used. */ 92 | } 93 | /*-----------------------------------------------------------*/ 94 | 95 | 96 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | #add_subdirectory(src/linux) 4 | add_subdirectory(src/linux) 5 | 6 | add_subdirectory(samples/linux) -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/samples/arduino/Hello/Hello.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. and others 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial contribution 15 | * Benjamin Cabe - adapt to IPStack, and add Yun instructions 16 | *******************************************************************************/ 17 | 18 | #define MQTTCLIENT_QOS2 1 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | char printbuf[100]; 27 | 28 | int arrivedcount = 0; 29 | 30 | void messageArrived(MQTT::MessageData& md) 31 | { 32 | MQTT::Message &message = md.message; 33 | 34 | sprintf(printbuf, "Message %d arrived: qos %d, retained %d, dup %d, packetid %d\n", 35 | ++arrivedcount, message.qos, message.retained, message.dup, message.id); 36 | Serial.print(printbuf); 37 | sprintf(printbuf, "Payload %s\n", (char*)message.payload); 38 | Serial.print(printbuf); 39 | } 40 | 41 | EthernetClient c; // replace by a YunClient if running on a Yun 42 | IPStack ipstack(c); 43 | MQTT::Client client = MQTT::Client(ipstack); 44 | 45 | byte mac[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; // replace with your device's MAC 46 | const char* topic = "linux-sample"; 47 | 48 | void connect() 49 | { 50 | char hostname[] = "iot.eclipse.org"; 51 | int port = 1883; 52 | sprintf(printbuf, "Connecting to %s:%d\n", hostname, port); 53 | Serial.print(printbuf); 54 | int rc = ipstack.connect(hostname, port); 55 | if (rc != 1) 56 | { 57 | sprintf(printbuf, "rc from TCP connect is %d\n", rc); 58 | Serial.print(printbuf); 59 | } 60 | 61 | Serial.println("MQTT connecting"); 62 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 63 | data.MQTTVersion = 3; 64 | data.clientID.cstring = (char*)"linux-sample"; 65 | rc = client.connect(data); 66 | if (rc != 0) 67 | { 68 | sprintf(printbuf, "rc from MQTT connect is %d\n", rc); 69 | Serial.print(printbuf); 70 | } 71 | Serial.println("MQTT connected"); 72 | 73 | rc = client.subscribe(topic, MQTT::QOS2, messageArrived); 74 | if (rc != 0) 75 | { 76 | sprintf(printbuf, "rc from MQTT subscribe is %d\n", rc); 77 | Serial.print(printbuf); 78 | } 79 | Serial.println("MQTT subscribed"); 80 | } 81 | 82 | void setup() 83 | { 84 | Serial.begin(9600); 85 | Ethernet.begin(mac); // replace by Bridge.begin() if running on a Yun 86 | Serial.println("MQTT Hello example"); 87 | connect(); 88 | } 89 | 90 | void loop() 91 | { 92 | if (!client.isConnected()) 93 | connect(); 94 | 95 | MQTT::Message message; 96 | 97 | arrivedcount = 0; 98 | 99 | // Send and receive QoS 0 message 100 | char buf[100]; 101 | sprintf(buf, "Hello World! QoS 0 message"); 102 | Serial.println(buf); 103 | message.qos = MQTT::QOS0; 104 | message.retained = false; 105 | message.dup = false; 106 | message.payload = (void*)buf; 107 | message.payloadlen = strlen(buf)+1; 108 | int rc = client.publish(topic, message); 109 | while (arrivedcount == 0) 110 | client.yield(1000); 111 | 112 | // Send and receive QoS 1 message 113 | sprintf(buf, "Hello World! QoS 1 message"); 114 | Serial.println(buf); 115 | message.qos = MQTT::QOS1; 116 | message.payloadlen = strlen(buf)+1; 117 | rc = client.publish(topic, message); 118 | while (arrivedcount == 1) 119 | client.yield(1000); 120 | 121 | // Send and receive QoS 2 message 122 | sprintf(buf, "Hello World! QoS 2 message"); 123 | Serial.println(buf); 124 | message.qos = MQTT::QOS2; 125 | message.payloadlen = strlen(buf)+1; 126 | rc = client.publish(topic, message); 127 | while (arrivedcount == 2) 128 | client.yield(1000); 129 | 130 | delay(2000); 131 | } 132 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/samples/linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCE_FILES hello.cpp) 2 | set(INCLUDE_DIRECTORIES ../../src ../../src/linux ../../../MQTTPacket/src) 3 | include_directories(${INCLUDE_DIRECTORIES}) 4 | 5 | add_executable(runPahoLinuxMqttClient_Hello ${SOURCE_FILES}) 6 | target_link_libraries(runPahoLinuxMqttClient_Hello MQTTPacket LinuxMqttClient) -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/samples/linux/build.sh: -------------------------------------------------------------------------------- 1 | g++ hello.cpp -I ../../src/ -I ../../src/linux -I ../../../MQTTPacket/src ../../../MQTTPacket/src/MQTTPacket.c ../../../MQTTPacket/src/MQTTDeserializePublish.c ../../../MQTTPacket/src/MQTTConnectClient.c ../../../MQTTPacket/src/MQTTSubscribeClient.c ../../../MQTTPacket/src/MQTTSerializePublish.c ../../../MQTTPacket/src/MQTTUnsubscribeClient.c -o hello 2 | 3 | g++ -g stdoutsub.cpp -I ../../src -I ../../src/linux -I ../../../MQTTPacket/src ../../../MQTTPacket/src/MQTTFormat.c ../../../MQTTPacket/src/MQTTPacket.c ../../../MQTTPacket/src/MQTTDeserializePublish.c ../../../MQTTPacket/src/MQTTConnectClient.c ../../../MQTTPacket/src/MQTTSubscribeClient.c ../../../MQTTPacket/src/MQTTSerializePublish.c -o stdoutsub ../../../MQTTPacket/src/MQTTConnectServer.c ../../../MQTTPacket/src/MQTTSubscribeServer.c ../../../MQTTPacket/src/MQTTUnsubscribeServer.c ../../../MQTTPacket/src/MQTTUnsubscribeClient.c 4 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/samples/linux/hello: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3ler/arduino-mqtt-sn-gateway/e5d1d7778945387e80e14fdc4a7e3cc1fe45c5c7/src/Implementation/paho/pahomqttembeddedc/MQTTClient/samples/linux/hello -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/samples/linux/hello.cpp: -------------------------------------------------------------------------------- 1 | #define MQTTCLIENT_QOS2 1 2 | 3 | #include 4 | 5 | #define DEFAULT_STACK_SIZE -1 6 | 7 | #include "linux.cpp" 8 | 9 | int arrivedcount = 0; 10 | 11 | void messageArrived(MQTT::MessageData& md) 12 | { 13 | MQTT::Message &message = md.message; 14 | 15 | printf("Message %d arrived: qos %d, retained %d, dup %d, packetid %d\n", 16 | ++arrivedcount, message.qos, message.retained, message.dup, message.id); 17 | printf("Payload %.*s\n", (int) message.payloadlen, (char*)message.payload); 18 | } 19 | 20 | 21 | int main(int argc, char* argv[]) 22 | { 23 | IPStack ipstack = IPStack(); 24 | float version = 0.3; 25 | const char* topic = "mbed-sample"; 26 | 27 | printf("Version is %f\n", version); 28 | 29 | MQTT::Client client = MQTT::Client(ipstack); 30 | 31 | const char* hostname = "iot.eclipse.org"; 32 | int port = 1883; 33 | printf("Connecting to %s:%d\n", hostname, port); 34 | int rc = ipstack.connect(hostname, port); 35 | if (rc != 0) 36 | printf("rc from TCP connect is %d\n", rc); 37 | 38 | printf("MQTT connecting\n"); 39 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 40 | data.MQTTVersion = 3; 41 | data.clientID.cstring = (char*)"mbed-icraggs"; 42 | rc = client.connect(data); 43 | if (rc != 0) 44 | printf("rc from MQTT connect is %d\n", rc); 45 | printf("MQTT connected\n"); 46 | 47 | rc = client.subscribe(topic, MQTT::QOS2, messageArrived); 48 | if (rc != 0) 49 | printf("rc from MQTT subscribe is %d\n", rc); 50 | 51 | MQTT::Message message; 52 | 53 | // QoS 0 54 | char buf[100]; 55 | sprintf(buf, "Hello World! QoS 0 message from app version %f", version); 56 | message.qos = MQTT::QOS0; 57 | message.retained = false; 58 | message.dup = false; 59 | message.payload = (void*)buf; 60 | message.payloadlen = strlen(buf)+1; 61 | rc = client.publish(topic, message); 62 | if (rc != 0) 63 | printf("Error %d from sending QoS 0 message\n", rc); 64 | else while (arrivedcount == 0) 65 | client.yield(100); 66 | 67 | // QoS 1 68 | printf("Now QoS 1\n"); 69 | sprintf(buf, "Hello World! QoS 1 message from app version %f", version); 70 | message.qos = MQTT::QOS1; 71 | message.payloadlen = strlen(buf)+1; 72 | rc = client.publish(topic, message); 73 | if (rc != 0) 74 | printf("Error %d from sending QoS 1 message\n", rc); 75 | else while (arrivedcount == 1) 76 | client.yield(100); 77 | 78 | // QoS 2 79 | sprintf(buf, "Hello World! QoS 2 message from app version %f", version); 80 | message.qos = MQTT::QOS2; 81 | message.payloadlen = strlen(buf)+1; 82 | rc = client.publish(topic, message); 83 | if (rc != 0) 84 | printf("Error %d from sending QoS 2 message\n", rc); 85 | while (arrivedcount == 2) 86 | client.yield(100); 87 | 88 | rc = client.unsubscribe(topic); 89 | if (rc != 0) 90 | printf("rc from unsubscribe was %d\n", rc); 91 | 92 | rc = client.disconnect(); 93 | if (rc != 0) 94 | printf("rc from disconnect was %d\n", rc); 95 | 96 | ipstack.disconnect(); 97 | 98 | printf("Finishing with %d messages received\n", arrivedcount); 99 | 100 | return 0; 101 | } 102 | 103 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/samples/linux/stdoutsub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/S3ler/arduino-mqtt-sn-gateway/e5d1d7778945387e80e14fdc4a7e3cc1fe45c5c7/src/Implementation/paho/pahomqttembeddedc/MQTTClient/samples/linux/stdoutsub -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/FP.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2013, 2014 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Sam Grove - initial API and implementation and/or initial documentation 15 | * Ian Craggs - added attached and detached member functions 16 | * Sam Grove - removed need for FP.cpp 17 | *******************************************************************************/ 18 | 19 | #ifndef FP_H 20 | #define FP_H 21 | 22 | /** Example using the FP Class with global functions 23 | * @code 24 | * #include "mbed.h" 25 | * #include "FP.h" 26 | * 27 | * FPfp; 28 | * DigitalOut myled(LED1); 29 | * 30 | * void handler(bool value) 31 | * { 32 | * myled = value; 33 | * return; 34 | * } 35 | * 36 | * int main() 37 | * { 38 | * fp.attach(&handler); 39 | * 40 | * while(1) 41 | * { 42 | * fp(1); 43 | * wait(0.2); 44 | * fp(0); 45 | * wait(0.2); 46 | * } 47 | * } 48 | * @endcode 49 | */ 50 | 51 | /** Example using the FP Class with different class member functions 52 | * @code 53 | * #include "mbed.h" 54 | * #include "FP.h" 55 | * 56 | * FPfp; 57 | * DigitalOut myled(LED4); 58 | * 59 | * class Wrapper 60 | * { 61 | * public: 62 | * Wrapper(){} 63 | * 64 | * void handler(bool value) 65 | * { 66 | * myled = value; 67 | * return; 68 | * } 69 | * }; 70 | * 71 | * int main() 72 | * { 73 | * Wrapper wrapped; 74 | * fp.attach(&wrapped, &Wrapper::handler); 75 | * 76 | * while(1) 77 | * { 78 | * fp(1); 79 | * wait(0.2); 80 | * fp(0); 81 | * wait(0.2); 82 | * } 83 | * } 84 | * @endcode 85 | */ 86 | 87 | /** Example using the FP Class with member FP and member function 88 | * @code 89 | * #include "mbed.h" 90 | * #include "FP.h" 91 | * 92 | * DigitalOut myled(LED2); 93 | * 94 | * class Wrapper 95 | * { 96 | * public: 97 | * Wrapper() 98 | * { 99 | * fp.attach(this, &Wrapper::handler); 100 | * } 101 | * 102 | * void handler(bool value) 103 | * { 104 | * myled = value; 105 | * return; 106 | * } 107 | * 108 | * FPfp; 109 | * }; 110 | * 111 | * int main() 112 | * { 113 | * Wrapper wrapped; 114 | * 115 | * while(1) 116 | * { 117 | * wrapped.fp(1); 118 | * wait(0.2); 119 | * wrapped.fp(0); 120 | * wait(0.2); 121 | * } 122 | * } 123 | * @endcode 124 | */ 125 | 126 | /** 127 | * @class FP 128 | * @brief API for managing Function Pointers 129 | */ 130 | template 131 | class FP 132 | { 133 | public: 134 | /** Create the FP object - only one callback can be attached to the object, that is 135 | * a member function or a global function, not both at the same time 136 | */ 137 | FP() 138 | { 139 | obj_callback = 0; 140 | c_callback = 0; 141 | } 142 | 143 | /** Add a callback function to the object 144 | * @param item - Address of the initialized object 145 | * @param member - Address of the member function (dont forget the scope that the function is defined in) 146 | */ 147 | template 148 | void attach(T *item, retT (T::*method)(argT)) 149 | { 150 | obj_callback = (FPtrDummy *)(item); 151 | method_callback = (retT (FPtrDummy::*)(argT))(method); 152 | return; 153 | } 154 | 155 | /** Add a callback function to the object 156 | * @param function - The address of a globally defined function 157 | */ 158 | void attach(retT (*function)(argT)) 159 | { 160 | c_callback = function; 161 | } 162 | 163 | /** Invoke the function attached to the class 164 | * @param arg - An argument that is passed into the function handler that is called 165 | * @return The return from the function hanlder called by this class 166 | */ 167 | retT operator()(argT arg) const 168 | { 169 | if( 0 != c_callback ) { 170 | return obj_callback ? (obj_callback->*method_callback)(arg) : (*c_callback)(arg); 171 | } 172 | return (retT)0; 173 | } 174 | 175 | /** Determine if an callback is currently hooked 176 | * @return 1 if a method is hooked, 0 otherwise 177 | */ 178 | bool attached() 179 | { 180 | return obj_callback || c_callback; 181 | } 182 | 183 | /** Release a function from the callback hook 184 | */ 185 | void detach() 186 | { 187 | obj_callback = 0; 188 | c_callback = 0; 189 | } 190 | 191 | private: 192 | 193 | // empty type used for casting 194 | class FPtrDummy; 195 | 196 | FPtrDummy *obj_callback; 197 | 198 | /** 199 | * @union Funciton 200 | * @brief Member or global callback function 201 | */ 202 | union { 203 | retT (*c_callback)(argT); /*!< Footprint for a global function */ 204 | retT (FPtrDummy::*method_callback)(argT); /*!< Footprint for a member function */ 205 | }; 206 | }; 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/MQTTLogging.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #if !defined(MQTT_LOGGING_H) 18 | #define MQTT_LOGGING_H 19 | 20 | #define STREAM stdout 21 | #if !defined(DEBUG) 22 | #define DEBUG(...) \ 23 | {\ 24 | fprintf(STREAM, "DEBUG: %s L#%d ", __PRETTY_FUNCTION__, __LINE__); \ 25 | fprintf(STREAM, ##__VA_ARGS__); \ 26 | fflush(STREAM); \ 27 | } 28 | #endif 29 | #if !defined(LOG) 30 | #define LOG(...) \ 31 | {\ 32 | fprintf(STREAM, "LOG: %s L#%d ", __PRETTY_FUNCTION__, __LINE__); \ 33 | fprintf(STREAM, ##__VA_ARGS__); \ 34 | fflush(STREAM); \ 35 | } 36 | #endif 37 | #if !defined(WARN) 38 | #define WARN(...) \ 39 | { \ 40 | fprintf(STREAM, "WARN: %s L#%d ", __PRETTY_FUNCTION__, __LINE__); \ 41 | fprintf(STREAM, ##__VA_ARGS__); \ 42 | fflush(STREAM); \ 43 | } 44 | #endif 45 | #if !defined(ERROR) 46 | #define ERROR(...) \ 47 | { \ 48 | fprintf(STREAM, "ERROR: %s L#%d ", __PRETTY_FUNCTION__, __LINE__); \ 49 | fprintf(STREAM, ##__VA_ARGS__); \ 50 | fflush(STREAM); \ 51 | exit(1); \ 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/arduino/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(SOURCE_FILES Countdown.h IPStack.h WifiIPStack.h) 3 | add_library(ArduinoMqttClient ${SOURCE_FILES}) -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/arduino/Countdown.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #if !defined(COUNTDOWN_H) 18 | #define COUNTDOWN_H 19 | 20 | class Countdown 21 | { 22 | public: 23 | Countdown() 24 | { 25 | interval_end_ms = 0L; 26 | } 27 | 28 | Countdown(int ms) 29 | { 30 | countdown_ms(ms); 31 | } 32 | 33 | bool expired() 34 | { 35 | return (interval_end_ms > 0L) && (millis() >= interval_end_ms); 36 | } 37 | 38 | void countdown_ms(unsigned long ms) 39 | { 40 | interval_end_ms = millis() + ms; 41 | } 42 | 43 | void countdown(int seconds) 44 | { 45 | countdown_ms((unsigned long)seconds * 1000L); 46 | } 47 | 48 | int left_ms() 49 | { 50 | return interval_end_ms - millis(); 51 | } 52 | 53 | private: 54 | unsigned long interval_end_ms; 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/arduino/IPStack.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Benjamin Cabe - generic IPStack 16 | *******************************************************************************/ 17 | 18 | #if !defined(IPSTACK_H) 19 | #define IPSTACK_H 20 | 21 | #include 22 | 23 | #include 24 | 25 | class IPStack 26 | { 27 | public: 28 | IPStack(Client& client) : client(&client) 29 | { 30 | 31 | } 32 | 33 | int connect(char* hostname, int port) 34 | { 35 | return client->connect(hostname, port); 36 | } 37 | 38 | int connect(uint32_t hostname, int port) 39 | { 40 | return client->connect(hostname, port); 41 | } 42 | 43 | int read(unsigned char* buffer, int len, int timeout) 44 | { 45 | int interval = 10; // all times are in milliseconds 46 | int total = 0, rc = -1; 47 | 48 | if (timeout < 30) 49 | interval = 2; 50 | while (client->available() < len && total < timeout) 51 | { 52 | delay(interval); 53 | total += interval; 54 | } 55 | if (client->available() >= len) 56 | rc = client->readBytes((char*)buffer, len); 57 | return rc; 58 | } 59 | 60 | int write(unsigned char* buffer, int len, int timeout) 61 | { 62 | client->setTimeout(timeout); 63 | return client->write((uint8_t*)buffer, len); 64 | } 65 | 66 | int disconnect() 67 | { 68 | client->stop(); 69 | return 0; 70 | } 71 | 72 | private: 73 | 74 | Client* client; 75 | }; 76 | 77 | #endif 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/arduino/WifiIPStack.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #ifndef ARDUINOWIFIIPSTACK_H 18 | #define ARDUINOWIFIIPSTACK_H 19 | 20 | #include 21 | 22 | class WifiIPStack 23 | { 24 | public: 25 | WifiIPStack() 26 | { 27 | //WiFi.begin(); // Use DHCP 28 | iface.setTimeout(1000); // 1 second Timeout 29 | } 30 | 31 | int connect(char* hostname, int port) 32 | { 33 | return iface.connect(hostname, port); 34 | } 35 | 36 | int connect(uint32_t hostname, int port) 37 | { 38 | return iface.connect(hostname, port); 39 | } 40 | 41 | int read(char* buffer, int len, int timeout) 42 | { 43 | iface.setTimeout(timeout); 44 | while(!iface.available()); 45 | return iface.readBytes(buffer, len); 46 | } 47 | 48 | int write(char* buffer, int len, int timeout) 49 | { 50 | iface.setTimeout(timeout); 51 | return iface.write((uint8_t*)buffer, len); 52 | } 53 | 54 | int disconnect() 55 | { 56 | iface.stop(); 57 | return 0; 58 | } 59 | 60 | private: 61 | 62 | WiFiClient iface; 63 | 64 | }; 65 | 66 | #endif 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include_directories(..) 3 | set(SOURCE_FILES linux.cpp ../MQTTClient.h ../MQTTLogging.h ../FP.h) 4 | add_library(LinuxMqttClient ${SOURCE_FILES}) -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/linux/linux.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | 36 | class IPStack 37 | { 38 | public: 39 | IPStack() 40 | { 41 | 42 | } 43 | 44 | int Socket_error(const char* aString) 45 | { 46 | int rc = 0; 47 | //if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && errno != EWOULDBLOCK) 48 | //{ 49 | if (strcmp(aString, "shutdown") != 0 || (errno != ENOTCONN && errno != ECONNRESET)) 50 | { 51 | // printf("Socket error %s in %s for socket %d\n", strerror(errno), aString, mysock); 52 | rc = errno; 53 | } 54 | //} 55 | return errno; 56 | } 57 | 58 | int connect(uint32_t ip, int port) 59 | { 60 | int type = SOCK_STREAM; 61 | struct sockaddr_in address; 62 | int rc = 0; 63 | sa_family_t family = AF_INET; 64 | 65 | 66 | address.sin_port = htons(port); 67 | address.sin_family = family; 68 | address.sin_addr.s_addr = htonl(ip); 69 | 70 | if (rc == 0) 71 | { 72 | mysock = socket(family, type, 0); 73 | if (mysock != -1) 74 | { 75 | int opt = 1; 76 | rc = ::connect(mysock, (struct sockaddr*)&address, sizeof(address)); 77 | } 78 | } 79 | 80 | return rc; 81 | } 82 | 83 | int connect(const char* hostname, int port) 84 | { 85 | int type = SOCK_STREAM; 86 | struct sockaddr_in address; 87 | int rc = -1; 88 | sa_family_t family = AF_INET; 89 | struct addrinfo *result = NULL; 90 | struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL}; 91 | 92 | if ((rc = getaddrinfo(hostname, NULL, &hints, &result)) == 0) 93 | { 94 | struct addrinfo* res = result; 95 | 96 | /* prefer ip4 addresses */ 97 | while (res) 98 | { 99 | if (res->ai_family == AF_INET) 100 | { 101 | result = res; 102 | break; 103 | } 104 | res = res->ai_next; 105 | } 106 | 107 | if (result->ai_family == AF_INET) 108 | { 109 | address.sin_port = htons(port); 110 | address.sin_family = family = AF_INET; 111 | address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr; 112 | } 113 | else 114 | rc = -1; 115 | 116 | freeaddrinfo(result); 117 | } 118 | 119 | if (rc == 0) 120 | { 121 | mysock = socket(family, type, 0); 122 | if (mysock != -1) 123 | { 124 | int opt = 1; 125 | 126 | //if (setsockopt(mysock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt)) != 0) 127 | // printf("Could not set SO_NOSIGPIPE for socket %d", mysock); 128 | 129 | rc = ::connect(mysock, (struct sockaddr*)&address, sizeof(address)); 130 | } 131 | } 132 | 133 | return rc; 134 | } 135 | 136 | int read(unsigned char* buffer, int len, int timeout_ms) 137 | { 138 | struct timeval interval = {timeout_ms / 1000, (timeout_ms % 1000) * 1000}; 139 | if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 0)) 140 | { 141 | interval.tv_sec = 0; 142 | interval.tv_usec = 100; 143 | } 144 | 145 | setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO, (char *)&interval, sizeof(struct timeval)); 146 | 147 | int bytes = 0; 148 | while (bytes < len) 149 | { 150 | int rc = ::recv(mysock, &buffer[bytes], (size_t)(len - bytes), 0); 151 | if (rc == -1) 152 | { 153 | if (Socket_error("read") != 0) 154 | { 155 | bytes = -1; 156 | break; 157 | } 158 | } 159 | else 160 | bytes += rc; 161 | } 162 | return bytes; 163 | } 164 | 165 | int write(unsigned char* buffer, int len, int timeout) 166 | { 167 | struct timeval tv; 168 | 169 | tv.tv_sec = 0; /* 30 Secs Timeout */ 170 | tv.tv_usec = timeout * 1000; // Not init'ing this can cause strange errors 171 | 172 | setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); 173 | int rc = ::write(mysock, buffer, len); 174 | //printf("write rc %d\n", rc); 175 | return rc; 176 | } 177 | 178 | int disconnect() 179 | { 180 | return ::close(mysock); 181 | } 182 | 183 | private: 184 | 185 | int mysock; 186 | 187 | }; 188 | 189 | 190 | class Countdown 191 | { 192 | public: 193 | Countdown() 194 | { 195 | 196 | } 197 | 198 | Countdown(int ms) 199 | { 200 | countdown_ms(ms); 201 | } 202 | 203 | 204 | bool expired() 205 | { 206 | struct timeval now, res; 207 | gettimeofday(&now, NULL); 208 | timersub(&end_time, &now, &res); 209 | //printf("left %d ms\n", (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000); 210 | //if (res.tv_sec > 0 || res.tv_usec > 0) 211 | // printf("expired %d %d\n", res.tv_sec, res.tv_usec); 212 | return res.tv_sec < 0 || (res.tv_sec == 0 && res.tv_usec <= 0); 213 | } 214 | 215 | 216 | void countdown_ms(int ms) 217 | { 218 | struct timeval now; 219 | gettimeofday(&now, NULL); 220 | struct timeval interval = {ms / 1000, (ms % 1000) * 1000}; 221 | //printf("interval %d %d\n", interval.tv_sec, interval.tv_usec); 222 | timeradd(&now, &interval, &end_time); 223 | } 224 | 225 | 226 | void countdown(int seconds) 227 | { 228 | struct timeval now; 229 | gettimeofday(&now, NULL); 230 | struct timeval interval = {seconds, 0}; 231 | timeradd(&now, &interval, &end_time); 232 | } 233 | 234 | 235 | int left_ms() 236 | { 237 | struct timeval now, res; 238 | gettimeofday(&now, NULL); 239 | timersub(&end_time, &now, &res); 240 | //printf("left %d ms\n", (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000); 241 | return (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000; 242 | } 243 | 244 | private: 245 | 246 | struct timeval end_time; 247 | }; 248 | 249 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/mbed/MQTTEthernet.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #if !defined(MQTTETHERNET_H) 18 | #define MQTTETHERNET_H 19 | 20 | #include "MQTT_mbed.h" 21 | #include "EthernetInterface.h" 22 | #include "MQTTSocket.h" 23 | 24 | class MQTTEthernet : public MQTTSocket 25 | { 26 | public: 27 | MQTTEthernet() 28 | { 29 | eth.init(); // Use DHCP 30 | eth.connect(); 31 | } 32 | 33 | private: 34 | 35 | EthernetInterface eth; 36 | 37 | }; 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTClient/src/mbed/MQTTSocket.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #if !defined(MQTTSOCKET_H) 18 | #define MQTTSOCKET_H 19 | 20 | #include "MQTT_mbed.h" 21 | #include "TCPSocketConnection.h" 22 | 23 | class MQTTSocket 24 | { 25 | public: 26 | int connect(char* hostname, int port, int timeout=1000) 27 | { 28 | mysock.set_blocking(false, timeout); // 1 second Timeout 29 | return mysock.connect(hostname, port); 30 | } 31 | 32 | int read(unsigned char* buffer, int len, int timeout) 33 | { 34 | mysock.set_blocking(false, timeout); 35 | return mysock.receive((char*)buffer, len); 36 | } 37 | 38 | int write(unsigned char* buffer, int len, int timeout) 39 | { 40 | mysock.set_blocking(false, timeout); 41 | return mysock.send((char*)buffer, len); 42 | } 43 | 44 | int disconnect() 45 | { 46 | return mysock.close(); 47 | } 48 | 49 | private: 50 | 51 | TCPSocketConnection mysock; 52 | 53 | }; 54 | 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(SOURCE_FILES 3 | src/MQTTConnect.h 4 | src/MQTTConnectClient.c 5 | src/MQTTConnectServer.c 6 | src/MQTTDeserializePublish.c 7 | src/MQTTFormat.c 8 | src/MQTTFormat.h 9 | src/MQTTPacket.c 10 | src/MQTTPacket.h 11 | src/MQTTPublish.h 12 | src/MQTTSerializePublish.c 13 | src/MQTTSubscribe.h 14 | src/MQTTSubscribeClient.c 15 | src/MQTTSubscribeServer.c 16 | src/MQTTUnsubscribe.h 17 | src/MQTTUnsubscribeClient.c 18 | src/MQTTUnsubscribeServer.c 19 | src/StackTrace.h 20 | ) 21 | 22 | add_library(MQTTPacket ${SOURCE_FILES}) -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/samples/build: -------------------------------------------------------------------------------- 1 | gcc -Wall -c transport.c -Os -s 2 | gcc qos0pub.c transport.o -I ../src ../src/MQTTConnectClient.c ../src/MQTTSerializePublish.c ../src/MQTTPacket.c -o qos0pub -Os -s 3 | 4 | gcc pub0sub1.c transport.o -I ../src ../src/MQTTConnectClient.c ../src/MQTTSerializePublish.c ../src/MQTTPacket.c ../src/MQTTSubscribeClient.c -o pub0sub1 ../src/MQTTDeserializePublish.c -Os -s ../src/MQTTConnectServer.c ../src/MQTTSubscribeServer.c ../src/MQTTUnsubscribeServer.c ../src/MQTTUnsubscribeClient.c -ggdb 5 | gcc pub0sub1_nb.c transport.o -I ../src ../src/MQTTConnectClient.c ../src/MQTTSerializePublish.c ../src/MQTTPacket.c ../src/MQTTSubscribeClient.c -o pub0sub1_nb ../src/MQTTDeserializePublish.c -Os -s ../src/MQTTConnectServer.c ../src/MQTTSubscribeServer.c ../src/MQTTUnsubscribeServer.c ../src/MQTTUnsubscribeClient.c -ggdb 6 | 7 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/samples/null.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char** argv) 2 | { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/samples/pub0sub1.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Sergio R. Caprile - clarifications and/or documentation extension 16 | *******************************************************************************/ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "MQTTPacket.h" 23 | #include "transport.h" 24 | 25 | /* This is in order to get an asynchronous signal to stop the sample, 26 | as the code loops waiting for msgs on the subscribed topic. 27 | Your actual code will depend on your hw and approach*/ 28 | #include 29 | 30 | int toStop = 0; 31 | 32 | void cfinish(int sig) 33 | { 34 | signal(SIGINT, NULL); 35 | toStop = 1; 36 | } 37 | 38 | void stop_init(void) 39 | { 40 | signal(SIGINT, cfinish); 41 | signal(SIGTERM, cfinish); 42 | } 43 | /* */ 44 | 45 | int main(int argc, char *argv[]) 46 | { 47 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 48 | int rc = 0; 49 | int mysock = 0; 50 | unsigned char buf[200]; 51 | int buflen = sizeof(buf); 52 | int msgid = 1; 53 | MQTTString topicString = MQTTString_initializer; 54 | int req_qos = 0; 55 | char* payload = "mypayload"; 56 | int payloadlen = strlen(payload); 57 | int len = 0; 58 | char *host = "m2m.eclipse.org"; 59 | int port = 1883; 60 | 61 | stop_init(); 62 | if (argc > 1) 63 | host = argv[1]; 64 | 65 | if (argc > 2) 66 | port = atoi(argv[2]); 67 | 68 | mysock = transport_open(host, port); 69 | if(mysock < 0) 70 | return mysock; 71 | 72 | printf("Sending to hostname %s port %d\n", host, port); 73 | 74 | data.clientID.cstring = "me"; 75 | data.keepAliveInterval = 20; 76 | data.cleansession = 1; 77 | data.username.cstring = "testuser"; 78 | data.password.cstring = "testpassword"; 79 | 80 | len = MQTTSerialize_connect(buf, buflen, &data); 81 | rc = transport_sendPacketBuffer(mysock, buf, len); 82 | 83 | /* wait for connack */ 84 | if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK) 85 | { 86 | unsigned char sessionPresent, connack_rc; 87 | 88 | if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0) 89 | { 90 | printf("Unable to connect, return code %d\n", connack_rc); 91 | goto exit; 92 | } 93 | } 94 | else 95 | goto exit; 96 | 97 | /* subscribe */ 98 | topicString.cstring = "substopic"; 99 | len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos); 100 | 101 | rc = transport_sendPacketBuffer(mysock, buf, len); 102 | if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK) /* wait for suback */ 103 | { 104 | unsigned short submsgid; 105 | int subcount; 106 | int granted_qos; 107 | 108 | rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen); 109 | if (granted_qos != 0) 110 | { 111 | printf("granted qos != 0, %d\n", granted_qos); 112 | goto exit; 113 | } 114 | } 115 | else 116 | goto exit; 117 | 118 | /* loop getting msgs on subscribed topic */ 119 | topicString.cstring = "pubtopic"; 120 | while (!toStop) 121 | { 122 | /* transport_getdata() has a built-in 1 second timeout, 123 | your mileage will vary */ 124 | if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH) 125 | { 126 | unsigned char dup; 127 | int qos; 128 | unsigned char retained; 129 | unsigned short msgid; 130 | int payloadlen_in; 131 | unsigned char* payload_in; 132 | int rc; 133 | MQTTString receivedTopic; 134 | 135 | rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic, 136 | &payload_in, &payloadlen_in, buf, buflen); 137 | printf("message arrived %.*s\n", payloadlen_in, payload_in); 138 | } 139 | 140 | printf("publishing reading\n"); 141 | len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen); 142 | rc = transport_sendPacketBuffer(mysock, buf, len); 143 | } 144 | 145 | printf("disconnecting\n"); 146 | len = MQTTSerialize_disconnect(buf, buflen); 147 | rc = transport_sendPacketBuffer(mysock, buf, len); 148 | 149 | exit: 150 | transport_close(mysock); 151 | 152 | return 0; 153 | } 154 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/samples/pub0sub1_nb.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Sergio R. Caprile - clarifications and/or documentation extension 16 | *******************************************************************************/ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "MQTTPacket.h" 23 | #include "transport.h" 24 | 25 | /* This is in order to get an asynchronous signal to stop the sample, 26 | as the code loops waiting for msgs on the subscribed topic. 27 | Your actual code will depend on your hw and approach*/ 28 | #include 29 | 30 | int toStop = 0; 31 | 32 | void cfinish(int sig) 33 | { 34 | signal(SIGINT, NULL); 35 | toStop = 1; 36 | } 37 | 38 | void stop_init(void) 39 | { 40 | signal(SIGINT, cfinish); 41 | signal(SIGTERM, cfinish); 42 | } 43 | /* */ 44 | 45 | int main(int argc, char *argv[]) 46 | { 47 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 48 | int rc = 0; 49 | int mysock = 0; 50 | unsigned char buf[200]; 51 | int buflen = sizeof(buf); 52 | int msgid = 1; 53 | MQTTString topicString = MQTTString_initializer; 54 | int req_qos = 0; 55 | char* payload = "mypayload"; 56 | int payloadlen = strlen(payload); 57 | int len = 0; 58 | char *host = "m2m.eclipse.org"; 59 | int port = 1883; 60 | MQTTTransport mytransport; 61 | 62 | stop_init(); 63 | if (argc > 1) 64 | host = argv[1]; 65 | 66 | if (argc > 2) 67 | port = atoi(argv[2]); 68 | 69 | mysock = transport_open(host, port); 70 | if(mysock < 0) 71 | return mysock; 72 | 73 | printf("Sending to hostname %s port %d\n", host, port); 74 | 75 | mytransport.sck = &mysock; 76 | mytransport.getfn = transport_getdatanb; 77 | mytransport.state = 0; 78 | data.clientID.cstring = "me"; 79 | data.keepAliveInterval = 20; 80 | data.cleansession = 1; 81 | data.username.cstring = "testuser"; 82 | data.password.cstring = "testpassword"; 83 | 84 | len = MQTTSerialize_connect(buf, buflen, &data); 85 | rc = transport_sendPacketBuffer(mysock, buf, len); 86 | 87 | /* wait for connack */ 88 | if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK) 89 | { 90 | unsigned char sessionPresent, connack_rc; 91 | 92 | if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0) 93 | { 94 | printf("Unable to connect, return code %d\n", connack_rc); 95 | goto exit; 96 | } 97 | } 98 | else 99 | goto exit; 100 | 101 | /* subscribe */ 102 | topicString.cstring = "substopic"; 103 | len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos); 104 | 105 | rc = transport_sendPacketBuffer(mysock, buf, len); 106 | do { 107 | int frc; 108 | if ((frc=MQTTPacket_readnb(buf, buflen, &mytransport)) == SUBACK) /* wait for suback */ 109 | { 110 | unsigned short submsgid; 111 | int subcount; 112 | int granted_qos; 113 | 114 | rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen); 115 | if (granted_qos != 0) 116 | { 117 | printf("granted qos != 0, %d\n", granted_qos); 118 | goto exit; 119 | } 120 | break; 121 | } 122 | else if (frc == -1) 123 | goto exit; 124 | } while (1); /* handle timeouts here */ 125 | /* loop getting msgs on subscribed topic */ 126 | topicString.cstring = "pubtopic"; 127 | while (!toStop) 128 | { 129 | /* handle timeouts */ 130 | if (MQTTPacket_readnb(buf, buflen, &mytransport) == PUBLISH) 131 | { 132 | unsigned char dup; 133 | int qos; 134 | unsigned char retained; 135 | unsigned short msgid; 136 | int payloadlen_in; 137 | unsigned char* payload_in; 138 | int rc; 139 | MQTTString receivedTopic; 140 | 141 | rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic, 142 | &payload_in, &payloadlen_in, buf, buflen); 143 | printf("message arrived %.*s\n", payloadlen_in, payload_in); 144 | printf("publishing reading\n"); 145 | len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen); 146 | rc = transport_sendPacketBuffer(mysock, buf, len); 147 | } 148 | } 149 | 150 | printf("disconnecting\n"); 151 | len = MQTTSerialize_disconnect(buf, buflen); 152 | rc = transport_sendPacketBuffer(mysock, buf, len); 153 | 154 | exit: 155 | transport_close(mysock); 156 | 157 | return 0; 158 | } 159 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/samples/qos0pub.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Sergio R. Caprile - clarifications and/or documentation extension 16 | *******************************************************************************/ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "MQTTPacket.h" 23 | #include "transport.h" 24 | 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 29 | int rc = 0; 30 | char buf[200]; 31 | int buflen = sizeof(buf); 32 | int mysock = 0; 33 | MQTTString topicString = MQTTString_initializer; 34 | char* payload = "mypayload"; 35 | int payloadlen = strlen(payload); 36 | int len = 0; 37 | char *host = "m2m.eclipse.org"; 38 | int port = 1883; 39 | 40 | if (argc > 1) 41 | host = argv[1]; 42 | 43 | if (argc > 2) 44 | port = atoi(argv[2]); 45 | 46 | mysock = transport_open(host,port); 47 | if(mysock < 0) 48 | return mysock; 49 | 50 | printf("Sending to hostname %s port %d\n", host, port); 51 | 52 | data.clientID.cstring = "me"; 53 | data.keepAliveInterval = 20; 54 | data.cleansession = 1; 55 | data.username.cstring = "testuser"; 56 | data.password.cstring = "testpassword"; 57 | data.MQTTVersion = 4; 58 | 59 | len = MQTTSerialize_connect((unsigned char *)buf, buflen, &data); 60 | 61 | topicString.cstring = "mytopic"; 62 | len += MQTTSerialize_publish((unsigned char *)(buf + len), buflen - len, 0, 0, 0, 0, topicString, (unsigned char *)payload, payloadlen); 63 | 64 | len += MQTTSerialize_disconnect((unsigned char *)(buf + len), buflen - len); 65 | 66 | rc = transport_sendPacketBuffer(mysock, buf, len); 67 | if (rc == len) 68 | printf("Successfully published\n"); 69 | else 70 | printf("Publish failed\n"); 71 | 72 | exit: 73 | transport_close(mysock); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/samples/transport.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Sergio R. Caprile - "commonalization" from prior samples and/or documentation extension 16 | *******************************************************************************/ 17 | 18 | #include 19 | 20 | #if !defined(SOCKET_ERROR) 21 | /** error in socket operation */ 22 | #define SOCKET_ERROR -1 23 | #endif 24 | 25 | #if defined(WIN32) 26 | /* default on Windows is 64 - increase to make Linux and Windows the same */ 27 | #define FD_SETSIZE 1024 28 | #include 29 | #include 30 | #define MAXHOSTNAMELEN 256 31 | #define EAGAIN WSAEWOULDBLOCK 32 | #define EINTR WSAEINTR 33 | #define EINVAL WSAEINVAL 34 | #define EINPROGRESS WSAEINPROGRESS 35 | #define EWOULDBLOCK WSAEWOULDBLOCK 36 | #define ENOTCONN WSAENOTCONN 37 | #define ECONNRESET WSAECONNRESET 38 | #define ioctl ioctlsocket 39 | #define socklen_t int 40 | #else 41 | #define INVALID_SOCKET SOCKET_ERROR 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #endif 56 | 57 | #if defined(WIN32) 58 | #include 59 | #else 60 | #include 61 | #include 62 | #endif 63 | 64 | /** 65 | This simple low-level implementation assumes a single connection for a single thread. Thus, a static 66 | variable is used for that connection. 67 | On other scenarios, the user must solve this by taking into account that the current implementation of 68 | MQTTPacket_read() has a function pointer for a function call to get the data to a buffer, but no provisions 69 | to know the caller or other indicator (the socket id): int (*getfn)(unsigned char*, int) 70 | */ 71 | static int mysock = INVALID_SOCKET; 72 | 73 | 74 | int transport_sendPacketBuffer(int sock, unsigned char* buf, int buflen) 75 | { 76 | int rc = 0; 77 | rc = write(sock, buf, buflen); 78 | return rc; 79 | } 80 | 81 | 82 | int transport_getdata(unsigned char* buf, int count) 83 | { 84 | int rc = recv(mysock, buf, count, 0); 85 | //printf("received %d bytes count %d\n", rc, (int)count); 86 | return rc; 87 | } 88 | 89 | int transport_getdatanb(void *sck, unsigned char* buf, int count) 90 | { 91 | int sock = *((int *)sck); /* sck: pointer to whatever the system may use to identify the transport */ 92 | /* this call will return after the timeout set on initialization if no bytes; 93 | in your system you will use whatever you use to get whichever outstanding 94 | bytes your socket equivalent has ready to be extracted right now, if any, 95 | or return immediately */ 96 | int rc = recv(sock, buf, count, 0); 97 | if (rc == -1) { 98 | /* check error conditions from your system here, and return -1 */ 99 | return 0; 100 | } 101 | return rc; 102 | } 103 | 104 | /** 105 | return >=0 for a socket descriptor, <0 for an error code 106 | @todo Basically moved from the sample without changes, should accomodate same usage for 'sock' for clarity, 107 | removing indirections 108 | */ 109 | int transport_open(char* addr, int port) 110 | { 111 | int* sock = &mysock; 112 | int type = SOCK_STREAM; 113 | struct sockaddr_in address; 114 | #if defined(AF_INET6) 115 | struct sockaddr_in6 address6; 116 | #endif 117 | int rc = -1; 118 | #if defined(WIN32) 119 | short family; 120 | #else 121 | sa_family_t family = AF_INET; 122 | #endif 123 | struct addrinfo *result = NULL; 124 | struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL}; 125 | static struct timeval tv; 126 | 127 | *sock = -1; 128 | if (addr[0] == '[') 129 | ++addr; 130 | 131 | if ((rc = getaddrinfo(addr, NULL, &hints, &result)) == 0) 132 | { 133 | struct addrinfo* res = result; 134 | 135 | /* prefer ip4 addresses */ 136 | while (res) 137 | { 138 | if (res->ai_family == AF_INET) 139 | { 140 | result = res; 141 | break; 142 | } 143 | res = res->ai_next; 144 | } 145 | 146 | #if defined(AF_INET6) 147 | if (result->ai_family == AF_INET6) 148 | { 149 | address6.sin6_port = htons(port); 150 | address6.sin6_family = family = AF_INET6; 151 | address6.sin6_addr = ((struct sockaddr_in6*)(result->ai_addr))->sin6_addr; 152 | } 153 | else 154 | #endif 155 | if (result->ai_family == AF_INET) 156 | { 157 | address.sin_port = htons(port); 158 | address.sin_family = family = AF_INET; 159 | address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr; 160 | } 161 | else 162 | rc = -1; 163 | 164 | freeaddrinfo(result); 165 | } 166 | 167 | if (rc == 0) 168 | { 169 | *sock = socket(family, type, 0); 170 | if (*sock != -1) 171 | { 172 | #if defined(NOSIGPIPE) 173 | int opt = 1; 174 | 175 | if (setsockopt(*sock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt)) != 0) 176 | Log(TRACE_MIN, -1, "Could not set SO_NOSIGPIPE for socket %d", *sock); 177 | #endif 178 | 179 | if (family == AF_INET) 180 | rc = connect(*sock, (struct sockaddr*)&address, sizeof(address)); 181 | #if defined(AF_INET6) 182 | else 183 | rc = connect(*sock, (struct sockaddr*)&address6, sizeof(address6)); 184 | #endif 185 | } 186 | } 187 | if (mysock == INVALID_SOCKET) 188 | return rc; 189 | 190 | tv.tv_sec = 1; /* 1 second Timeout */ 191 | tv.tv_usec = 0; 192 | setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)); 193 | return mysock; 194 | } 195 | 196 | int transport_close(int sock) 197 | { 198 | int rc; 199 | 200 | rc = shutdown(sock, SHUT_WR); 201 | rc = recv(sock, NULL, (size_t)0, 0); 202 | rc = close(sock); 203 | 204 | return rc; 205 | } 206 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/samples/transport.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Sergio R. Caprile - "commonalization" from prior samples and/or documentation extension 16 | *******************************************************************************/ 17 | 18 | int transport_sendPacketBuffer(int sock, unsigned char* buf, int buflen); 19 | int transport_getdata(unsigned char* buf, int count); 20 | int transport_getdatanb(void *sck, unsigned char* buf, int count); 21 | int transport_open(char* host, int port); 22 | int transport_close(int sock); 23 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTConnect.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTCONNECT_H_ 19 | #define MQTTCONNECT_H_ 20 | 21 | #if !defined(DLLImport) 22 | #define DLLImport 23 | #endif 24 | #if !defined(DLLExport) 25 | #define DLLExport 26 | #endif 27 | 28 | 29 | typedef union 30 | { 31 | unsigned char all; /**< all connect flags */ 32 | #if defined(REVERSED) 33 | struct 34 | { 35 | unsigned int username : 1; /**< 3.1 user name */ 36 | unsigned int password : 1; /**< 3.1 password */ 37 | unsigned int willRetain : 1; /**< will retain setting */ 38 | unsigned int willQoS : 2; /**< will QoS value */ 39 | unsigned int will : 1; /**< will flag */ 40 | unsigned int cleansession : 1; /**< clean session flag */ 41 | unsigned int : 1; /**< unused */ 42 | } bits; 43 | #else 44 | struct 45 | { 46 | unsigned int : 1; /**< unused */ 47 | unsigned int cleansession : 1; /**< cleansession flag */ 48 | unsigned int will : 1; /**< will flag */ 49 | unsigned int willQoS : 2; /**< will QoS value */ 50 | unsigned int willRetain : 1; /**< will retain setting */ 51 | unsigned int password : 1; /**< 3.1 password */ 52 | unsigned int username : 1; /**< 3.1 user name */ 53 | } bits; 54 | #endif 55 | } MQTTConnectFlags; /**< connect flags byte */ 56 | 57 | 58 | 59 | /** 60 | * Defines the MQTT "Last Will and Testament" (LWT) settings for 61 | * the connect packet. 62 | */ 63 | typedef struct 64 | { 65 | /** The eyecatcher for this structure. must be MQTW. */ 66 | char struct_id[4]; 67 | /** The version number of this structure. Must be 0 */ 68 | int struct_version; 69 | /** The LWT topic to which the LWT message will be published. */ 70 | MQTTString topicName; 71 | /** The LWT payload. */ 72 | MQTTString message; 73 | /** 74 | * The retained flag for the LWT message (see MQTTAsync_message.retained). 75 | */ 76 | unsigned char retained; 77 | /** 78 | * The quality of service setting for the LWT message (see 79 | * MQTTAsync_message.qos and @ref qos). 80 | */ 81 | char qos; 82 | } MQTTPacket_willOptions; 83 | 84 | 85 | #define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 } 86 | 87 | 88 | typedef struct 89 | { 90 | /** The eyecatcher for this structure. must be MQTC. */ 91 | char struct_id[4]; 92 | /** The version number of this structure. Must be 0 */ 93 | int struct_version; 94 | /** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1 95 | */ 96 | unsigned char MQTTVersion; 97 | MQTTString clientID; 98 | unsigned short keepAliveInterval; 99 | unsigned char cleansession; 100 | unsigned char willFlag; 101 | MQTTPacket_willOptions will; 102 | MQTTString username; 103 | MQTTString password; 104 | } MQTTPacket_connectData; 105 | 106 | typedef union 107 | { 108 | unsigned char all; /**< all connack flags */ 109 | #if defined(REVERSED) 110 | struct 111 | { 112 | unsigned int sessionpresent : 1; /**< session present flag */ 113 | unsigned int : 7; /**< unused */ 114 | } bits; 115 | #else 116 | struct 117 | { 118 | unsigned int : 7; /**< unused */ 119 | unsigned int sessionpresent : 1; /**< session present flag */ 120 | } bits; 121 | #endif 122 | } MQTTConnackFlags; /**< connack flags byte */ 123 | 124 | #define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \ 125 | MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} } 126 | 127 | DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options); 128 | DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len); 129 | 130 | DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent); 131 | DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen); 132 | 133 | DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen); 134 | DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen); 135 | 136 | #endif /* MQTTCONNECT_H_ */ 137 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTConnectServer.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "StackTrace.h" 18 | #include "MQTTPacket.h" 19 | #include 20 | 21 | #define min(a, b) ((a < b) ? a : b) 22 | 23 | 24 | /** 25 | * Validates MQTT protocol name and version combinations 26 | * @param protocol the MQTT protocol name as an MQTTString 27 | * @param version the MQTT protocol version number, as in the connect packet 28 | * @return correct MQTT combination? 1 is true, 0 is false 29 | */ 30 | int MQTTPacket_checkVersion(MQTTString* protocol, int version) 31 | { 32 | int rc = 0; 33 | 34 | if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp", 35 | min(6, protocol->lenstring.len)) == 0) 36 | rc = 1; 37 | else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT", 38 | min(4, protocol->lenstring.len)) == 0) 39 | rc = 1; 40 | return rc; 41 | } 42 | 43 | 44 | /** 45 | * Deserializes the supplied (wire) buffer into connect data structure 46 | * @param data the connect data structure to be filled out 47 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 48 | * @param len the length in bytes of the data in the supplied buffer 49 | * @return error code. 1 is success, 0 is failure 50 | */ 51 | int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len) 52 | { 53 | MQTTHeader header = {0}; 54 | MQTTConnectFlags flags = {0}; 55 | unsigned char* curdata = buf; 56 | unsigned char* enddata = &buf[len]; 57 | int rc = 0; 58 | MQTTString Protocol; 59 | int version; 60 | int mylen = 0; 61 | 62 | FUNC_ENTRY; 63 | header.byte = readChar(&curdata); 64 | if (header.bits.type != CONNECT) 65 | goto exit; 66 | 67 | curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */ 68 | 69 | if (!readMQTTLenString(&Protocol, &curdata, enddata) || 70 | enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */ 71 | goto exit; 72 | 73 | version = (int)readChar(&curdata); /* Protocol version */ 74 | /* If we don't recognize the protocol version, we don't parse the connect packet on the 75 | * basis that we don't know what the format will be. 76 | */ 77 | if (MQTTPacket_checkVersion(&Protocol, version)) 78 | { 79 | flags.all = readChar(&curdata); 80 | data->cleansession = flags.bits.cleansession; 81 | data->keepAliveInterval = readInt(&curdata); 82 | if (!readMQTTLenString(&data->clientID, &curdata, enddata)) 83 | goto exit; 84 | data->willFlag = flags.bits.will; 85 | if (flags.bits.will) 86 | { 87 | data->will.qos = flags.bits.willQoS; 88 | data->will.retained = flags.bits.willRetain; 89 | if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) || 90 | !readMQTTLenString(&data->will.message, &curdata, enddata)) 91 | goto exit; 92 | } 93 | if (flags.bits.username) 94 | { 95 | if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata)) 96 | goto exit; /* username flag set, but no username supplied - invalid */ 97 | if (flags.bits.password && 98 | (enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata))) 99 | goto exit; /* password flag set, but no password supplied - invalid */ 100 | } 101 | else if (flags.bits.password) 102 | goto exit; /* password flag set without username - invalid */ 103 | rc = 1; 104 | } 105 | exit: 106 | FUNC_EXIT_RC(rc); 107 | return rc; 108 | } 109 | 110 | 111 | /** 112 | * Serializes the connack packet into the supplied buffer. 113 | * @param buf the buffer into which the packet will be serialized 114 | * @param buflen the length in bytes of the supplied buffer 115 | * @param connack_rc the integer connack return code to be used 116 | * @param sessionPresent the MQTT 3.1.1 sessionPresent flag 117 | * @return serialized length, or error if 0 118 | */ 119 | int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent) 120 | { 121 | MQTTHeader header = {0}; 122 | int rc = 0; 123 | unsigned char *ptr = buf; 124 | MQTTConnackFlags flags = {0}; 125 | 126 | FUNC_ENTRY; 127 | if (buflen < 2) 128 | { 129 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 130 | goto exit; 131 | } 132 | header.byte = 0; 133 | header.bits.type = CONNACK; 134 | writeChar(&ptr, header.byte); /* write header */ 135 | 136 | ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ 137 | 138 | flags.all = 0; 139 | flags.bits.sessionpresent = sessionPresent; 140 | writeChar(&ptr, flags.all); 141 | writeChar(&ptr, connack_rc); 142 | 143 | rc = ptr - buf; 144 | exit: 145 | FUNC_EXIT_RC(rc); 146 | return rc; 147 | } 148 | 149 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTDeserializePublish.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "StackTrace.h" 18 | #include "MQTTPacket.h" 19 | #include 20 | 21 | #define min(a, b) ((a < b) ? 1 : 0) 22 | 23 | /** 24 | * Deserializes the supplied (wire) buffer into publish data 25 | * @param dup returned integer - the MQTT dup flag 26 | * @param qos returned integer - the MQTT QoS value 27 | * @param retained returned integer - the MQTT retained flag 28 | * @param packetid returned integer - the MQTT packet identifier 29 | * @param topicName returned MQTTString - the MQTT topic in the publish 30 | * @param payload returned byte buffer - the MQTT publish payload 31 | * @param payloadlen returned integer - the length of the MQTT payload 32 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 33 | * @param buflen the length in bytes of the data in the supplied buffer 34 | * @return error code. 1 is success 35 | */ 36 | int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName, 37 | unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen) 38 | { 39 | MQTTHeader header = {0}; 40 | unsigned char* curdata = buf; 41 | unsigned char* enddata = NULL; 42 | int rc = 0; 43 | int mylen = 0; 44 | 45 | FUNC_ENTRY; 46 | header.byte = readChar(&curdata); 47 | if (header.bits.type != PUBLISH) 48 | goto exit; 49 | *dup = header.bits.dup; 50 | *qos = header.bits.qos; 51 | *retained = header.bits.retain; 52 | 53 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 54 | enddata = curdata + mylen; 55 | 56 | if (!readMQTTLenString(topicName, &curdata, enddata) || 57 | enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */ 58 | goto exit; 59 | 60 | if (*qos > 0) 61 | *packetid = readInt(&curdata); 62 | 63 | *payloadlen = enddata - curdata; 64 | *payload = curdata; 65 | rc = 1; 66 | exit: 67 | FUNC_EXIT_RC(rc); 68 | return rc; 69 | } 70 | 71 | 72 | 73 | /** 74 | * Deserializes the supplied (wire) buffer into an ack 75 | * @param packettype returned integer - the MQTT packet type 76 | * @param dup returned integer - the MQTT dup flag 77 | * @param packetid returned integer - the MQTT packet identifier 78 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 79 | * @param buflen the length in bytes of the data in the supplied buffer 80 | * @return error code. 1 is success, 0 is failure 81 | */ 82 | int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen) 83 | { 84 | MQTTHeader header = {0}; 85 | unsigned char* curdata = buf; 86 | unsigned char* enddata = NULL; 87 | int rc = 0; 88 | int mylen; 89 | 90 | FUNC_ENTRY; 91 | header.byte = readChar(&curdata); 92 | *dup = header.bits.dup; 93 | *packettype = header.bits.type; 94 | 95 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 96 | enddata = curdata + mylen; 97 | 98 | if (enddata - curdata < 2) 99 | goto exit; 100 | *packetid = readInt(&curdata); 101 | 102 | rc = 1; 103 | exit: 104 | FUNC_EXIT_RC(rc); 105 | return rc; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTFormat.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #if !defined(MQTTFORMAT_H) 18 | #define MQTTFORMAT_H 19 | 20 | #include "StackTrace.h" 21 | #include "MQTTPacket.h" 22 | 23 | const char* MQTTPacket_getName(unsigned short packetid); 24 | int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data); 25 | int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent); 26 | int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained, 27 | unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen); 28 | int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid); 29 | int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count, 30 | MQTTString topicFilters[], int requestedQoSs[]); 31 | int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs); 32 | int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, 33 | int count, MQTTString topicFilters[]); 34 | char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen); 35 | char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTPacket.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTPACKET_H_ 19 | #define MQTTPACKET_H_ 20 | 21 | #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */ 22 | extern "C" { 23 | #endif 24 | 25 | #if defined(WIN32_DLL) || defined(WIN64_DLL) 26 | #define DLLImport __declspec(dllimport) 27 | #define DLLExport __declspec(dllexport) 28 | #elif defined(LINUX_SO) 29 | #define DLLImport extern 30 | #define DLLExport __attribute__ ((visibility ("default"))) 31 | #else 32 | #define DLLImport 33 | #define DLLExport 34 | #endif 35 | 36 | enum errors 37 | { 38 | MQTTPACKET_BUFFER_TOO_SHORT = -2, 39 | MQTTPACKET_READ_ERROR = -1, 40 | MQTTPACKET_READ_COMPLETE 41 | }; 42 | 43 | enum msgTypes 44 | { 45 | CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, 46 | PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, 47 | PINGREQ, PINGRESP, DISCONNECT 48 | }; 49 | 50 | /** 51 | * Bitfields for the MQTT header byte. 52 | */ 53 | typedef union 54 | { 55 | unsigned char byte; /**< the whole byte */ 56 | #if defined(REVERSED) 57 | struct 58 | { 59 | unsigned int type : 4; /**< message type nibble */ 60 | unsigned int dup : 1; /**< DUP flag bit */ 61 | unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ 62 | unsigned int retain : 1; /**< retained flag bit */ 63 | } bits; 64 | #else 65 | struct 66 | { 67 | unsigned int retain : 1; /**< retained flag bit */ 68 | unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ 69 | unsigned int dup : 1; /**< DUP flag bit */ 70 | unsigned int type : 4; /**< message type nibble */ 71 | } bits; 72 | #endif 73 | } MQTTHeader; 74 | 75 | typedef struct 76 | { 77 | int len; 78 | char* data; 79 | } MQTTLenString; 80 | 81 | typedef struct 82 | { 83 | char* cstring; 84 | MQTTLenString lenstring; 85 | } MQTTString; 86 | 87 | #define MQTTString_initializer {NULL, {0, NULL}} 88 | 89 | int MQTTstrlen(MQTTString mqttstring); 90 | 91 | #include "MQTTConnect.h" 92 | #include "MQTTPublish.h" 93 | #include "MQTTSubscribe.h" 94 | #include "MQTTUnsubscribe.h" 95 | #include "MQTTFormat.h" 96 | 97 | int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid); 98 | int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen); 99 | 100 | int MQTTPacket_len(int rem_len); 101 | int MQTTPacket_equals(MQTTString* a, char* b); 102 | 103 | int MQTTPacket_encode(unsigned char* buf, int length); 104 | int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value); 105 | int MQTTPacket_decodeBuf(unsigned char* buf, int* value); 106 | 107 | int readInt(unsigned char** pptr); 108 | char readChar(unsigned char** pptr); 109 | void writeChar(unsigned char** pptr, char c); 110 | void writeInt(unsigned char** pptr, int anInt); 111 | int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata); 112 | void writeCString(unsigned char** pptr, const char* string); 113 | void writeMQTTString(unsigned char** pptr, MQTTString mqttstring); 114 | 115 | DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int)); 116 | 117 | typedef struct { 118 | int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */ 119 | void *sck; /* pointer to whatever the system may use to identify the transport */ 120 | int multiplier; 121 | int rem_len; 122 | int len; 123 | char state; 124 | }MQTTTransport; 125 | 126 | int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp); 127 | 128 | #ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ 129 | } 130 | #endif 131 | 132 | 133 | #endif /* MQTTPACKET_H_ */ 134 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTPublish.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTPUBLISH_H_ 19 | #define MQTTPUBLISH_H_ 20 | 21 | #if !defined(DLLImport) 22 | #define DLLImport 23 | #endif 24 | #if !defined(DLLExport) 25 | #define DLLExport 26 | #endif 27 | 28 | DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid, 29 | MQTTString topicName, unsigned char* payload, int payloadlen); 30 | 31 | DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName, 32 | unsigned char** payload, int* payloadlen, unsigned char* buf, int len); 33 | 34 | DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid); 35 | DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid); 36 | DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid); 37 | 38 | #endif /* MQTTPUBLISH_H_ */ 39 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTSerializePublish.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144 16 | *******************************************************************************/ 17 | 18 | #include "MQTTPacket.h" 19 | #include "StackTrace.h" 20 | 21 | #include 22 | 23 | 24 | /** 25 | * Determines the length of the MQTT publish packet that would be produced using the supplied parameters 26 | * @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0) 27 | * @param topicName the topic name to be used in the publish 28 | * @param payloadlen the length of the payload to be sent 29 | * @return the length of buffer needed to contain the serialized version of the packet 30 | */ 31 | int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen) 32 | { 33 | int len = 0; 34 | 35 | len += 2 + MQTTstrlen(topicName) + payloadlen; 36 | if (qos > 0) 37 | len += 2; /* packetid */ 38 | return len; 39 | } 40 | 41 | 42 | /** 43 | * Serializes the supplied publish data into the supplied buffer, ready for sending 44 | * @param buf the buffer into which the packet will be serialized 45 | * @param buflen the length in bytes of the supplied buffer 46 | * @param dup integer - the MQTT dup flag 47 | * @param qos integer - the MQTT QoS value 48 | * @param retained integer - the MQTT retained flag 49 | * @param packetid integer - the MQTT packet identifier 50 | * @param topicName MQTTString - the MQTT topic in the publish 51 | * @param payload byte buffer - the MQTT publish payload 52 | * @param payloadlen integer - the length of the MQTT payload 53 | * @return the length of the serialized data. <= 0 indicates error 54 | */ 55 | int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid, 56 | MQTTString topicName, unsigned char* payload, int payloadlen) 57 | { 58 | unsigned char *ptr = buf; 59 | MQTTHeader header = {0}; 60 | int rem_len = 0; 61 | int rc = 0; 62 | 63 | FUNC_ENTRY; 64 | if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen) 65 | { 66 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 67 | goto exit; 68 | } 69 | 70 | header.bits.type = PUBLISH; 71 | header.bits.dup = dup; 72 | header.bits.qos = qos; 73 | header.bits.retain = retained; 74 | writeChar(&ptr, header.byte); /* write header */ 75 | 76 | ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; 77 | 78 | writeMQTTString(&ptr, topicName); 79 | 80 | if (qos > 0) 81 | writeInt(&ptr, packetid); 82 | 83 | memcpy(ptr, payload, payloadlen); 84 | ptr += payloadlen; 85 | 86 | rc = ptr - buf; 87 | 88 | exit: 89 | FUNC_EXIT_RC(rc); 90 | return rc; 91 | } 92 | 93 | 94 | 95 | /** 96 | * Serializes the ack packet into the supplied buffer. 97 | * @param buf the buffer into which the packet will be serialized 98 | * @param buflen the length in bytes of the supplied buffer 99 | * @param type the MQTT packet type 100 | * @param dup the MQTT dup flag 101 | * @param packetid the MQTT packet identifier 102 | * @return serialized length, or error if 0 103 | */ 104 | int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid) 105 | { 106 | MQTTHeader header = {0}; 107 | int rc = 0; 108 | unsigned char *ptr = buf; 109 | 110 | FUNC_ENTRY; 111 | if (buflen < 4) 112 | { 113 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 114 | goto exit; 115 | } 116 | header.bits.type = packettype; 117 | header.bits.dup = dup; 118 | header.bits.qos = (packettype == PUBREL) ? 1 : 0; 119 | writeChar(&ptr, header.byte); /* write header */ 120 | 121 | ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ 122 | writeInt(&ptr, packetid); 123 | rc = ptr - buf; 124 | exit: 125 | FUNC_EXIT_RC(rc); 126 | return rc; 127 | } 128 | 129 | 130 | /** 131 | * Serializes a puback packet into the supplied buffer. 132 | * @param buf the buffer into which the packet will be serialized 133 | * @param buflen the length in bytes of the supplied buffer 134 | * @param packetid integer - the MQTT packet identifier 135 | * @return serialized length, or error if 0 136 | */ 137 | int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid) 138 | { 139 | return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid); 140 | } 141 | 142 | 143 | /** 144 | * Serializes a pubrel packet into the supplied buffer. 145 | * @param buf the buffer into which the packet will be serialized 146 | * @param buflen the length in bytes of the supplied buffer 147 | * @param dup integer - the MQTT dup flag 148 | * @param packetid integer - the MQTT packet identifier 149 | * @return serialized length, or error if 0 150 | */ 151 | int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid) 152 | { 153 | return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid); 154 | } 155 | 156 | 157 | /** 158 | * Serializes a pubrel packet into the supplied buffer. 159 | * @param buf the buffer into which the packet will be serialized 160 | * @param buflen the length in bytes of the supplied buffer 161 | * @param packetid integer - the MQTT packet identifier 162 | * @return serialized length, or error if 0 163 | */ 164 | int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid) 165 | { 166 | return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid); 167 | } 168 | 169 | 170 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTSubscribe.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTSUBSCRIBE_H_ 19 | #define MQTTSUBSCRIBE_H_ 20 | 21 | #if !defined(DLLImport) 22 | #define DLLImport 23 | #endif 24 | #if !defined(DLLExport) 25 | #define DLLExport 26 | #endif 27 | 28 | DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, 29 | int count, MQTTString topicFilters[], int requestedQoSs[]); 30 | 31 | DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, 32 | int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len); 33 | 34 | DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs); 35 | 36 | DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len); 37 | 38 | 39 | #endif /* MQTTSUBSCRIBE_H_ */ 40 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTSubscribeClient.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | /** 23 | * Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters 24 | * @param count the number of topic filter strings in topicFilters 25 | * @param topicFilters the array of topic filter strings to be used in the publish 26 | * @return the length of buffer needed to contain the serialized version of the packet 27 | */ 28 | int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[]) 29 | { 30 | int i; 31 | int len = 2; /* packetid */ 32 | 33 | for (i = 0; i < count; ++i) 34 | len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */ 35 | return len; 36 | } 37 | 38 | 39 | /** 40 | * Serializes the supplied subscribe data into the supplied buffer, ready for sending 41 | * @param buf the buffer into which the packet will be serialized 42 | * @param buflen the length in bytes of the supplied bufferr 43 | * @param dup integer - the MQTT dup flag 44 | * @param packetid integer - the MQTT packet identifier 45 | * @param count - number of members in the topicFilters and reqQos arrays 46 | * @param topicFilters - array of topic filter names 47 | * @param requestedQoSs - array of requested QoS 48 | * @return the length of the serialized data. <= 0 indicates error 49 | */ 50 | int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count, 51 | MQTTString topicFilters[], int requestedQoSs[]) 52 | { 53 | unsigned char *ptr = buf; 54 | MQTTHeader header = {0}; 55 | int rem_len = 0; 56 | int rc = 0; 57 | int i = 0; 58 | 59 | FUNC_ENTRY; 60 | if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen) 61 | { 62 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 63 | goto exit; 64 | } 65 | 66 | header.byte = 0; 67 | header.bits.type = SUBSCRIBE; 68 | header.bits.dup = dup; 69 | header.bits.qos = 1; 70 | writeChar(&ptr, header.byte); /* write header */ 71 | 72 | ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; 73 | 74 | writeInt(&ptr, packetid); 75 | 76 | for (i = 0; i < count; ++i) 77 | { 78 | writeMQTTString(&ptr, topicFilters[i]); 79 | writeChar(&ptr, requestedQoSs[i]); 80 | } 81 | 82 | rc = ptr - buf; 83 | exit: 84 | FUNC_EXIT_RC(rc); 85 | return rc; 86 | } 87 | 88 | 89 | 90 | /** 91 | * Deserializes the supplied (wire) buffer into suback data 92 | * @param packetid returned integer - the MQTT packet identifier 93 | * @param maxcount - the maximum number of members allowed in the grantedQoSs array 94 | * @param count returned integer - number of members in the grantedQoSs array 95 | * @param grantedQoSs returned array of integers - the granted qualities of service 96 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 97 | * @param buflen the length in bytes of the data in the supplied buffer 98 | * @return error code. 1 is success, 0 is failure 99 | */ 100 | int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen) 101 | { 102 | MQTTHeader header = {0}; 103 | unsigned char* curdata = buf; 104 | unsigned char* enddata = NULL; 105 | int rc = 0; 106 | int mylen; 107 | 108 | FUNC_ENTRY; 109 | header.byte = readChar(&curdata); 110 | if (header.bits.type != SUBACK) 111 | goto exit; 112 | 113 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 114 | enddata = curdata + mylen; 115 | if (enddata - curdata < 2) 116 | goto exit; 117 | 118 | *packetid = readInt(&curdata); 119 | 120 | *count = 0; 121 | while (curdata < enddata) 122 | { 123 | if (*count > maxcount) 124 | { 125 | rc = -1; 126 | goto exit; 127 | } 128 | grantedQoSs[(*count)++] = readChar(&curdata); 129 | } 130 | 131 | rc = 1; 132 | exit: 133 | FUNC_EXIT_RC(rc); 134 | return rc; 135 | } 136 | 137 | 138 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTSubscribeServer.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | 23 | /** 24 | * Deserializes the supplied (wire) buffer into subscribe data 25 | * @param dup integer returned - the MQTT dup flag 26 | * @param packetid integer returned - the MQTT packet identifier 27 | * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays 28 | * @param count - number of members in the topicFilters and requestedQoSs arrays 29 | * @param topicFilters - array of topic filter names 30 | * @param requestedQoSs - array of requested QoS 31 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 32 | * @param buflen the length in bytes of the data in the supplied buffer 33 | * @return the length of the serialized data. <= 0 indicates error 34 | */ 35 | int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[], 36 | int requestedQoSs[], unsigned char* buf, int buflen) 37 | { 38 | MQTTHeader header = {0}; 39 | unsigned char* curdata = buf; 40 | unsigned char* enddata = NULL; 41 | int rc = -1; 42 | int mylen = 0; 43 | 44 | FUNC_ENTRY; 45 | header.byte = readChar(&curdata); 46 | if (header.bits.type != SUBSCRIBE) 47 | goto exit; 48 | *dup = header.bits.dup; 49 | 50 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 51 | enddata = curdata + mylen; 52 | 53 | *packetid = readInt(&curdata); 54 | 55 | *count = 0; 56 | while (curdata < enddata) 57 | { 58 | if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata)) 59 | goto exit; 60 | if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */ 61 | goto exit; 62 | requestedQoSs[*count] = readChar(&curdata); 63 | (*count)++; 64 | } 65 | 66 | rc = 1; 67 | exit: 68 | FUNC_EXIT_RC(rc); 69 | return rc; 70 | } 71 | 72 | 73 | /** 74 | * Serializes the supplied suback data into the supplied buffer, ready for sending 75 | * @param buf the buffer into which the packet will be serialized 76 | * @param buflen the length in bytes of the supplied buffer 77 | * @param packetid integer - the MQTT packet identifier 78 | * @param count - number of members in the grantedQoSs array 79 | * @param grantedQoSs - array of granted QoS 80 | * @return the length of the serialized data. <= 0 indicates error 81 | */ 82 | int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs) 83 | { 84 | MQTTHeader header = {0}; 85 | int rc = -1; 86 | unsigned char *ptr = buf; 87 | int i; 88 | 89 | FUNC_ENTRY; 90 | if (buflen < 2 + count) 91 | { 92 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 93 | goto exit; 94 | } 95 | header.byte = 0; 96 | header.bits.type = SUBACK; 97 | writeChar(&ptr, header.byte); /* write header */ 98 | 99 | ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */ 100 | 101 | writeInt(&ptr, packetid); 102 | 103 | for (i = 0; i < count; ++i) 104 | writeChar(&ptr, grantedQoSs[i]); 105 | 106 | rc = ptr - buf; 107 | exit: 108 | FUNC_EXIT_RC(rc); 109 | return rc; 110 | } 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTUnsubscribe.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTUNSUBSCRIBE_H_ 19 | #define MQTTUNSUBSCRIBE_H_ 20 | 21 | #if !defined(DLLImport) 22 | #define DLLImport 23 | #endif 24 | #if !defined(DLLExport) 25 | #define DLLExport 26 | #endif 27 | 28 | DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, 29 | int count, MQTTString topicFilters[]); 30 | 31 | DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[], 32 | unsigned char* buf, int len); 33 | 34 | DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid); 35 | 36 | DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len); 37 | 38 | #endif /* MQTTUNSUBSCRIBE_H_ */ 39 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTUnsubscribeClient.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | /** 23 | * Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters 24 | * @param count the number of topic filter strings in topicFilters 25 | * @param topicFilters the array of topic filter strings to be used in the publish 26 | * @return the length of buffer needed to contain the serialized version of the packet 27 | */ 28 | int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[]) 29 | { 30 | int i; 31 | int len = 2; /* packetid */ 32 | 33 | for (i = 0; i < count; ++i) 34 | len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/ 35 | return len; 36 | } 37 | 38 | 39 | /** 40 | * Serializes the supplied unsubscribe data into the supplied buffer, ready for sending 41 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 42 | * @param buflen the length in bytes of the data in the supplied buffer 43 | * @param dup integer - the MQTT dup flag 44 | * @param packetid integer - the MQTT packet identifier 45 | * @param count - number of members in the topicFilters array 46 | * @param topicFilters - array of topic filter names 47 | * @return the length of the serialized data. <= 0 indicates error 48 | */ 49 | int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, 50 | int count, MQTTString topicFilters[]) 51 | { 52 | unsigned char *ptr = buf; 53 | MQTTHeader header = {0}; 54 | int rem_len = 0; 55 | int rc = -1; 56 | int i = 0; 57 | 58 | FUNC_ENTRY; 59 | if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen) 60 | { 61 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 62 | goto exit; 63 | } 64 | 65 | header.byte = 0; 66 | header.bits.type = UNSUBSCRIBE; 67 | header.bits.dup = dup; 68 | header.bits.qos = 1; 69 | writeChar(&ptr, header.byte); /* write header */ 70 | 71 | ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; 72 | 73 | writeInt(&ptr, packetid); 74 | 75 | for (i = 0; i < count; ++i) 76 | writeMQTTString(&ptr, topicFilters[i]); 77 | 78 | rc = ptr - buf; 79 | exit: 80 | FUNC_EXIT_RC(rc); 81 | return rc; 82 | } 83 | 84 | 85 | /** 86 | * Deserializes the supplied (wire) buffer into unsuback data 87 | * @param packetid returned integer - the MQTT packet identifier 88 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 89 | * @param buflen the length in bytes of the data in the supplied buffer 90 | * @return error code. 1 is success, 0 is failure 91 | */ 92 | int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen) 93 | { 94 | unsigned char type = 0; 95 | unsigned char dup = 0; 96 | int rc = 0; 97 | 98 | FUNC_ENTRY; 99 | rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen); 100 | if (type == UNSUBACK) 101 | rc = 1; 102 | FUNC_EXIT_RC(rc); 103 | return rc; 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/MQTTUnsubscribeServer.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | 23 | /** 24 | * Deserializes the supplied (wire) buffer into unsubscribe data 25 | * @param dup integer returned - the MQTT dup flag 26 | * @param packetid integer returned - the MQTT packet identifier 27 | * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays 28 | * @param count - number of members in the topicFilters and requestedQoSs arrays 29 | * @param topicFilters - array of topic filter names 30 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 31 | * @param buflen the length in bytes of the data in the supplied buffer 32 | * @return the length of the serialized data. <= 0 indicates error 33 | */ 34 | int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[], 35 | unsigned char* buf, int len) 36 | { 37 | MQTTHeader header = {0}; 38 | unsigned char* curdata = buf; 39 | unsigned char* enddata = NULL; 40 | int rc = 0; 41 | int mylen = 0; 42 | 43 | FUNC_ENTRY; 44 | header.byte = readChar(&curdata); 45 | if (header.bits.type != UNSUBSCRIBE) 46 | goto exit; 47 | *dup = header.bits.dup; 48 | 49 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 50 | enddata = curdata + mylen; 51 | 52 | *packetid = readInt(&curdata); 53 | 54 | *count = 0; 55 | while (curdata < enddata) 56 | { 57 | if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata)) 58 | goto exit; 59 | (*count)++; 60 | } 61 | 62 | rc = 1; 63 | exit: 64 | FUNC_EXIT_RC(rc); 65 | return rc; 66 | } 67 | 68 | 69 | /** 70 | * Serializes the supplied unsuback data into the supplied buffer, ready for sending 71 | * @param buf the buffer into which the packet will be serialized 72 | * @param buflen the length in bytes of the supplied buffer 73 | * @param packetid integer - the MQTT packet identifier 74 | * @return the length of the serialized data. <= 0 indicates error 75 | */ 76 | int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid) 77 | { 78 | MQTTHeader header = {0}; 79 | int rc = 0; 80 | unsigned char *ptr = buf; 81 | 82 | FUNC_ENTRY; 83 | if (buflen < 2) 84 | { 85 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 86 | goto exit; 87 | } 88 | header.byte = 0; 89 | header.bits.type = UNSUBACK; 90 | writeChar(&ptr, header.byte); /* write header */ 91 | 92 | ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ 93 | 94 | writeInt(&ptr, packetid); 95 | 96 | rc = ptr - buf; 97 | exit: 98 | FUNC_EXIT_RC(rc); 99 | return rc; 100 | } 101 | 102 | 103 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/src/StackTrace.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Ian Craggs - fix for bug #434081 16 | *******************************************************************************/ 17 | 18 | #ifndef STACKTRACE_H_ 19 | #define STACKTRACE_H_ 20 | 21 | #include 22 | #define NOSTACKTRACE 1 23 | 24 | #if defined(NOSTACKTRACE) 25 | #define FUNC_ENTRY 26 | #define FUNC_ENTRY_NOLOG 27 | #define FUNC_ENTRY_MED 28 | #define FUNC_ENTRY_MAX 29 | #define FUNC_EXIT 30 | #define FUNC_EXIT_NOLOG 31 | #define FUNC_EXIT_MED 32 | #define FUNC_EXIT_MAX 33 | #define FUNC_EXIT_RC(x) 34 | #define FUNC_EXIT_MED_RC(x) 35 | #define FUNC_EXIT_MAX_RC(x) 36 | 37 | #else 38 | 39 | #if defined(WIN32) 40 | #define inline __inline 41 | #define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) 42 | #define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) 43 | #define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) 44 | #define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) 45 | #define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) 46 | #define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1) 47 | #define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) 48 | #define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) 49 | #define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) 50 | #define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) 51 | #define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) 52 | #else 53 | #define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) 54 | #define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) 55 | #define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) 56 | #define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) 57 | #define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) 58 | #define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) 59 | #define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) 60 | #define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) 61 | #define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) 62 | #define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) 63 | #define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) 64 | 65 | void StackTrace_entry(const char* name, int line, int trace); 66 | void StackTrace_exit(const char* name, int line, void* return_value, int trace); 67 | 68 | void StackTrace_printStack(FILE* dest); 69 | char* StackTrace_get(unsigned long); 70 | 71 | #endif 72 | 73 | #endif 74 | 75 | 76 | 77 | 78 | #endif /* STACKTRACE_H_ */ 79 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/MQTTPacket/test/build_test: -------------------------------------------------------------------------------- 1 | gcc -Wall test1.c -o test1 -I../src ../src/MQTTConnectClient.c ../src/MQTTConnectServer.c ../src/MQTTPacket.c ../src/MQTTSerializePublish.c ../src/MQTTDeserializePublish.c ../src/MQTTSubscribeServer.c ../src/MQTTSubscribeClient.c ../src/MQTTUnsubscribeServer.c ../src/MQTTUnsubscribeClient.c 2 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/Makefile: -------------------------------------------------------------------------------- 1 | #******************************************************************************* 2 | # Copyright (c) 2009, 2014 IBM Corp. 3 | # 4 | # All rights reserved. This program and the accompanying materials 5 | # are made available under the terms of the Eclipse Public License v1.0 6 | # and Eclipse Distribution License v1.0 which accompany this distribution. 7 | # 8 | # The Eclipse Public License is available at 9 | # http://www.eclipse.org/legal/epl-v10.html 10 | # and the Eclipse Distribution License is available at 11 | # http://www.eclipse.org/org/documents/edl-v10.php. 12 | # 13 | # Contributors: 14 | # Xiang Rong - 442039 Add makefile to Embedded C client 15 | #*******************************************************************************/ 16 | 17 | # Note: on OS X you should install XCode and the associated command-line tools 18 | 19 | SHELL = /bin/sh 20 | .PHONY: clean, mkdir, install, uninstall, html 21 | 22 | # assume this is normally run in the main Paho directory 23 | ifndef srcdir 24 | srcdir = MQTTPacket/src 25 | endif 26 | 27 | ifndef blddir 28 | blddir = build/output 29 | endif 30 | 31 | ifndef prefix 32 | prefix = /usr/local 33 | endif 34 | 35 | ifndef exec_prefix 36 | exec_prefix = ${prefix} 37 | endif 38 | 39 | bindir = $(exec_prefix)/bin 40 | includedir = $(prefix)/include 41 | libdir = $(exec_prefix)/lib 42 | 43 | SOURCE_FILES_C = $(srcdir)/*.c 44 | 45 | HEADERS = $(srcdir)/*.h 46 | 47 | 48 | SAMPLE_FILES_C = pub0sub1 qos0pub 49 | SYNC_SAMPLES = ${addprefix ${blddir}/samples/,${SAMPLE_FILES_C}} 50 | 51 | 52 | TEST_FILES_C = test1 53 | SYNC_TESTS = ${addprefix ${blddir}/test/,${TEST_FILES_C}} 54 | 55 | 56 | # The names of libraries to be built 57 | MQTT_EMBED_LIB_C = paho-embed-mqtt3c 58 | 59 | 60 | # determine current platform 61 | ifeq ($(OS),Windows_NT) 62 | OSTYPE = $(OS) 63 | else 64 | OSTYPE = $(shell uname -s) 65 | MACHINETYPE = $(shell uname -m) 66 | endif 67 | 68 | ifeq ($(OSTYPE),Linux) 69 | 70 | CC ?= gcc 71 | 72 | ifndef INSTALL 73 | INSTALL = install 74 | endif 75 | INSTALL_PROGRAM = $(INSTALL) 76 | INSTALL_DATA = $(INSTALL) -m 644 77 | 78 | MAJOR_VERSION = 1 79 | MINOR_VERSION = 0 80 | VERSION = ${MAJOR_VERSION}.${MINOR_VERSION} 81 | 82 | EMBED_MQTTLIB_C_TARGET = ${blddir}/lib${MQTT_EMBED_LIB_C}.so.${VERSION} 83 | 84 | 85 | CCFLAGS_SO = -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO 86 | FLAGS_EXE = -I ${srcdir} -L ${blddir} 87 | 88 | LDFLAGS_C = -shared -Wl,-soname,lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} 89 | 90 | all: build 91 | 92 | build: | mkdir ${EMBED_MQTTLIB_C_TARGET} ${SYNC_SAMPLES} ${SYNC_TESTS} 93 | 94 | clean: 95 | rm -rf ${blddir}/* 96 | 97 | mkdir: 98 | -mkdir -p ${blddir}/samples 99 | -mkdir -p ${blddir}/test 100 | 101 | ${SYNC_TESTS}: ${blddir}/test/%: ${srcdir}/../test/%.c 102 | ${CC} -g -o ${blddir}/test/${basename ${+F}} $< -l${MQTT_EMBED_LIB_C} ${FLAGS_EXE} 103 | 104 | 105 | ${SYNC_SAMPLES}: ${blddir}/samples/%: ${srcdir}/../samples/%.c ${srcdir}/../samples/transport.o 106 | ${CC} -o $@ $^ -l${MQTT_EMBED_LIB_C} ${FLAGS_EXE} 107 | 108 | 109 | 110 | ${EMBED_MQTTLIB_C_TARGET}: ${SOURCE_FILES_C} ${HEADERS_C} 111 | ${CC} ${CCFLAGS_SO} -o $@ ${SOURCE_FILES_C} ${LDFLAGS_C} 112 | -ln -s lib$(MQTT_EMBED_LIB_C).so.${VERSION} ${blddir}/lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} 113 | -ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} ${blddir}/lib$(MQTT_EMBED_LIB_C).so 114 | 115 | 116 | strip_options: 117 | $(eval INSTALL_OPTS := -s) 118 | 119 | install-strip: build strip_options install 120 | 121 | install: build 122 | $(INSTALL_DATA) ${INSTALL_OPTS} ${EMBED_MQTTLIB_C_TARGET} $(DESTDIR)${libdir} 123 | 124 | 125 | /sbin/ldconfig $(DESTDIR)${libdir} 126 | ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so 127 | 128 | 129 | uninstall: 130 | rm $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so.${VERSION} 131 | 132 | /sbin/ldconfig $(DESTDIR)${libdir} 133 | rm $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so 134 | 135 | 136 | html: 137 | 138 | ARDUINO_LIB_FILES = MQTTClient/src/*.h MQTTClient/src/arduino/*.h $(srcdir)/* 139 | ARDUINO_SAMPLES = MQTTClient/samples/arduino/* 140 | LEGAL_FILES = edl-v10 epl-v10 notice.html about.html CONTRIBUTING.md README.md 141 | 142 | arduino: mkdir 143 | -mkdir -p ${blddir}/arduino/MQTTClient/examples 144 | cp $(ARDUINO_LIB_FILES) ${blddir}/arduino/MQTTClient 145 | cp $(LEGAL_FILES) ${blddir}/arduino/MQTTClient 146 | cp -R $(ARDUINO_SAMPLES) ${blddir}/arduino/MQTTClient/examples 147 | cd ${blddir}/arduino && zip -r arduino MQTTClient 148 | 149 | endif 150 | 151 | 152 | 153 | ifeq ($(OSTYPE),Darwin) 154 | 155 | CC ?= gcc 156 | 157 | ifndef INSTALL 158 | INSTALL = install 159 | endif 160 | INSTALL_PROGRAM = $(INSTALL) 161 | INSTALL_DATA = $(INSTALL) -m 644 162 | 163 | MAJOR_VERSION = 1 164 | MINOR_VERSION = 0 165 | VERSION = ${MAJOR_VERSION}.${MINOR_VERSION} 166 | 167 | EMBED_MQTTLIB_C_TARGET = ${blddir}/lib${MQTT_EMBED_LIB_C}.so.${VERSION} 168 | 169 | 170 | CCFLAGS_SO = -g -fPIC -Os -Wall -fvisibility=hidden -Wno-deprecated-declarations -DUSE_NAMED_SEMAPHORES 171 | FLAGS_EXE = -I ${srcdir} -L ${blddir} 172 | 173 | LDFLAGS_C = -shared -Wl,-install_name,lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} 174 | 175 | all: build 176 | 177 | build: | mkdir ${EMBED_MQTTLIB_C_TARGET} ${SYNC_SAMPLES} ${SYNC_TESTS} 178 | 179 | clean: 180 | rm -rf ${blddir}/* 181 | 182 | mkdir: 183 | -mkdir -p ${blddir}/samples 184 | -mkdir -p ${blddir}/test 185 | 186 | ${SYNC_TESTS}: ${blddir}/test/%: ${srcdir}/../test/%.c 187 | ${CC} -g -o ${blddir}/test/${basename ${+F}} $< -l${MQTT_EMBED_LIB_C} ${FLAGS_EXE} 188 | 189 | ${SYNC_SAMPLES}: ${blddir}/samples/%: ${srcdir}/../samples/%.c 190 | ${CC} -o ${blddir}/samples/${basename ${+F}} $< ${FLAGS_EXE} -l${MQTT_EMBED_LIB_C} 191 | 192 | ${EMBED_MQTTLIB_C_TARGET}: ${SOURCE_FILES_C} ${HEADERS_C} 193 | ${CC} ${CCFLAGS_SO} -o $@ ${SOURCE_FILES_C} ${LDFLAGS_C} 194 | -ln -s lib$(MQTT_EMBED_LIB_C).so.${VERSION} ${blddir}/lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} 195 | -ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} ${blddir}/lib$(MQTT_EMBED_LIB_C).so 196 | 197 | 198 | strip_options: 199 | $(eval INSTALL_OPTS := -s) 200 | 201 | install-strip: build strip_options install 202 | 203 | install: build 204 | $(INSTALL_DATA) ${INSTALL_OPTS} ${EMBED_MQTTLIB_C_TARGET} $(DESTDIR)${libdir} 205 | 206 | /sbin/ldconfig $(DESTDIR)${libdir} 207 | ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so 208 | 209 | 210 | uninstall: 211 | rm $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so.${VERSION} 212 | /sbin/ldconfig $(DESTDIR)${libdir} 213 | rm $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so 214 | 215 | 216 | html: 217 | 218 | 219 | endif 220 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/README.md: -------------------------------------------------------------------------------- 1 | # Eclipse Paho MQTT C/C++ client for Embedded platforms 2 | 3 | This repository contains the source code for the [Eclipse Paho](http://eclipse.org/paho) MQTT C/C++ client library for Embedded platorms. 4 | 5 | It is dual licensed under the EPL and EDL (see about.html and notice.html for more details). You can choose which of these licenses you want to use the code under. The EDL allows you to embed the code into your application, and distribute your application in binary or source form without contributing any of your code, or any changes you make back to Paho. See the EDL for the exact conditions. 6 | 7 | The MQTTPacket directory contains the lowest level C library with the smallest requirements. This supplies simple serialization 8 | and deserialization routines. It is mainly up to you to write and read to and from the network. 9 | 10 | The MQTTClient directory contains the next level C++ library. This still avoids most networking code so that you can plugin the 11 | network of your choice. 12 | 13 | ## Build requirements / compilation 14 | 15 | There are helper scripts (build...) in various directories. The client library is a set of building blocks which you pick and choose from, so that the smallest MQTT application can be built. 16 | 17 | ## Usage and API 18 | 19 | See the samples directory for examples of intended use. 20 | 21 | 22 | ## Runtime tracing 23 | 24 | As yet, there is no tracing. For the smallest client, should we have tracing? 25 | 26 | 27 | ## Reporting bugs 28 | 29 | This project uses GitHub Issues here: [github.com/eclipse/paho.mqtt.embedded-c/issues](https://github.com/eclipse/paho.mqtt.embedded-c/issues) to track ongoing development and issues. 30 | 31 | ## More information 32 | 33 | Discussion of the Paho clients takes place on the [Eclipse paho-dev mailing list](https://dev.eclipse.org/mailman/listinfo/paho-dev). 34 | 35 | General questions about the MQTT protocol are discussed in the [MQTT Google Group](https://groups.google.com/forum/?hl=en-US&fromgroups#!forum/mqtt). 36 | 37 | There is much more information available via the [MQTT community site](http://mqtt.org). 38 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | About 5 | 6 | 7 |

About This Content

8 | 9 |

December 9, 2013

10 |

License

11 | 12 |

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise 13 | indicated below, the Content is provided to you under the terms and conditions of the 14 | Eclipse Public License Version 1.0 ("EPL") and Eclipse Distribution License Version 1.0 ("EDL"). 15 | A copy of the EPL is available at 16 | http://www.eclipse.org/legal/epl-v10.html 17 | and a copy of the EDL is available at 18 | http://www.eclipse.org/org/documents/edl-v10.php. 19 | For purposes of the EPL, "Program" will mean the Content.

20 | 21 |

If you did not receive this Content directly from the Eclipse Foundation, the Content is 22 | being redistributed by another party ("Redistributor") and different terms and conditions may 23 | apply to your use of any object code in the Content. Check the Redistributor's license that was 24 | provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise 25 | indicated below, the terms and conditions of the EPL still apply to any source code in the Content 26 | and such source code may be obtained at http://www.eclipse.org.

27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Implementation/paho/pahomqttembeddedc/edl-v10: -------------------------------------------------------------------------------- 1 | 2 | Eclipse Distribution License - v 1.0 3 | 4 | Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. 5 | 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | 10 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 11 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 | 16 | -------------------------------------------------------------------------------- /src/LoggerInterface.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 06.01.17. 3 | // 4 | 5 | #ifndef ESPARDUINOMQTTSNGATEWAY_LOGGERINTERFACE_H 6 | #define ESPARDUINOMQTTSNGATEWAY_LOGGERINTERFACE_H 7 | 8 | #include 9 | 10 | class LoggerInterface { 11 | 12 | public: 13 | 14 | virtual ~LoggerInterface() {}; 15 | 16 | /** 17 | * Initializes logger 18 | * @return if logger is successfully initialized or not 19 | */ 20 | virtual bool begin()=0; 21 | 22 | /** 23 | * Set the logging level only message with log_lvl smaller or equal then the set logging level will be logged. 24 | * The default level is 2, only message with log_lvl 2,1 and 0 are printed. 25 | * Note: 26 | * Logging level shall indicate how detailed the loggin output is. Higher means more detailled. 27 | * A logging level 0 shall only be used for fatal errors inside the Gateway and will be always logged. 28 | * @param log_lvl 29 | */ 30 | virtual void set_log_lvl(uint8_t log_lvl)=0; 31 | 32 | /** 33 | * logs a single line with timestamp or whatever at the beginning. 34 | * @param msg to be logged 35 | */ 36 | virtual void log(char *msg, uint8_t log_lvl)=0; 37 | 38 | /** 39 | * logs a single line with timestamp or whatever at the beginning. 40 | * @param msg to be logged 41 | */ 42 | virtual void log(const char *msg, uint8_t log_lvl)=0; 43 | 44 | /** 45 | * logs a line can be appended with append_log 46 | * @param msg 47 | */ 48 | virtual void start_log(char *msg, uint8_t log_lvl)=0; 49 | 50 | /** 51 | * logs a line can be appended with append_log 52 | * @param msg 53 | */ 54 | virtual void start_log(const char *msg, uint8_t log_lvl)=0; 55 | 56 | 57 | /** 58 | * sets the log lvl for log message to be printed 59 | * @param msg 60 | */ 61 | virtual void set_current_log_lvl(uint8_t log_lvl)=0; 62 | 63 | /** 64 | * append message to the last log message 65 | * @param msg to be appended 66 | */ 67 | virtual void append_log(char *msg)=0; 68 | 69 | /** 70 | * append message to the last log message 71 | * @param msg to be appended 72 | */ 73 | virtual void append_log(const char *msg)=0; 74 | 75 | }; 76 | 77 | #endif //ESPARDUINOMQTTSNGATEWAY_LOGGERINTERFACE_H 78 | -------------------------------------------------------------------------------- /src/MqttMessageHandlerInterface.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 17.12.16. 3 | // 4 | 5 | #include "MqttMessageHandlerInterface.h" 6 | -------------------------------------------------------------------------------- /src/MqttMessageHandlerInterface.h: -------------------------------------------------------------------------------- 1 | #ifndef GATEWAY_MQTTMESSAGEHANDLERINTERFACE_H 2 | #define GATEWAY_MQTTMESSAGEHANDLERINTERFACE_H 3 | 4 | 5 | #include 6 | #include "CoreInterface.h" 7 | #include "LoggerInterface.h" 8 | 9 | class Core; 10 | 11 | class MqttMessageHandlerInterface { 12 | public: 13 | virtual ~MqttMessageHandlerInterface() {}; 14 | 15 | virtual bool begin() = 0; 16 | 17 | virtual void setCore(Core *core) = 0; 18 | 19 | virtual void setLogger(LoggerInterface *logger) = 0; 20 | 21 | virtual void setServer(uint8_t *ip, uint16_t port) = 0; 22 | 23 | virtual void setServer(const char *hostname, uint16_t port) = 0; 24 | 25 | // we always connect with the clean flag! 26 | virtual bool connect(const char *id) = 0; 27 | 28 | virtual bool connect(const char *id, const char *user, const char *pass) = 0; 29 | 30 | virtual bool 31 | connect(const char *id, const char *willTopic, uint8_t willQos, bool willRetain, const uint8_t *willMessage, 32 | const uint16_t willMessageLength) = 0; 33 | 34 | virtual bool 35 | connect(const char *id, const char *user, const char *pass, const char *willTopic, uint8_t willQos, bool willRetain, 36 | const uint8_t *willMessage, const uint16_t willMessageLength) = 0; 37 | 38 | virtual void disconnect() = 0; 39 | 40 | virtual bool publish(const char *topic, const uint8_t *payload, uint16_t plength, uint8_t qos, bool retained) = 0; 41 | 42 | virtual bool subscribe(const char *topic, uint8_t qos) = 0; 43 | 44 | virtual bool unsubscribe(const char *topic) = 0; 45 | 46 | /** 47 | * Call this method when you received a publish from the broker. 48 | * Implementation Note: 49 | * - Call publish in this method internally. 50 | * @param topic 51 | * @param payload 52 | * @param length 53 | * @return true if everthing worked fine, else otherwise. 54 | * // TODO adept message signature with retain and qos 55 | */ 56 | virtual bool receive_publish(char* topic, uint8_t * payload, uint32_t length) = 0; 57 | 58 | virtual bool loop() = 0; 59 | 60 | }; 61 | 62 | 63 | #endif //GATEWAY_MQTTMESSAGEHANDLERINTERFACE_H 64 | -------------------------------------------------------------------------------- /src/PersistentInterface.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 17.12.16. 3 | // 4 | 5 | #include "PersistentInterface.h" 6 | -------------------------------------------------------------------------------- /src/SocketInterface.cpp: -------------------------------------------------------------------------------- 1 | //PubSubClient 2 | // Created by bele on 09.12.16. 3 | // 4 | 5 | #include "SocketInterface.h" 6 | 7 | -------------------------------------------------------------------------------- /src/SocketInterface.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by bele on 09.12.16. 3 | // 4 | 5 | #ifndef GATEWAY_SOCKETINTERFACE_H 6 | #define GATEWAY_SOCKETINTERFACE_H 7 | 8 | 9 | #include "global_defines.h" 10 | #include "MqttSnMessageHandler.h" 11 | #include "LoggerInterface.h" 12 | #include 13 | 14 | class MqttSnMessageHandler; 15 | 16 | class SocketInterface { 17 | public: 18 | virtual ~SocketInterface() {} 19 | 20 | /** 21 | * Initialize the network stack below, with what ever you have to do to establish the connection to the network. 22 | * @return true if the connection is successfully established, false in any other case. 23 | */ 24 | virtual bool begin() =0 ; 25 | 26 | /** 27 | * Sets the Logger. 28 | * @param logger to be used 29 | */ 30 | virtual void setLogger(LoggerInterface *logger) = 0; 31 | 32 | /** 33 | * Set the MqttSnMessageHandler the receiveData method shall be called. 34 | * @param mqttSnMessageHandler 35 | */ 36 | virtual void setMqttSnMessageHandler(MqttSnMessageHandler *mqttSnMessageHandler) = 0; 37 | 38 | /** 39 | * Get the abstract broadcast address to send pakets to. 40 | * Implementation Note: 41 | * - If your network stack does not provide any broadcast address, map it to a address you save as not-to-send-address. 42 | * - If your network stack has a procedure to broadcast packets, map it to a address you save as to-broadcast-address. 43 | * @return the abstract broadcast address as device address from of the network stack below. 44 | */ 45 | virtual device_address* getBroadcastAddress() = 0; 46 | 47 | /** 48 | * Get your own address converted to an abstract device address. 49 | * This is used in the GWINFO messages, despite the mqtt-sn standard does not tell to. 50 | * // TODO maybe we can change this, depend on the Mqtt-Sn client implementation 51 | * @return the abstract own device address provided by the network stack below. 52 | */ 53 | virtual device_address* getAddress() = 0; 54 | 55 | /** 56 | * Get the maximum count of bytes the network stack you use can provide as payload in a single message. 57 | * The minimum value you should provide is 8 bytes and the maximum the mqtt-sn standard supports are 255 bytes. 58 | * If you support more then 255 bytes payload in a message return 255. 59 | * Implementation Note: 60 | * - The absolute minimum are 8 bytes, but can only publish 1 byte raw data. 61 | * 7 bytes are needed by the header, you have only 1 byte data left. 62 | * If this makes sense is up to you. 63 | * - The maximum are 255 bytes. because the mqtt-sn standard message length up to 255 bytes. 64 | * The Length field in each Mqtt-Sn message is only 1 byte long. 65 | * Supporting longer message are out of the standard and will break the gateway implementation. 66 | * @return the maximum count of bytes the network stack can send 67 | */ 68 | virtual uint8_t getMaximumMessageLength() = 0; 69 | 70 | /** 71 | * Abstract and simple message to send the bytes of the mqtt-sn message 72 | * @param destination is the abstract destination address to send the payload 73 | * @param bytes is the pointer to the bytes to be send 74 | * @param bytes_len is the length of the bytes send to, maximum is 255, minimum 8. See method: getMaximumMessageLength 75 | * @return true if the connection to the network still exist. 76 | */ 77 | virtual bool send(device_address* destination, uint8_t* bytes, uint16_t bytes_len) = 0; 78 | 79 | /** 80 | * Abstract and simple message to send the bytes of the mqtt-sn message with a maximum signal strength parsed out of a SEARCHGW message. 81 | * Implementation Note: 82 | * - If your network stack below does not have the ability to change the signal strength or does it automatically, ignore the parameter. 83 | * @param destination is the abstract destination address to send the payload 84 | * @param bytes is the pointer to the bytes to be send 85 | * @param bytes_len is the length of the bytes send to, maximum is 255, minimum 8. See method: getMaximumMessageLength 86 | * @param signal_strength is the strength of the signal from the radius field received from the SEARCHGW message from the client with the destination_address. 87 | * @return true if the connection to the network still exist. 88 | */ 89 | virtual bool send(device_address* destination, uint8_t* bytes, uint16_t bytes_len, uint8_t signal_strength) = 0; 90 | 91 | virtual bool loop() = 0; 92 | 93 | }; 94 | 95 | 96 | #endif //GATEWAY_SOCKET_H 97 | -------------------------------------------------------------------------------- /src/System.h: -------------------------------------------------------------------------------- 1 | #ifndef ESPARDUINOMQTTSNGATEWAY_SYSTEM_H 2 | #define ESPARDUINOMQTTSNGATEWAY_SYSTEM_H 3 | 4 | #include 5 | /** 6 | * Defines basic functionality provided by an underlying OS or must be implemented otherwise. 7 | */ 8 | class System { 9 | public: 10 | /** 11 | * Sets the heartbeat value where the System perform regular checks. 12 | * Default value is a period of 30 000 ms 13 | * @param period 14 | */ 15 | virtual void set_heartbeat(uint32_t period)=0; 16 | 17 | /** 18 | * Gets the heartbeat value where the System perform regular checks. 19 | * Default value is a period of 30 000 ms 20 | */ 21 | virtual uint32_t get_heartbeat()=0; 22 | 23 | /** 24 | * Checks if the heartbeat is timed out. 25 | * @return true if the heartbeat value was reached, false otherwise. 26 | */ 27 | virtual bool has_beaten()=0; 28 | 29 | /** 30 | * Get the elapsed time between two calls of this function. 31 | * @return the elapsed time between two calls 32 | */ 33 | virtual uint32_t get_elapsed_time()=0; 34 | 35 | /** 36 | * Lets the execution sleep for some seconds. 37 | */ 38 | virtual void sleep(uint32_t duration)=0; 39 | 40 | /** 41 | * Stop/exit the whole program or restart it if you want to. 42 | */ 43 | virtual void exit()=0; 44 | }; 45 | 46 | #endif //ESPARDUINOMQTTSNGATEWAY_SYSTEM_H 47 | -------------------------------------------------------------------------------- /src/core_defines.h: -------------------------------------------------------------------------------- 1 | #ifndef GATEWAY_CORE_DEFINES_H 2 | #define GATEWAY_CORE_DEFINES_H 3 | #include 4 | 5 | enum CORE_RESULT : int16_t { 6 | SUCCESS = 1, 7 | ZERO = 0, 8 | CLIENTNONEXISTENCE = -1, 9 | CLIENTSUBSCRIPTIONFULL = -2, 10 | TOPICIDNONEXISTENCE = -3, 11 | FULL = -4, 12 | MOREPUBLISHESAVAILABLE = -5, 13 | TOOMUCHDATA = -6, 14 | }; 15 | 16 | 17 | enum CLIENT_STATUS : uint8_t { 18 | EMPTY = 0, 19 | ACTIVE = 1, 20 | ASLEEP = 2, 21 | AWAKE = 3, 22 | DISCONNECTED = 4, 23 | LOST = 5, 24 | }; 25 | 26 | 27 | #endif //GATEWAY_DATABASE_DEFINES_H 28 | -------------------------------------------------------------------------------- /src/global_defines.h: -------------------------------------------------------------------------------- 1 | ///home/bele/git/SmartWateringWatererPlatformIO 2 | // Created by bele on 09.12.16. 3 | // 4 | 5 | #ifndef GATEWAY_GLOBAL_DEFINES_H 6 | #define GATEWAY_GLOBAL_DEFINES_H 7 | 8 | #include 9 | 10 | struct device_address { 11 | uint8_t bytes[6]; // mac 12 | device_address(){ 13 | bytes[0] = 0x0; 14 | bytes[1] = 0x0; 15 | bytes[2] = 0x0; 16 | bytes[3] = 0x0; 17 | bytes[4] = 0x0; 18 | bytes[5] = 0x0; 19 | } 20 | }; 21 | #endif //GATEWAY_GLOBAL_DEFINES_H 22 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "Gateway.h" 5 | #include "Implementation/SDPersistentImpl.h" 6 | #include "Implementation/ArduinoLogger.h" 7 | #include "Implementation/ArduinoSystem.h" 8 | 9 | 10 | Gateway gateway; 11 | UdpSocketImpl udpSocket; 12 | SDPersistentImpl persistent; 13 | 14 | PahoMqttMessageHandler mqtt; 15 | ArduinoLogger logger; 16 | ArduinoSystem systemImpl; 17 | 18 | std::string getexepath() 19 | { 20 | char result[ PATH_MAX ]; 21 | ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX ); 22 | return std::string( result, (count > 0) ? count : 0 ); 23 | } 24 | 25 | // TODOS: 26 | // implement message saving 27 | // implement resubscribing on startup 28 | 29 | void setup() { 30 | logger.start_log("Linux MQTT-SN Gateway version 0.0.1a starting", 1); 31 | logger.append_log("Ethernet connected!"); 32 | 33 | gateway.setLoggerInterface(&logger); 34 | gateway.setSocketInterface(&udpSocket); 35 | gateway.setMqttInterface(&mqtt); 36 | gateway.setPersistentInterface(&persistent); 37 | gateway.setSystemInterface(&systemImpl); 38 | 39 | while (!gateway.begin()) { 40 | logger.log("Error starting gateway components", 0); 41 | systemImpl.sleep(5000); 42 | systemImpl.exit(); 43 | } 44 | logger.log("Gateway ready", 1); 45 | } 46 | 47 | int main(int argc, char* argv[]) { 48 | std::string workingDir = getexepath() + "/../DB"; 49 | workingDir = "/home/bele/git/arduino-mqtt-sn-gateway/cmake-build-debug/DB"; 50 | persistent.setRootPath((char *) workingDir.c_str()); 51 | setup(); 52 | while(true){ 53 | gateway.loop(); 54 | } 55 | } 56 | 57 | 58 | 59 | --------------------------------------------------------------------------------