convert to mqtt clock

This commit is contained in:
mreenen 2023-01-26 23:33:16 +01:00
parent 0df4ec2435
commit 9e2a88bb5f
30 changed files with 5176 additions and 195 deletions

11
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "cppdbg"
}
]
}

9
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
"makefile.launchConfigurations": [
{
"cwd": "/home/mreenen/Documents/git/relayClient",
"binaryPath": "/home/mreenen/Documents/git/relayClient/relayClient",
"binaryArgs": []
}
]
}

9
Makefile Normal file
View File

@ -0,0 +1,9 @@
SRC := src/main.c src/mqtt.c
INC := -I src -I include/paho-mqtt
LIBS := -Llibs/paho-mqtt -lpthread -lpaho-mqtt3a -lpaho-mqtt3c
all: build
build: $(SRC)
gcc $(SRC) $(LIBS) -o relayClient $(INC)

View File

@ -1,6 +1,6 @@
#!/bin/bash
gcc src/main.c src/mqtt.c src/gpio.c \
-lpthread -lpaho-mqtt3a -lbcm2835 \
gcc src/main.c src/gpio.c \
-lpthread -lpaho-mqtt3a \
-o relayClient \
-I src
-I src -I include/paho-mqtt

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,277 @@
/*******************************************************************************
* Copyright (c) 2009, 2020 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
/**
* @file
* \brief This structure represents a persistent data store, used to store
* outbound and inbound messages, in order to achieve reliable messaging.
*
* The MQTT Client persists QoS1 and QoS2 messages in order to meet the
* assurances of delivery associated with these @ref qos levels. The messages
* are saved in persistent storage
* The type and context of the persistence implementation are specified when
* the MQTT client is created (see MQTTClient_create()). The default
* persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based
* persistence mechanism. The <i>persistence_context</i> argument passed to
* MQTTClient_create() when using the default peristence is a string
* representing the location of the persistence directory. If the context
* argument is NULL, the working directory will be used.
*
* To use memory-based persistence, an application passes
* ::MQTTCLIENT_PERSISTENCE_NONE as the <i>persistence_type</i> to
* MQTTClient_create(). This can lead to message loss in certain situations,
* but can be appropriate in some cases (see @ref qos).
*
* Client applications can provide their own persistence mechanism by passing
* ::MQTTCLIENT_PERSISTENCE_USER as the <i>persistence_type</i>. To implement a
* custom persistence mechanism, the application must pass an initialized
* ::MQTTClient_persistence structure as the <i>persistence_context</i>
* argument to MQTTClient_create().
*
* If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the
* state of the persisted data should remain as it was prior to the function
* being called. For example, if Persistence_put() returns
* ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store
* does not contain the data that was passed to the function. Similarly, if
* Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is
* assumed that the data to be removed is still held in the persistent store.
*
* It is up to the persistence implementation to log any error information that
* may be required to diagnose a persistence mechanism failure.
*/
/*
/// @cond EXCLUDE
*/
#if !defined(MQTTCLIENTPERSISTENCE_H)
#define MQTTCLIENTPERSISTENCE_H
/*
/// @endcond
*/
/**
* This <i>persistence_type</i> value specifies the default file system-based
* persistence mechanism (see MQTTClient_create()).
*/
#define MQTTCLIENT_PERSISTENCE_DEFAULT 0
/**
* This <i>persistence_type</i> value specifies a memory-based
* persistence mechanism (see MQTTClient_create()).
*/
#define MQTTCLIENT_PERSISTENCE_NONE 1
/**
* This <i>persistence_type</i> value specifies an application-specific
* persistence mechanism (see MQTTClient_create()).
*/
#define MQTTCLIENT_PERSISTENCE_USER 2
/**
* Application-specific persistence functions must return this error code if
* there is a problem executing the function.
*/
#define MQTTCLIENT_PERSISTENCE_ERROR -2
/**
* @brief Initialize the persistent store.
*
* Either open the existing persistent store for this client ID or create a new
* one if one doesn't exist. If the persistent store is already open, return
* without taking any action.
*
* An application can use the same client identifier to connect to many
* different servers. The <i>clientid</i> in conjunction with the
* <i>serverURI</i> uniquely identifies the persistence store required.
*
* @param handle The address of a pointer to a handle for this persistence
* implementation. This function must set handle to a valid reference to the
* persistence following a successful return.
* The handle pointer is passed as an argument to all the other
* persistence functions. It may include the context parameter and/or any other
* data for use by the persistence functions.
* @param clientID The client identifier for which the persistent store should
* be opened.
* @param serverURI The connection string specified when the MQTT client was
* created (see MQTTClient_create()).
* @param context A pointer to any data required to initialize the persistent
* store (see ::MQTTClient_persistence).
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context);
/**
* @brief Close the persistent store referred to by the handle.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_close)(void* handle);
/**
* @brief Put the specified data into the persistent store.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param key A string used as the key for the data to be put in the store. The
* key is later used to retrieve data from the store with Persistence_get().
* @param bufcount The number of buffers to write to the persistence store.
* @param buffers An array of pointers to the data buffers associated with
* this <i>key</i>.
* @param buflens An array of lengths of the data buffers. <i>buflen[n]</i>
* gives the length of <i>buffer[n]</i>.
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]);
/**
* @brief Retrieve the specified data from the persistent store.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param key A string that is the key for the data to be retrieved. This is
* the same key used to save the data to the store with Persistence_put().
* @param buffer The address of a pointer to a buffer. This function sets the
* pointer to point at the retrieved data, if successful.
* @param buflen The address of an int that is set to the length of
* <i>buffer</i> by this function if successful.
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen);
/**
* @brief Remove the data for the specified key from the store.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param key A string that is the key for the data to be removed from the
* store. This is the same key used to save the data to the store with
* Persistence_put().
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_remove)(void* handle, char* key);
/**
* @brief Returns the keys in this persistent data store.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param keys The address of a pointer to pointers to strings. Assuming
* successful execution, this function allocates memory to hold the returned
* keys (strings used to store the data with Persistence_put()). It also
* allocates memory to hold an array of pointers to these strings. <i>keys</i>
* is set to point to the array of pointers to strings.
* @param nkeys A pointer to the number of keys in this persistent data store.
* This function sets the number of keys, if successful.
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys);
/**
* @brief Clears the persistence store, so that it no longer contains any
* persisted data.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_clear)(void* handle);
/**
* @brief Returns whether any data has been persisted using the specified key.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param key The string to be tested for existence in the store.
* @return Return 0 if the key was found in the store, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_containskey)(void* handle, char* key);
/**
* @brief A structure containing the function pointers to a persistence
* implementation and the context or state that will be shared across all
* the persistence functions.
*/
typedef struct {
/**
* A pointer to any data required to initialize the persistent store.
*/
void* context;
/**
* A function pointer to an implementation of Persistence_open().
*/
Persistence_open popen;
/**
* A function pointer to an implementation of Persistence_close().
*/
Persistence_close pclose;
/**
* A function pointer to an implementation of Persistence_put().
*/
Persistence_put pput;
/**
* A function pointer to an implementation of Persistence_get().
*/
Persistence_get pget;
/**
* A function pointer to an implementation of Persistence_remove().
*/
Persistence_remove premove;
/**
* A function pointer to an implementation of Persistence_keys().
*/
Persistence_keys pkeys;
/**
* A function pointer to an implementation of Persistence_clear().
*/
Persistence_clear pclear;
/**
* A function pointer to an implementation of Persistence_containskey().
*/
Persistence_containskey pcontainskey;
} MQTTClient_persistence;
/**
* A callback which is invoked just before a write to persistence. This can be
* used to transform the data, for instance to encrypt it.
* @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite
* @param bufcount The number of buffers to write to the persistence store.
* @param buffers An array of pointers to the data buffers.
* @param buflens An array of lengths of the data buffers.
* @return Return 0 if the function completes successfully, otherwise non 0.
*/
typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]);
/**
* A callback which is invoked just after a read from persistence. This can be
* used to transform the data, for instance to decrypt it.
* @param context The context as set in ::MQTTAsync_setAfterPersistenceRead
* @param buffer The address of a pointer to a buffer.
* @param buflen The address of an int that is the length of the buffer.
* @return Return 0 if the function completes successfully, otherwise non 0.
*/
typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen);
#endif

View File

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2020, 2020 Andreas Walter
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Andreas Walter - initially moved export declarations into separate fle
*******************************************************************************/
#if !defined(EXPORTDECLARATIONS_H)
#define EXPORTDECLARATIONS_H
#if defined(_WIN32) || defined(_WIN64)
# if defined(PAHO_MQTT_EXPORTS)
# define LIBMQTT_API __declspec(dllexport)
# elif defined(PAHO_MQTT_IMPORTS)
# define LIBMQTT_API __declspec(dllimport)
# else
# define LIBMQTT_API
# endif
#else
# if defined(PAHO_MQTT_EXPORTS)
# define LIBMQTT_API __attribute__ ((visibility ("default")))
# else
# define LIBMQTT_API extern
# endif
#endif
#endif

View File

@ -0,0 +1,219 @@
/*******************************************************************************
* Copyright (c) 2017, 2020 IBM Corp. and others
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTPROPERTIES_H)
#define MQTTPROPERTIES_H
#include "MQTTExportDeclarations.h"
#define MQTT_INVALID_PROPERTY_ID -2
/** The one byte MQTT V5 property indicator */
enum MQTTPropertyCodes {
MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */
MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */
MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */
MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */
MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */
MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */
MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */
MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */
MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */
MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */
MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */
MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */
MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */
MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */
MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */
MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */
MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */
MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/
MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */
MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */
MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */
MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */
MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */
MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */
MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */
MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */
MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */
};
/**
* Returns a printable string description of an MQTT V5 property code.
* @param value an MQTT V5 property code.
* @return the printable string description of the input property code.
* NULL if the code was not found.
*/
LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value);
/** The one byte MQTT V5 property type */
enum MQTTPropertyTypes {
MQTTPROPERTY_TYPE_BYTE,
MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER,
MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER,
MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER,
MQTTPROPERTY_TYPE_BINARY_DATA,
MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING,
MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR
};
/**
* Returns the MQTT V5 type code of an MQTT V5 property.
* @param value an MQTT V5 property code.
* @return the MQTT V5 type code of the input property. -1 if the code was not found.
*/
LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value);
/**
* The data for a length delimited string
*/
typedef struct
{
int len; /**< the length of the string */
char* data; /**< pointer to the string data */
} MQTTLenString;
/**
* Structure to hold an MQTT version 5 property of any type
*/
typedef struct
{
enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */
/** The value of the property, as a union of the different possible types. */
union {
unsigned char byte; /**< holds the value of a byte property type */
unsigned short integer2; /**< holds the value of a 2 byte integer property type */
unsigned int integer4; /**< holds the value of a 4 byte integer property type */
struct {
MQTTLenString data; /**< The value of a string property, or the name of a user property. */
MQTTLenString value; /**< The value of a user property. */
};
} value;
} MQTTProperty;
/**
* MQTT version 5 property list
*/
typedef struct MQTTProperties
{
int count; /**< number of property entries in the array */
int max_count; /**< max number of properties that the currently allocated array can store */
int length; /**< mbi: byte length of all properties */
MQTTProperty *array; /**< array of properties */
} MQTTProperties;
#define MQTTProperties_initializer {0, 0, 0, NULL}
/**
* Returns the length of the properties structure when serialized ready for network transmission.
* @param props an MQTT V5 property structure.
* @return the length in bytes of the properties when serialized.
*/
int MQTTProperties_len(MQTTProperties* props);
/**
* Add a property pointer to the property array. There is no memory allocation.
* @param props The property list to add the property to.
* @param prop The property to add to the list.
* @return 0 on success, -1 on failure.
*/
LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop);
/**
* Serialize the given property list to a character buffer, e.g. for writing to the network.
* @param pptr pointer to the buffer - move the pointer as we add data
* @param properties pointer to the property list, can be NULL
* @return whether the write succeeded or not: number of bytes written, or < 0 on failure.
*/
int MQTTProperties_write(char** pptr, const MQTTProperties* properties);
/**
* Reads a property list from a character buffer into an array.
* @param properties pointer to the property list to be filled. Should be initalized but empty.
* @param pptr pointer to the character buffer.
* @param enddata pointer to the end of the character buffer so we don't read beyond.
* @return 1 if the properties were read successfully.
*/
int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata);
/**
* Free all memory allocated to the property list, including any to individual properties.
* @param properties pointer to the property list.
*/
LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties);
/**
* Copy the contents of a property list, allocating additional memory if needed.
* @param props pointer to the property list.
* @return the duplicated property list.
*/
LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props);
/**
* Checks if property list contains a specific property.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @return 1 if found, 0 if not.
*/
LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid);
/**
* Returns the number of instances of a property id. Most properties can exist only once.
* User properties and subscription ids can exist more than once.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @return the number of times found. Can be 0.
*/
LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid);
/**
* Returns the integer value of a specific property. The property given must be a numeric type.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @return the integer value of the property. -9999999 on failure.
*/
LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid);
/**
* Returns the integer value of a specific property when it's not the only instance.
* The property given must be a numeric type.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @param index the instance number, starting at 0.
* @return the integer value of the property. -9999999 on failure.
*/
LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index);
/**
* Returns a pointer to the property structure for a specific property.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @return the pointer to the property structure if found. NULL if not found.
*/
LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid);
/**
* Returns a pointer to the property structure for a specific property when it's not the only instance.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @param index the instance number, starting at 0.
* @return the pointer to the property structure if found. NULL if not found.
*/
LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index);
#endif /* MQTTPROPERTIES_H */

View File

@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2017, 2020 IBM Corp. and others
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTREASONCODES_H)
#define MQTTREASONCODES_H
#include "MQTTExportDeclarations.h"
/** The MQTT V5 one byte reason code */
enum MQTTReasonCodes {
MQTTREASONCODE_SUCCESS = 0,
MQTTREASONCODE_NORMAL_DISCONNECTION = 0,
MQTTREASONCODE_GRANTED_QOS_0 = 0,
MQTTREASONCODE_GRANTED_QOS_1 = 1,
MQTTREASONCODE_GRANTED_QOS_2 = 2,
MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4,
MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16,
MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17,
MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24,
MQTTREASONCODE_RE_AUTHENTICATE = 25,
MQTTREASONCODE_UNSPECIFIED_ERROR = 128,
MQTTREASONCODE_MALFORMED_PACKET = 129,
MQTTREASONCODE_PROTOCOL_ERROR = 130,
MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131,
MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132,
MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133,
MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134,
MQTTREASONCODE_NOT_AUTHORIZED = 135,
MQTTREASONCODE_SERVER_UNAVAILABLE = 136,
MQTTREASONCODE_SERVER_BUSY = 137,
MQTTREASONCODE_BANNED = 138,
MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139,
MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140,
MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141,
MQTTREASONCODE_SESSION_TAKEN_OVER = 142,
MQTTREASONCODE_TOPIC_FILTER_INVALID = 143,
MQTTREASONCODE_TOPIC_NAME_INVALID = 144,
MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145,
MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146,
MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147,
MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148,
MQTTREASONCODE_PACKET_TOO_LARGE = 149,
MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150,
MQTTREASONCODE_QUOTA_EXCEEDED = 151,
MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152,
MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153,
MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154,
MQTTREASONCODE_QOS_NOT_SUPPORTED = 155,
MQTTREASONCODE_USE_ANOTHER_SERVER = 156,
MQTTREASONCODE_SERVER_MOVED = 157,
MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158,
MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159,
MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160,
MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161,
MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162
};
/**
* Returns a printable string description of an MQTT V5 reason code.
* @param value an MQTT V5 reason code.
* @return the printable string description of the input reason code.
* NULL if the code was not found.
*/
LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value);
#endif

View File

@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2018 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(SUBOPTS_H)
#define SUBOPTS_H
/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */
typedef struct MQTTSubscribe_options
{
/** The eyecatcher for this structure. Must be MQSO. */
char struct_id[4];
/** The version number of this structure. Must be 0.
*/
int struct_version;
/** To not receive our own publications, set to 1.
* 0 is the original MQTT behaviour - all messages matching the subscription are received.
*/
unsigned char noLocal;
/** To keep the retain flag as on the original publish message, set to 1.
* If 0, defaults to the original MQTT behaviour where the retain flag is only set on
* publications sent by a broker if in response to a subscribe request.
*/
unsigned char retainAsPublished;
/** 0 - send retained messages at the time of the subscribe (original MQTT behaviour)
* 1 - send retained messages on subscribe only if the subscription is new
* 2 - do not send retained messages at all
*/
unsigned char retainHandling;
} MQTTSubscribe_options;
#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 }
#endif

View File

@ -0,0 +1 @@
libpaho-mqtt3a.so.1

View File

@ -0,0 +1 @@
libpaho-mqtt3a.so.1.3.12

Binary file not shown.

View File

@ -0,0 +1 @@
libpaho-mqtt3as.so.1

View File

@ -0,0 +1 @@
libpaho-mqtt3as.so.1.3.12

Binary file not shown.

View File

@ -0,0 +1 @@
libpaho-mqtt3c.so.1

View File

@ -0,0 +1 @@
libpaho-mqtt3c.so.1.3.12

Binary file not shown.

View File

@ -0,0 +1 @@
libpaho-mqtt3cs.so.1

View File

@ -0,0 +1 @@
libpaho-mqtt3cs.so.1.3.12

Binary file not shown.

Binary file not shown.

View File

@ -1,11 +1,9 @@
#if !defined(CONF_H)
#define CONF_H
#define ADDRESS "tcp://test.mosquitto.org:1883"
#define CLIENTID "relayClient"
#define TOPIC "coolhaven/relayClient"
#define PAYLOAD "relay1=on"
#define QOS 1
#define ADDRESS "tcp://localhost:1883"
#define CLIENTID "mqttClock"
#define TOPIC "coolhaven/clock"
#define TIMEOUT 10000L
#define RECON_TIMEOUT 60

View File

@ -1,26 +0,0 @@
// const uint LED_PIN = PICO_DEFAULT_LED_PIN;
// gpio_init(LED_PIN);
// gpio_set_dir(LED_PIN, GPIO_OUT);
// while (true) {
// gpio_put(LED_PIN, 1);
// sleep_ms(250);
// gpio_put(LED_PIN, 0);
// sleep_ms(250);
// }
#include <stdio.h>
#include <bcm2835.h>
void gpio_init(unsigned int p){
bcm2835_init();
}
void gpio_set_dir(unsigned int gpio, int out){
printf("DEBUG: set gpio pin %d to an %s\n", gpio, (out) ? "output" : "input");
bcm2835_gpio_fsel(gpio, (out) ? BCM2835_GPIO_FSEL_OUTP : BCM2835_GPIO_FSEL_INPT);
}
void gpio_put(unsigned int gpio, int value){
bcm2835_gpio_write(gpio, (value) ? HIGH : LOW);
}

View File

@ -1,5 +0,0 @@
void gpio_init(unsigned int p);
void gpio_set_dir(unsigned int gpio, int out);
void gpio_put(unsigned int gpio, int value);

View File

@ -1,126 +1,84 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "conf.h"
#include "MQTTAsync.h"
#include "mqtt.h"
#include "gpio.h"
// 4: relay displays
// 17: led strip
// 22: relay2
// 27: relay3
void onConnect(void* context){
MQTT_subscribe("coolhaven/relayClient", 1);
}
const int gpio_pin[] = {4, 17, 22, 27, -1, -1, -1, -1, -1, -1};
typedef enum action_e {TURN_ON, TURN_OFF, TOGGLE} action_t;
void action(int relay, action_t acct){
if(gpio_pin[relay] == -1){
printf("WARING: invalid relay number");
return;
}
switch (acct) {
case TURN_ON:
printf("ACTION: turn relay%d on\n", relay);
gpio_put(gpio_pin[relay], 0);
break;
case TURN_OFF:
printf("ACTION: turn relay%d off\n", relay);
gpio_put(gpio_pin[relay], 1);
break;
case TOGGLE:
// printf("ACTION: Toggle relay%d\n", relay);
printf("WARNING: Toogle not suported yet\n");
break;
}
}
void relayClient(MQTTAsync_message* message){
//message->payloadlen, (char*)message->payload
if(message->payloadlen < 6){
printf("ERROR: playload to short\n");
return;
}
if(!strncmp(message->payload, "relay", 5)){
printf("ERROR: invalid playload\n");
return;
}
char relay = *((char*)(message->payload + 5));
if(relay < '0' && relay > '9'){
printf("ERROR: invalid playload\n");
return;
}
relay -= '0';
if(message->payloadlen == 6){
action(relay, TOGGLE);
return;
}
if(*((char*)(message->payload + 6)) != '='){
printf("ERROR: invalid playload\n");
return;
}
if(message->payloadlen == 9 && strncmp(message->payload + 6, "on", 2)){
action(relay, TURN_ON);
return;
}
if(message->payloadlen == 10 && strncmp(message->payload + 6, "off", 3)){
action(relay, TURN_OFF);
return;
}
return;
}
void onMessage(char* topicName, int topicLen, MQTTAsync_message* message){
char* topic = "coolhaven/relayClient";
char result = 1;
for (int i = 0; i < topicLen && i < strlen(topic); i++) {
if(*(topicName+i) != *(topic+i)){
result = 0;
printf("topic corect until char %d\n", i);
break;
}
}
if(result){
relayClient(message);
return;
}
// if(strncmp(topicName, "coolhaven/relayClient", topicLen)){
// relayClient(message);
// return;
// }
printf("invlid topic (%.*s; %d)\n", topicLen, topicName, topicLen);
return;
return;
}
void sendTick(char* name, struct tm* t)
{
char topic[100] = TOPIC "/";
strcat(&topic[0], name);
char payload[50];
sprintf(&payload[0], "%04d-%02d-%02dT%02d:%02d:%02d",
t->tm_year,
t->tm_mon + 1,
t->tm_mday,
t->tm_hour,
t->tm_min,
t->tm_sec
);
MQTT_publish(topic, &payload[0], 1);
}
int main(int argc, char* argv[]){
printf("==============================\n"
"=== relayClient ==============\n"
"==============================\n\n");
printf("==============================\n"
"=== mqttClock ================\n"
"==============================\n\n");
gpio_init(5);
for(int i=0; i<10; i++){
if(gpio_pin[i] == 0)
continue;
gpio_set_dir(gpio_pin[i], 1);
}
clientConf_t* client = MQTT_connect(&onConnect, &onMessage);
clientConf_t* client = MQTT_connect(&onConnect, &onMessage);
if(client == NULL){
return -1;
}
if(client != NULL){
int lastMin = 0;
int lastHour = 0;
char ch = 0;
while(ch != 'Q' && ch != 'q'){
ch = getchar();
switch (ch) {
case 'q':
case 'Q':
MQTT_disconnect(client);
return 0;
}
int returnCode = 1;
while (returnCode = 1)
{
time_t rowNow = time(NULL);
struct tm* now = gmtime(&rowNow);
sendTick("second", now);
if (now->tm_min != lastMin)
{
sendTick("minute", now);
lastMin = now->tm_min;
if (now->tm_hour != lastHour)
{
sendTick("hour", now);
lastHour = now->tm_hour;
}
}
char ch = getchar();
switch (ch) {
case 'q':
case 'Q':
returnCode = 0;
MQTT_disconnect(client);
}
}
}
else
{
printf("failt to connect to mqtt\n");
return -1;
}
return 0;
}

View File

@ -4,105 +4,106 @@
#include "conf.h"
#include "MQTTClient.h"
#include "MQTTAsync.h"
#include "mqtt.h"
clientConf_t* client;
void reconnect(){
int rc;
int rc;
if(client->last_reconn.t + RECON_TIMEOUT > time(NULL)){
if(client->last_reconn.c < 10){
printf("Wait %d seconds until reconect. reconect counter on %d\n", RECON_TIMEOUT, client->last_reconn.c);
SLEEP(RECON_TIMEOUT);
} else {
printf("Wait one hour until reconect. reconect counter on %d\n", client->last_reconn.c);
SLEEP(3600);
}
}
if(client->last_reconn.t + RECON_TIMEOUT > time(NULL)){
if(client->last_reconn.c < 10){
printf("Wait %d seconds until reconect. reconect counter on %d\n", RECON_TIMEOUT, client->last_reconn.c);
SLEEP(RECON_TIMEOUT);
} else {
printf("Wait one hour until reconect. reconect counter on %d\n", client->last_reconn.c);
SLEEP(3600);
}
}
printf("Reconnecting to MQTT server\n");
rc = MQTTAsync_connect(client->client, &(client->conn_opts));
rc = MQTTAsync_connect(client->client, &(client->conn_opts));
if (rc != MQTTASYNC_SUCCESS){
printf("ERROR: Failed to reconnect, return code %d\n", rc);
client->last_reconn.t = time(NULL);
client->last_reconn.c++;
client->last_reconn.t = time(NULL);
client->last_reconn.c++;
} else {
client->last_reconn.c = 0;
}
client->last_reconn.c = 0;
}
}
void connlost(void *context, char *cause){
printf("\nERROR: Lost connection to MQTT\n");
if(cause){
printf(" cause: %s\n", cause);
}
}
reconnect();
reconnect();
}
int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message){
printf("Message arrived\n");
printf(" topic: %s\n", topicName);
printf(" message: %.*s\n", message->payloadlen, (char*)message->payload);
printf("Message arrived\n");
printf(" topic: %s\n", topicName);
printf(" message: %.*s\n", message->payloadlen, (char*)message->payload);
(*(client->onMessage))(topicName, topicLen, message);
(*(client->onMessage))(topicName, topicLen, message);
MQTTAsync_freeMessage(&message);
MQTTAsync_free(topicName);
return 1;
MQTTAsync_freeMessage(&message);
MQTTAsync_free(topicName);
return 1;
}
void onConnectFailure(void* context, MQTTAsync_failureData* response){
printf("Connect failed, rc %d\n", response->code);
reconnect();
reconnect();
}
void onConn(void* context, MQTTAsync_successData* response){
printf("connected to MQTT server\n");
(*(client->onConnect))(client);
(*(client->onConnect))(client);
}
clientConf_t* MQTT_connect(void (*onConnect_cb)(void* context), void (*onMessage)(char* topicName, int topicLen, MQTTAsync_message* message)){
client = (clientConf_t*) malloc(sizeof(clientConf_t)); // keep this util i say so
client = (clientConf_t*) malloc(sizeof(clientConf_t)); // keep this util i say so
int rc;
int ch;
rc = MQTTAsync_create(&(client->client), ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
rc = MQTTAsync_create(&(client->client), ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTASYNC_SUCCESS){
printf("Failed to create client, return code %d\n", rc);
free(client);
free(client);
return NULL;
}
client->onMessage = onMessage;
client->onConnect = onConnect_cb;
client->last_reconn.c = 0;
client->last_reconn.t = 0;
client->onMessage = onMessage;
client->onConnect = onConnect_cb;
client->last_reconn.c = 0;
client->last_reconn.t = 0;
rc = MQTTAsync_setCallbacks(client->client, client, &connlost, &msgarrvd, NULL);
rc = MQTTAsync_setCallbacks(client->client, client, &connlost, &msgarrvd, NULL);
if (rc != MQTTASYNC_SUCCESS){
printf("Failed to set callbacks, return code %d\n", rc);
MQTTAsync_destroy(&(client->client));
free(client);
MQTTAsync_destroy(&(client->client));
free(client);
return NULL;
}
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
client->conn_opts = conn_opts;
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
client->conn_opts = conn_opts;
client->conn_opts.keepAliveInterval = 20;
client->conn_opts.cleansession = 1;
client->conn_opts.onSuccess = onConn;
client->conn_opts.onFailure = onConnectFailure;
client->conn_opts.context = &client;
printf("connecting to MQTT server (%s)\n", ADDRESS);
rc = MQTTAsync_connect(client->client, &(client->conn_opts));
printf("connecting to MQTT server (%s)\n", ADDRESS);
rc = MQTTAsync_connect(client->client, &(client->conn_opts));
if(rc != MQTTASYNC_SUCCESS){
printf("Failed to start connect, return code %d\n", rc);
MQTTAsync_destroy(&(client->client));
free(client);
MQTTAsync_destroy(&(client->client));
free(client);
return NULL;
}
@ -113,22 +114,22 @@ clientConf_t* MQTT_connect(void (*onConnect_cb)(void* context), void (*onMessage
void onDisconnectFailure(void* context, MQTTAsync_failureData* response){
printf("Faild to discontect from MQTT, rc %d\n", response->code);
MQTTAsync_destroy(client->client);
free(client);
MQTTAsync_destroy(client->client);
free(client);
}
void onDisconnect(void* context, MQTTAsync_successData* response){
printf("disconnected from MQTT server\n");
MQTTAsync_destroy(client->client);
free(client);
MQTTAsync_destroy(client->client);
free(client);
}
void MQTT_disconnect(){
int rc;
MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
int rc;
MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
disc_opts.onSuccess = &onDisconnect;
disc_opts.onFailure = &onDisconnectFailure;
rc = MQTTAsync_disconnect(client->client, &disc_opts);
rc = MQTTAsync_disconnect(client->client, &disc_opts);
if (rc != MQTTASYNC_SUCCESS){
printf("Failed to start disconnect, return code %d\n", rc);
MQTTAsync_destroy(client->client);
@ -154,9 +155,14 @@ void MQTT_subscribe(char* topic, int qos){
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
opts.onSuccess = &onSubscribe;
opts.onFailure = &onSubscribeFailure;
opts.context = topic;
rc = MQTTAsync_subscribe(client->client, topic, qos, &opts);
opts.context = topic;
rc = MQTTAsync_subscribe(client->client, topic, qos, &opts);
if (rc != MQTTASYNC_SUCCESS){
printf("ERROR: Failed to start subscribe, return code %d\n", rc);
}
}
void MQTT_publish(char* topic, char* payload, int qos)
{
MQTTClient_publish(client->client, topic, len(topic), payload, qos, 0, NULL);
}

View File

@ -20,5 +20,6 @@ clientConf_t* MQTT_connect(void (*onConnect)(void* context), void (*onMessage)(c
void MQTT_disconnect();
void MQTT_subscribe(char* topic, int qos);
void MQTT_publish(char* topic, char* payload, int qos);
#endif