diff --git a/.cproject b/.cproject index b8205bb..4bb06e0 100644 --- a/.cproject +++ b/.cproject @@ -26,10 +26,9 @@ - - + @@ -42,10 +41,9 @@ - - + @@ -58,10 +56,9 @@ - - + diff --git a/.project b/.project index 11b3465..25dab8c 100644 --- a/.project +++ b/.project @@ -72,10 +72,5 @@ 2 ECLIPSE_HOME/arduinoPlugin/libraries/FastLED/3.1.6 - - libraries/pubsubclient - 2 - /home/wn/Arduino/libraries/pubsubclient - diff --git a/ConfigGenerator/configGen.py b/ConfigGenerator/configGen.py index c6ad5f9..4efc30d 100644 --- a/ConfigGenerator/configGen.py +++ b/ConfigGenerator/configGen.py @@ -16,7 +16,7 @@ configItems = [ {"label":"MQTT Password", "key":"mqttPass", "type":"C", "length":32, "default":"geheim123"}, {"label":"MQTT ClientId", "key":"mqttClientId", "type":"C", "length":32, "default":"RgbLed1"}, {"label":"MQTT Port", "key":"mqttPort", "type":"I", "default":8883}, - {"label":"MQTT Topic Number of LEDs", "key":"mqttTopicNumOfLeds", "type":"C", "length":64, "default":"IoT/RgbLed1/NumOfLeds"}, + {"label":"MQTT Topic Command", "key":"mqttTopicCommand", "type":"C", "length":64, "default":"IoT/RgbLed1/Command"}, {"label":"MQTT Topic Color to all LEDs", "key":"mqttTopicColorAllLed", "type":"C", "length":64, "default":"IoT/RgbLed1/ColorAllLed"}, {"label":"MQTT Topic Color to one LED", "key":"mqttTopicColorOneLed", "type":"C", "length":64, "default":"IoT/RgbLed1/ColorLed"}, {"label":"MQTT Topic Status to all LED", "key":"mqttTopicStatusAllLed", "type":"C", "length":64, "default":"IoT/RgbLed1/StatusAllLed"}, diff --git a/configuration.cpp b/configuration.cpp index b69d527..41b9f92 100644 --- a/configuration.cpp +++ b/configuration.cpp @@ -36,7 +36,7 @@ void configServeIndex() { strcpy(configBlock.mqttPass, "geheim123"); strcpy(configBlock.mqttClientId, "RgbLed1"); configBlock.mqttPort = 8883; - strcpy(configBlock.mqttTopicNumOfLeds, "IoT/RgbLed1/NumOfLeds"); + strcpy(configBlock.mqttTopicCommand, "IoT/RgbLed1/Command"); strcpy(configBlock.mqttTopicColorAllLed, "IoT/RgbLed1/ColorAllLed"); strcpy(configBlock.mqttTopicColorOneLed, "IoT/RgbLed1/ColorLed"); strcpy(configBlock.mqttTopicStatusAllLed, "IoT/RgbLed1/StatusAllLed"); @@ -202,13 +202,13 @@ void configServeIndex() { " " " " " " - " " + " " " " - " "); - Serial.print("mqttTopicNumOfLeds = <"); - Serial.print(configBlock.mqttTopicNumOfLeds); + Serial.print("mqttTopicCommand = <"); + Serial.print(configBlock.mqttTopicCommand); Serial.println(">"); Serial.print("mqttTopicColorAllLed = <"); diff --git a/configuration.h b/configuration.h index 8961a7d..f62c412 100644 --- a/configuration.h +++ b/configuration.h @@ -9,7 +9,7 @@ typedef struct { char mqttPass[32]; char mqttClientId[32]; uint32_t mqttPort; - char mqttTopicNumOfLeds[64]; + char mqttTopicCommand[64]; char mqttTopicColorAllLed[64]; char mqttTopicColorOneLed[64]; char mqttTopicStatusAllLed[64]; diff --git a/defines.h b/defines.h index cb4349c..80d8ed8 100644 --- a/defines.h +++ b/defines.h @@ -12,8 +12,9 @@ #define EEPROM_ADDR 0 -#define CONFIG_SWITCH 5 +#define CONFIG_SWITCH 2 #define PIXEL_PIN 1 +#define NUM_OF_LEDs 16 #endif /* DEFINES_H_ */ diff --git a/productionMode.cpp b/productionMode.cpp index f02b02d..0a79e14 100644 --- a/productionMode.cpp +++ b/productionMode.cpp @@ -17,6 +17,9 @@ #include #include +#define FASTLED_ESP8266_NODEMCU_PIN_ORDER +#include + #include "configuration.h" @@ -29,6 +32,11 @@ void callback(char* topic, byte* payload, unsigned int length); WiFiClientSecure espClient; PubSubClient client(espClient); + + +CRGB leds[NUM_OF_LEDs]; + + void setup_wifi() { delay(10); WiFi.mode(WIFI_STA); @@ -80,36 +88,27 @@ void callback(char* topic, byte* payload, unsigned int length) { Serial.println(buffer); #endif - if (! strcmp(topic, configBlock.mqttTopicLed1)) { - if (! strcmp(buffer, "red")) { - digitalWrite(LED_1_RED, HIGH); - digitalWrite(LED_1_GREEN, LOW); - } - if (! strcmp(buffer, "green")) { - digitalWrite(LED_1_RED, LOW); - digitalWrite(LED_1_GREEN, HIGH); - } - if (! strcmp(buffer, "off")) { - digitalWrite(LED_1_RED, LOW); - digitalWrite(LED_1_GREEN, LOW); - } + + if (! strcmp(topic, configBlock.mqttTopicCommand)) { } - if (! strcmp(topic, configBlock.mqttTopicLed2)) { - if (! strcmp(buffer, "red")) { - digitalWrite(LED_2_RED, HIGH); - digitalWrite(LED_2_GREEN, LOW); - } - if (! strcmp(buffer, "green")) { - digitalWrite(LED_2_RED, LOW); - digitalWrite(LED_2_GREEN, HIGH); - } - if (! strcmp(buffer, "off")) { - digitalWrite(LED_2_RED, LOW); - digitalWrite(LED_2_GREEN, LOW); - } + if (! strcmp(topic, configBlock.mqttTopicColorAllLed)) { } + if (! strncmp(topic, configBlock.mqttTopicColorOneLed, strlen(configBlock.mqttTopicColorOneLed))) { + + } + + if (! strcmp(topic, configBlock.mqttTopicStatusAllLed)) { + uint8_t v = ! strcmp(buffer, "on") ? 255 : 0; + + for (uint8_t i = 0; i < NUM_OF_LEDs; i++) { + leds[i].r = v; + leds[i].g = v; + leds[i].b = v; + } + FastLED.show(); + } } } @@ -134,8 +133,13 @@ void reconnect() { client.publish(configBlock.mqttDebugTopic, "hello world"); client.publish(configBlock.mqttDebugTopic, WiFi.localIP().toString().c_str()); - client.subscribe(configBlock.mqttTopicLed1); - client.subscribe(configBlock.mqttTopicLed2); + client.subscribe(configBlock.mqttTopicCommand); + client.subscribe(configBlock.mqttTopicColorAllLed); + client.subscribe(configBlock.mqttTopicStatusAllLed); + char buf[66]; + strncpy(buf, configBlock.mqttTopicColorOneLed, sizeof(buf)); + strncat(buf, "/#", sizeof(buf)); + client.subscribe(buf); } else { #ifdef DEBUG Serial.print("failed, rc="); @@ -161,13 +165,10 @@ bool mqtt_connect() { void setupProduction() { - pinMode(LED_1_GREEN, OUTPUT); - pinMode(LED_1_RED, OUTPUT); - pinMode(LED_2_GREEN, OUTPUT); - pinMode(LED_2_RED, OUTPUT); - setup_wifi(); client.setServer(configBlock.mqttBroker, configBlock.mqttPort); + + FastLED.addLeds(leds, NUM_OF_LEDs); } diff --git a/pubsubclient/PubSubClient.cpp b/pubsubclient/PubSubClient.cpp new file mode 100644 index 0000000..89d0f05 --- /dev/null +++ b/pubsubclient/PubSubClient.cpp @@ -0,0 +1,670 @@ +/* + PubSubClient.cpp - A simple client for MQTT. + Nick O'Leary + http://knolleary.net +*/ + +#include "PubSubClient.h" +#include "Arduino.h" + +#ifdef ESP8266 + #define INIT_FINGERPRINT() this->fingerprint = NULL; +#else + #define INIT_FINGERPRINT() +#endif + +PubSubClient::PubSubClient() { + this->_state = MQTT_DISCONNECTED; + this->_client = NULL; + this->stream = NULL; + setCallback(NULL); + this->_available = 0; + INIT_FINGERPRINT() +} + +PubSubClient::PubSubClient(Client& client) { + this->_state = MQTT_DISCONNECTED; + setClient(client); + this->stream = NULL; + this->_available = 0; + INIT_FINGERPRINT() +} + +#ifdef ESP8266 +PubSubClient::PubSubClient(WiFiClientSecure& client, const char* fingerprint) { + this->_state = MQTT_DISCONNECTED; + setClient(client); + this->stream = NULL; + this->_available = 0; + this->fingerprint = fingerprint; +} +#endif + +PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) { + this->_state = MQTT_DISCONNECTED; + setServer(addr, port); + setClient(client); + this->stream = NULL; + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) { + this->_state = MQTT_DISCONNECTED; + setServer(addr,port); + setClient(client); + setStream(stream); + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { + this->_state = MQTT_DISCONNECTED; + setServer(addr, port); + setCallback(callback); + setClient(client); + this->stream = NULL; + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { + this->_state = MQTT_DISCONNECTED; + setServer(addr,port); + setCallback(callback); + setClient(client); + setStream(stream); + this->_available = 0; + INIT_FINGERPRINT() +} + +PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) { + this->_state = MQTT_DISCONNECTED; + setServer(ip, port); + setClient(client); + this->stream = NULL; + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) { + this->_state = MQTT_DISCONNECTED; + setServer(ip,port); + setClient(client); + setStream(stream); + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { + this->_state = MQTT_DISCONNECTED; + setServer(ip, port); + setCallback(callback); + setClient(client); + this->stream = NULL; + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { + this->_state = MQTT_DISCONNECTED; + setServer(ip,port); + setCallback(callback); + setClient(client); + setStream(stream); + this->_available = 0; + INIT_FINGERPRINT() +} + +PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) { + this->_state = MQTT_DISCONNECTED; + setServer(domain,port); + setClient(client); + this->stream = NULL; + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) { + this->_state = MQTT_DISCONNECTED; + setServer(domain,port); + setClient(client); + setStream(stream); + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { + this->_state = MQTT_DISCONNECTED; + setServer(domain,port); + setCallback(callback); + setClient(client); + this->stream = NULL; + this->_available = 0; + INIT_FINGERPRINT() +} +PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { + this->_state = MQTT_DISCONNECTED; + setServer(domain,port); + setCallback(callback); + setClient(client); + setStream(stream); + this->_available = 0; + INIT_FINGERPRINT() +} + +boolean PubSubClient::connect(const char *id) { + return connect(id,NULL,NULL,0,0,0,0); +} + +boolean PubSubClient::connect(const char *id, const char *user, const char *pass) { + return connect(id,user,pass,0,0,0,0); +} + +boolean PubSubClient::connect(const char *id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) { + return connect(id,NULL,NULL,willTopic,willQos,willRetain,willMessage); +} + +boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) { + if (!connected()) { + int result = 0; + + if (domain != NULL) { + result = _client->connect(this->domain, this->port); + } else { + result = _client->connect(this->ip, this->port); + } + +#ifdef ESP8266 + if (fingerprint != NULL) { + if (domain != NULL) { + // there's only one way to set fingerprint: using the WiFiClientSecure-based constructor, so this cast is safe + if (!static_cast(_client)->verify(fingerprint, domain)) { + _state = MQTT_TLS_BAD_SERVER_CREDENTIALS; + return false; + } + } + else { + char buffer[16]; // IPv4 only (which is what IPAddress supports anyway) + + ip.toString().toCharArray(buffer, 16); + + if (!static_cast(_client)->verify(fingerprint, buffer)) { + _state = MQTT_TLS_BAD_SERVER_CREDENTIALS; + return false; + } + } + } +#endif + + if (result == 1) { + nextMsgId = 1; + // Leave room in the buffer for header and variable length field + uint16_t length = 5; + unsigned int j; + +#if MQTT_VERSION == MQTT_VERSION_3_1 + uint8_t d[9] = {0x00,0x06,'M','Q','I','s','d','p', MQTT_VERSION}; +#define MQTT_HEADER_VERSION_LENGTH 9 +#elif MQTT_VERSION == MQTT_VERSION_3_1_1 + uint8_t d[7] = {0x00,0x04,'M','Q','T','T',MQTT_VERSION}; +#define MQTT_HEADER_VERSION_LENGTH 7 +#endif + for (j = 0;j>1); + } + } + + buffer[length++] = v; + + buffer[length++] = ((MQTT_KEEPALIVE) >> 8); + buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF); + length = writeString(id,buffer,length); + if (willTopic) { + length = writeString(willTopic,buffer,length); + length = writeString(willMessage,buffer,length); + } + + if(user != NULL) { + length = writeString(user,buffer,length); + if(pass != NULL) { + length = writeString(pass,buffer,length); + } + } + + write(MQTTCONNECT,buffer,length-5); + + lastInActivity = lastOutActivity = millis(); + + while (!available()) { + unsigned long t = millis(); + if (t-lastInActivity >= ((int32_t) MQTT_SOCKET_TIMEOUT*1000UL)) { + _state = MQTT_CONNECTION_TIMEOUT; + _client->stop(); + return false; + } + } + uint8_t llen; + uint16_t len = readPacket(&llen); + + if (len == 4) { + if (buffer[3] == 0) { + lastInActivity = millis(); + pingOutstanding = false; + _state = MQTT_CONNECTED; + return true; + } else { + _state = buffer[3]; + } + } + _client->stop(); + } else { + _state = MQTT_CONNECT_FAILED; + } + return false; + } + return true; +} + +// return and cache the available number of bytes in the client; +// remember to reduce the available count when consuming the buffer +int PubSubClient::available() { + if (_available == 0) { + _available = _client->available(); + } + return _available; +} + +// reads a byte into result +boolean PubSubClient::readByte(uint8_t * result) { + uint32_t previousMillis = millis(); + while(!available()) { + uint32_t currentMillis = millis(); + if(currentMillis - previousMillis >= ((int32_t) MQTT_SOCKET_TIMEOUT * 1000)){ + return false; + } + } + *result = _client->read(); + _available -= 1; + return true; +} + +// reads a byte into result[*index] and increments index +boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){ + uint16_t current_index = *index; + uint8_t * write_address = &(result[current_index]); + if(readByte(write_address)){ + *index = current_index + 1; + return true; + } + return false; +} + +uint16_t PubSubClient::readPacket(uint8_t* lengthLength) { + uint16_t len = 0; + if(!readByte(buffer, &len)) return 0; + bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH; + uint32_t multiplier = 1; + uint16_t length = 0; + uint8_t digit = 0; + uint16_t skip = 0; + uint8_t start = 0; + + do { + if(!readByte(&digit)) return 0; + buffer[len++] = digit; + length += (digit & 127) * multiplier; + multiplier *= 128; + } while ((digit & 128) != 0); + *lengthLength = len-1; + + if (isPublish) { + // Read in topic length to calculate bytes to skip over for Stream writing + if(!readByte(buffer, &len)) return 0; + if(!readByte(buffer, &len)) return 0; + skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2]; + start = 2; + if (buffer[0]&MQTTQOS1) { + // skip message id + skip += 2; + } + } + + for (uint16_t i = start;istream) { + if (isPublish && len-*lengthLength-2>skip) { + this->stream->write(digit); + } + } + if (len < MQTT_MAX_PACKET_SIZE) { + buffer[len] = digit; + } + len++; + } + + if (!this->stream && len > MQTT_MAX_PACKET_SIZE) { + len = 0; // This will cause the packet to be ignored. + } + + return len; +} + +boolean PubSubClient::loop() { + if (connected()) { + do { + unsigned long t = millis(); + if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) { + if (pingOutstanding) { + this->_state = MQTT_CONNECTION_TIMEOUT; + _client->stop(); + return false; + } else { + buffer[0] = MQTTPINGREQ; + buffer[1] = 0; + _client->write(buffer,2); + lastOutActivity = t; + lastInActivity = t; + pingOutstanding = true; + } + } + + if (available()) { + uint8_t llen; + uint16_t len = readPacket(&llen); + uint16_t msgId = 0; + uint8_t *payload; + if (len > 0) { + lastInActivity = t; + uint8_t type = buffer[0]&0xF0; + if (type == MQTTPUBLISH) { + if (callback) { + uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2]; /* topic length in bytes */ + memmove(buffer+llen+2,buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */ + buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */ + char *topic = (char*) buffer+llen+2; + // msgId only present for QOS>0 + if ((buffer[0]&0x06) == MQTTQOS1) { + msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1]; + payload = buffer+llen+3+tl+2; + callback(topic,payload,len-llen-3-tl-2); + + buffer[0] = MQTTPUBACK; + buffer[1] = 2; + buffer[2] = (msgId >> 8); + buffer[3] = (msgId & 0xFF); + _client->write(buffer,4); + lastOutActivity = t; + + } else { + payload = buffer+llen+3+tl; + callback(topic,payload,len-llen-3-tl); + } + } + } else if (type == MQTTPINGREQ) { + buffer[0] = MQTTPINGRESP; + buffer[1] = 0; + _client->write(buffer,2); + } else if (type == MQTTPINGRESP) { + pingOutstanding = false; + } + } + } + } while (_available > 0); // can't leave data in the buffer, or subsequent publish() calls + // may fail (axTLS is only half-duplex, so writes will fail, to + // avoid losing information) + return true; + } + return false; +} + +boolean PubSubClient::publish(const char* topic, const char* payload) { + return publish(topic,(const uint8_t*)payload,strlen(payload),false); +} + +boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) { + return publish(topic,(const uint8_t*)payload,strlen(payload),retained); +} + +boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) { + return publish(topic, payload, plength, false); +} + +boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) { + if (connected()) { + if (MQTT_MAX_PACKET_SIZE < 5 + 2+strlen(topic) + plength) { + // Too long + return false; + } + // Leave room in the buffer for header and variable length field + uint16_t length = 5; + length = writeString(topic,buffer,length); + uint16_t i; + for (i=0;i 0) { + digit |= 0x80; + } + buffer[pos++] = digit; + llen++; + } while(len>0); + + pos = writeString(topic,buffer,pos); + + rc += _client->write(buffer,pos); + + for (i=0;iwrite((char)pgm_read_byte_near(payload + i)); + } + + lastOutActivity = millis(); + + return rc == tlen + 4 + plength; +} + +boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) { + uint8_t lenBuf[4]; + uint8_t llen = 0; + uint8_t digit; + uint8_t pos = 0; + uint16_t rc; + uint16_t len = length; + do { + digit = len % 128; + len = len / 128; + if (len > 0) { + digit |= 0x80; + } + lenBuf[pos++] = digit; + llen++; + } while(len>0); + + buf[4-llen] = header; + for (int i=0;i 0) && result) { + bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining; + rc = _client->write(writeBuf,bytesToWrite); + result = (rc == bytesToWrite); + bytesRemaining -= rc; + writeBuf += rc; + } + return result; +#else + rc = _client->write(buf+(4-llen),length+1+llen); + lastOutActivity = millis(); + return (rc == 1+llen+length); +#endif +} + +boolean PubSubClient::subscribe(const char* topic) { + return subscribe(topic, 0); +} + +boolean PubSubClient::subscribe(const char* topic, uint8_t qos) { + if (qos < 0 || qos > 1) { + return false; + } + if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) { + // Too long + return false; + } + if (connected()) { + // Leave room in the buffer for header and variable length field + uint16_t length = 5; + nextMsgId++; + if (nextMsgId == 0) { + nextMsgId = 1; + } + buffer[length++] = (nextMsgId >> 8); + buffer[length++] = (nextMsgId & 0xFF); + length = writeString((char*)topic, buffer,length); + buffer[length++] = qos; + return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-5); + } + return false; +} + +boolean PubSubClient::unsubscribe(const char* topic) { + if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) { + // Too long + return false; + } + if (connected()) { + uint16_t length = 5; + nextMsgId++; + if (nextMsgId == 0) { + nextMsgId = 1; + } + buffer[length++] = (nextMsgId >> 8); + buffer[length++] = (nextMsgId & 0xFF); + length = writeString(topic, buffer,length); + return write(MQTTUNSUBSCRIBE|MQTTQOS1,buffer,length-5); + } + return false; +} + +void PubSubClient::disconnect() { + buffer[0] = MQTTDISCONNECT; + buffer[1] = 0; + _client->write(buffer,2); + _state = MQTT_DISCONNECTED; + _client->stop(); + lastInActivity = lastOutActivity = millis(); +} + +uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t pos) { + const char* idp = string; + uint16_t i = 0; + pos += 2; + while (*idp) { + buf[pos++] = *idp++; + i++; + } + buf[pos-i-2] = (i >> 8); + buf[pos-i-1] = (i & 0xFF); + return pos; +} + + +boolean PubSubClient::connected() { + boolean rc; + if (_client == NULL ) { + rc = false; + } else { + rc = (int)_client->connected(); + if (!rc) { + if (this->_state == MQTT_CONNECTED) { + this->_state = MQTT_CONNECTION_LOST; + _client->flush(); + _client->stop(); + } + } + } + return rc; +} + +PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) { + IPAddress addr(ip[0],ip[1],ip[2],ip[3]); + return setServer(addr,port); +} + +PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) { + this->ip = ip; + this->port = port; + this->domain = NULL; + return *this; +} + +PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) { + this->domain = domain; + this->port = port; + return *this; +} + +PubSubClient& PubSubClient::setCallback(MQTT_CALLBACK_SIGNATURE) { + this->callback = callback; + return *this; +} + +PubSubClient& PubSubClient::setClient(Client& client){ + this->_client = &client; + return *this; +} + +PubSubClient& PubSubClient::setStream(Stream& stream){ + this->stream = &stream; + return *this; +} + +int PubSubClient::state() { + return this->_state; +} diff --git a/pubsubclient/PubSubClient.h b/pubsubclient/PubSubClient.h new file mode 100644 index 0000000..16bf8d3 --- /dev/null +++ b/pubsubclient/PubSubClient.h @@ -0,0 +1,160 @@ +/* + PubSubClient.h - A simple client for MQTT. + Nick O'Leary + http://knolleary.net +*/ + +#ifndef PubSubClient_h +#define PubSubClient_h + +#include +#include "IPAddress.h" +#include "Client.h" +#include "Stream.h" + +#ifdef ESP8266 +#include "WiFiClientSecure.h" +#endif + +#define MQTT_VERSION_3_1 3 +#define MQTT_VERSION_3_1_1 4 + +// MQTT_VERSION : Pick the version +//#define MQTT_VERSION MQTT_VERSION_3_1 +#ifndef MQTT_VERSION +#define MQTT_VERSION MQTT_VERSION_3_1_1 +#endif + +// MQTT_MAX_PACKET_SIZE : Maximum packet size +#ifndef MQTT_MAX_PACKET_SIZE +#define MQTT_MAX_PACKET_SIZE 128 +#endif + +// MQTT_KEEPALIVE : keepAlive interval in Seconds +#ifndef MQTT_KEEPALIVE +#define MQTT_KEEPALIVE 15 +#endif + +// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds +#ifndef MQTT_SOCKET_TIMEOUT +#define MQTT_SOCKET_TIMEOUT 15 +#endif + +// MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client +// in each write call. Needed for the Arduino Wifi Shield. Leave undefined to +// pass the entire MQTT packet in each write call. +//#define MQTT_MAX_TRANSFER_SIZE 80 + +// Possible values for client.state() +#define MQTT_TLS_BAD_SERVER_CREDENTIALS -5 +#define MQTT_CONNECTION_TIMEOUT -4 +#define MQTT_CONNECTION_LOST -3 +#define MQTT_CONNECT_FAILED -2 +#define MQTT_DISCONNECTED -1 +#define MQTT_CONNECTED 0 +#define MQTT_CONNECT_BAD_PROTOCOL 1 +#define MQTT_CONNECT_BAD_CLIENT_ID 2 +#define MQTT_CONNECT_UNAVAILABLE 3 +#define MQTT_CONNECT_BAD_CREDENTIALS 4 +#define MQTT_CONNECT_UNAUTHORIZED 5 + +#define MQTTCONNECT 1 << 4 // Client request to connect to Server +#define MQTTCONNACK 2 << 4 // Connect Acknowledgment +#define MQTTPUBLISH 3 << 4 // Publish message +#define MQTTPUBACK 4 << 4 // Publish Acknowledgment +#define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1) +#define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2) +#define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3) +#define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request +#define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment +#define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request +#define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment +#define MQTTPINGREQ 12 << 4 // PING Request +#define MQTTPINGRESP 13 << 4 // PING Response +#define MQTTDISCONNECT 14 << 4 // Client is Disconnecting +#define MQTTReserved 15 << 4 // Reserved + +#define MQTTQOS0 (0 << 1) +#define MQTTQOS1 (1 << 1) +#define MQTTQOS2 (2 << 1) + +#ifdef ESP8266 +#include +#define MQTT_CALLBACK_SIGNATURE std::function callback +#else +#define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int) +#endif + +class PubSubClient { +private: + Client* _client; + uint8_t buffer[MQTT_MAX_PACKET_SIZE]; + uint16_t nextMsgId; + unsigned long lastOutActivity; + unsigned long lastInActivity; + int _available; + bool pingOutstanding; + MQTT_CALLBACK_SIGNATURE; + int available(); + uint16_t readPacket(uint8_t*); + boolean readByte(uint8_t * result); + boolean readByte(uint8_t * result, uint16_t * index); + boolean write(uint8_t header, uint8_t* buf, uint16_t length); + uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos); + IPAddress ip; + const char* domain; + uint16_t port; + Stream* stream; + int _state; + +#ifdef ESP8266 + const char* fingerprint; +#endif + +public: + PubSubClient(); + PubSubClient(Client& client); + PubSubClient(IPAddress, uint16_t, Client& client); + PubSubClient(IPAddress, uint16_t, Client& client, Stream&); + PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); + PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); + PubSubClient(uint8_t *, uint16_t, Client& client); + PubSubClient(uint8_t *, uint16_t, Client& client, Stream&); + PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); + PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); + PubSubClient(const char*, uint16_t, Client& client); + PubSubClient(const char*, uint16_t, Client& client, Stream&); + PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); + PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); + +#ifdef ESP8266 + PubSubClient(WiFiClientSecure& client, const char* fingerprint); +#endif + + PubSubClient& setServer(IPAddress ip, uint16_t port); + PubSubClient& setServer(uint8_t * ip, uint16_t port); + PubSubClient& setServer(const char * domain, uint16_t port); + PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE); + PubSubClient& setClient(Client& client); + PubSubClient& setStream(Stream& stream); + + boolean connect(const char* id); + boolean connect(const char* id, const char* user, const char* pass); + boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); + boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); + void disconnect(); + boolean publish(const char* topic, const char* payload); + boolean publish(const char* topic, const char* payload, boolean retained); + boolean publish(const char* topic, const uint8_t * payload, unsigned int plength); + boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); + boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); + boolean subscribe(const char* topic); + boolean subscribe(const char* topic, uint8_t qos); + boolean unsubscribe(const char* topic); + boolean loop(); + boolean connected(); + int state(); +}; + + +#endif diff --git a/snippet/snippet1 b/snippet/snippet1 new file mode 100755 index 0000000..987408e Binary files /dev/null and b/snippet/snippet1 differ diff --git a/snippet/snippet1.c b/snippet/snippet1.c new file mode 100644 index 0000000..593a7a0 --- /dev/null +++ b/snippet/snippet1.c @@ -0,0 +1,12 @@ +#include +#include + +int main() { + char text1[15] = "Wolfgang/11"; + char text2[15] = "Wolfgang"; + + if (0 == strncmp(text1, text2, strlen(text2))) { + printf("match\n"); + } +} +