diff --git a/.cproject b/.cproject index 439b340..6dc5729 100644 --- a/.cproject +++ b/.cproject @@ -4,16 +4,16 @@ - + - + @@ -41,9 +41,7 @@ - - - + @@ -53,16 +51,16 @@ - + - + @@ -91,8 +89,6 @@ - - diff --git a/MQTTSNPacket/samples/IBMIoTUDPExample.cpp b/MQTTSNPacket/samples/IBMIoTUDPExample.cpp new file mode 100644 index 0000000..5f2f4db --- /dev/null +++ b/MQTTSNPacket/samples/IBMIoTUDPExample.cpp @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - refactoring to remove STL and other changes + *******************************************************************************/ + +#define WARN printf + +#include "MQTTClient.h" + +#define DEFAULT_STACK_SIZE -1 + +#include "linux.cpp" + +#include + +// Configuration values needed to connect to IBM IoT Cloud +#define ORG "quickstart" // For a registered connection, replace with your org +#define ID "8002f7f1ad23" // For a registered connection, replace with your id +#define AUTH_TOKEN "" // For a registered connection, replace with your auth-token +#define TYPE "mytype" // For a registered connection, replace with your type + +#define MQTT_PORT 1883 +#define MQTT_TLS_PORT 8883 +#define IBM_IOT_PORT MQTT_PORT + +#define MQTT_MAX_PACKET_SIZE 250 + +bool quickstartMode = true; +char org[11] = ORG; +char type[30] = TYPE; +char id[30] = ID; // mac without colons +char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode + +bool connected = false; +const char* joystickPos = "CENTRE"; +int blink_interval = 0; + + + +int connect(MQTT::Client* client, IPStack* ipstack) +{ + const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com"; + + char hostname[strlen(org) + strlen(iot_ibm) + 1]; + sprintf(hostname, "%s%s", org, iot_ibm); + DEBUG("connecting to %s\n", hostname); + int rc = ipstack->connect(hostname, IBM_IOT_PORT); + if (rc != 0) + return rc; + + // Construct clientId - d:org:type:id + char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; + sprintf(clientId, "d:%s:%s:%s", org, type, id); + DEBUG("clientid is %s\n", clientId); + + // MQTT Connect + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.MQTTVersion = 4; + data.clientID.cstring = clientId; + + if (!quickstartMode) + { + data.username.cstring = "use-token-auth"; + data.password.cstring = auth_token; + } + + if ((rc = client->connect(data)) == 0) + connected = true; + return rc; +} + + +int getConnTimeout(int attemptNumber) +{ // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute + // after 20 attempts, retry every 10 minutes + return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; +} + + +void attemptConnect(MQTT::Client* client, IPStack* ipstack) +{ + int retryAttempt = 0; + connected = false; + + while (connect(client, ipstack) != 0) + { + int timeout = getConnTimeout(++retryAttempt); + WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); + + // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed + // or maybe just add the proper members to do this disconnect and call attemptConnect(...) + + sleep(timeout); + } +} + + +int publish(MQTT::Client* client, IPStack* ipstack) +{ + MQTT::Message message; + char* pubTopic = "iot-2/evt/status/fmt/json"; + static const char* joypos[] = {"LEFT", "RIGHT", "CENTRE", "UP", "DOWN"}; + + char buf[250]; + sprintf(buf, + "{\"d\":{\"myName\":\"IoT mbed\",\"accelX\":%0.4f,\"accelY\":%0.4f,\"accelZ\":%0.4f,\"temp\":%0.4f,\"joystick\":\"%s\",\"potentiometer1\":%0.4f,\"potentiometer2\":%0.4f}}", + (rand() % 10) * 2.0, (rand() % 10) * 2.0, (rand() % 10) * 2.0, (rand() % 10) + 18.0, joypos[rand() % 5], (rand() % 10) * 30.0, (rand() % 10) * 30.0); + //MMA.x(), MMA.y(), MMA.z(), sensor.temp(), joystickPos, ain1.read(), ain2.read()); + message.qos = MQTT::QOS0; + message.retained = false; + message.dup = false; + message.payload = (void*)buf; + message.payloadlen = strlen(buf); + + LOG("Publishing %s\n", buf); + return client->publish(pubTopic, message); +} + + +void messageArrived(MQTT::MessageData& md) +{ + MQTT::Message &message = md.message; + char topic[md.topicName.lenstring.len + 1]; + + sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data); + + LOG("Message arrived on topic %s: %.*s\n", topic, message.payloadlen, message.payload); + + // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/ + char* start = strstr(topic, "/cmd/") + 5; + int len = strstr(topic, "/fmt/") - start; + + if (memcmp(start, "blink", len) == 0) + { + char payload[message.payloadlen + 1]; + sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload); + + char* pos = strchr(payload, '}'); + if (pos != NULL) + { + *pos = '\0'; + if ((pos = strchr(payload, ':')) != NULL) + { + int blink_rate = atoi(pos + 1); + blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate); + } + } + } + else + WARN("Unsupported command: %.*s\n", len, start); +} + + +int main() +{ + quickstartMode = (strcmp(org, "quickstart") == 0); + + IPStack ipstack = IPStack(); + MQTT::Client client(ipstack); + + attemptConnect(&client, &ipstack); + + if (!quickstartMode) + { + int rc = 0; + if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0) + WARN("rc from MQTT subscribe is %d\n", rc); + } + + int count = 0; + while (true) + { + if (++count == 100) + { // Publish a message every second + if (publish(&client, &ipstack) != 0) + attemptConnect(&client, &ipstack); // if we have lost the connection + count = 0; + } + client.yield(10); // allow the MQTT client to receive messages + } +} + diff --git a/samples/build b/MQTTSNPacket/samples/build similarity index 100% rename from samples/build rename to MQTTSNPacket/samples/build diff --git a/MQTTSNPacket/samples/linux/udp/build b/MQTTSNPacket/samples/linux/udp/build new file mode 100644 index 0000000..b600bb1 --- /dev/null +++ b/MQTTSNPacket/samples/linux/udp/build @@ -0,0 +1,7 @@ +gcc -Wall -c lowlevel.c -Os -s +gcc -Wall qos0pub.c lowlevel.o -I ../src ../src/MQTTSNSerializePublish.c ../src/MQTTSNPacket.c ../src/MQTTSNConnectClient.c -o qos0pub -Os -s +gcc -Wall qos0pub_register.c lowlevel.o -I ../src ../src/MQTTSNSerializePublish.c ../src/MQTTSNDeserializePublish.c ../src/MQTTSNPacket.c ../src/MQTTSNConnectClient.c -o qos0pub_register -Os -s +gcc -Wall qos-1pub.c lowlevel.o -I ../src ../src/MQTTSNSerializePublish.c ../src/MQTTSNPacket.c -o qos-1pub -Os -s +gcc -Wall qos-1pub_extended.c lowlevel.o -I ../src ../src/MQTTSNSerializePublish.c ../src/MQTTSNPacket.c -o qos-1pub_extended -Os -s +gcc -Wall qos1pub.c lowlevel.o -I ../src ../src/MQTTSNSerializePublish.c ../src/MQTTSNDeserializePublish.c ../src/MQTTSNPacket.c ../src/MQTTSNConnectClient.c -o qos1pub -Os -s +gcc -Wall pub0sub1.c lowlevel.o -I ../src ../src/MQTTSNSerializePublish.c ../src/MQTTSNDeserializePublish.c ../src/MQTTSNPacket.c ../src/MQTTSNConnectClient.c ../src/MQTTSNSubscribeClient.c -o pub0sub1 -Os -s diff --git a/MQTTSNPacket/samples/linux/udp/lowlevel.c b/MQTTSNPacket/samples/linux/udp/lowlevel.c new file mode 100644 index 0000000..89cb3f6 --- /dev/null +++ b/MQTTSNPacket/samples/linux/udp/lowlevel.c @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * 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 + * Sergio R. Caprile - "commonalization" from prior samples and/or documentation extension + *******************************************************************************/ + +#include + +#if !defined(SOCKET_ERROR) + /** error in socket operation */ + #define SOCKET_ERROR -1 +#endif + +#if defined(WIN32) +/* default on Windows is 64 - increase to make Linux and Windows the same */ +#define FD_SETSIZE 1024 +#include +#include +#define MAXHOSTNAMELEN 256 +#define EAGAIN WSAEWOULDBLOCK +#define EINTR WSAEINTR +#define EINVAL WSAEINVAL +#define EINPROGRESS WSAEINPROGRESS +#define EWOULDBLOCK WSAEWOULDBLOCK +#define ENOTCONN WSAENOTCONN +#define ECONNRESET WSAECONNRESET +#define ioctl ioctlsocket +#define socklen_t int +#else +#define INVALID_SOCKET SOCKET_ERROR +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#if defined(WIN32) +#include +#else +#include +#include +#endif + +/** +This simple low-level implementation assumes a single connection for a single thread. Thus, a static +variable is used for that connection. +On other scenarios, the user must solve this by taking into account that the current implementation of +MQTTSNPacket_read() has a function pointer for a function call to get the data to a buffer, but no provisions +to know the caller or other indicator (the socket id): int (*getfn)(unsigned char*, int) +*/ +static int mysock = INVALID_SOCKET; + +int Socket_error(char* aString, int sock) +{ +#if defined(WIN32) + int errno; +#endif + +#if defined(WIN32) + errno = WSAGetLastError(); +#endif + if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && errno != EWOULDBLOCK) + { + if (strcmp(aString, "shutdown") != 0 || (errno != ENOTCONN && errno != ECONNRESET)) + { + int orig_errno = errno; + char* errmsg = strerror(errno); + + printf("Socket error %d (%s) in %s for socket %d\n", orig_errno, errmsg, aString, sock); + } + } + return errno; +} + + +int lowlevel_sendPacketBuffer(char* host, int port, unsigned char* buf, int buflen) +{ + struct sockaddr_in cliaddr; + int rc = 0; + + memset(&cliaddr, 0, sizeof(cliaddr)); + cliaddr.sin_family = AF_INET; + cliaddr.sin_addr.s_addr = inet_addr(host); + cliaddr.sin_port = htons(port); + + if ((rc = sendto(mysock, buf, buflen, 0, (const struct sockaddr*)&cliaddr, sizeof(cliaddr))) == SOCKET_ERROR) + Socket_error("sendto", mysock); + else + rc = 0; + return rc; +} + + +int lowlevel_getdata(unsigned char* buf, int count) +{ + int rc = recvfrom(mysock, buf, count, 0, NULL, NULL); + //printf("received %d bytes count %d\n", rc, (int)count); + return rc; +} + +/** +return >=0 for a socket descriptor, <0 for an error code +*/ +int lowlevel_open() +{ + mysock = socket(AF_INET, SOCK_DGRAM, 0); + if (mysock == INVALID_SOCKET) + return Socket_error("socket", mysock); + + return mysock; +} + +int lowlevel_close() +{ +int rc; + + rc = shutdown(mysock, SHUT_WR); + rc = close(mysock); + + return rc; +} diff --git a/MQTTSNPacket/samples/linux/udp/lowlevel.h b/MQTTSNPacket/samples/linux/udp/lowlevel.h new file mode 100644 index 0000000..bb0966f --- /dev/null +++ b/MQTTSNPacket/samples/linux/udp/lowlevel.h @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * 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 + * Sergio R. Caprile - "commonalization" from prior samples and/or documentation extension + *******************************************************************************/ + +int lowlevel_sendPacketBuffer(char* host, int port, unsigned char* buf, int buflen); +int lowlevel_getdata(unsigned char* buf, int count); +int lowlevel_open(void); +int lowlevel_close(void); diff --git a/MQTTSNPacket/samples/linux/udp/pub0sub1.c b/MQTTSNPacket/samples/linux/udp/pub0sub1.c new file mode 100644 index 0000000..a0d864c --- /dev/null +++ b/MQTTSNPacket/samples/linux/udp/pub0sub1.c @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * 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 + * Sergio R. Caprile - clarifications and/or documentation extension + * + * Description: + * Normal topic name is automatically registered at subscription, then + * a message is published and the node receives it itself + *******************************************************************************/ + +#include +#include +#include + +#include "MQTTSNPacket.h" +#include "lowlevel.h" + + +int main(int argc, char** argv) +{ + int rc = 0; + int mysock; + unsigned char buf[200]; + int buflen = sizeof(buf); + MQTTSN_topicid topic; + unsigned char* payload = (unsigned char*)"mypayload"; + int payloadlen = strlen((char*)payload); + int len = 0; + unsigned char dup = 0; + int qos = 1; + unsigned char retained = 0; + short packetid = 1; + char *topicname = "a long topic name"; + char *host = "127.0.0.1"; + int port = 1883; + MQTTSNPacket_connectData options = MQTTSNPacket_connectData_initializer; + unsigned short topicid; + + mysock = lowlevel_open(); + if(mysock < 0) + return mysock; + + if (argc > 1) + host = argv[1]; + + if (argc > 2) + port = atoi(argv[2]); + + printf("Sending to hostname %s port %d\n", host, port); + + options.clientID.cstring = "pub0sub1 MQTT-SN"; + len = MQTTSNSerialize_connect(buf, buflen, &options); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + /* wait for connack */ + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_CONNACK) + { + int connack_rc = -1; + + if (MQTTSNDeserialize_connack(&connack_rc, buf, buflen) != 1 || connack_rc != 0) + { + printf("Unable to connect, return code %d\n", connack_rc); + goto exit; + } + else + printf("connected rc %d\n", connack_rc); + } + else + goto exit; + + + /* subscribe */ + printf("Subscribing\n"); + topic.type = MQTTSN_TOPIC_TYPE_NORMAL; + topic.data.long_.name = topicname; + topic.data.long_.len = strlen(topic.data.long_.name); + len = MQTTSNSerialize_subscribe(buf, buflen, 0, 2, packetid, &topic); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_SUBACK) /* wait for suback */ + { + unsigned short submsgid; + int granted_qos; + unsigned char returncode; + + rc = MQTTSNDeserialize_suback(&granted_qos, &topicid, &submsgid, &returncode, buf, buflen); + if (granted_qos != 2 || returncode != 0) + { + printf("granted qos != 2, %d return code %d\n", granted_qos, returncode); + goto exit; + } + else + printf("suback topic id %d\n", topicid); + } + else + goto exit; + + printf("Publishing\n"); + /* publish with short name */ + topic.type = MQTTSN_TOPIC_TYPE_NORMAL; + topic.data.id = topicid; + ++packetid; + len = MQTTSNSerialize_publish(buf, buflen, dup, qos, retained, packetid, + topic, payload, payloadlen); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + /* wait for puback */ + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_PUBACK) + { + unsigned short packet_id, topic_id; + unsigned char returncode; + + if (MQTTSNDeserialize_puback(&topic_id, &packet_id, &returncode, buf, buflen) != 1 || returncode != MQTTSN_RC_ACCEPTED) + printf("Unable to publish, return code %d\n", returncode); + else + printf("puback received, msgid %d topic id %d\n", packet_id, topic_id); + } + else + goto exit; + + printf("Receive publish\n"); + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_PUBLISH) + { + unsigned short packet_id; + int qos, payloadlen; + unsigned char* payload; + unsigned char dup, retained; + MQTTSN_topicid pubtopic; + + if (MQTTSNDeserialize_publish(&dup, &qos, &retained, &packet_id, &pubtopic, + &payload, &payloadlen, buf, buflen) != 1) + printf("Error deserializing publish\n"); + else + printf("publish received, id %d qos %d\n", packet_id, qos); + + if (qos == 1) + { + len = MQTTSNSerialize_puback(buf, buflen, pubtopic.data.id, packet_id, MQTTSN_RC_ACCEPTED); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + if (rc == 0) + printf("puback sent\n"); + } + } + else + goto exit; + + len = MQTTSNSerialize_disconnect(buf, buflen, 0); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + +exit: + lowlevel_close(); + + return 0; +} diff --git a/MQTTSNPacket/samples/linux/udp/qos-1pub.c b/MQTTSNPacket/samples/linux/udp/qos-1pub.c new file mode 100644 index 0000000..0f1cced --- /dev/null +++ b/MQTTSNPacket/samples/linux/udp/qos-1pub.c @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * 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 + * Sergio R. Caprile - clarifications and/or documentation extension + * + * Description: + * A qos -1 message can be sent without connecting + * Short topic name used to avoid registration process + *******************************************************************************/ + +#include +#include +#include + +#include "MQTTSNPacket.h" +#include "lowlevel.h" + + +int main(int argc, char** argv) +{ + int rc = 0; + int mysock; + unsigned char buf[200]; + int buflen = sizeof(buf); + MQTTSN_topicid topic; + unsigned char* payload = (unsigned char*)"mypayload"; + int payloadlen = strlen((char*)payload); + int len = 0; + int dup = 0; + int qos = 3; + int retained = 0; + short packetid = 0; + char *host = "127.0.0.1"; + int port = 1883; + + mysock = lowlevel_open(); + if(mysock < 0) + return mysock; + + if (argc > 1) + host = argv[1]; + + if (argc > 2) + port = atoi(argv[2]); + + printf("Sending to hostname %s port %d\n", host, port); + + /* publish with short name */ + topic.type = MQTTSN_TOPIC_TYPE_SHORT; + memcpy(topic.data.short_name, "tt", 2); + len = MQTTSNSerialize_publish(buf, buflen, dup, qos, retained, packetid, + topic, payload, payloadlen); + + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + lowlevel_close(); + + return 0; +} diff --git a/MQTTSNPacket/samples/linux/udp/qos-1pub_extended.c b/MQTTSNPacket/samples/linux/udp/qos-1pub_extended.c new file mode 100644 index 0000000..28a1015 --- /dev/null +++ b/MQTTSNPacket/samples/linux/udp/qos-1pub_extended.c @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * 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 + * Sergio R. Caprile - clarifications and/or documentation extension + * + * Description: + * Extension to the specs in which a node can send a normal (long) topic name inside the + * payload area to avoid the registration process and the usage of short/predefined types + *******************************************************************************/ + +#include +#include +#include + +#include "MQTTSNPacket.h" +#include "lowlevel.h" + + +int main(int argc, char** argv) +{ + int rc = 0; + int mysock; + unsigned char buf[200]; + int buflen = sizeof(buf); + MQTTSN_topicid topic; + unsigned char* payload = (unsigned char*)"mypayload"; + int payloadlen = strlen((char*)payload); + int len = 0; + int dup = 0; + int qos = 3; + int retained = 0; + short packetid = 0; + char *topicname = "a long topic name"; + char *host = "127.0.0.1"; + int port = 1883; + + mysock = lowlevel_open(); + if(mysock < 0) + return mysock; + + if (argc > 1) + host = argv[1]; + + if (argc > 2) + port = atoi(argv[2]); + + printf("Sending to hostname %s port %d\n", host, port); + + topic.type = MQTTSN_TOPIC_TYPE_NORMAL; + topic.data.long_.name = topicname; + topic.data.long_.len = strlen(topicname); + + len = MQTTSNSerialize_publish(buf, buflen, dup, qos, retained, packetid, + topic, payload, payloadlen); + + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + lowlevel_close(); + + return 0; +} diff --git a/MQTTSNPacket/samples/linux/udp/qos0pub.c b/MQTTSNPacket/samples/linux/udp/qos0pub.c new file mode 100644 index 0000000..96c9a2f --- /dev/null +++ b/MQTTSNPacket/samples/linux/udp/qos0pub.c @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * 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 + * Sergio R. Caprile - clarifications and/or documentation extension + * + * Description: + * Short topic name used to avoid registration process + *******************************************************************************/ + +#include +#include +#include + +#include "MQTTSNPacket.h" +#include "lowlevel.h" + + +int main(int argc, char** argv) +{ + int rc = 0; + int mysock; + unsigned char buf[200]; + int buflen = sizeof(buf); + MQTTSN_topicid topic; + unsigned char* payload = (unsigned char*)"mypayload"; + int payloadlen = strlen((char*)payload); + int len = 0; + int dup = 0; + int qos = 0; + int retained = 0; + short packetid = 0; +// char *topicname = "a long topic name"; + char *host = "127.0.0.1"; + int port = 1883; + MQTTSNPacket_connectData options = MQTTSNPacket_connectData_initializer; + + mysock = lowlevel_open(); + if(mysock < 0) + return mysock; + + if (argc > 1) + host = argv[1]; + + if (argc > 2) + port = atoi(argv[2]); + + printf("Sending to hostname %s port %d\n", host, port); + + options.clientID.cstring = "myclientid"; + len = MQTTSNSerialize_connect(buf, buflen, &options); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + /* wait for connack */ + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_CONNACK) + { + int connack_rc = -1; + + if (MQTTSNDeserialize_connack(&connack_rc, buf, buflen) != 1 || connack_rc != 0) + { + printf("Unable to connect, return code %d\n", connack_rc); + goto exit; + } + else + printf("connected rc %d\n", connack_rc); + } + else + goto exit; + + + /* publish with short name */ + topic.type = MQTTSN_TOPIC_TYPE_SHORT; + memcpy(topic.data.short_name, "tt", 2); + len = MQTTSNSerialize_publish(buf, buflen, dup, qos, retained, packetid, + topic, payload, payloadlen); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + printf("rc %d from send packet for publish length %d\n", rc, len); + +exit: + lowlevel_close(); + + return 0; +} diff --git a/samples/qos0pub_register.c b/MQTTSNPacket/samples/linux/udp/qos0pub_register.c similarity index 87% rename from samples/qos0pub_register.c rename to MQTTSNPacket/samples/linux/udp/qos0pub_register.c index d8be047..5d3023f 100644 --- a/samples/qos0pub_register.c +++ b/MQTTSNPacket/samples/linux/udp/qos0pub_register.c @@ -23,7 +23,7 @@ #include #include "MQTTSNPacket.h" -#include "transport.h" +#include "lowlevel.h" int main(int argc, char** argv) @@ -47,7 +47,7 @@ int main(int argc, char** argv) MQTTSNPacket_connectData options = MQTTSNPacket_connectData_initializer; unsigned short topicid; - mysock = transport_open(); + mysock = lowlevel_open(); if(mysock < 0) return mysock; @@ -61,10 +61,10 @@ int main(int argc, char** argv) options.clientID.cstring = "myclientid"; len = MQTTSNSerialize_connect(buf, buflen, &options); - rc = transport_sendPacketBuffer(host, port, buf, len); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); /* wait for connack */ - if (MQTTSNPacket_read(buf, buflen, transport_getdata) == MQTTSN_CONNACK) + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_CONNACK) { int connack_rc = -1; @@ -84,9 +84,9 @@ int main(int argc, char** argv) topicstr.cstring = topicname; topicstr.lenstring.len = strlen(topicname); len = MQTTSNSerialize_register(buf, buflen, 0, packetid, &topicstr); - rc = transport_sendPacketBuffer(host, port, buf, len); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); - if (MQTTSNPacket_read(buf, buflen, transport_getdata) == MQTTSN_REGACK) /* wait for regack */ + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_REGACK) /* wait for regack */ { unsigned short submsgid; unsigned char returncode; @@ -110,12 +110,12 @@ int main(int argc, char** argv) ++packetid; len = MQTTSNSerialize_publish(buf, buflen, dup, qos, retained, packetid, topic, payload, payloadlen); - rc = transport_sendPacketBuffer(host, port, buf, len); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); printf("rc %d from send packet for publish length %d\n", rc, len); exit: - transport_close(); + lowlevel_close(); return 0; } diff --git a/MQTTSNPacket/samples/linux/udp/qos1pub.c b/MQTTSNPacket/samples/linux/udp/qos1pub.c new file mode 100644 index 0000000..60001eb --- /dev/null +++ b/MQTTSNPacket/samples/linux/udp/qos1pub.c @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * 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 + * Sergio R. Caprile - clarifications and/or documentation extension + * + * Description: + * Short topic name used to avoid registration process + *******************************************************************************/ + +#include +#include +#include + +#include "MQTTSNPacket.h" +#include "lowlevel.h" + + +int main(int argc, char** argv) +{ + int rc = 0; + int mysock; + unsigned char buf[200]; + int buflen = sizeof(buf); + MQTTSN_topicid topic; + unsigned char* payload = (unsigned char*)"mypayload"; + int payloadlen = strlen((char*)payload); + int len = 0; + int dup = 0; + int qos = 1; + int retained = 0; + short packetid = 1; + char *host = "127.0.0.1"; + int port = 1883; + MQTTSNPacket_connectData options = MQTTSNPacket_connectData_initializer; + + mysock = lowlevel_open(); + if(mysock < 0) + return mysock; + + if (argc > 1) + host = argv[1]; + + if (argc > 2) + port = atoi(argv[2]); + + printf("Sending to hostname %s port %d\n", host, port); + + options.clientID.cstring = "myclientid"; + len = MQTTSNSerialize_connect(buf, buflen, &options); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + /* wait for connack */ + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_CONNACK) + { + int connack_rc = -1; + + if (MQTTSNDeserialize_connack(&connack_rc, buf, buflen) != 1 || connack_rc != 0) + { + printf("Unable to connect, return code %d\n", connack_rc); + goto exit; + } + else + printf("connected rc %d\n", connack_rc); + } + else + goto exit; + + /* publish with short name */ + topic.type = MQTTSN_TOPIC_TYPE_SHORT; + memcpy(topic.data.short_name, "tt", 2); + len = MQTTSNSerialize_publish(buf, buflen - len, dup, qos, retained, packetid, + topic, payload, payloadlen); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + + /* wait for puback */ + if (MQTTSNPacket_read(buf, buflen, lowlevel_getdata) == MQTTSN_PUBACK) + { + unsigned short packet_id, topic_id; + unsigned char returncode; + + if (MQTTSNDeserialize_puback(&topic_id, &packet_id, &returncode, buf, buflen) != 1 || returncode != MQTTSN_RC_ACCEPTED) + printf("Unable to publish, return code %d\n", returncode); + else + printf("puback received, id %d\n", packet_id); + } + else + goto exit; + + len = MQTTSNSerialize_disconnect(buf, buflen, 0); + rc = lowlevel_sendPacketBuffer(host, port, buf, len); + +exit: + lowlevel_close(); + + return 0; +} diff --git a/samples/pub0sub1.c b/MQTTSNPacket/samples/pub0sub1.c similarity index 100% rename from samples/pub0sub1.c rename to MQTTSNPacket/samples/pub0sub1.c diff --git a/samples/qos-1pub.c b/MQTTSNPacket/samples/qos-1pub.c similarity index 100% rename from samples/qos-1pub.c rename to MQTTSNPacket/samples/qos-1pub.c diff --git a/samples/qos-1pub_extended.c b/MQTTSNPacket/samples/qos-1pub_extended.c similarity index 100% rename from samples/qos-1pub_extended.c rename to MQTTSNPacket/samples/qos-1pub_extended.c diff --git a/samples/qos0pub.c b/MQTTSNPacket/samples/qos0pub.c similarity index 100% rename from samples/qos0pub.c rename to MQTTSNPacket/samples/qos0pub.c diff --git a/MQTTSNPacket/samples/qos0pub_register.c b/MQTTSNPacket/samples/qos0pub_register.c new file mode 100644 index 0000000..c1bbba4 --- /dev/null +++ b/MQTTSNPacket/samples/qos0pub_register.c @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * 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 + * Sergio R. Caprile - clarifications and/or documentation extension + * + * Description: + * Normal topic name used to show registration process + *******************************************************************************/ + +#include +#include +#include +#include + +#include "MQTTSNPacket.h" +#include "transport.h" + + +int main(int argc, char** argv) +{ + int rc = 0; + int mysock; + unsigned char buf[500]; + int buflen = sizeof(buf); + MQTTSN_topicid topic; + MQTTSNString topicstr; + int len = 0; + int retained = 0; + char *topicname = "iot-2/evt/status/fmt/json"; + char *host = "127.0.0.1"; + int port = 20000; + MQTTSNPacket_connectData options = MQTTSNPacket_connectData_initializer; + unsigned short topicid; + + mysock = transport_open(); + if(mysock < 0) + return mysock; + + if (argc > 1) + host = argv[1]; + + if (argc > 2) + port = atoi(argv[2]); + + printf("Sending to hostname %s port %d\n", host, port); + + options.clientID.cstring = "d:quickstart:udptest:9002f7f1ad23"; + len = MQTTSNSerialize_connect(buf, buflen, &options); + rc = transport_sendPacketBuffer(host, port, buf, len); + + /* wait for connack */ + if (MQTTSNPacket_read(buf, buflen, transport_getdata) == MQTTSN_CONNACK) + { + int connack_rc = -1; + + if (MQTTSNDeserialize_connack(&connack_rc, buf, buflen) != 1 || connack_rc != 0) + { + printf("Unable to connect, return code %d\n", connack_rc); + goto exit; + } + else + printf("connected rc %d\n", connack_rc); + } + else + { + printf("could not connect to gateway\n"); + goto exit; + } + + /* register topic name */ + printf("Registering\n"); + int packetid = 1; + topicstr.cstring = topicname; + topicstr.lenstring.len = strlen(topicname); + len = MQTTSNSerialize_register(buf, buflen, 0, packetid, &topicstr); + rc = transport_sendPacketBuffer(host, port, buf, len); + + if (MQTTSNPacket_read(buf, buflen, transport_getdata) == MQTTSN_REGACK) /* wait for regack */ + { + unsigned short submsgid; + unsigned char returncode; + + rc = MQTTSNDeserialize_regack(&topicid, &submsgid, &returncode, buf, buflen); + if (returncode != 0) + { + printf("return code %d\n", returncode); + goto exit; + } + else + printf("regack topic id %d\n", topicid); + } + else + goto exit; + + while (1) + { + if (1) + { + /* publish with obtained id */ + printf("Publishing\n"); + topic.type = MQTTSN_TOPIC_TYPE_NORMAL; + topic.data.id = topicid; + static const char* joypos[] = {"SN-LEFT", "SN-RIGHT", "SN-CENTRE", "SN-UP", "SN-DOWN"}; + + unsigned char payload[250]; + int payloadlen = sprintf((char*)payload, + "{\"d\":{\"myName\":\"IoT mbed\",\"accelX\":%0.4f,\"accelY\":%0.4f,\"accelZ\":%0.4f,\"temp\":%0.4f,\"joystick\":\"%s\",\"potentiometer1\":%0.4f,\"potentiometer2\":%0.4f}}", + (rand() % 10) * 2.0, (rand() % 10) * 2.0, (rand() % 10) * 2.0, (rand() % 10) + 18.0, joypos[rand() % 5], (rand() % 10) * 30.0, (rand() % 10) * 30.0); + len = MQTTSNSerialize_publish(buf, buflen, 0, 0, retained, 0, topic, payload, payloadlen); + rc = transport_sendPacketBuffer(host, port, buf, len); + + printf("rc %d from send packet for publish length %d\n", rc, len); + } + sleep(1); // Publish a message every second + } +exit: + transport_close(); + + return 0; +} diff --git a/samples/qos1pub.c b/MQTTSNPacket/samples/qos1pub.c similarity index 100% rename from samples/qos1pub.c rename to MQTTSNPacket/samples/qos1pub.c diff --git a/samples/transport.c b/MQTTSNPacket/samples/transport.c similarity index 100% rename from samples/transport.c rename to MQTTSNPacket/samples/transport.c diff --git a/samples/transport.h b/MQTTSNPacket/samples/transport.h similarity index 100% rename from samples/transport.h rename to MQTTSNPacket/samples/transport.h diff --git a/src/MQTTSNConnect.h b/MQTTSNPacket/src/MQTTSNConnect.h similarity index 100% rename from src/MQTTSNConnect.h rename to MQTTSNPacket/src/MQTTSNConnect.h diff --git a/src/MQTTSNConnectClient.c b/MQTTSNPacket/src/MQTTSNConnectClient.c similarity index 100% rename from src/MQTTSNConnectClient.c rename to MQTTSNPacket/src/MQTTSNConnectClient.c diff --git a/src/MQTTSNConnectServer.c b/MQTTSNPacket/src/MQTTSNConnectServer.c similarity index 100% rename from src/MQTTSNConnectServer.c rename to MQTTSNPacket/src/MQTTSNConnectServer.c diff --git a/src/MQTTSNDeserializePublish.c b/MQTTSNPacket/src/MQTTSNDeserializePublish.c similarity index 99% rename from src/MQTTSNDeserializePublish.c rename to MQTTSNPacket/src/MQTTSNDeserializePublish.c index dbf1bdc..9aae227 100644 --- a/src/MQTTSNDeserializePublish.c +++ b/MQTTSNPacket/src/MQTTSNDeserializePublish.c @@ -116,7 +116,7 @@ exit: /** * Deserializes the supplied (wire) buffer into an ack - * @param type returned integer - the MQTT packet type + * @param packettype returned integer - the MQTT packet type * @param packetid returned integer - the MQTT packet identifier * @param buf the raw buffer data, of the correct length determined by the remaining length field * @param buflen the length in bytes of the data in the supplied buffer diff --git a/src/MQTTSNPacket.c b/MQTTSNPacket/src/MQTTSNPacket.c similarity index 100% rename from src/MQTTSNPacket.c rename to MQTTSNPacket/src/MQTTSNPacket.c diff --git a/src/MQTTSNPacket.h b/MQTTSNPacket/src/MQTTSNPacket.h similarity index 100% rename from src/MQTTSNPacket.h rename to MQTTSNPacket/src/MQTTSNPacket.h diff --git a/src/MQTTSNPublish.h b/MQTTSNPacket/src/MQTTSNPublish.h similarity index 100% rename from src/MQTTSNPublish.h rename to MQTTSNPacket/src/MQTTSNPublish.h diff --git a/src/MQTTSNSearch.h b/MQTTSNPacket/src/MQTTSNSearch.h similarity index 100% rename from src/MQTTSNSearch.h rename to MQTTSNPacket/src/MQTTSNSearch.h diff --git a/src/MQTTSNSearchClient.c b/MQTTSNPacket/src/MQTTSNSearchClient.c similarity index 100% rename from src/MQTTSNSearchClient.c rename to MQTTSNPacket/src/MQTTSNSearchClient.c diff --git a/src/MQTTSNSearchServer.c b/MQTTSNPacket/src/MQTTSNSearchServer.c similarity index 100% rename from src/MQTTSNSearchServer.c rename to MQTTSNPacket/src/MQTTSNSearchServer.c diff --git a/src/MQTTSNSerializePublish.c b/MQTTSNPacket/src/MQTTSNSerializePublish.c similarity index 100% rename from src/MQTTSNSerializePublish.c rename to MQTTSNPacket/src/MQTTSNSerializePublish.c diff --git a/src/MQTTSNSubscribe.h b/MQTTSNPacket/src/MQTTSNSubscribe.h similarity index 100% rename from src/MQTTSNSubscribe.h rename to MQTTSNPacket/src/MQTTSNSubscribe.h diff --git a/src/MQTTSNSubscribeClient.c b/MQTTSNPacket/src/MQTTSNSubscribeClient.c similarity index 100% rename from src/MQTTSNSubscribeClient.c rename to MQTTSNPacket/src/MQTTSNSubscribeClient.c diff --git a/src/MQTTSNSubscribeServer.c b/MQTTSNPacket/src/MQTTSNSubscribeServer.c similarity index 100% rename from src/MQTTSNSubscribeServer.c rename to MQTTSNPacket/src/MQTTSNSubscribeServer.c diff --git a/src/MQTTSNUnsubscribe.h b/MQTTSNPacket/src/MQTTSNUnsubscribe.h similarity index 100% rename from src/MQTTSNUnsubscribe.h rename to MQTTSNPacket/src/MQTTSNUnsubscribe.h diff --git a/src/MQTTSNUnsubscribeClient.c b/MQTTSNPacket/src/MQTTSNUnsubscribeClient.c similarity index 100% rename from src/MQTTSNUnsubscribeClient.c rename to MQTTSNPacket/src/MQTTSNUnsubscribeClient.c diff --git a/src/MQTTSNUnsubscribeServer.c b/MQTTSNPacket/src/MQTTSNUnsubscribeServer.c similarity index 99% rename from src/MQTTSNUnsubscribeServer.c rename to MQTTSNPacket/src/MQTTSNUnsubscribeServer.c index 57dd7bc..4dff54f 100644 --- a/src/MQTTSNUnsubscribeServer.c +++ b/MQTTSNPacket/src/MQTTSNUnsubscribeServer.c @@ -16,7 +16,6 @@ #include "StackTrace.h" #include "MQTTSNPacket.h" -#include int MQTTSNDeserialize_unsubscribe(unsigned short* packetid, MQTTSN_topicid* topicFilter, unsigned char* buf, int buflen) diff --git a/src/StackTrace.h b/MQTTSNPacket/src/StackTrace.h similarity index 100% rename from src/StackTrace.h rename to MQTTSNPacket/src/StackTrace.h diff --git a/test/build_test b/MQTTSNPacket/test/build_test similarity index 100% rename from test/build_test rename to MQTTSNPacket/test/build_test diff --git a/test/test1.c b/MQTTSNPacket/test/test1.c similarity index 100% rename from test/test1.c rename to MQTTSNPacket/test/test1.c diff --git a/test/test2.c b/MQTTSNPacket/test/test2.c similarity index 100% rename from test/test2.c rename to MQTTSNPacket/test/test2.c