Compare commits

..

11 Commits

Author SHA1 Message Date
9e22556d36 fix logging 2020-12-26 22:08:59 +01:00
1ac129a027 add -Wall and -Werror 2020-11-20 11:12:36 +01:00
44647d686f larger buffer 2020-11-15 01:46:41 +01:00
3d52c14d53 api docs 2020-11-13 14:55:49 +01:00
f27e286e57 api docs 2020-11-13 14:52:25 +01:00
dab7dd22a5 api docs 2020-11-13 14:49:28 +01:00
7497aa9921 change in comment in Makefile 2020-11-13 14:42:33 +01:00
931eddce41 readme changed 2020-11-13 14:41:08 +01:00
796b25b7ad readme changed 2020-11-13 14:38:01 +01:00
e4d9be0106 fix clientRead function 2020-11-13 14:13:43 +01:00
477f3e2e3f fixes 2020-11-13 12:37:17 +01:00
6 changed files with 113 additions and 32 deletions

View File

@@ -1,11 +1,10 @@
# Makefile - A simple client for MQTT in C
# Derived from the PubSubClient from Nick O'Leary
# Wolfgang Hottgenroth <woho@hottis.de>
# https://home.hottis.de/gitlab/wolutator/pubsubc
CFLAGS?=-mcpu=cortex-m3 -mthumb -Og -fdata-sections -ffunction-sections -g -gdwarf-2
CFLAGS?=-mcpu=cortex-m3 -mthumb -Og -fdata-sections -ffunction-sections -g -gdwarf-2 -Wall -Werror
CC=arm-none-eabi-gcc
AR=arm-none-eabi-ar

View File

@@ -1,5 +1,85 @@
# pubsubc
This is a minimal MQTT client library in C.
It comes with an adaption layer for the ioLibrary_Driver for the
WizNet chips which can be found here https://github.com/Wiznet/ioLibrary_Driver.
You find a fork with a Makefile a STMCubeMX generated project here
https://home.hottis.de/gitlab/wolutator/ioLibrary_Driver/-/tree/WolfgangsOwnBranch.
Using this adaption layer you should find it easy to adjust it for
other platforms.
This work is directly derived from the famous PubSubClient library
of Nick O'Leary, which can be found at https://pubsubclient.knolleary.net/
It is most or less a plain C rewrite.
All honour for this working MQTT client library goes to Nick O'Leary,
all blame for bugs in the C port shall go to me.
## API
The library provides the following functions:
### Initialization
void mqttClientInit(mqttClient_t *mqttClient, client_t *client, callback_t callback);
Initializes the MQTT client, handover a client handle according to the definition
from ``platformAdaption.h`` and a callback function for incoming messages.
Implement this callback function for incoming messages with this footprint:
typedef void (*callback_t)(char*, uint8_t*, uint16_t);
### Connect
bool mqttConnect(mqttClient_t *mqttClient,
uint8_t *address, uint16_t port,
const char *id,
const char *user, const char *pass,
const char *willTopic, uint8_t willQos,
bool willRetain, const char *willMessage,
bool cleanSession);
In the original C++ implementation multiple variants of the ``connect``method are available
with less and lesser arguments. Unfortunately, in C this is no option. If you don't care
about authentication and the whole will stuff you can call it
mqttConnect(&mqttClient, brokerAddress, brokerPort, clientId, NULL, NULL, NULL, 0, false, NULL, false);
### Disconnect
void mqttDisconnect(mqttClient_t *mqttClient);
### Publish
bool publish(mqttClient_t *mqttClient,
const char *topic,
const uint8_t *payload, uint16_t plength,
bool retained);
### Subscribe and Unsubscribe
bool subscribe(mqttClient_t *mqttClient,
const char *topic, uint8_t qos);
bool unsubscribe(mqttClient_t *mqttClient,
const char* topic);
### Loop
bool mqttLoop(mqttClient_t *mqttClient);
Call this function in your idle loop. For my own part, I've implemented a time-triggered system
and call it with a period of 100ms.
### Connection status
bool mqttConnected(mqttClient_t *mqttClient);

View File

@@ -17,24 +17,24 @@ int clientConnect(client_t *client, uint8_t *host, uint16_t port) {
int8_t res = socket(client->sockNum, Sn_MR_TCP, port, SF_IO_NONBLOCK);
if (res != client->sockNum) {
close(client->sockNum);
return INVALID_RESPONSE;
return PSC_INVALID_RESPONSE;
}
logMsg("clientConnect: socket initialized");
res = connect(client->sockNum, host, port);
if (res != SOCK_BUSY) {
close(client->sockNum);
return INVALID_RESPONSE;
return PSC_INVALID_RESPONSE;
}
uint32_t startTime = HAL_GetTick();
while (startTime + TIMEOUT_MS > HAL_GetTick()) {
while (startTime + PSC_TIMEOUT_MS > HAL_GetTick()) {
uint8_t sockState = getSn_SR(client->sockNum);
if (sockState == SOCK_ESTABLISHED) {
logMsg("clientConnect: connection established");
return SUCCESS;
return PSC_SUCCESS;
}
}
return TIMED_OUT;
return PSC_TIMED_OUT;
}
int clientAvailable(client_t *client) {
@@ -46,11 +46,11 @@ void clientStop(client_t *client) {
if (res != SOCK_BUSY) {
close(client->sockNum);
logMsg("clientStop: disconnect returns 0x%02x, invalid response, ignore it", res);
logMsg("clientStop: disconnect returns %d, invalid response, ignore it", res);
} else {
bool successfullyClosed = false;
uint32_t startTime = HAL_GetTick();
while (startTime + TIMEOUT_MS > HAL_GetTick()) {
while (startTime + PSC_TIMEOUT_MS > HAL_GetTick()) {
uint8_t sockState = getSn_SR(client->sockNum);
if (sockState == SOCK_CLOSED) {
logMsg("clientStop: connection closed");
@@ -72,7 +72,7 @@ int clientRead(client_t *client) {
int res = -1;
if (clientAvailable(client) >= 1) {
uint8_t buf;
int32_t res = recv(client->sockNum, &buf, 1);
res = recv(client->sockNum, &buf, 1);
if (res == 1) {
res = (int) buf;
}
@@ -100,3 +100,5 @@ bool clientConnected(client_t *client) {
uint32_t millis() {
return HAL_GetTick();
}

View File

@@ -14,13 +14,13 @@
#include <stdbool.h>
const int SUCCESS = 1;
const int TIMED_OUT = -1;
const int INVALID_SERVER = -2;
const int TRUNCATED = -3;
const int INVALID_RESPONSE = -4;
#define PSC_SUCCESS 1
#define PSC_TIMED_OUT -1
#define PSC_INVALID_SERVER -2
#define PSC_TRUNCATED -3
#define PSC_INVALID_RESPONSE -4
const uint32_t TIMEOUT_MS = 1000;
#define PSC_TIMEOUT_MS 1000
typedef struct {

View File

@@ -150,14 +150,14 @@ void mqttClientInit(mqttClient_t *mqttClient, client_t *client, callback_t callb
memset(mqttClient->buffer, 0, mqttClient->bufferSize);
}
bool connect(mqttClient_t *mqttClient,
bool mqttConnect(mqttClient_t *mqttClient,
uint8_t *address, uint16_t port,
const char *id,
const char *user, const char *pass,
const char *willTopic, uint8_t willQos,
bool willRetain, const char *willMessage,
bool cleanSession) {
if (!connected(mqttClient)) {
if (!mqttConnected(mqttClient)) {
int result = 0;
if(clientConnected(mqttClient->client)) {
@@ -259,7 +259,7 @@ bool connect(mqttClient_t *mqttClient,
return true;
}
void disconnect(mqttClient_t *mqttClient) {
void mqttDisconnect(mqttClient_t *mqttClient) {
mqttClient->buffer[0] = MQTTDISCONNECT;
mqttClient->buffer[1] = 0;
clientWrite(mqttClient->client, mqttClient->buffer, 2);
@@ -269,8 +269,8 @@ void disconnect(mqttClient_t *mqttClient) {
mqttClient->lastInActivity = mqttClient->lastOutActivity = millis();
}
bool loop(mqttClient_t *mqttClient) {
if (connected(mqttClient)) {
bool mqttLoop(mqttClient_t *mqttClient) {
if (mqttConnected(mqttClient)) {
uint32_t t = millis();
if ((t - mqttClient->lastInActivity > mqttClient->keepAlive*1000UL) ||
(t - mqttClient->lastOutActivity > mqttClient->keepAlive*1000UL)) {
@@ -325,7 +325,7 @@ bool loop(mqttClient_t *mqttClient) {
} else if (type == MQTTPINGRESP) {
mqttClient->pingOutstanding = false;
}
} else if (!connected(mqttClient)) {
} else if (!mqttConnected(mqttClient)) {
// readPacket has closed the connection
return false;
}
@@ -335,7 +335,7 @@ bool loop(mqttClient_t *mqttClient) {
return false;
}
bool connected(mqttClient_t *mqttClient) {
bool mqttConnected(mqttClient_t *mqttClient) {
bool rc;
if (mqttClient->client == NULL ) {
rc = false;
@@ -358,7 +358,7 @@ bool publish(mqttClient_t *mqttClient,
const char *topic,
const uint8_t *payload, uint16_t plength,
bool retained) {
if (connected(mqttClient)) {
if (mqttConnected(mqttClient)) {
if (mqttClient->bufferSize < MQTT_MAX_HEADER_SIZE + 2 + strnlen(topic, mqttClient->bufferSize) + plength) {
// Too long
return false;
@@ -395,7 +395,7 @@ bool subscribe(mqttClient_t *mqttClient,
// Too long
return false;
}
if (connected(mqttClient)) {
if (mqttConnected(mqttClient)) {
// Leave room in the buffer for header and variable length field
uint16_t length = MQTT_MAX_HEADER_SIZE;
mqttClient->nextMsgId++;
@@ -421,7 +421,7 @@ bool unsubscribe(mqttClient_t *mqttClient,
// Too long
return false;
}
if (connected(mqttClient)) {
if (mqttConnected(mqttClient)) {
uint16_t length = MQTT_MAX_HEADER_SIZE;
mqttClient->nextMsgId++;
if (mqttClient->nextMsgId == 0) {

View File

@@ -22,7 +22,7 @@
// MQTT_MAX_PACKET_SIZE : Maximum packet size. Override with setBufferSize().
#ifndef MQTT_MAX_PACKET_SIZE
#define MQTT_MAX_PACKET_SIZE 256
#define MQTT_MAX_PACKET_SIZE 512
#endif
// MQTT_KEEPALIVE : keepAlive interval in Seconds. Override with setKeepAlive()
@@ -100,7 +100,7 @@ typedef struct {
void mqttClientInit(mqttClient_t *mqttClient, client_t *client, callback_t callback);
bool connect(mqttClient_t *mqttClient,
bool mqttConnect(mqttClient_t *mqttClient,
uint8_t *address, uint16_t port,
const char *id,
const char *user, const char *pass,
@@ -108,7 +108,7 @@ bool connect(mqttClient_t *mqttClient,
bool willRetain, const char *willMessage,
bool cleanSession);
void disconnect(mqttClient_t *mqttClient);
void mqttDisconnect(mqttClient_t *mqttClient);
bool publish(mqttClient_t *mqttClient,
const char *topic,
@@ -120,8 +120,8 @@ bool subscribe(mqttClient_t *mqttClient,
bool unsubscribe(mqttClient_t *mqttClient,
const char* topic);
bool loop(mqttClient_t *mqttClient);
bool mqttLoop(mqttClient_t *mqttClient);
bool connected(mqttClient_t *mqttClient);
bool mqttConnected(mqttClient_t *mqttClient);
#endif // _PUBSUBC_H_