first commit

This commit is contained in:
Nicholas O'Leary 2009-02-02 11:12:39 +00:00
commit 0cd448ffa5
6 changed files with 290 additions and 0 deletions

12
CHANGES.txt Normal file
View File

@ -0,0 +1,12 @@
1.1
* Reduced size of library
* Added support for Will messages
* Clarified licensing - see LICENSE.txt
1.0
* Only Quality of Service (QOS) 0 messaging is supported
* The maximum message size, including header, is 128 bytes
* The keepalive interval is set to 30 seconds
* No support for Will messages

20
LICENSE.txt Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2008-2009 Nicholas O'Leary
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

190
PubSubClient.cpp Normal file
View File

@ -0,0 +1,190 @@
/*
PubSubClient.cpp - A simple client for MQTT.
Nicholas O'Leary
http://knolleary.net
*/
#include "WConstants.h"
#include "PubSubClient.h"
#include "Client.h"
#include "string.h"
#define MQTTCONNECT 1<<4
#define MQTTPUBLISH 3<<4
#define MQTTSUBSCRIBE 8<<4
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, void (*callback)(char*,uint8_t*,int)) : _client(ip,port) {
this->callback = callback;
}
int PubSubClient::connect(char *id) {
return connect(id,0,0,0,0);
}
int PubSubClient::connect(char *id, char* willTopic, uint8_t willQos, uint8_t willRetain, char* willMessage) {
if (!_client.connected()) {
if (_client.connect()) {
nextMsgId = 1;
uint8_t d[9] = {0x00,0x06,0x4d,0x51,0x49,0x73,0x64,0x70,0x03};
uint8_t length = 0;
int j;
for (j = 0;j<9;j++) {
buffer[length++] = d[j];
}
if (willTopic) {
buffer[length++] = 0x06|(willQos<<3)|(willRetain<<5);
} else {
buffer[length++] = 0x02;
}
buffer[length++] = 0;
buffer[length++] = (KEEPALIVE/500);
length = writeString(id,buffer,length);
if (willTopic) {
length = writeString(willTopic,buffer,length);
length = writeString(willMessage,buffer,length);
}
write(MQTTCONNECT,buffer,length);
while (!_client.available()) {}
uint8_t len = readPacket();
if (len == 4 && buffer[3] == 0) {
lastActivity = millis();
return 1;
}
_client.stop();
}
}
return 0;
}
uint8_t PubSubClient::readPacket() {
uint8_t len = 0;
buffer[len++] = _client.read();
uint8_t multiplier = 1;
uint8_t length = 0;
uint8_t digit = 0;
do {
digit = _client.read();
buffer[len++] = digit;
length += (digit & 127) * multiplier;
multiplier *= 128;
} while ((digit & 128) != 0);
for (int i = 0;i<length;i++)
{
if (len < MAX_PACKET_SIZE) {
buffer[len++] = _client.read();
} else {
_client.read();
len = 0; // This will cause the packet to be ignored.
}
}
return len;
}
int PubSubClient::loop() {
if (_client.connected()) {
long t = millis();
if (t - lastActivity > KEEPALIVE) {
_client.write(192);
_client.write(0);
lastActivity = t;
}
if (_client.available()) {
uint8_t len = readPacket();
if (len > 0) {
uint8_t type = buffer[0]>>4;
if (type == 3) { // PUBLISH
if (callback) {
uint8_t tl = (buffer[2]<<3)+buffer[3];
char topic[tl+1];
for (int i=0;i<tl;i++) {
topic[i] = buffer[4+i];
}
topic[tl] = 0;
// ignore msgID - only support QoS 0 subs
uint8_t *payload = buffer+4+tl;
callback(topic,payload,len-4-tl);
}
} else if (type == 12) { // PINGREG
_client.write(208);
_client.write(0);
lastActivity = t;
}
}
}
return 1;
}
return 0;
}
int PubSubClient::publish(char* topic, char* payload) {
return publish(topic,(uint8_t*)payload,strlen(payload));
}
int PubSubClient::publish(char* topic, uint8_t* payload, uint8_t plength) {
if (_client.connected()) {
uint8_t length = writeString(topic,buffer,0);
int i;
for (i=0;i<plength;i++) {
buffer[length++] = payload[i];
}
//header |= 1; retain
write(MQTTPUBLISH,buffer,length);
return 1;
}
return 0;
}
int PubSubClient::write(uint8_t header, uint8_t* buf, uint8_t length) {
_client.write(header);
_client.write(length);
for (int i=0;i<length;i++) {
_client.write(buf[i]);
}
return 0;
}
void PubSubClient::subscribe(char* topic) {
if (_client.connected()) {
uint8_t length = 2;
nextMsgId++;
buffer[0] = nextMsgId >> 8;
buffer[1] = nextMsgId - (buffer[0]<<8);
length = writeString(topic, buffer,length);
buffer[length++] = 0; // Only do QoS 0 subs
write(MQTTSUBSCRIBE,buffer,length);
}
}
void PubSubClient::disconnect() {
_client.write(224);
_client.write(0);
_client.stop();
lastActivity = millis();
}
uint8_t PubSubClient::writeString(char* string, uint8_t* buf, uint8_t pos) {
char* idp = string;
uint8_t i = 0;
pos += 2;
while (*idp) {
buf[pos++] = *idp++;
i++;
}
buf[pos-i-2] = 0;
buf[pos-i-1] = i;
return pos;
}
int PubSubClient::connected() {
return (int)_client.connected();
}

39
PubSubClient.h Normal file
View File

@ -0,0 +1,39 @@
/*
PubSubClient.h - A simple client for MQTT.
Nicholas O'Leary
http://knolleary.net
*/
#ifndef PubSubClient_h
#define PubSubClient_h
#include "Client.h"
#define MAX_PACKET_SIZE 128
#define KEEPALIVE 15000 // max value = 255000
class PubSubClient {
private:
Client _client;
uint8_t buffer[MAX_PACKET_SIZE];
uint8_t nextMsgId;
long lastActivity;
void (*callback)(char*,uint8_t*,int);
uint8_t readPacket();
int write(uint8_t header, uint8_t* buf, uint8_t length);
uint8_t writeString(char* string, uint8_t* buf, uint8_t pos);
public:
PubSubClient(uint8_t *, uint16_t, void(*)(char*,uint8_t*,int));
int connect(char *);
int connect(char*, char*, uint8_t, uint8_t, char*);
void disconnect();
int publish(char *, char *);
int publish(char *, uint8_t *, uint8_t);
void subscribe(char *);
int loop();
int connected();
};
#endif

4
README Normal file
View File

@ -0,0 +1,4 @@
A client library for the Arduino Ethernet Shield that provides support for MQTT.
Nicholas O'Leary
http://knolleary.net/arduino-client-for-mqtt/

25
keywords.txt Executable file
View File

@ -0,0 +1,25 @@
#######################################
# Syntax Coloring Map For Ultrasound
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
PubSubClient KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
connect KEYWORD2
disconnect KEYWORD2
publish KEYWORD2
subscribe KEYWORD2
loop KEYWORD2
connected KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################